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

Kubernetesマニアック

 Kubernetesマニアック

「隅からスミまでKubernetes総復習 - cndjpシーズン1まとめ」の後半分の資料です。
現地で手元で確認したい向け。セクションごとに整理して後ほどアップし直す予定です。

hhiroshell

June 14, 2018
Tweet

More Decks by hhiroshell

Other Decks in Technology

Transcript

  1. Cloud Native Developers JP Podの配置を制御するために使われる機能 機能 どんなもの? nodeSelector Nodeにあらかじめ設定されたLabelを使って、 Podの配置先を制御する

    Node Affinity nodeSelectorと同様の役割だが、より多機能な 制御が可能 Pod Affinity Nodeで稼働中のPodにもとづいて、新たなPod の配置先を制御する TaintとToleration Nodeに条件を設定して、特定の条件を満たした Podだけがスケジュールされるようにする 4
  2. Cloud Native Developers JP nodeSelector • Nodeにあらかじめ所定のLabelを設 定しておく • Pod側でnodeSelector要素を指定し、

    条件にマッチするNodeから配置先 が選択される 6 apiVersion: v1 kind: Pod metadata: name: nginx labels: env: test spec: containers: - name: nginx image: nginx imagePullPolicy: IfNotPresent nodeSelector: disktype: ssd
  3. Cloud Native Developers JP build-in node Lables • 利用者が追加しなくても、Nodeに設定されているLabelもある –

    kubernetes.io/hostname – beta.kubernetes.io/instance-type – beta.kubernetes.io/os – beta.kubernetes.io/arch – failure-domain.beta.kubernetes.io/zone – failure-domain.beta.kubernetes.io/region 7 マネージド・サービスを利用する場合に 通常設定されているもの ZoneやRegionを分けてPodを分散配置 したい場合に利用する
  4. Cloud Native Developers JP Affinityとanti-Affinity • Podが配置されるNodeを制御するという意味では、nodeSelectorと 同様の役割 • nodeSelectorと比較して

    – 表現力が高い(ANDやマッチングだけではない) – 設定された条件を満たさなくても妥協的に残Nodeに配置することができる – すでに可動しているPodのLabelを条件に使える(同居させたい/させたくな いPodを指定可能) • 提供する機能に応じていくつか種類がある – node affinity – inter-pod affinity/anti-affinity 9
  5. Cloud Native Developers JP Node Affinity (beta feature) • Node

    Affinityを設定するために、2種類のエントリーが利用可能 • requiredDuringSchedulingIgnoredDuringExecution – Podのスケジューリング時にチェックする条件 – 条件を満たすNodeがない場合はスケジューリングされない(required) • preferredDuringSchedulingIgnoredDuringExecution – Podのスケジューリング時にチェックする条件(同じく) – 条件を満たすNodeがあればそれに従い、ない場合もどこかに配置される (preferred) 10
  6. Cloud Native Developers JP 設定例 • この例では – kube…/e2e-az-name が”e2e-az1”または”e2e-az2”

    のNodeを要求 – another…-keyがanother…- valueのNodeに余剰があれば それに配置 • Nodeが満たす条件の weightの合計が高いほど、 そのNodeに配置され易い • operator: – In, NotIn, Exists, DoesNotExist, Gt, Lt – 複数のValueを組み合わせた 条件を設定 11 apiVersion: v1 kind: Pod … spec: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/e2e-az-name operator: In values: - e2e-az1 - e2e-az2 preferredDuringSchedulingIgnoredDuringExecution: - weight: 1 preference: matchExpressions: - key: another-node-label-key operator: In values: - another-node-label-value
  7. Cloud Native Developers JP Inter-pod affinityとanti-affinity (beta feature) • すでに可動しているPodにもとづいて、新しいPodを配置する条件を

    指定 • nodeAffinityと同様の文法で条件を記述 – requiredDuringSchedulingIgnoredDuringExecution →条件を満たさなければPodはスケジュールされない – preferredDuringSchedulingIgnoredDuringExecution →条件を満たすPodがなくともスケジュールされうる • topologyKeyによって、配置先のZoneやNodeを更に絞る • namespaceを指定して、配置先namespaceを絞る事もできる 12
  8. Cloud Native Developers JP Inter-pod affinityとanti-affinityの利用例 • Redisクラスターとクライアント – Redisキャッシュのコンテナを

    Nodeをまたいで分散配置 – Redisのクライアントアプリを 各Redisコンテナと同じNode に配置 • manifestの例はこちらに – https://kubernetes.io/docs/conce pts/configuration/assign-pod- node/#more-practical-use-cases 13 Redis Redis Redis App App App
  9. Cloud Native Developers JP 設定例 • この例では – securityがS1のPodが配置 されているNodeと同じ

    ZoneのNodeを要求 – securityがS2のPodが配置 されているNodeへのスケ ジュールは避けようとする • operatorで使えるもの は: – In, NotIn, Exists, DoesNotExist 14 apiVersion: v1 kind: Pod … spec: affinity: podAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: security operator: In values: - S1 topologyKey: failure-domain.beta.kubernetes.io/zone podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 100 podAffinityTerm: labelSelector: matchExpressions: - key: security operator: In values: - S2 topologyKey: kubernetes.io/hostname
  10. Cloud Native Developers JP topologyKeyには制約がいろいろある • podAffinityとpodAntiAffinityでは、 requiredDuringSchedulingIgnoredDuringExecutionを使う場合は topologyKeyが必須 •

    podAntiAffinityにrequiredDuringSchedulingIgnoredDuringExecutionを組 み合わせる場合、kubernets.io/hostnameのtopologyKeyはadmission controllerにより無効化される。この条件を使いたい場合はadmission controllerを無効にする必要がある • podAntiAffinityにpreferredDuringSchedulingIgnoredDuringExecutionを 組み合わせる場合で、topologyKeyを省略すると”全てのトポロジーを許 可”として解釈される • 上述の条件を除けば、topologyKeyには任意のLabelのKeyを設定できる 15
  11. Cloud Native Developers JP TaintsとTolerations • Taint: 汚点、汚染 → Nodeに設定

    • Toleration: 忍耐、容認 → Podに設定 • Nodeに条件を設定して、特定の条件を満たしたPodだけがスケ ジュールされるようにする 17 Node gpu=true: NoSchedule GPUが使いたいPod以外はスケジュールするなー OK! NG! Pod Pod gpu=true operator: Equal (Tolerationなし)
  12. Cloud Native Developers JP TaintsとTolerations • Taintsはkubectlから設定 • TorerationはPodのmanifestに記述 –

    上記のTaintsにマッチする(スケジュールされる)例 18 tolerations: - key: "key" value: “value” operator: "Equal" effect: "NoSchedule" tolerations: - key: "key" operator: "Exists" effect: "NoSchedule" $ kubectl taint nodes node1 key=value:NoSchedule ↑一致するkeyのTaintがあればマッチ ↑keyとvalueが一致するTaintがあればマッチ
  13. Cloud Native Developers JP TaintsとTolerations その他のルール • keyが設定されない場合、Existsオペレーターが全てのキーにマッチ する •

    effectが設定されない場合、keyが一致すれば全てマッチする 19 tolerations: - operator: "Exists" tolerations: - key: "key" operator: "Exists"
  14. Cloud Native Developers JP TaintsとTolerations – Effectに設定できる値 • NoSchedule: –

    TaintにマッチしないPodは配置しない • PreferNoSchedule: – TaintもマッチしないPodのスケジュールを避けようとするが、他にNodeがな い場合にはスケジュールされる場合もある • NoExecute: – Taintを設定したときすでに稼働中のPodに対しても効果が及ぶ – すでに可動中のPodでこのTaintにTolerationがマッチしない場合、Podから排 除され、それ以降スケジュールされない – tolerationsSecondsを指定することで、そのPodが排除されるまでの猶予時間 を指定できる 20
  15. Cloud Native Developers JP TaintsとTolerations – 使用例 • Dedicated Nodes

    – 特定の範囲のユーザーだけにNodeを使わせたいケース – 管理者の作業は目的のNodeにTaintを設定するだけでよい。マッチする Tolerationを設定していないPodを全て乗らないようにできる • Node with Special Hardware – GPUのような特殊なHWを積んだNodeを、それを必要としないPodに使わせ ないようにするケース – PodはHWの利用を明示的に宣言(Tolerationを設定)することで、それを利 用するということを明確にさせる 21
  16. Cloud Native Developers JP Kubernetesの拡張ポイント • Custom ResourceとKubernetes APIの拡張 •

    インフラの拡張 – Device Plugins – Network Plugins • Container Runtime Interface 23
  17. Cloud Native Developers JP その前に…PodとController • ほとんどのケースでは、DeploymentなどのControllerオブジェクト を作成することにより、結果的にPodが作成される – 例:

    Deploymentを作成してからPodが作成されるまで 25 Deployment Controller Deployment ReplicaSet Deployment Controller ReplicaSet Object/Resource Controller Watch Create Watch Create Create kubectl
  18. Cloud Native Developers JP PodとControllerとController Manager • 目的のユースケースに合わせて、Podをよしなに制御してくれるの が標準Controller •

    Deployment, ReplicaSetなどの標準Controllerを動かしているデーモ ンプロセスがcontroller-manager • Custom Controller – Controllerは所定のオブジェクト/リソースの状態をウォッチして、必要に応 じて更新処理を走らせるプロセス – このように動くものは自分でも作れるし、クラスターにデプロイすることも できる→Custom Controller 26
  19. Cloud Native Developers JP Custom ResourceとKubernetes APIの拡張 • Kubernetesに独自のリソース(Custom Object)を追加して利用する

    拡張方法 • 以下の3つの実装をセットにして、機能が成立 – Kubernetes APIの拡張: Custom Objectを操作可能なAPIの追加 – Custom Objectの作成: 拡張されたAPIを利用してリソースを作成 – Custom Controllerの作成: Custom Objectの登録を受けて実行する処理の実装 27 Custom Controller Custom Object Object/Resource Controller Watch Update 拡張された Kubernets API Create
  20. Cloud Native Developers JP Kubernetes APIの拡張 • Kubernetes APIを拡張する(≒Custom Objectを取り扱えるように

    する)2通りの方法 1. CustomResourceDefinition(CRD) • 利用者が追加作成できるリソース・タイプの定義 • CRDリソースをAPI Serverに登録することで、Custom Objectを取り扱えるようになる • v1.7まで使えたThirdPartyResourceの後継 2. Aggregation Layerの追加 • APIServiceオブジェクトを追加することで、標準のAPI Serverとは独立したAPI機能 (extension api-server)をクラスター内に立てる • Kubernetes APIの所定のPathにアクセスすると、extension api-serverにリクエストがプロ キシされる 28
  21. Cloud Native Developers JP CRDによるAPIの拡張 • CRDを登録すればOK – これをkubectl create

    –fで 登録するとAPI Serverの所定 のパスでこのリソースを操作 できる – /apis/stable.example.com/v 1/namespaces/*/crontabs/. .. – kubectlでも操作できる(次 ページ) 29 apiVersion: apiextensions.k8s.io/v1beta1 kind: CustomResourceDefinition metadata: name: crontabs.stable.example.com spec: group: stable.example.com version: v1 scope: Namespaced names: # plural name used in the URL: /apis/<group>/<version>/<plural> plural: crontabs # singular name to be used as an alias on the CLI and for display singular: crontab # kind is normally the CamelCased singular type kind: CronTab # shortNames to match your resource on the CLI shortNames: - ct
  22. Cloud Native Developers JP Custom Objectの作成 • Custom Objectを追加する –

    右例のようなmanifestを作成して kubectl create -f 30 apiVersion: "stable.example.com/v1" kind: CronTab metadata: name: my-new-cron-object spec: cronSpec: "* * * * */5" image: my-awesome-cron-image
  23. Cloud Native Developers JP Custom Controllerの作成 – 1. client-goの生成 •

    全て自力で実装することも不可能ではないと思われるが、クライア ントライブラリ(client-go)の生成ツールがある – https://github.com/kubernetes/code-generator – Custom Objectの型定義とAPIのメタ情報をgoで記述して、ツールにかませる と、Custom Controllerで利用可能なクライアントライブラリが生成される 31
  24. Cloud Native Developers JP Custom Controllerの作成 – 2. Controllerの実装 •

    client-goを使って Custom Controllerを 実装する – サンプルがあるのでそれを 参考に頑張る…。 https://github.com/kubernetes/kubernetes/tre e/master/staging/src/k8s.io/sample-controller 32 client-goが やってくれるところ controllerとして 実装するところ https://github.com/kubernetes/kubernetes/blob/master/staging/src/k8s.io/sampl e-controller/docs/controller-client-go.md
  25. Cloud Native Developers JP Custom Controllerの作成 – 3. Controllerのデプロイ •

    もちろんコンテナ化してデプロイします。 – コンテナ化してレジストリにプッシュ – DeploymentオブジェクトでControllerのコンテナイメージを指定やればよい 33
  26. Cloud Native Developers JP Custom Controller関連の参考リンク • Custom Controllerの作成は情報がまとまっていないのが辛い •

    以下参考にできるリンク – 「KubernetesのCRD(Custom Resource Definition)とカスタムコントローラーの作 成」 • https://qiita.com/__Attsun__/items/785008ef970ad82c679c – 公式のsample-controller実装: • https://github.com/kubernetes/kubernetes/tree/master/staging/src/k8s.io/sample- controller – クライアントライブラリ生成ツール: • https://github.com/kubernetes/code-generator – CRD周りの公式ドキュメント: • https://kubernetes.io/docs/tasks/access-kubernetes-api/extend-api-custom-resource- definitions/ 34
  27. Cloud Native Developers JP Infrastructureの拡張 – Device Plugin • Nodeに実装された特殊なデバイスを利用するためのプラグインの仕

    組み – 例えば、NVIDIA製GPUをコンテナから利用して機械学習を行うなど • 利用のするまでの流れ 1. デバイスプラグイン本体の準備→デバイスベンダーからの情報に従う • e.g. NVIDIAのGPUのドキュメント: https://github.com/NVIDIA/k8s-device-plugin 2. kubeletのDevice Pluginサポートを有効化 • kubeletの設定ファイル /etc/systemd/system/kubelet.service.d/10-kubeadm.conf に以下の環境オプショ ンを設定→kubeletを再起動 – Environment="KUBELET_EXTRA_ARGS=--feature-gates=DevicePlugins=true“ 3. Podでデバイスの利用を宣言 36
  28. Cloud Native Developers JP GPUを利用するPodの例 • resource limits/requestを 設定することで、所望のデ バイスのリソースを利用す

    ることを宣言 37 apiVersion: v1 kind: Pod metadata: name: gpu-pod spec: containers: - name: cuda-container image: nvidia/cuda:9.0-devel resources: limits: nvidia.com/gpu: 2 # requesting 2 GPUs - name: digits-container image: nvidia/digits:6.0 resources: limits: nvidia.com/gpu: 2 # requesting 2 GPUs
  29. Cloud Native Developers JP Infrastructureの拡張 – Network Plugin(alpha) • KubernetesはOverlay

    Networkに相当する部分をプラグインするこ とができ、CNI, kubenetの2方式がある 38 Node Pod Container eth0: 10.100.0.2 docker0: 1.0.1.1 veth0: 1.0.1.2 Node Pod Container eth0: 10.100.0.3 docker0: 1.0.2.1 veth0: 1.0.2.2 この辺の構成は Kubernetesのプロセスが やってくれる Overlay Network / ここをプラグイン的に別実装に変えられる
  30. Cloud Native Developers JP Network Plugin - CNI • CNCFのプロジェクトとして仕様策定が行われている

    – https://github.com/containernetworking/cni/blob/master/SPEC.md#netwo rk-configuration • KubernetesはCNIの各種実装をOverlay Networkにプラグインでき る – Calico, Weave … 39
  31. Cloud Native Developers JP CNIの導入方法 • CNIを使うために必要な作業 – CNIの設定ファイルを作成してNodeに配置 –

    プラグイン本体のバイナリを用意してNodeに配置 – kubelet の起動時に以下のオプションを指定 • --network-plugin=cni • --cni-conf-dir=[CNIの設定ファイルのパス] • --cni-bin-dir=[プラグイン本体のバイナリのパス] • 詳しくは公式を – https://github.com/containernetworking/cni/blob/master/SPEC.md#netwo rk-configuration 40
  32. Cloud Native Developers JP Network Plugin - kubenet • kubenet

    – クラウドプロバイダーのネットワークインフラに実装されたノード間ルー ティングと組み合わせて利用することを想定しているプラグイン – GKEなどでクラスターを作成すると自動で構成される – 内部にCNIのインタフェースを使っている部分もあるらしい… 41
  33. Cloud Native Developers JP Container Runtime Interface(CRI) • Kubernetes Container

    Runtime Interface(CRI) – KubeletからPodおよび Containerを操作するため の共通インターフェース – CRIに対応した実装の例 • cri-o, rktlet, Frakti, Docker CRI shim • cri-oはOCI標準に準拠し たランタイムを実行する 仕組み 43 CRIのインターフェース OCI標準準拠のランタイムを実行
  34. Cloud Native Developers JP Open Container Initiatives(OCI) • OCI –

    CNCFに属する下位組織(?) – コンテナランタイムの標準仕様を策定している • OCIの標準仕様 – runtime-spec / image-spec で構成 – コンテナの配布プロトコルの標準化も始めている • OCIのスペックに準拠したコンテナ・ランタイムの例 – runC(リファレンス実装), containerd, railcar 44
  35. Cloud Native Developers JP やりきれなかったところ • スケジューリングの制御周りはまだいろいろあります – Custom Schedulers

    • スケジューラーを独自実装して利用する機能 • デフォルトのスケジューラーと併せて、複数のCustom Schedulerを同時に利用可能 – Disruptions / Pod Disruption Budget – Taint based Evictions – Taint Nodes by Condition – Pod Priority and Preemption • オートスケーリングも大事 – Horizontal Pod Autoscaler – Cluster Autoscaling 47 • ストレージもプラグインできます – Storage Plugins