Slide 1

Slide 1 text

Production Ready Kubernetes に必要な15のこと 2019/11/28 CloudNative Days Kansai 2019

Slide 2

Slide 2 text

2 名前: 磯 賢大(@go_vargo) 所属: 株式会社コロプラ    インフラグループ 第2チーム 趣味: Kubernetesの裏側の仕組みを知ること / コントリビューション(minikube) 出版: 「実践Helm」インプレスR&D 自己紹介 外部発表: ・コロプラが実践しているSpinnakerを用いたデプロイ戦略 @ kubernetes Meetup #21 ・ゼロから始めるKubernetes Controller @ kubernetes Meetup #23 ・Docker Meetup, CloudNative Meetup, 他...

Slide 3

Slide 3 text

3 ・本番環境のKubernetesマニフェストに最低限必要な7のこと https://speakerdeck.com/masayaaoyama/jkd1812-prd-manifests ・Kubernetesを運用したことで学んだアンチパターン https://speakerdeck.com/goto_hidenobu/cloudnativedaystokyo-2019-slide ・The Twelve-Factor App https://12factor.net/ ・Cluster Ready Checklist for Kubernetes https://www.weave.works/blog/production-ready-checklist-kubernetes ・Application Checklist for Kubernetes https://www.weave.works/blog/application-checklist-kubernetes ・12 Kubernetes configuration best practices https://www.stackrox.com/post/2019/09/12-kubernetes-configuration-best-practices/ 参考にした資料

Slide 4

Slide 4 text

4 本講演で目指すこと - Kubernetesプラットフォームを構築する上で、押さえておきたい考慮点をまとめること ※ 特に分散システムならではの、本番環境を想定した、気をつけておきたい箇所 注意点 - 本講演で想定しているのは、Webアプリケーション基盤におけるKubernetesです - Kubernetesクラスタ自体をどうセキュアに構築すべきか、という点には触れていません ※クラスタが構築されている上で、気をつけるべきものをピックアップしています - 自社でのベストプラクティスの考え方も入れていますが、 全てが全てベストプラクティスとは考えてはいません(模索しているものもあります) - 自社で各テーマをどのように取り組んでいるかを随所で紹介していますが、 あくまで一例と捉えていただけると幸いです 目的

Slide 5

Slide 5 text

5 1. CI/CD 2. Manifest Management 3. Observability 4. Initial Processing 5. Graceful Shutdown 6. HealthCheck 7. Config Injection 8. Maintenance / Upgrade Agenda 9. Resource Management 10. Scheduling 11. Scaling 12. Security / Auth / Authz 13. External Traffic 14. Tuning 15. Stateful Application - Appendix

Slide 6

Slide 6 text

1. CI/CD

Slide 7

Slide 7 text

7 CI/CD CI/CDはOrchestrationの手前に あるものです。 Production Ready Kubernetes には必須と言えます。 = CI/CDはきちんと作りましょう CI/CDのツールは、非常に多くの 選択肢があります。 何を使うかはユースケースに合わ せて検討しましょう。 出典: CNCF TraipMap https://github.com/cncf/trailmap

Slide 8

Slide 8 text

8 CI/CD CNCF Product 出典: CNCF Landscape https://landscape.cncf.io 時代はCI/CD戦国時代です。 CI/CDを実現するためのツールの選択肢は 非常に多くあります。 KubernetesがDeclarative APIであることを活 かして、マニフェストファイルを用いたCI/CD として、GitOpsモデルでデリバリすることを 想定したプロダクトも多くあります。 参考: Kubernetes anti-patterns: Let's do GitOps, not CIOps! https://www.weave.works/blog/kuberne tes-anti-patterns-let-s-do-gitops-not-ci ops

Slide 9

Slide 9 text

9 GitOps with Single Source of Truth 引用元: https://www.weave.works/technologies/gitops/ 参考: 5 GitOps Best Practices https://blog.argoproj.io/5-gitops-best-practices-d95cb0cbe9ff

Slide 10

Slide 10 text

10 CI/CD @ Colopl CI: GitLab Runner CD: Spinnaker Spinnakerで、多様なデプロイ戦略を ステージという形で表現できるため 採用しました カナリアリリースの他に、 新規環境構築のPipelineなどを構築 事例詳細は下記資料に記載 コロプラが実践しているSpinnaker を用いたデプロイ戦略 https://speakerdeck.com/govargo/depl oy-strategy-with-spinnaker-at-colopl

Slide 11

Slide 11 text

2. Manifest Management

Slide 12

Slide 12 text

12 マニフェスト管理 Kubernetesの管理には直結しない部分で 重要になるものの一つが マニフェスト管理です。 Infrastructure as Codeであるため、 マニフェストファイルを管理する 必要があります。 マニフェスト管理にも代表的なツールや 管理方法に種類があります。 どちらが優れている、というものでは ないので、ユースケースに合わせて 選択しましょう。 出典: CNCF TraipMap https://github.com/cncf/trailmap

Slide 13

Slide 13 text

