Upgrade to Pro — share decks privately, control downloads, hide ads and more …

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

go_vargo
November 28, 2019

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

go_vargo

November 28, 2019
Tweet

More Decks by go_vargo

Other Decks in Technology

Transcript

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

    View Slide

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

    View Slide

  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/
    参考にした資料

    View Slide

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

    View Slide

  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

    View Slide

  6. 1. CI/CD

    View Slide

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

    View Slide

  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

    View Slide

  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

    View Slide

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

    View Slide

  11. 2. Manifest Management

    View Slide

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

    View Slide

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

    View Slide

  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

    View Slide

  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. マニフェスト差分比較ツール

    View Slide

  16. 3. Monitoring

    View Slide

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

    View Slide

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

    View Slide

  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”))
    }
    リクエストが来ると、カウンタをインクリメントする例

    View Slide

  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/

    View Slide

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

    View Slide

  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

    View Slide

  23. 4. Initial Processing

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  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

    View Slide

  28. 5. Graceful Shutdown

    View Slide

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

    View Slide

  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

    View Slide

  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
    リクエスト停止
    サービスアウト

    View Slide

  32. 6. HealthCheck

    View Slide

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

    View Slide

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

    View Slide

  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での参考セッション

    View Slide

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

    View Slide

  37. 7. Config Injection

    View Slide

  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

    View Slide

  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
    ⚡ すぐにデコードできてしまう ⚡

    View Slide

  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への
    リファレンスだけ書くため、セキュア

    View Slide

  41. 8. Maintenance / Upgrade

    View Slide

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

    View Slide

  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を定義

    View Slide

  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での参考セッション

    View Slide

  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

    View Slide

  46. 9. Resource Management

    View Slide

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

    View Slide

  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

    View Slide

  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を増やす)しか
    回避方法がありません。

    View Slide

  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
    優先度
    低 高

    View Slide

  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.

    View Slide

  52. 10. Scheduling

    View Slide

  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の考慮点

    View Slide

  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/

    View Slide

  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

    View Slide

  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

    View Slide

  57. 11. Scaling

    View Slide

  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

    View Slide

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

    View Slide

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

    View Slide

  61. 12. Security / Auth / Authz

    View Slide

  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/

    View Slide

  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

    View Slide

  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での参考セッション

    View Slide

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

    View Slide

  66. 13. External Traffic

    View Slide

  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

    View Slide

  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

    View Slide

  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での参考セッション

    View Slide

  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)

    View Slide

  71. 14. Tuning /
    Garbage Collection

    View Slide

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

    View Slide

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

    View Slide

  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

    View Slide

  75. 15. Stateful Application

    View Slide

  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/

    View Slide

  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のイメージ

    View Slide

  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

    View Slide

  79. Summary

    View Slide

  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を実現するメンテナンス戦略を立てる

    View Slide

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

    View Slide

  82. 82
    Thank you for listening!!!

    View Slide

  83. Appendix

    View Slide

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

    View Slide

  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

    View Slide

  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

    View Slide

  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/

    View Slide