「隅からスミまでKubernetes総復習 - cndjpシーズン1まとめ」の前半分の発表資料です。 当日手元で閲覧するためのものです。あとでセクションごとに分けた形にしてアップロードし直すと思います。
Cloud Native Developers JPKubernetes応用@hhiroshell1
View Slide
Cloud Native Developers JPお品書き• Podの起動時/終了時にできること• ポリシーを適用して制御する2
Cloud Native Developers JPPodの起動時/終了時にできること3
Cloud Native Developers JPPod• 複数のコンテナを束ねる単位• 論理的なホストのように機能する– 内包されるコンテナ群はストレージとネットワークを共有– ひとつのPodにClusterIPがひとつ割当たる。コンテナ群はそれを共有– コンテナの生成/破棄等はPod単位で行われる• 内包される複数のコンテナは、必ず同じNode上で稼働PodContainer4Worker NodeMaster Node
Cloud Native Developers JP 5Podの起動時の動きPhase: PendingPodの生成を指示Phase: RunningInit Containerの起動と実行終了イベントNodeへの配置のスケジューリング(続きは後述)PostStart hookの実行readiness proveによる起動確認 liveness proveによる死活監視コンテナの起動とENTRYPOINTの処理開始PostStart hookの実行
Cloud Native Developers JP 6Podの起動時の動きPhase: PendingPodの生成を指示Phase: RunningInit Containerの起動と実行終了イベントNodeへの配置のスケジューリング(続きは後述)PostStart hookの実行readiness proveによる起動確認 liveness proveによる死活監視コンテナの起動とENTRYPOINTの処理開始PostStart hookの実行
Cloud Native Developers JPPod生成の指示とスケジューリング• Pod生成の指示– API Server経由でControllerを作成する。これがAcceptされることがPod生成処理の起点になる– ControllerからPodの生成をスケジューリングする(ここでどのNodeにPodが配置されるかが決まる)– PodのphaseはPendingからスタート• スケジューリング– Podを配置可能なNodeを識別し、Podの作成をスケジューリング(キューに投入)する7
Cloud Native Developers JP 8Podの起動時の動きPhase: PendingPodの生成を指示Phase: RunningInitContainerの起動と実行終了イベントNodeへの配置のスケジューリング(続きは後述)PostStart hookの実行readiness proveによる起動確認 liveness proveによる死活監視コンテナの起動とENTRYPOINTの処理開始PostStart hookの実行
Cloud Native Developers JPInitContainer• アプリケーションの用のコンテナが起動する前に、前処理を行うために利用するコンテナ– コンテナの処理が終了したら廃棄される– 複数のInitContainerを使う場合、ひとつずつシーケンシャルに実行される– 前処理でのみ必要なパッケージや権限をInitContainerに集約して、リソースの節約とセキュリティ向上を図る• 利用例– アプリケーション用コンテナを起動するための前処理(設定ファイルの生成など)– アプリが依存する別サービスが起動するまでの待機処理9
Cloud Native Developers JPInitContainerの利用例: KubernetesでKafka broker• zookeeperが配備済みの状態から説明します10zookeeperKubernetesクラスター ストレージ(e.g. AWS EBS)
Cloud Native Developers JPInitContainerの利用例: KubernetesでKafka broker• server.propertiesのテンプレートとそれを編集するスクリプトをConfigMapオブジェクトに含めて配備する11zookeeperbroker-configinit.shserver.propertiesKubernetesクラスター ストレージ(e.g. AWS EBS)ConfigMapserver.propertiesのテンプレートserver.propertiesを編集するスクリプト
Cloud Native Developers JPInitContainerの利用例: KubernetesでKafka broker• brokerを動かすためのPodの配備を開始• VolumeにConfigMap内のファイルがコピーされる12zookeeperbroker-configinit.shserver.propertiesinit.shserver.propertiesKubernetesクラスター ストレージ(e.g. AWS EBS)kafka-0PodファイルをコピーVolume
Cloud Native Developers JPInitContainerの利用例: KubernetesでKafka broker• initContanerが立ち上がり、前ページのVolumeをマウント• init.shを実行して、環境に合わせてserver.propertiesを書き換え13zookeeperbroker-configinit.shserver.propertiesinit.shserver.propertiesKubernetesクラスター ストレージ(e.g. AWS EBS)kafka-0init-cofnigマウントinit.shを実行してserver.propertiesを書き換えinitContainer
Cloud Native Developers JPInitContainerの利用例: KubernetesでKafka broker• brokerを可動させるコンテナを起動• brokerのデータを保持するためのVolumeオブジェクトをマウント14zookeeperkafka-0broker-configinit.shserver.propertiesbrokerinit.shserver.propertiesKubernetesクラスター ストレージ(e.g. AWS EBS)Containerマウント
Cloud Native Developers JPInitContainerの利用例: KubernetesでKafka broker• PersistentVolumeClaim(PVC)に記述されたストレージの要件(容量、サービスレベルなど)に従い、StorageClassがプロビジョニング15zookeeperkafka-0broker-configinit.shserver.propertiesbrokerinit.shserver.propertiesKubernetesクラスター ストレージ(e.g. AWS EBS)PersistentVolumeClaim(PVC) StorageClassPVCに記述された要件に従い、StorageClassがストレージをプロビジョニング
Cloud Native Developers JP 16Podの起動時の動きPhase: PendingPodの生成を指示Phase: RunningInitContainerの起動と実行終了イベントNodeへの配置のスケジューリング(続きは後述)PostStart hookの実行readiness proveによる起動確認 liveness proveによる死活監視コンテナの起動とENTRYPOINTの処理開始PostStart hookの実行
Cloud Native Developers JPContainer Lifecycle Hooks• コンテナの生成、破棄をフックして実行される処理– PostStart hook(←こっち)• コンテナの起動直後に実行される• コンテナのENTRYPOINTが開始される前に実行されるという保証があるわけではない– PreStop hook• コンテナの破棄を開始する前に実行される• これが完了していないとのコンテナの破棄には進まない• 非同期的に実行して終了すると、即座にメインプロセスにSIGTERMが送られるので注意• ExecとHTTPの2種類の実装を指定できる– Exec: 任意のシェルコマンドを実行– HTTP: 任意のエンドポイントにHTTPリクエストを発行17
Cloud Native Developers JP 18Podの起動時の動きPhase: PendingPodの生成を指示Phase: RunningInitContainerの起動と実行終了イベントNodeへの配置のスケジューリング(続きは後述)PostStart hookの実行readiness proveによる起動確認 liveness proveによる死活監視コンテナの起動とENTRYPOINTの処理開始PostStart hookの実行
Cloud Native Developers JPContainer Probes(readiness prove/liveness probe)• readiness probe– コンテナへのトラフィックの配信を行ってよいか(起動したか)を確認するための仕組み– 所定の間隔でrediness probeを実行し、一定時間失敗が繰り返されるとコンテナが再起動される(起動失敗とみなされる)• Iiveness probe– コンテナの死活監視を実装するための仕組み– 所定の間隔でliveness probeを実行し、失敗があるとコンテナが自動で再起動される19
Cloud Native Developers JPContainer Probeの実装方法• 以下3種類のいずれかで実装– ExecAction:• 指定したコマンドの実行• 終了コードが0なら成功– HTTPGetAction:• 指定のエンドポイントにHTTP GETを送信• 200位上400未満で成功– TCPSocketAction:• TCP Socketのコネクションを張ることができれば成功• proveの成否が正しくコンテナの死活を反映するように注意20…spec:containers:- name: goproxyimage: k8s.gcr.io/goproxy:0.1ports:- containerPort: 8080readinessProbe:tcpSocket:port: 8080initialDelaySeconds: 5periodSeconds: 10livenessProbe:tcpSocket:port: 8080initialDelaySeconds: 15periodSeconds: 20
Cloud Native Developers JP 21Podの廃棄時の動き終了イベントPreStop hookの実行PreStop hookの実行 SIGKILLSIGTEAMPhase: RunningServiceのEndpointリストから除外トラフィックが送られなくなるGracePeriodSeconds経過(デフォルト30秒)Phase: Succeeded/Failed
Cloud Native Developers JP 22Podの廃棄時の動き終了イベントPreStop hookの実行PreStop hookの実行 SIGKILLSIGTEAMPhase: RunningServiceのEndpointリストから除外トラフィックが送られなくなるGracePeriodSeconds経過(デフォルト30秒)Phase: Succeeded/Failed
Cloud Native Developers JPPodの終了イベント• Podのアンデプロイを伴う操作の指示– Deployment等にのreplica数を減らす– Deployment等に記述したpod templateを更新する– Podをdeleteする– etc…注)ここには終了処理のできない死に方は含まれません– H/W障害、カーネルパニック、ネットワーク的なNodeの離脱…23
Cloud Native Developers JP 24Podの廃棄時の動き終了イベントPreStop hookの実行PreStop hookの実行 SIGKILLSIGTEAMPhase: RunningServiceのEndpointリストから除外トラフィックが送られなくなるGracePeriodSeconds経過(デフォルト30秒)Phase: Succeeded/Failed
Cloud Native Developers JPPodの廃棄が開始されると1. API Serverへの問い合わせ時に、Podの状態がTerminatingになる2. 上記と同時に以下の2つの処理が開始される– 各コンテナにおいて、preStop hookが実行される– ServiceのEndpointリストから、当該Podが削除される(トラフィックが送られなくなる)• 注)上記1. と2. の各処理は、順序は保証されない25
Cloud Native Developers JPContainer Lifecycle Hooks(再掲)• コンテナの生成、破棄をフックして実行される処理– PostStart hook• コンテナの起動直後に実行される• コンテナのENTRYPOINTが開始される前に実行されるという保証があるわけではない– PreStop hook(←こっち)• コンテナの破棄を開始する前に実行される• これが完了していないとのコンテナの破棄には進まない• 非同期的に実行して終了すると、即座にメインプロセスにSIGTERMが送られるので注意• ExecとHTTPの2種類の実装を指定できる– Exec: 任意のシェルコマンドを実行– HTTP: 任意のエンドポイントにHTTPリクエストを発行26
Cloud Native Developers JP 27Podの廃棄時の動き終了イベントPreStop hookの実行PreStop hookの実行 SIGKILLSIGTEAMPhase: RunningServiceのEndpointリストから除外トラフィックが送られなくなるgracePeriodSeconds経過(デフォルト30秒)Phase: Succeeded/Failed
Cloud Native Developers JPコンテナのプロセスの停止• コンテナのプロセスは、kubeletからのSIGTERMまたはSIGKILLシグナルによって停止される• どちらのシグナルで終了するかは、gracePeriodSecondsが関係する– preStop hookがgracePeriodSeconds経過より早く終了した場合• SIGTERMシグナルが送られる(Gracefulな終了)• preStop hookを非同期に実行して終了すると即座にSIGTERMシグナルが送信される– preStop hookがgracePeriodSecondsを経過しても終了しない場合• SIGKILLシグナルが送られる(強制終了)28
Cloud Native Developers JPgracePeriodSecondsの設定方法• kubectlのオプションで指定する場合– --grace-period オプションで指定• manifestに記述する場合– Podのtemplateに、terminationGracePeriodSecondsで指定29$ kubectl delete deployment test --grace-period=60apiVersion: extensions/v1beta1kind: Deployment…template:spec:containers:- name: testimage: ...terminationGracePeriodSeconds: 60
Cloud Native Developers JPポリシーを適用して制御する30
Cloud Native Developers JPPodに適用可能なポリシーポリシー どんなもの?Resource Limit / Request Pod内の各コンテナに対して設定可能な、リソースの上限消費量(Limit)と最低要求量(Request)Resource Quota namespace単位で設定可能なリソース使用量の制限Pod Security Policy セキュリティ的に注意が必要な設定について、Pod specificationで適用可能な項目を調整する機能Network Policy Podが他のエンドポイント(Podやクラスター外のエンドポイント)に通信を行うときのポリシーを設定31
Cloud Native Developers JPResource Limit / Request32
Cloud Native Developers JPResource limits / Resource requests• Pod内の各コンテナに対して、消費リソースの下限/上限を設定• Resource limits / requestsを指定できるリソース– CPU– Memory– Local ephemeral storage(v1.10 beta)– Extended Resource33
Cloud Native Developers JPResource limits / requestsとNodeへのPodの配置• Podの配置前– 内包するコンテナ群のResource requestの合計まかなえるだけのCPU/Memory余剰がないNodeには、Podはスケジューリングされない• Podの配置後– コンテナのメモリ使用量が設定された上限を超えると、設定されたrestartPolicyに基づいてコンテナが再起動される– requestsより多くのメモリを使っているContainerがあると、Nodeがメモリ不足になったときにそのPodが排除される可能性がある– CPU利用量がlimitを超える場合もあり得るが、Podが廃棄されることはない34
Cloud Native Developers JPLocal Ephemeral Storage• Nodeのrootパーティションの利用量に対して limit / requestを設定– limitを超えるとPodごとNodeから排除される– requestを満たせないNodeにはスケジュールされない参考)Nodeのrootパーティション– kubeletが配置されるrootディレクトリや ログの保存先(/var/log)として利用されている– PodからはEmptyDirのVolumeとしてマウントすることで利用できる35apiVersion: v1kind: Podmetadata:name: frontendspec:containers:- - name: wpimage: wordpressresources:requests:ephemeral-storage: "2Gi"limits:ephemeral-storage: "4Gi"
Cloud Native Developers JPExtended Resource• Kubernetesが通常サポートする以外に、独自に管理したいリソースをExtended Resourceとして追加できる• Node-levelとCluster-levelとがある– Node-level: Node毎にリソースの量を設定するもの– Cluster-level: クラスター全体としてリソース量を設定するもの36
Cloud Native Developers JPNode-LevelのExtended Resource• Node毎にリソースの量を設定するもの• 以下の2種類がある– Device plugin managed resources• Device pluginによって管理されるリソース(GPUなど)。Device pluginの実装によって、制限のされ方が異なる– Other Resources• 任意の名前を指定した仮想的なリソースを、リソースの総量とともに設定できる• Kubernetes API経由で設定を行う(下例)37curl --header "Content-Type: application/json-patch+json" ¥--request PATCH ¥--data '[{"op": "add", "path": "/status/capacity/example.com~1dongle", "value": "4"}]' ¥http://localhost:8001/api/v1/nodes//status
Cloud Native Developers JPExtended Resourceのlimits/requests• Extended Resourceのlimits/requestsも、他のリソースと同じようにPodに設定できる38apiVersion: v1kind: Podmetadata:name: my-podspec:containers:- name: my-containerimage: myimageresources:requests:cpu: 2example.com/dongle: 1limits:example.com/dongle: 2
Cloud Native Developers JPResource Quota39
Cloud Native Developers JPResource Quota• namespace単位で設定可能なリソース使用量の制限• ResourceQuotaオブジェクトを登録することで設定する• Quotaを指定可能なリソース– CPU– Memory– Extended Resources– Storage Resource– Object Count40apiVersion: v1kind: ResourceQuotametadata:name: compute-resourcesspec:hard:pods: "4"requests.cpu: "1"requests.memory: 1Gilimits.cpu: "2"limits.memory: 2Girequests.nvidia.com/gpu: 4
Cloud Native Developers JPPod Security Policy41
Cloud Native Developers JPPod Security Policy• セキュリティ的に注意が必要な設定について、Pod specificationで適用可能な項目を調整する機能※ Pod単位/コンテナ単位のポリシー(PodSecuriyContext/SecurityContext)もある• Admission controllerを組み合わせて実装されており、KubernetesAPIを実行するアカウントにポリシーが適用される制御可能な項目の例42全ての項目は→ https://kubernetes.io/docs/concepts/policy/pod-security-policy/項目 Pod specでのフィールド名Privileged containerの利用可否 privilegedホストのファイルシステムの利用 allowedHostPathsコンテナのユーザーID、グループID runAsUser, supplementalGroupsコンテナが利用するAppArmorプロファイル (annotationで設定)
Cloud Native Developers JP参考)Admission Controllerとは• Kubernetes APIの呼び出しをフックして所定の処理を実行する仕組み– API呼び出しのvalidation(権限チェック、フォーマット適合確認など)– API呼び出しのmutate(作成しようとするリソースに変更を加えるなど)43API ServerCreate API callkubectlAdmissionWebhooks認証認可Object/Resource
Cloud Native Developers JPPod Security Policyの利用• Pod Security Policyを有効化するまでの流れ1. 許可するPolicyを設定(PodSecurityPolicyオブジェクトを作成)2. RBACでアカウントとPodSecurityPolicyを紐づけ• このアカウントでKubernetes APIを実行するとき、PodSecurityPolicyを満たさないPodが作成できないように制御される3. PodSecurityPolicy admission controllerを有効化– 詳細はZ Labの@tkusumiさんの記事(https://qiita.com/tkusumi/items/6692af743ae03dc0fdcc)に詳しい• 利用例– チームでクラスターを共有する運用で、ユーザー毎にできることを制限したいとき– pliviegedなコンテナを作成する操作はクラスター管理者のみに許可(監視系のコンテナを各Nodeに配置するなど)44
Cloud Native Developers JPNetwork Policy45
Cloud Native Developers JPNetwork Policy• Podが他のエンドポイント(Podやクラスター外のエンドポイント)に通信を行うときのポリシーを設定• NetworkPolicyリソースを作成することで有効になる• NetworkPolicyリソースには以下を記述– ingress/egressのポリシー– 適用対象Pod(LabelSelectorで指定)46kind: NetworkPolicyapiVersion: networking.k8s.io/v1metadata:name: access-nginxspec:podSelector:matchLabels:run: nginxingress:- from:- podSelector:matchLabels:access: "true"
Cloud Native Developers JPNetwork Policyを利用する上での注意点• NetworkPolicyは、それをサポートするnetwork providerを利用する必要がある…例えば、– 例)Calico, Cilium, Kube-router, Romana, Weave Net• よく見かけるflunnelは単体ではサポートしていない– canalを使うとCalicoと組み合わせてflannelが使えるということらしいが…• canal: https://github.com/projectcalico/canal47
Cloud Native Developers JPFin.48