13 マニフェスト管理の考え方 Mono Repository Multi Repository or アプリケーション ソース インフラ マニフェスト アプリケーション ソース インフラ マニフェスト

Slide 14

Slide 14 text

14 Helm ・CNCF Incubating Projectのプロダクトで、Kubernetesのパッケージマネージャ ・Chartと呼ばれるマニフェストテンプレートをK8sクラスタにインストールする ・Releaseという単位で、インストールやアップデート、削除などを実施可能 ・values.yamlと呼ばれる設定値を記載したYAMLによって挙動を変更できる Kustomize ・kubectl(v1.14〜)に統合されているマニフェスト管理ツール ・overlayによって、環境ごとにマニフェストの設定値(variants)を変更できる ・YAMLを生成するGenerator機能や、YAMLの変更を行うTransform機能がある ・他SIGs(※) Project(Kubebuilder)でも活用されている よく使われるマニフェスト管理ツール ※SIGs https://github.com/kubernetes/community/blob/master/sig-list.md

Slide 15

Slide 15 text

15 マニフェスト管理にはHelm(v2)を利用しています(Helm3に移行検証中)。 プロジェクト横断で使える共通のHelm ChartをGit Submodule用に用意しており、 values.yaml(マニフェストファイルの設定値)のみProject固有のGitリポジトリで 管理しています。 マニフェスト管理 @ Colopl 公式: https://helm.sh/ Project A / ┣ Chart A Directory / ┃ ┣ Common Chart A / ┃ ┣ values.dev.yaml ┃ ┣ values.stg.yaml ┃ ┗ values.prd.yaml Project B / ┣ Chart B Directory / ┃ ┣ Common Chart B / ...... マニフェスト管理の例 よく使うコマンド類はスクリプト化しています e.g. マニフェスト差分比較ツール

Slide 16

Slide 16 text

3. Monitoring

Slide 17

Slide 17 text

17 Observability コンテナオーケストレーションに 必要なものの一つがObservability です。 Observabilityを築く観点として ・Monitoring ・Logging ・Tracing が挙げられます 出典: CNCF TraipMap https://github.com/cncf/trailmap

Slide 18

Slide 18 text

18 MonitoringのOSS Productとして最も有力な選択肢がCNCF Graduated Projectの Prometheusです。ある程度大規模になるとThanosやCortexのような冗長化の仕組 みが必要になります。Metrics Agentのスケジューリングも注意が必要です(後述)。 Monitoringの仕組みとして、Managedサービスを使うケースも多いでしょう。 Monitoring 出典: CNCF Landscape https://landscape.cncf.io

Slide 19

Slide 19 text

19 Metricsには、Cluster(Infrastructure)としてのMetricsとApplicationとしてのMetricsの 2種類のMetricsがあります。 たとえばPrometheusの場合、exporterを使うことでInfrastructure〜Middlewareの 主要なMetricsを取得することができます(i.e. node_exporter, cAdvisor)。 特に、Application側はMetricsを透過的に取得できるように作りましょう。 Metrics import ( “github.com/prometheus/client_golang/prometheus” ... ) … func handler(w http.ResponseWriter, r *http.Request) { requests.Inc() w.Write([]byte(“OK”)) } リクエストが来ると、カウンタをインクリメントする例

Slide 20

Slide 20 text

20 コンテナオーケストレーションの常套手段として、ログはコンテナの標準出力/標準 エラー出力に表示し、各ノードに配置したAgentがそのログを収集し、Aggregator Serverにログを集約するモデル(Aggregator Pattern)が一般的です。 その際、CNCF Graduated Projectであるfluentdが採用されることが多いです。 また、CNCF ProjectのLogging OSSとして、Grafana LabのGrafana lokiに注目が 集まっています。 Logging 出典: CNCF Landscape https://landscape.cncf.io Grafana loki: https://grafana.com/oss/loki/

Slide 21

Slide 21 text

21 TracingはアプリケーションレイヤーでのObservabilityを確保するために有効な手法 です。ログに出ないエラーやパフォーマンスの調査、システムの状態把握などに 役立ちます。 CNCF ProductとしてはOpenCencusとOpenTracingの2Projectを統合した、 OpenTelemetryが2020年1Qに公開予定です。 Tracing OpenTelemetry: https://opentelemetry.io/ 出典: CNCF Landscape https://landscape.cncf.io

Slide 22

Slide 22 text

22 Monitoring: Prometheus + Grafanaを使ってMonitoring Prometheusだけで負荷分散できない時はVictoriaMetrics を使って水平スケーリングしています。 Logging: DaemonSetで配置したFluentdでログを収集し、 Stackdriver Loggingにてフィルターします。 Tracing: 以前はOpenCencusをアプリケーションコードに組み込 んで、Stackdriver Tracingで結果を確認していました。 現在はDatadog APMを活用しています Observability @ Colopl Monitoring Logging Stackdriver Logging + Tracing Stackdriver Tracing + Datadog APM

Slide 23

Slide 23 text

4. Initial Processing

Slide 24

Slide 24 text

