KubeCon NA 2019(Day1) 参加メモ

# Day1

自分用参加・聴講メモ
※Keynoteは省略

![7C436797-C7C2-48D7-9E95-E19FD6B37F3E.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314463/8e620eaa-205b-3dde-7773-c244ca4f2168.jpeg)

## [Kubernetes at Cruise: Two Years of Multitenancy](https://static.sched.com/hosted_files/kccncna19/14/Kubernetes%20Multitenancy%20-%20Karl%20Isenberg%20-%20KubeCon%20NA%202019.pdf)

資料公開なし

Cruiseは自動運転の会社
Cluster: 12-26
64or32vCPUで1,000node
(セッション情報では100,000Pod, 4000Nodeとあったけど、間違ってそう...)

![1D327FB7-5C6D-4C94-A451-BDA0739E1EF2.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314463/0ac7f7a8-6a8f-e09c-db78-c4a6606a7fe1.jpeg)

![AEBC2E6D-6F92-4712-BA81-1F78E3243317.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314463/73bb570d-752e-5398-b9e9-1621bb2be3d1.jpeg)

Multitenancyは論理的に隔離されているが、物理的には統合されている
CruiseはK8sのNamespaceで論理的に隔離している
クラスタ数を少なくすることで、Costを減らす狙いがあった

![F776A026-C1F3-4B36-BC24-9793A7DAB7D3.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314463/cc80c68d-0b8a-5961-9004-fafd5026870d.jpeg)

秘密情報の管理にVaultを使っている
ClientであるDAYTONAをinitContainerで使っている

