[CNDK2019]Production Ready Kubernetesに必要な15のこと / Production Ready Kubernetes 15 Rules

C174e1ef0c746f53d989b1902b4e674e?s=47 go_vargo
November 28, 2019

[CNDK2019]Production Ready Kubernetesに必要な15のこと / Production Ready Kubernetes 15 Rules

C174e1ef0c746f53d989b1902b4e674e?s=128

go_vargo

November 28, 2019
Tweet

Transcript

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

  2. 2 名前: 磯 賢大(@go_vargo) 所属: 株式会社コロプラ    インフラグループ 第2チーム 趣味:

    Kubernetesの裏側の仕組みを知ること / コントリビューション(minikube) 出版: 「実践Helm」インプレスR&D 自己紹介 外部発表: ・コロプラが実践しているSpinnakerを用いたデプロイ戦略 @ kubernetes Meetup #21 ・ゼロから始めるKubernetes Controller @ kubernetes Meetup #23 ・Docker Meetup, CloudNative Meetup, 他...
  3. 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/ 参考にした資料
  4. 4 本講演で目指すこと - Kubernetesプラットフォームを構築する上で、押さえておきたい考慮点をまとめること ※ 特に分散システムならではの、本番環境を想定した、気をつけておきたい箇所 注意点 - 本講演で想定しているのは、Webアプリケーション基盤におけるKubernetesです -

    Kubernetesクラスタ自体をどうセキュアに構築すべきか、という点には触れていません ※クラスタが構築されている上で、気をつけるべきものをピックアップしています - 自社でのベストプラクティスの考え方も入れていますが、 全てが全てベストプラクティスとは考えてはいません(模索しているものもあります) - 自社で各テーマをどのように取り組んでいるかを随所で紹介していますが、 あくまで一例と捉えていただけると幸いです 目的
  5. 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
  6. 1. CI/CD

  7. 7 CI/CD CI/CDはOrchestrationの手前に あるものです。 Production Ready Kubernetes には必須と言えます。 = CI/CDはきちんと作りましょう

    CI/CDのツールは、非常に多くの 選択肢があります。 何を使うかはユースケースに合わ せて検討しましょう。 出典: CNCF TraipMap https://github.com/cncf/trailmap
  8. 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
  9. 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
  10. 10 CI/CD @ Colopl CI: GitLab Runner CD: Spinnaker Spinnakerで、多様なデプロイ戦略を

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

  12. 12 マニフェスト管理 Kubernetesの管理には直結しない部分で 重要になるものの一つが マニフェスト管理です。 Infrastructure as Codeであるため、 マニフェストファイルを管理する 必要があります。

    マニフェスト管理にも代表的なツールや 管理方法に種類があります。 どちらが優れている、というものでは ないので、ユースケースに合わせて 選択しましょう。 出典: CNCF TraipMap https://github.com/cncf/trailmap
  13. 13 マニフェスト管理の考え方 Mono Repository Multi Repository or アプリケーション ソース インフラ

    マニフェスト アプリケーション ソース インフラ マニフェスト
  14. 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
  15. 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. マニフェスト差分比較ツール
  16. 3. Monitoring

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

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

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

    出典: CNCF Landscape https://landscape.cncf.io
  22. 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
  23. 4. Initial Processing

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

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

    etc...) ・etc... Initial Processing
  26. 26 Kubernetesでの初期処理/前処理の設定方法として下記の方法があります。 1. initContainer ・Main Container起動前に、初期化用のコンテナを起動する 2. Entrypoint ・Container起動時のスクリプト内で、初期化処理を記載しておく 3.

    SideCar ・Main Containerと並行して、Containerを立ち上げてデータを更新する 4. postStart ・Container内のプロセスが起動した直後に、スクリプトを実行する Kubernetesにおける初期処理の実行方法
  27. 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
  28. 5. Graceful Shutdown

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

    ・実行中のジョブをワーカーキューに戻す(バッチ) ・etc… Graceful Shutdown 参考: The TWELVE-FACTOR-APP Disposability https://12factor.net/disposability
  30. 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
  31. 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 リクエスト停止 サービスアウト
  32. 6. HealthCheck

  33. 33 Kubernetesのメリットの一つが自己回復性です。 Kubernetes上で実行するプロセスはPodを適切に廃棄・再起動するように、 コンテナ内のプロセスが起動しているか・正常に稼働しているかをチェックする 必要があります。 Kubernetes上のコンテナプロセスの監視に、次の二つの項目を設定ができます。 ・LivenessProbe: コンテナが生きているかどうかをヘルスチェック ・ReadinessProbe: コンテナが応答可能かどうか(正常稼働か)をヘルスチェック

    LivenessProbeが失敗すると、コンテナを再起動します。 ReadinessProbeが失敗すると、PodがService ResourceのEndpointから外されて、 通信が届かなくなります(サービスアウト)。 HealthCheck on Kubernetes
  34. 34 LivenessProbe & ReadinessProbe Fail APP Running APP Running APP

    Running LivenessProbe: Failed APP Running APP Terminate APP Running ReadinessProbe: Failed ReadinessProbe LivenessProbe
  35. 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での参考セッション
  36. 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 <?php // このファイルが時間内に実行されなかったら // サーバーが再起動される LivenessProbe: heartbeat.php ReadinessProbe: healthcheck.php <?php const HEALTHCHECK = '../app.health'; /** .health ファイルをチェックして状態を確認する * 1: 正常動作 */ 0: LBから外す if (intval(@file_get_contents(HEALTHCHECK)) === 0) { header('HTTP/1.1 404 Not Found'); return; }
  37. 7. Config Injection

  38. 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
  39. 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 ⚡ すぐにデコードできてしまう ⚡
  40. 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への リファレンスだけ書くため、セキュア
  41. 8. Maintenance / Upgrade

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

    Blue/Green ・In-place Maintenance / Upgrade
  43. 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を定義
  44. 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での参考セッション
  45. 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
  46. 9. Resource Management

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

    最低限Podに割り当てるResource量 ・Limits: Podに割り当てるResource量の上限 これらの設定はリソース管理だけでなく、安全なスケジューリングにも役立ちます。 Resource Management
  48. 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
  49. 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を増やす)しか 回避方法がありません。
  50. 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 優先度 低 高
  51. 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.
  52. 10. Scheduling

  53. 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の考慮点
  54. 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/
  55. 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
  56. 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
  57. 11. Scaling

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

    リクエスト 小 ~スケールイン~ ClusterAutoScaler Horizontal Pod Autoscaler ClusterAutoScaler Horizontal Pod Autoscaler リクエスト 大 ~スケールアウト~
  60. 60 Horizontal Pod AutoscalerとCluster AutoScalerを併用したAutoScaleを 設定しています。ClusterAutoscalerは、Cold StartでNodeをProvisioningします。 そのため、スパイク時にはAutoScaleに伴うNode Provisioningに時間がかかるため、 事前にNodeをスケールアウトしておきます。

    HPA × CA @ Colopl ClusterAutoScaler Horizontal Pod Autoscaler 事前 スケールアウト (ゲームの)イベントによるスパイク
  61. 12. Security / Auth / Authz

  62. 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/
  63. 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
  64. 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での参考セッション
  65. 65 CNCF Landscapeには、Kubernetesエコシステムとして数多くのプロダクトがありま す。コロプラでは、Kubernetesの標準機能以外に、コンテナセキュリティの担保とし てFalcoを利用しています。 Security and Compliance 出典: CNCF

    Landscape https://landscape.cncf.io
  66. 13. External Traffic

  67. 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
  68. 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
  69. 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での参考セッション
  70. 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)
  71. 14. Tuning / Garbage Collection

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

    ・ログのローテート Podのカーネルパラメータの調整は、spec.securityContext.sysctlsやinitContainer でも変更できますが、本発表では割愛します。 Tuning / Garbage Collection
  73. 73 Tuning / Garbage Collectionはなぜ必要? $ docker images REPOSITORY TAG

    <none> dev1-20191001 <none> dev1-20191001 …… log log log Nodeの性能アップ 溜まっていくログファイル... 溜まっていくコンテナイメージ... 溜まっていくイメージレイヤー... kernel Docker Registry
  74. 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
  75. 15. Stateful Application

  76. 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/
  77. 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のイメージ
  78. 78 コロプラではKubernetes上のミドルウェアに、Stateful Applicationを利用しています。 ゲームの要件に合わせて、KVSやメッセージングキュー・RDBMS(MySQL)などの Stateful ApplicationをKubernetes上で管理しています。 Stateful Application @ Colopl

    ゲームのマスターデータ MySQL Operator Disk Provision Backup / Restore ※Coloplで自作したOperator Operatorでもそれ以外でも、なんらかの仕組みや工夫・考慮が必要になります。 Garbage Collection
  79. Summary

  80. 80 Production Readyに必要なこと まとめ(1/2) 1. CI/CDを整備する 2. マニフェスト管理の戦略を立てる 3. Observabilityを担保する

    4. 初期処理でコストの高い処理を事前に行う 5. シグナルハンドル/preStopを使ってGraceful Shutdown 6. HealthCheckで自己回復性を高める 7. Configは外部注入できる形にして、Secretはセキュアに管理 8. zero-downtimeを実現するメンテナンス戦略を立てる
  81. 81 Production Readyに必要なこと まとめ(2/2) 9. リソース管理をして、ノイジーネイバーを回避する 10. Podに優先度をつける・Workloadを分割する 11. HPAとCAでオートスケーリングのメリットを最大化する

    12. RBACの権限管理で足りない部分は、別の仕組みで補う 13. 外部通信(L7)にはIngressを使う 14. WorkerNodeをチューニング・ガベージコレクション 15. (ステートフルなものがある場合は)仕組みを考える
  82. 82 Thank you for listening!!!

  83. Appendix

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

  85. 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
  86. 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
  87. 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/