24 Container Orchestration ここから先はKubernetes上での 考慮点を挙げていきます 出典: CNCF TraipMap https://github.com/cncf/trailmap

Slide 25

Slide 25 text

25 Kubernetes上で稼働するアプリケーションは、いつ・どこでプロセスを開始して、 プロセスを終了するかが分かりません。 コンテナのスケーリングをオーケストレータが自動で決定しているためです。 そのため、コンテナ起動時に事前に初期処理をする必要があるケースがあります。 たとえば、初期化が必要な例として次のケースがあります。 ・ファイルを作成する ・ファイル/ディレクトリのパーミッションを変更する ・Warmupを行う(DBへのSessionを作る, データの初期ロードを行う, etc...) ・etc... Initial Processing

Slide 26

Slide 26 text

26 Kubernetesでの初期処理/前処理の設定方法として下記の方法があります。 1. initContainer ・Main Container起動前に、初期化用のコンテナを起動する 2. Entrypoint ・Container起動時のスクリプト内で、初期化処理を記載しておく 3. SideCar ・Main Containerと並行して、Containerを立ち上げてデータを更新する 4. postStart ・Container内のプロセスが起動した直後に、スクリプトを実行する Kubernetesにおける初期処理の実行方法

Slide 27

Slide 27 text

27 Initial Processing @ Colopl コンテナのEntrypointの処理の中で、コストのかかるWarmupを、プロセス起動前に行う Process Start #!/bin/bash artisan db:warmup artisan master-data:preload echo 1 > /app/.health startup.sh entrypoint.sh Warmup 前処理 HealthCheck ステータス更新 APP DB Warmup Preload

Slide 28

Slide 28 text

5. Graceful Shutdown

Slide 29

Slide 29 text

29 (再掲)Kubernetes上で稼働するアプリケーションは、いつ・どこでプロセスを 開始して、プロセスを終了するかが分かりません。 コンテナのスケーリングをオーケストレータが自動で決定しているためです。 PodがTerminatingする時、コンテナ内のプロセスはGracefulにシャットダウン (Graceful Shutdown)し、突然のプロセス終了に対して堅牢であるべきです たとえば、後処理が必要な例として次のケースがあります。 ・リクエスト受付を停止して、残っているセッションの処理を完了する(Webアプリ) ・オンメモリ上のデータを外部DataSourceに移行する(ミドルウェア) ・実行中のジョブをワーカーキューに戻す(バッチ) ・etc… Graceful Shutdown 参考: The TWELVE-FACTOR-APP Disposability https://12factor.net/disposability

Slide 30

Slide 30 text

30 Kubernetesでの後処理の設定方法として下記の方法があります。 1. Entrypoint ・コードやスクリプト内でシグナルハンドリングする 2. preStop ・コンテナ停止時にHookで起動する Graceful Shutdownになるよう停止処理を書く Kubernetesにおける後処理の実行方法 preStop SIGTERM SIGKILL Delete Pod Running SIGTERM送信 SIGKILL送信 Pod削除 terminationGracePeriodSeconds(default: 30s) Terminatin g 任意のスクリプト やhttpGetなど Terminated Pod Terminating LifeCycle

Slide 31

Slide 31 text

31 Graceful Shutdown @ Colopl spec.containers[].lifecycle.preStopでGraceful Shutdown用のスクリプトを実行 Process End #!/bin/bash echo 0 > /app/.health sleep 28 PID=$(cat /run/nginx.pid) nginx -s quit while [ -d /proc/$PID ]; do sleep 0.1 done ... shutdown.sh プロセス停止確認 HealthCheck ステータス更新 リクエスト受付停止 (Endpoint削除 + LBサービスアウト) Nginxプロセス停止 APP Terminate APP Running APP Running リクエスト停止 サービスアウト

Slide 32

Slide 32 text

6. HealthCheck

Slide 33

Slide 33 text

33 Kubernetesのメリットの一つが自己回復性です。 Kubernetes上で実行するプロセスはPodを適切に廃棄・再起動するように、 コンテナ内のプロセスが起動しているか・正常に稼働しているかをチェックする 必要があります。 Kubernetes上のコンテナプロセスの監視に、次の二つの項目を設定ができます。 ・LivenessProbe: コンテナが生きているかどうかをヘルスチェック ・ReadinessProbe: コンテナが応答可能かどうか(正常稼働か)をヘルスチェック LivenessProbeが失敗すると、コンテナを再起動します。 ReadinessProbeが失敗すると、PodがService ResourceのEndpointから外されて、 通信が届かなくなります(サービスアウト)。 HealthCheck on Kubernetes

Slide 34

Slide 34 text

34 LivenessProbe & ReadinessProbe Fail APP Running APP Running APP Running LivenessProbe: Failed APP Running APP Terminate APP Running ReadinessProbe: Failed ReadinessProbe LivenessProbe

Slide 35

Slide 35 text