また、[k-rail](https://github.com/cruise-automation/k-rail)という、Cruiseで作ったOSSでWorkloadのPolicyを管理している

Team単位でNamespaceを切っている

[Google Groups for GKE](https://cloud.google.com/kubernetes-engine/docs/how-to/role-based-access-control#groups-setup-gsuite)でのRBACでもPermission Layerでの隔離を実現している

[isopod](https://github.com/cruise-automation/isopod)も自作のOSSでYAMLなしで、DSLで設定が書ける

Junoというインフラ管理ツールでGCP Project, Vault Namespace, K8sNamespaceなどをUIで管理している
※Junoは非公開

Networkは、NATGateway, Ingress/Egress QPS, Bandwidthを工夫

![2A2BB223-6CA7-4E7D-9AB4-D319B017C85E.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314463/8efc2d0b-5204-0a37-5352-fb117fddeab6.jpeg)

Firewallは、Network PolicyやIstioの機能などを活用して、Virtual Firewallで隔離

![0D6F78B3-266E-47BC-98D6-5FCE8249365A.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314463/c7280c3f-3189-c54f-0e22-1c3c4a5574a2.jpeg)

Shard Ingressとして、VMでNginx Ingressを立てている

![D7A16190-06C3-4690-844E-28D30F444E6D.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314463/68e8894e-7d60-a712-a81b-798ff20ed2e3.jpeg)

Shared DNSとして、Node Local DNSやNode PoolごとのDNSを立てている

![1544EB9B-8251-44C7-AD06-39E734DB8DF9.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314463/af6fd91e-71c5-c12c-6df6-b923e2d7f2e3.jpeg)

Shared Observabilityとして、Log, Metrics, Tracing, Dashboardを工夫

#### 感想

巨大クラスタの運用について、話が聞けるかと思って受講したが、内容はMultitenancyでの論理的な隔離性を様々な観点(Namespace, Secret, Permission, Policy, RBAC, Network, etc...)で担保している、という内容が主軸だった
そのため(自分が)望んでいた内容ではなかったが、Multitenancyで考慮しなければならない観点については充分学べたと思う


## [Rethinking the K8s DNS for the Modern Enterprise](https://static.sched.com/hosted_files/kccncna19/97/Rethinking%20the%20K8s%20DNS%20for%20the%20Modern%20Enterprise.pdf)

※どうやら発表用の資料と公開用の資料が違う模様。詳しく知りたい場合はYoutubeの方が良さそう

Multiple ClusterやMultiple Cloudになると、DNSによるService Discoveryが重要になる

DNSにはObservabilityとSecurityが求められる
 - TenantごとのTelemetry
 - (DoT/DoHで)DNSのQureyのEncryotion

K8sのDNS(kube-dns)はTenantごとの隔離性がなく、動的設定変更ができず、Secureでもない

DNS ObservabilityとSecurity用に[ServiceMonitor](https://coreos.com/operators/prometheus/docs/latest/user-guides/cluster-monitoring.html)というCRDを使う
またDNS Filtering用のCRDを使って、EnvoyをProxy(代理人パターン)として、Proxy LayerでFilteringを行う

DNS Filterを使うことで、DNSとProxy間はTLS通信ができ、ProxyのFilterChainでDNS QueryのFilteringもできる

#### 感想

Multi Clusterに関わると、DNSの問題は避けられず、CoreDNSを起点にしてソリューションを考える必要がどうしても出てくる
EnvoyをProxyとして、Observability/Securityを満たす、という観点は非常に面白かった
おそらくMulti Clusterでのベストプラクティスになる気がしている


## [Managing Helm Deployments with Gitops at CERN](https://static.sched.com/hosted_files/kccncna19/4e/Managing%20Helm%20Deployments%20with%20GitOPS%20at%20CERN.pdf)

物理マシンの話から始まり、Cloud → Containerにメリットを感じて利用している
Docker, Kubernetes, エコシステムの学習コストがある中、マニフェストの管理としてHelmを利用している

Chart RepositoryとしてS3にChartを保管している
S3をバックエンドとして、ChartMuseumを利用している

![6CB54379-3596-4A08-AA6E-2EE6F60DD46D.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314463/864da04d-d99e-c869-bab8-d75fd9b4f9bf.jpeg)

Secret管理

![5A3CB54A-6846-4DC3-8926-9EFE8EFFAC21.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314463/d78e7dd2-07f3-2a9a-8237-9af0aa1ce7fc.jpeg)
![8251B072-BEC8-465C-98A2-C7B0943F51DD.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314463/d04c9b8e-f9e7-30f4-5bce-c582e8ab2c02.jpeg)

CIと統合して、Git pushするとHelm lintとHelm testが走る

CDにはFluxを使ったGitOpsを実践している
Flux + Helm CRD + Helm Operator
HelmのRelease(Helm上の、Chartのデプロイの単位)を[FluxのCR YAML](https://docs.fluxcd.io/projects/helm-operator/en/latest/references/helmrelease-custom-resource.html)として宣言的にK8sにApplyする

![5A43F16F-15D3-463A-9BDB-BCD03825F044.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314463/10bfa52c-7b2a-fdf1-1f52-6a25a03f9c6c.jpeg)

![C7761FBC-A39F-4C58-84A1-B27483683352.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314463/8e34226f-7d0e-4933-926d-858334a736f2.jpeg)

一つのHelm Releaseで全てのAddons(Prometheus, 他)を管理している

次のステップとしては、Helm v3やChartの保守の自動化、Service Meshを利用した高度なDeployなど

![57D7F76E-F0F6-4C17-821F-38D5AD6F0A67.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314463/42e4eb85-a00e-71e8-0109-785b3d7c22b4.jpeg)

#### 感想

仕事でもHelmを利用しているので、使っているツールやツールの使い方はある程度想像できたが、CIでの活用で、Helm lintやHelm testをきちんと行なっているのには思っている以上にしっかりやっていて好感がもてた(自分のところはできていない)

また、Fluxも名前は知っていたもののHelm ReleaseをCustom Resourceとして宣言できることは知らなかった。
FluxでHelm ReleaseをSingle Source of Truthとして宣言的にまとめて、GitOpsでCDできることの柔軟性にも魅力を感じた

## [Admission Webhooks: Configuration and Debugging Best Practices](https://static.sched.com/hosted_files/kccncna19/ce/Admission%20Webhooks%20Configuration%20and%20Debugging%20Best%20Practices.pdf)

Admission WebhookはKubernetesの拡張方法の一つ
簡単にいうと、API ServerがRequestを処理している間に、任意の処理を挟むことができる
Admission Controlには、Mutating(変更フェーズ)・Validating(検証フェーズ)の二つがある

Kubernetesに提供されているAdmission ControlとしてはResouceQuotaがある

Admission Webhookという形で、APIのRequeustを処理する途中に、任意のWebserverにhookさせることができる

#### Best Practice

1.(Admission Webhookの結果に)冪等性を保つ
Mutating Webhookがなぜ2回呼ばれるか？
→順番を保つのが難しいから。順番によって結果が違ってくる

[Reinvocation policy](https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#reinvocation-policy)で制御できる

2.オブジェクトの全バージョンをインタセプトする

例えばDeployment Resourceで、extension/beta, apps/beta, apps/v1などのバージョン互換性を保つ
[MatchPolicy](https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#matching-requests-matchpolicy)を設定する

3.Availability

Admission Webhookは、APIのRequestをWebhook Serverに飛ばしてから(Webhook Serverでの)処理が始まるため、API Latencyが長くなりやすい
Timeoutが設定できるので、それでLatencyが遅くなりすぎないようにする

4.オブジェクトの最後の状態を保証する

Mutation Webhookを使うのであれば、Validation Webhookで結果を保証するようにする

5.Side Effect
 - 副作用はなるべく避ける
 - Reconcile Mechanismを目指す
 - [sideEffect](https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#side-effects)フィールドを設定して、副作用を避ける

6.kube-systemのNamespaceでのオペレーションを避ける

System Critical(kube-system)を安全のために避ける
Namespaceが存在している場合、Namespace ScopeでだけWebhookを飛ばすことができるように設定できるので、設定する

#### Debug編

・Webhookが失敗・拒否された時は400か500のステータスが返るが、理由は多岐にわたる
failurePolicy:Ignoreを使うと、Timeout/Connection/Malformed Errorが起きた時に無視できる

・response・Metricsを収集する

・何がどこでどのように起きたかを確かめたい時は、Audit Logを設定する

mutation.webhook.admission.k8s.io/round_{}_index_{}
patch.webhook.admission.k8s.io/round_{}_index_{}
e.g. mutation.webhook.admission.k8s.io/round_0_index_1のような形式でAudit Eventを記録する
Requestごとにindexがインクリメントされる

#### 結論

・BestPracticeに従って、Admission Webhookを設定する
・MetricsとAudit Logを使って、Monitoring, Tracingできるようにする

#### 感想

Admission WebhookのBest Practiceについて非常に参考になった
最近Webhook Serverを書いているが、知らなかったこと・やったほうが良いができていないことに気づけたのは良い収穫だった


## [Scaling Kubernetes to Thousands of Nodes Across Multiple Clusters](https://static.sched.com/hosted_files/kccncna19/46/KubeCon%202019%20Scaling%20Kubernetes%20to%20Thousands%20of%20Nodes.pdf)

AirbnbでのMultiple ClusterへとScaleしたお話

(Clusterの)Nodeが450台からスタート
→ "Multiple Clusterを考え始めよう"

KubernetesのSLOとして、Nodeの上限は5000台まで
実際に動かせるとしたら2500台ほど
Alibabaは10,000Nodeを動かしたBlog postがあって、素晴らしい仕事をした

450台 → 900台 → 1800台とNodeがどんどん増えていき、etcdがOOMKillされた
"etcdがOOMKillされたらまずいよね？"

とうとう2400台(限界)まで来て、Multile Clusterへ

Multiple Clusterにすることで
・Workloadをどのクラスタでもランダムにアサインできる
・Clusterはマシンとメモリの単なる集まり
・Service(Discovery)が作られると、どのクラスタにするか設定で選ぶことができる

AirbnbのService Meshフレームワーク「SmartStack」だと、Type: NodePortでServiceを払い出して、Node LevelのIPを指定する

VPC CNIを使うと、NodeのIPではなく、PodのIPでCluster間を直接Pod to Podで通信できる

##### どうClusterを管理しているか

Clusterを他のWorkload(Pod, Service)のように扱う
Clusterに必要な要素を一つのユニットとしてデプロイする
具体的にはComponentをHelm Chartとして書き、umbrella chartとして扱う
自作のフレームワーク(kube-gen)でアプリケーションをデプロイする
裏側ではChef, terraformも使っている
10分未満でデプロイできる

Cluster Typeという、オブジェクト指向でいうClassを用意し、ClusterをInstanceとしてデプロイする

##### 変化との向き合い方

→ 変化を簡単にすると、より変化が起きやすくなる

変えるのが簡単なもの(新規クラスタ, アップグレード, IAM追加)もあれば、全然簡単ではないもの(Network, Certificate,etc)もある

現在も仕掛かり中とのことだが、すごい規模だ...
・22 Cluster Type
・36 Cluster
・7000+ Nodes

#### 感想

ある程度以上(1000台以上)にClusterのサイズが育っていくと、取るべき方法はだいたい二極化しているように感じる
1. Masterを強化, 改造する(ebay, alibabaなど)
2. Multiple Clusterにする(今回のAirbnb)

今回は2のMulti Clusterの話だったが、非常に参考になる話だった(仕事でもペインポイント)
Multi ClusterになるとOperation Costの関係で、当然一個一個のClusterを盆栽を育てるように大切に育てていける訳ではないため、どうしても自動化にモチベーションが向かっていく
日本ではたとえばZLabさんやサイボウズさんのクラスタ自動構築・運用の仕組みが有名だが、一つの巨大なサービスを支えるCluster(Multi Cluster)の自動化というのは初めて聞けたので非常に興味深かった

Cluster越しにPod間で通信する仕組みは、(毎回LoadBalancer立てるわけにもいかないと思うし)Multi Clusterでは必須になると思う

Cluster TypeとInstanceとしてのCluster、という考え方も汎用性が高そうで面白い仕組みだと思った
以下は推測だが、
VM Layer          -< Chef, Terraform
K8s(Master) Layer -< Helm(umbrella chart)
Application Layer -< kube-gen
という対応関係でCluster(とWorkload)をデプロイしていると思うが、慣れ親しんでいるツールで実現可能性が高そうなのも良い
(たとえばこれを全部CRD+CustomControllerでやるとなると、作るのと保守にコストがかかることが想像できる)

問題があるとしたら、そうしたCluster構築・デプロイツールを各社が実装しないと実際問題使い物にならない、というところだろうか
Multiple Clusterの必要性自体はまだまだ少数派だと思うが、これから、よりエコシステムが育ってほしい
(個人的には、SIG Multiclusterに期待している)