Kubernetes上でアプリケーションを 運用するまでの道のり/The way to run applications with Kubernetes

Kubernetes上でアプリケーションを 運用するまでの道のり/The way to run applications with Kubernetes

6ee833afddca37209631fb25a0cec547?s=128

Shunya Murata

January 31, 2019
Tweet

Transcript

  1. Kubernetes上でアプリケーションを 運⽤するまでの道のり Mix Leep Study #32 / January 30, 2019

    Shunya Murata <shmurata@zlab.co.jp> @shmurata_
  2. ▶ アジェンダ 1. Kubernetes に向いたアプリケーションを作る・作り変える 2. アプリケーションをコンテナにする 3. Kubernetesにデプロイする 1.

    デプロイの⽅法 2. マニフェストの管理 4. 本番環境で動作させる 5. まとめ 2
  3. Shunya Murata/ @shmurata_ ▶ ゼットラボ株式会社 ソフトウェアエンジニア ▶ 2010年にヤフー株式会社に新卒⼊社、2015年ゼットラボ株式会社に出向 3

  4. Kubernetesに向いたアプリケーション を作る・作り変える

  5. ▶ Kuberneteに向いたアプリケーションとは ▶ Pod(コンテナ)は⼀時的なオブジェクトとして扱えるようにすべき + Pod はいつでも終了して別のNodeへ移動できるように作るべき ▶ 特定のノードに依存しない +

    IP アドレスなどのノード固有の情報に依存しない ▶ アプリケーション例 + The Twelve Factor App: https://12factor.net/ja/ 5 https://cdn.chrisshort.net/The-Illustrated-Childrens-Guide-to-Kubernetes.pdf
  6. アプリケーションをコンテナにする

  7. ▶ Dockerfile のベストプラクティス ▶ コンテナはエフェメラルであるべき ▶ コンテナ毎に1つのプロセスだけ実⾏ ▶ 不要なパッケージのインストールは避ける +

    multi-stage build 7 https://docs.docker.com/develop/develop-images/dockerfile_best-practices/
  8. Kubernetesにデプロイする

  9. ▶ 宣⾔的なアプローチでデプロイしよう ▶ kubectl + 命令的なコマンド : kubectl run, kubectl

    create deployment + 命令的なオブジェクトの操作: kubectl create -f, kubectl replace -f + 宣⾔的なオブジェクトの操作: kubectl apply -f 9 https://kubernetes.io/docs/concepts/overview/object-management-kubectl/declarative-config/
  10. 10 https://twitter.com/jbeda/status/815298029452279808

  11. 11 https://github.com/kubernetes/community/blob/master/contributors/design-proposals/architecture/declarative-application-management.md

  12. ▶ 宣⾔的なアプローチのメリット ▶ This declarative approach is critical to the

    system’s self-healing, autonomic capabilities, and application updates. + セルフヒーリングや⾃⽴制御、更新しやすい ▶ Version control facilitates reproducibility, reversibility, and an audit trail. + 再現性、可逆性、監査 ▶ Version control enables the use of familiar tools and processes for change control, review, and conflict resolution. + 変更管理、レビュー、コンフリクトの解消が容易 12
  13. ▶ YAMLでデプロイしよう! ▶ 構成がシンプルになる ▶ Kubernetes API の変更に強い ▶ 既存のツールとの連携が容易

    ▶ 抽象化されたDSLやGUIの使い⽅を覚えなくて良い + まだスタンダートとなるプロダクトがない + Kuberentes の標準オブジェクトの API はほぼ仕様が固まってきている + バージョン管理も明確に⾏われている ▶ YAMLにはKubernetesの考え⽅や仕組みが詰まっている + YAMLを覚えれば Kubernetes の理解が進む + 結局問題が起きると理解する必要が出てくる 13
  14. apiVersion: apps/v1 kind: Deployment metadata: creationTimestamp: null labels: app: nginx

    name: nginx spec: replicas: 1 selector: matchLabels: app: nginx strategy: {} template: metadata: creationTimestamp: null labels: app: nginx spec: containers: - image: nginx name: nginx resources: {} status: {} ▶ kubectl create deployment nginx --image=nginx -- dry-run -o yaml ▶ kubectl explain ▶ マニフェストを作成する 14
  15. ▶ マニフェストの管理 ▶ 環境別の設定 + kustomize: https://github.com/kubernetes-sigs/kustomize + helm: https://helm.sh/

    + ksonnet: https://ksonnet.io/ ▶ SCM(バージョン管理システム)で管理 + GitOps: https://www.weave.works/blog/gitops-operations-by-pull-request + CI/CD パイプラインを作成して git の操作だけでオペレーションする 15
  16. ▶ kubectl apply -f ▶ 差分を検知して変更点を反映する + 差分の反映は単純な上書きではないので注意が必要 + applyで作成したオブジェクトはapply以外では変更しない

    ▶ 詳しくは 「Kubernetes: kubectl apply の動作」 @tkusumi + https://qiita.com/tkusumi/items/0bf5417c865ef716b221 16 https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands
  17. 本番環境で動作させる

  18. apiVersion: apps/v1 kind: Deployment metadata: creationTimestamp: null labels: app: nginx

    name: nginx spec: replicas: 1 selector: matchLabels: app: nginx strategy: {} template: metadata: creationTimestamp: null labels: app: nginx spec: containers: - image: nginx name: nginx resources: {} status: {} ▶ 本番環境で動作させるには設定が⾜りていない 18
  19. ▶ 本番環境で動作させるには? ▶ リソースを考慮したスケジュールを⾏えるようにする ▶ アプリケーションのハングアップを⾃動復旧する ▶ ゼロダウンタイムでアプリケーションを更新する ▶ クラスタのメンテナンスに対応する

    19
  20. ▶ リソースを考慮したスケジュールを⾏えるようにする ▶ Kubernetesのリソース管理 + Podの要求したリソース量を利⽤できるNodeにスケジュールされる 20 Kubernetes スケジューラ Node:

    32GB Pod: 16GB Node: 32GB Node: 32GB Pod: 16GB Pod: 16GB Pod: 16GB Pod: 16GB Pod: 16GB
  21. ▶ Pod が要求するリソース量を設定する必要がある ▶ Pod.spec.containers[].resource.requests + コンテナが最低限利⽤するリソース量 + 指定しないとリソース量が0でも構わないという意味になる +

    スケジューラはこの値をもとにPodをスケジュールする ▶ Pod.spec.containers[].resource.limis + コンテナが最⼤利⽤できるリソース量 + 指定しないと無制限に利⽤しても構わないという意味になる 21 https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/
  22. ▶ アプリケーションのハングアップから⾃動復旧する ▶ アプリケーションは様々な要因でハングアップする + リソースリーク、デッドロック ▶ Pod.spec.containers[].livenessProbe + コンテナの状態を監視する

    + httpGet, tcpSocket, exec + 監視の結果ダウンしていると判断したらコンテナを再起動 22 https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/
  23. ▶ ゼロダウンタイムでアプリケーションを更新する ▶ Deploymentのローリングアップデート + ゼロダウンタイムでReplicaSet(Pod)を更新するオブジェクト ▶ ゼロダウンタイムにするには仕組みを理解して適切に設定する必要がある + GracefulShutdown

    + ReadinessProbe + Serviceのロードバランス先の更新 23
  24. ▶ GracefulShutdown ▶ アプリケーション⾃体をグレースフルにシャットダウンできるようにする + SIGTERMシグナルまたはpreStopフックを受けてから短時間 (TerminationGracePeriodSeconds)に終了する必要がある ▶ Pod.spec.containers[]. lifecycle.preStop

    + Podの終了時に実⾏したいコマンドを実⾏することができる + SIGTERMでは終了処理を実現できない場合などに利⽤できる 24 https://kubernetes.io/docs/tasks/configure-pod-container/attach-handler-lifecycle-event/
  25. ▶ ReadinessProbe ▶ Pod.spec.containers[].ReadinessProbe + リクエストを受け付けられる(Readiness)状態であるかを監視する + httpGet, tcpSocket, exec

    + Readiness な状態と判断したら Service からリクエストが送られるようになる 25 https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/
  26. ▶ Serviceの更新 ▶ Serviceのロードバランス先の更新 + 終了中または終了したPodへリクエストを送らないようにする + Kuberentesのコントローラが⾃動的に実施するが現時点では注意が必要 ▶ つぎの2つの処理は並列に実施されるため考慮が必要

    + Podの終了 + Serviceのロードバランス先の更新 26
  27. ▶ Serviceの更新への対応 ▶ ワークアラウンドの対応 + preStopフックで Service の更新が終わるのを待つようにする + 終了中もリクエストを受け付けられるようにする

    27
  28. ▶ Podの終了処理 ▶ ৄ͘͠͸ ʮKubernetes: ৄղ Pods ͷऴྃʯ@superbrothers + https://qiita.com/superbrothers/items/3ac78daba3560ea406b2

    28
  29. ▶ クラスタのメンテナンスに対応する ▶ Kuberentesクラスタのメンテナンス + 全体を⽌めないように少しずつ停⽌して更新していく + kubectl drain node

    + 指定のNodeを unschedulable にして Pod を退去(evict)する ▶ 特定の Node に Pod が偏っていると意図しないレプリカ数に減る可能性がある + PodDisruptionBudget + 指定した条件を満たすように削除を待つ + 例: 最低1Pod動いていることを条件にする 29 https://kubernetes.io/docs/tasks/run-application/configure-pdb/
  30. ▶ PodDisruptionBudget未設定 30 Node a Pod(Running) Node b Pod(Running) kubectl

    drain node a Kubernetes evict
  31. ▶ PodDisruptionBudget未設定 31 Node a Node b Kubernetes Pod(Terminating) Pod(Terminating)

    ͢΂ͯͷ Pod ͕ఀࢭ͢ΔՄೳੑ͕͋Δ
  32. ▶ PodDisruptionBudget設定済み 32 Node a Pod(Running) Node b Pod(Running) kubectl

    drain node a Kubernetes evict PDB minAvailable: 1
  33. ▶ PodDisruptionBudget設定済み 33 Node a Pod(Running) Node b Kubernetes Pod(Terminating)

    PDBͷઃఆʹج͍ͮͯୀڈΛ଴ͭ PDB minAvailable: 1
  34. Node b ▶ PodDisruptionBudget設定済み 34 Node a Pod(Running) Kubernetes Pod(Terminating)

    PDBͷઃఆʹج͍ͮͯୀڈΛ଴ͭ Pod(Terminated) PDB minAvailable: 1
  35. ▶ PodDisruptionBudget設定済み 35 Node a Node b Kubernetes αʔϏεΛఀࢭͤͣʹ҆શʹNodeΛఀࢭͰ͖Δ Pod(Running)

    Pod(Running) Pod(Terminated) PDB minAvailable: 1
  36. まとめ

  37. ▶ まとめ ▶ Kubernetes でアプリケーションを運⽤するまでの道のり + マニフェストの管理 + 宣⾔的にシステムの状態をファイルで定義 +

    ファイルをバージョン管理 + 本番環境に必要な設定 + resource.request + ReadinessProbe/LivenessProbe + GracefulShutdown/preStop + PodDisruptionBudget 37
  38. Fin.