35 The Gotchas of Zero-Downtime Traffic /w Kubernetes - Leigh Capili, Weaveworks Zero-Downtimeでの(Web)サービスの更新を達成するために必要なことが 分かりやすくまとまっています。 セッション情報: https://kccncna19.sched.com/event/Uads/the-gotchas-of-zero-downtime-traffic-w-kubernetes-leigh-capili-weaveworks スライド: https://static.sched.com/hosted_files/kccncna19/f7/The%20Gotchas%20of%20Zero-Downtime%20Traffic.pdf Youtube: https://www.youtube.com/watch?v=0o5C12kzEDI Appendix)KubeConNA2019での参考セッション

Slide 36

Slide 36 text

36 HealthCheck @ Colopl livenessProbe: httpGet: path: /heartbeat.php port: 80 initialDelaySeconds: 60 periodSeconds: 5 successThreshold: 1 failureThreshold: 5 timeoutSeconds: 20 readinessProbe: httpGet: path: /healthcheck.php port: 80 initialDelaySeconds: 60 periodSeconds: 3 successThreshold: 2 failureThreshold: 3 timeoutSeconds: 2

Slide 37

Slide 37 text

7. Config Injection

Slide 38

Slide 38 text

38 アプリケーションの設定情報は、アプリケーションと分離して外部から注入できる ようにします。 参考: The TWELVE-FACTOR-APP Config https://12factor.net/config Kubernetes上でアプリケーションのConfigを設定する方法として、 ・ConfigMap ・Secret の二つの方法があります。 基本的な考えとして、 設定ファイルや環境変数 ⇨ ConfigMap 秘密情報、秘密情報を含んだ環境変数 ⇨ Secret に含めて、Podにマウントします。 設定ファイルや環境変数を外部から注入し、 CodeBaseを変更することなく、 アプリの挙動を変更できます。 Config Injection APP APP DB_URL: AAA DB_URL: BBB DEV PROD AAA BBB

Slide 39

Slide 39 text

39 Secret Management Infrastructure as Codeで設定方法を管理する際に特に重要になるのが、 Secretの管理です。 Secret Resourceは文字列を単純にBase64で エンコードします。よりセキュアに管理するには Kubernetes以外の仕組みが必要です。 ソリューション例 ・Sealed Secret ・kubesec ・Vault ・Berglas(GKEの場合) apiVersion: v1 kind: Secret metadata: name: database_secret data: PASS: cGFzc3dvcmQ= Secret.yaml $ echo cGFzc3dvcmQ= | base64 --decode password ⚡ すぐにデコードできてしまう ⚡

Slide 40

Slide 40 text

40 Secret Management @ Colopl GCPのSercret管理ツールであるBerglasとAdmission Webhook(Mutating, Validating) を利用した、透過的なSecret管理を導入中です。 apiVersion: v1 kind: Secret metadata: name: database_secret data: PASS: berglas://.../pass Mutating Webhook Server Validating Webhook Server Key Management Service Secret GCS Secret.yaml ① kubectl apply -f Secret.yaml ② Admission Webhook ③ Mutating ⑤ Validating (Error Check) ④ Decode マニフェスト上にはBerglasへの リファレンスだけ書くため、セキュア

Slide 41

Slide 41 text

8. Maintenance / Upgrade

Slide 42

Slide 42 text

42 Kubernetesは定期的なバージョンアップがあり、Kubernetesを利用している以上、 バージョンアップの作業が必要不可欠になります。 安全にクラスタをメンテナンス・バージョンアップするには、 Kubernetes上のアプリケーションとKubernetesクラスタ自体の両方に考慮が 必要になります。 基本的なアプリケーションやクラスタのデプロイ戦略として次のものがあります。 ・Blue/Green(Red/Black) ・Canary ・Rolling Blue/Green ・In-place Maintenance / Upgrade

Slide 43

Slide 43 text

43 Kubernetesでノードのメンテナンスを行う時は、 kubectl drain を使います。 kubectl drain を実行すると、そのノードはスケジュール対象外になります。 またノード上のPodを終了して、別のNodeにスケジューリングさせます。 その際、PodDisruptionBudget Resourceを設定することで、リクエスト受付可 能なPodが0にならないようにします。 Drain & PodDisruptionBudget Node Old Node New Node Old Node New kubectl drain Not Ready Ready Ready Not Ready Ready Ready kind: PodDisruptionBudget ... spec: maxUnavailable: 1 selector: matchLabels: ... 利用可能なPodの最小数 or 停止可能なPodの最大数 PodDisruptionBudgetで次のSpecを定義

Slide 44

Slide 44 text

44 Handling Risky Business: Cluster Upgrades - Puneet Pruthi, Lyft LyftでのKubernetesクラスタを自動更新する仕組みを構築した話です セッション情報: https://kccncna19.sched.com/event/UaYz/handling-risky-business-cluster-upgrades-puneet-pruthi-lyft スライド: https://static.sched.com/hosted_files/kccncna19/a0/Handling%20Cluster%20Upgrades%20-%20K8srotator.pdf Youtube: https://www.youtube.com/watch?v=Z_2KQP-BMUE Appendix)KubeConNA2019での参考セッション

Slide 45

Slide 45 text

45 コロプラではGKEを利用しているため、Kubernetesのバージョンアップは NodePool(Node Instance Subset)単位で行います。 デプロイ戦略として、Red/Black(Blue/Green) Deployを採用しています。 NodePoolとDeploymentに、それぞれRed/BlackのLabelを持たせておき、 NodePool単位で環境を切り替えます。 Maintenance / Upgrade @ Colopl NodePool v000 NodePool v001

Slide 46

Slide 46 text

9. Resource Management

Slide 47

Slide 47 text

47 (再掲)Kubernetes上で稼働するアプリケーションは、いつ・どこでプロセスを 開始して、プロセスを終了するかが分かりません。 コンテナのスケーリングをオーケストレータが自動で決定しているためです。 特定のNodeにPodが集中するタイミングが重なると、NodeがResource不足に陥り 正常に起動しない場合や、既に起動しているPodがエラーになる場合があります (ノイジーネイバー問題)。 そういった事態にならないよう、Podに割り当てるResourceを適切に設定する必要が あります。PodにResourceを設定するには次の項目を設定します。 ・Requests: 最低限Podに割り当てるResource量 ・Limits: Podに割り当てるResource量の上限 これらの設定はリソース管理だけでなく、安全なスケジューリングにも役立ちます。 Resource Management

Slide 48

Slide 48 text

48 Requests apiVersion: v1 kind: Pod … spec: … resources: requests: cpu: 100m memory: 1Gi limits: cpu: 1000m memory: 2Gi 2Gi 1Gi 1Gi 1Gi 2Gi 1Gi 2Gi 2Gi 3Gi 2Gi 1Gi 2Gi Requestsの値を元に、System Resourceが充分なNodeにPodはAssignされます。 実際のResource利用量に関係なく、Requestsの値でNodeにAssignされるため、使用量を 計測した上での適切な設定が必要です(Schedulingも考慮する)。 Assign 1Gi requests.memory

Slide 49

Slide 49 text

49 Limits & Eviction 2Gi 1Gi 4Gi 1.5Gi Node Capacity 実際の使用量 (実行中Pod: 3) Capacity以上にResourceを消費 優先度が低く、Resource消費量の高いPod からEvictしていく = QoSが低く、Resource消費量の高いPod からEvictしていく LimitsはPodが使用できるResourceの上限ですが、スケジューリングの際に Limitsの値は考慮されません。 そのため、実際のPodの使用量がNodeが提供しているResource量を上回ることが あります。Node Capacityを超えてしまうと、KubernetesはPodを強制的にEvict (退避)します。 Evictionが発生するとResourceを増やす(Podを減らす・Nodeを増やす)しか 回避方法がありません。

Slide 50

Slide 50 text

50 QoS Class Evictionの際にどのPodから退避するかを決定する時に考慮されるのがQoS Classです。 重要なPodほどEvictionされないように、QoSを高く設定する必要があります。 apiVersion: v1 kind: Pod … spec: … resources: {} apiVersion: v1 kind: Pod … spec: ... requests: cpu: 100m memory: 1Gi limits: cpu: 1000m memory: 2Gi apiVersion: v1 kind: Pod … spec: ... requests: cpu: 1000m memory: 2Gi limits: cpu: 1000m memory: 2Gi Resources未設定 RequestsとLimits不一致 RequestsとLimits一致 QoS Class: QoS Class: QoS Class: BestEffort Burstable Guranteed 優先度 低 高

Slide 51

Slide 51 text

51 Appedix) CPU Limitを設定すべきか? 圧縮可能ResourceであるCPUはRequestで最低限のResourceを確保すれば、 Limitを設定しなくてもよいといった意見もあり、一概に決めるのは難しいところです。 ただし、CPU Limitを設定しないと、QoSはGuranteedにならずBurstableになります。 https://twitter.com/thockin/status/1134193838841401345 https://twitter.com/tpeitz_dus/status/113364829133226 3936 ※以下の一連のスレッドを見ると、Limitについて いろんな意見があり読むと面白いかもしれません e.g.

Slide 52

Slide 52 text

10. Scheduling

Slide 53

Slide 53 text

53 Kubernetes上のPodのSchedulingは、Scheduler Componentが自動的に決定します。 SchedulerがPodのSchedulingを自動で決定してくれるとはいえ、考慮すべき点が いくつかあります。 PodのSchedulingの挙動はある程度、マニフェストファイルで指定できます。 Kubernetesでは、次の項目の設定でScheduleの変更が可能です。 ・nodeSelector ・Node Affinity / Node Anti-Affinity ・Inter-Pod Affinity / Inter-Pod Anti-Affinity ・Taints / Tolerations ・PriorityClass ※各項目の設定については取り上げませんが、必要に合わせて設定してください Schedulingの考慮点

Slide 54

Slide 54 text

54 PriorityClassによる優先度付けの例 参考: Pod Priority and Preemption https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/ Node APP APP APP APP 同じ優先度 システム上重要なPodをAssignしようとしても、 Nodeが既に空いていない可能性がある Pending Node APP APP APP 優先度が高 高 低 低 低 優先度が高いPriorityClassをPodに指定すること で、Scheduleが優先される apiVersion: ... kind: PriorityClass metadata: name: high-priority value: 1000000 globalDefault: false description: "..." PriorityClass ※ PriorityClassの設定に伴うPreemptionには注意 https://grafana.com/blog/2019/07/24/how-a-production-outage-was-caused-using-kubernetes-pod-priorities/

Slide 55

Slide 55 text

55 複数種類のWorkloadが同じNodeに同居していると、 ノイジーネイバー問題やResourceの見積もりに 影響が出ます。Workloadはなるべく分離しましょう。 Workloadを分離する BATCH APP BATCH SYSTEM APP DB KVS APP BATCH SYSTEM 良くない例 望ましい例 pool=app:NoSchedule pool=batch:NoSchedule pool=system:NoSchedule taint

Slide 56

Slide 56 text

56 GKEのNode PoolとTaints / Tolerationsを組み合わせて、WorkloadをNodePool単 位で分割しています。また、システムで重要なPodには優先度の高いPriorityClass を付けて、優先的にスケジューリングされるようにしています。 Scheduling @ Colopl Kubernetes cluster backend pool ZoneA ZoneB Instance Group label: back taint: back Instance Group label: back taint: back app pool ZoneA ZoneB Instance Group label: app taint: app Instance Group label: app taint: app prometheus pool ZoneA ZoneB Instance Group label: prom taint: prom Instance Group label: prom taint: prom system pool ZoneA ZoneB Instance Group label: system taint: system Instance Group label: system taint: system

Slide 57

Slide 57 text

11. Scaling

Slide 58

Slide 58 text

58 Kubernetesの強みの一つとして、AutoScalingが挙げられます。 PodレベルやNodeレベルのAutoScaleを公式機能としてサポートしており、 マネージドであれば、クラスタサイズごと簡単にScaleさせられます。 この機能は十分に活用したいところです。 KubernetesのAutoScalingの機能として、次のものがあります。 ・HPA(Horizontal Pod Autoscaler): PodのReplicasの調整 ・VPA(Vertical Pod Autoscaler): Pod.Spec.Containers[].Resourcesの自動調整 ・CA(Cluster AutoScaler): Cluster Node Sizeの調整 HPAの利用にはResources.Requestsの設定が必須のため、 Resourcesは必ず設定しましょう。 AutoScaling

Slide 59

Slide 59 text

59 Horizontal Pod Autoscaler(HPA)とCluster AutoScaler(CA)を併用することで、 KubernetesにPod・Nodeのスケールアウト・スケールインを委ねられます。 ※スパイク時には対応できないので、その場合は事前スケーリングも必要です HPA × CAによるAutoScaling リクエスト 小 ~スケールイン~ ClusterAutoScaler Horizontal Pod Autoscaler ClusterAutoScaler Horizontal Pod Autoscaler リクエスト 大 ~スケールアウト~

Slide 60

Slide 60 text

60 Horizontal Pod AutoscalerとCluster AutoScalerを併用したAutoScaleを 設定しています。ClusterAutoscalerは、Cold StartでNodeをProvisioningします。 そのため、スパイク時にはAutoScaleに伴うNode Provisioningに時間がかかるため、 事前にNodeをスケールアウトしておきます。 HPA × CA @ Colopl ClusterAutoScaler Horizontal Pod Autoscaler 事前 スケールアウト (ゲームの)イベントによるスパイク

Slide 61

Slide 61 text

12. Security / Auth / Authz

Slide 62

Slide 62 text

62 Kubernetesは標準でSecurityやAuthentication(認証) / Authorization(認可)の 機能を持っています。言うまでもなく、これらを適切に設定することが重要です。 Kubernetesで設定可能な機能として、次のものがあります。 ・RBAC(Role-based access control) ・PodSecurityPolicy (Admission Control) ・Pod Security Context ・NetworkPolicy ・Audit Logging ※Clusterのセキュリティ担保 / 証明書の管理 / ContainerRuntimeなどもSecurityに関係してきますが時間の関係で割愛 Security 最低限どうセキュリティを担保するか、を考える時には、次の記事が参考になります 参考: 9 Kubernetes Security Best Practices Everyone Must Follow https://www.cncf.io/blog/2019/01/14/9-kubernetes-security-best-practices-everyone-must-follow/

Slide 63

Slide 63 text

63 Kubernetesはシステムユーザーを含めた全ての権限管理にRBACを利用しています Authorization by RBAC 参考: Introduction to Open Policy Agent https://speakerdeck.com/ken5scal/introduction-to-open-policy-agent DeveloperA ServiceAcount RoleBinding Role Developer Role × RBACサンプル DeveloperやAdminなどといったRoleを用意しておき、 ServiceAcountにRoleを紐付ける(RoleBinding) Role単位で権限を考えることになりますが、組織の実態にそぐわない場合もあります そうした場合はOpen Policy Agentなどの別の仕組みが必要になるかもしれません 参考: Open Policy Agent https://www.openpolicyagent.org/ CNCF Incubating Project

Slide 64

Slide 64 text

64 OPA Introduction & Community Update セッション情報: https://kccncna19.sched.com/event/Uahw/opa-introduction-community-update-rita-zhang-microsoft-patrick-east-styra OPA Deep Dive セッション情報: https://kccncna19.sched.com/event/Uafr/opa-deep-dive-tim-hinrichs-torin-sandall-styra Kubernetes Policy Enforcement Using OPA At Goldman Sachs セッション情報: https://kccncna19.sched.com/event/UaaX/kubernetes-policy-enforcement-using-opa-at-goldman-sachs-miguel-uzcategui-g oldman-sachs-tim-hinrichs-styra Appendix)KubeConNA2019での参考セッション

Slide 65

Slide 65 text

65 CNCF Landscapeには、Kubernetesエコシステムとして数多くのプロダクトがありま す。コロプラでは、Kubernetesの標準機能以外に、コンテナセキュリティの担保とし てFalcoを利用しています。 Security and Compliance 出典: CNCF Landscape https://landscape.cncf.io

Slide 66

Slide 66 text

13. External Traffic

Slide 67

Slide 67 text

67 Kubernetes上で内部通信や外部通信する時に利用するのがService(Discovery) Resourceです。Serviceには次のTypeがあります。 ・ClusterIP(+ Headless Service) ・ExternalName ・NodePort ・LoadBalancer また外部通信に利用するResourceとして、Ingressがあります。 Type: LoadBalancerとIngressは扱うレイヤーが異なります。 Service Discovery L4 Layer L7 Layer Service: LoadBalancer Ingress

Slide 68

Slide 68 text

68 LoadBalancerとIngressはどのように使い分けるべきでしょうか? 基本的にHTTP通信(L7 Layer)には、Ingressを利用しましょう。 LoadBalancer/Ingress for External Traffic Load Balancer Load Balancer NodePort Ingress × Ingress Controller Type: LoadBalancer Ingress /path Path Based Request TCP/UDP Internal LB

Slide 69

Slide 69 text

69 Evolving the Kubernetes Ingress APIs to GA and Beyond - Christopher M Luciano, IBM & Bowei Du, Google Ingress v1 GAに向けた更新の話と、Ingress v2のAPI Resource構想についての セッションとして必見です セッション情報: https://kccncna19.sched.com/event/UaYG/evolving-the-kubernetes-ingress-apis-to-ga-and-beyond-christopher-m-luciano-i bm-bowei-du-google スライド: https://static.sched.com/hosted_files/kccncna19/a5/Kubecon%20San%20Diego%202019%20-%20Evolving%20the%20Kuber netes%20Ingress%20APIs%20to%20GA%20and%20Beyond%20%5BPUBLIC%5D.pdf Youtube: https://www.youtube.com/watch?v=cduG0FrjdJA Appendix)KubeConNA2019での参考セッション

Slide 70

Slide 70 text

70 Player versus Player(PvP)要素のあるMultiPlayer Gameでは、PvP Clusterを用意しま す。そのため、Cluster間の疎通やCluster自体の疎通などを複合的に構築しています。 Multiple Player GameServer @ Colopl Internal LB APP APP APP APP Game Server Game Server Game Server APP Cluster PvP Cluster ①API Call ②Get GameServer Info (IP and Port) ③Connect to GameServer Client(Smart Phone)

Slide 71

Slide 71 text

14. Tuning / Garbage Collection

Slide 72

Slide 72 text

72 Kubernetes上では、アプリケーションコンテナをWorkNode上で実行します。 コンテナの思想はエフェメラル(一時的)が特徴ですが、長期運用を考えると NodeのTuningやGarbage Collectionが必要になってきます。 ここでいうTuningやGarbage Collectionは次のものを想定しています。 ・カーネルパラメータの調整 ・コンテナイメージのガベージコレクション ・コンテナレジストリのガベージコレクション ・ログのローテート Podのカーネルパラメータの調整は、spec.securityContext.sysctlsやinitContainer でも変更できますが、本発表では割愛します。 Tuning / Garbage Collection

Slide 73

Slide 73 text

73 Tuning / Garbage Collectionはなぜ必要? $ docker images REPOSITORY TAG dev1-20191001 dev1-20191001 …… log log log Nodeの性能アップ 溜まっていくログファイル... 溜まっていくコンテナイメージ... 溜まっていくイメージレイヤー... kernel Docker Registry

Slide 74

Slide 74 text

74 Tuning / Garbage Collection @ Colopl $ docker image prune -a -f deleted: sha256:d0bddce440f93 deleted: sha256:ec0659a3a34fa deleted: sha256:6fa14e84825ab ... log Nodeの性能アップ ログローテート レジストリの掃除 イメージレイヤーの掃除 kernel sysctl Alpine Cloud SDK Container Registry delete DaemonSetでNodeのTuning & Garbage Collection

Slide 75

Slide 75 text

15. Stateful Application

Slide 76

Slide 76 text

76 Kubernetes上で動くコンテナには特徴として、エフェメラル(一時的)であることが 挙げられます。対照的に、状態を持ったアプリケーションになると考えなければ ならないことが多くなります。 ※ここではミドルウェアを想定しています KubernetesではそうしたStateful Applicationに対して次の仕組みを提供しています。 ・StatefulSet ・Persistent Volume ・PersistentVolumeClaim また昨今ではOperatorでStateful Applicationを自動化する試みも盛んになっています ※Operator = Custom Resource Definition(CRD) + Custom Controller Stateful Application 参考: OperatorHub https://operatorhub.io/

Slide 77

Slide 77 text

77 Operatorは、Kubernetesの拡張機能を利用して、アプリケーションに必要な運用を コード化し、宣言的なAPIとして利用できるようにしたものです。 Stateful Application with Operator apiVersion: example.com/v1alpha1 kind: Cluster metadata: name: example-cluster spec: members: 5 apiVersion: example.com/v1alpha1 kind: Backup metadata: name: example-backup spec: schedule: '*/30 * * * *' ... Custom Resourceのイメージ

Slide 78

Slide 78 text

78 コロプラではKubernetes上のミドルウェアに、Stateful Applicationを利用しています。 ゲームの要件に合わせて、KVSやメッセージングキュー・RDBMS(MySQL)などの Stateful ApplicationをKubernetes上で管理しています。 Stateful Application @ Colopl ゲームのマスターデータ MySQL Operator Disk Provision Backup / Restore ※Coloplで自作したOperator Operatorでもそれ以外でも、なんらかの仕組みや工夫・考慮が必要になります。 Garbage Collection

Slide 79

Slide 79 text

Summary

Slide 80

Slide 80 text

80 Production Readyに必要なこと まとめ(1/2) 1. CI/CDを整備する 2. マニフェスト管理の戦略を立てる 3. Observabilityを担保する 4. 初期処理でコストの高い処理を事前に行う 5. シグナルハンドル/preStopを使ってGraceful Shutdown 6. HealthCheckで自己回復性を高める 7. Configは外部注入できる形にして、Secretはセキュアに管理 8. zero-downtimeを実現するメンテナンス戦略を立てる

Slide 81

Slide 81 text

81 Production Readyに必要なこと まとめ(2/2) 9. リソース管理をして、ノイジーネイバーを回避する 10. Podに優先度をつける・Workloadを分割する 11. HPAとCAでオートスケーリングのメリットを最大化する 12. RBACの権限管理で足りない部分は、別の仕組みで補う 13. 外部通信(L7)にはIngressを使う 14. WorkerNodeをチューニング・ガベージコレクション 15. (ステートフルなものがある場合は)仕組みを考える

Slide 82

Slide 82 text

82 Thank you for listening!!!

Slide 83

Slide 83 text

Appendix

Slide 84

Slide 84 text

84 大規模クラスタにおける負荷対策 (コロプラのケース)

Slide 85

Slide 85 text

85 Conntrack Table Podへのルーティングの実態はiptablesの書き換えです。その際、Kernelモジュール であるconntrack tableのエントリとしてトラッキングされます。 ノードあたりのWorkload(Pod)が多いと、conntrack tableが枯渇してパケットが Kernelによってドロップされることがあります。 nf_conntrack: table full, dropping packet conntrack枯渇の問題を回避するには、次の方法があります。 ・クラスタのサイズを大きくする(ことによってNodeあたりのWorkloadを減らす) ・WorkerNodeのカーネルパラメータを調整する 参考: https://cloud.google.com/kubernetes-engine/docs/troubleshooting#intermittent_failed_connections https://www.weave.works/blog/racy-conntrack-and-dns-lookup-timeouts

Slide 86

Slide 86 text

86 Node Local DNS Cache kube-dnsはkube-system namespaceに存在するSystem Componentの一つですが、 Kubernetes上の全ての名前解決がkube-dnsに殺到します。つまりスパイクする場合は 対策が必要です。その対策の一つとして、Node Local DNS Cacheがあります。 Pod Pod Pod kube-dns kube-system Node Local DNS Cache https://kubernetes.io/docs/tasks/administer-cluster/nodelocaldns/ https://aws.amazon.com/jp/blogs/containers/eks-dns-at-scale-and-spikeiness/ Pod Pod Pod kube-dns kube-system 参考: 通常のkube-dnsによる名前解決 CoreDNS

Slide 87

Slide 87 text

87 数百万DAU(Daily Active User)規模の負荷では、Prometheus単体では限界が来ます。 そのため、PrometheusのスケーリングとしてVictoriaMetricsを採用しています。 Monitoring Scale with Victoria Metrics … 通常タイトルにおける構成 一部タイトルにおける構成 Grafana Prometheus VictoriaMetrics Cluster Mode vmselect1 vminsertM vmstorage1 vmstorageN vminsert1 vmselectP 参考: https://victoriametrics.com/