$30 off During Our Annual Pro Sale. View Details »

Kubernetesマニアック

 Kubernetesマニアック

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

hhiroshell

June 14, 2018
Tweet

More Decks by hhiroshell

Other Decks in Technology

Transcript

  1. Cloud Native Developers JP Kubernetesマニアック @hhiroshell 1

  2. Cloud Native Developers JP お品書き • Podの配置を制御する • Kubernetesの拡張 2

  3. Cloud Native Developers JP Podの配置を制御する 3

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

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

  6. 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
  7. 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を分散配置 したい場合に利用する
  8. Cloud Native Developers JP Node Affinity / Pod Affinity 8

  9. Cloud Native Developers JP Affinityとanti-Affinity • Podが配置されるNodeを制御するという意味では、nodeSelectorと 同様の役割 • nodeSelectorと比較して

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

    Affinityを設定するために、2種類のエントリーが利用可能 • requiredDuringSchedulingIgnoredDuringExecution – Podのスケジューリング時にチェックする条件 – 条件を満たすNodeがない場合はスケジューリングされない(required) • preferredDuringSchedulingIgnoredDuringExecution – Podのスケジューリング時にチェックする条件(同じく) – 条件を満たすNodeがあればそれに従い、ない場合もどこかに配置される (preferred) 10
  11. 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
  12. Cloud Native Developers JP Inter-pod affinityとanti-affinity (beta feature) • すでに可動しているPodにもとづいて、新しいPodを配置する条件を

    指定 • nodeAffinityと同様の文法で条件を記述 – requiredDuringSchedulingIgnoredDuringExecution →条件を満たさなければPodはスケジュールされない – preferredDuringSchedulingIgnoredDuringExecution →条件を満たすPodがなくともスケジュールされうる • topologyKeyによって、配置先のZoneやNodeを更に絞る • namespaceを指定して、配置先namespaceを絞る事もできる 12
  13. 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
  14. 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
  15. 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
  16. Cloud Native Developers JP TaintとToleration 16

  17. 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なし)
  18. 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があればマッチ
  19. Cloud Native Developers JP TaintsとTolerations その他のルール • keyが設定されない場合、Existsオペレーターが全てのキーにマッチ する •

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

    TaintにマッチしないPodは配置しない • PreferNoSchedule: – TaintもマッチしないPodのスケジュールを避けようとするが、他にNodeがな い場合にはスケジュールされる場合もある • NoExecute: – Taintを設定したときすでに稼働中のPodに対しても効果が及ぶ – すでに可動中のPodでこのTaintにTolerationがマッチしない場合、Podから排 除され、それ以降スケジュールされない – tolerationsSecondsを指定することで、そのPodが排除されるまでの猶予時間 を指定できる 20
  21. 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
  22. Cloud Native Developers JP Kubernetesの拡張 22

  23. Cloud Native Developers JP Kubernetesの拡張ポイント • Custom ResourceとKubernetes APIの拡張 •

    インフラの拡張 – Device Plugins – Network Plugins • Container Runtime Interface 23
  24. Cloud Native Developers JP Custom ResourceとKubernetes APIの拡張 24

  25. 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
  26. Cloud Native Developers JP PodとControllerとController Manager • 目的のユースケースに合わせて、Podをよしなに制御してくれるの が標準Controller •

    Deployment, ReplicaSetなどの標準Controllerを動かしているデーモ ンプロセスがcontroller-manager • Custom Controller – Controllerは所定のオブジェクト/リソースの状態をウォッチして、必要に応 じて更新処理を走らせるプロセス – このように動くものは自分でも作れるし、クラスターにデプロイすることも できる→Custom Controller 26
  27. 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
  28. 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
  29. 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
  30. 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
  31. Cloud Native Developers JP Custom Controllerの作成 – 1. client-goの生成 •

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

    もちろんコンテナ化してデプロイします。 – コンテナ化してレジストリにプッシュ – DeploymentオブジェクトでControllerのコンテナイメージを指定やればよい 33
  34. 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
  35. Cloud Native Developers JP インフラの拡張 35

  36. 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
  37. 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
  38. 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 / ここをプラグイン的に別実装に変えられる
  39. 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
  40. 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
  41. Cloud Native Developers JP Network Plugin - kubenet • kubenet

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

  43. 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標準準拠のランタイムを実行
  44. Cloud Native Developers JP Open Container Initiatives(OCI) • OCI –

    CNCFに属する下位組織(?) – コンテナランタイムの標準仕様を策定している • OCIの標準仕様 – runtime-spec / image-spec で構成 – コンテナの配布プロトコルの標準化も始めている • OCIのスペックに準拠したコンテナ・ランタイムの例 – runC(リファレンス実装), containerd, railcar 44
  45. Cloud Native Developers JP oci-oの利用方法 • 具体的な手順はこちら – https://adtech.cyberagent.io/techblog/archives/4036 –

    (渋谷方面に足を向けて寝られない) 45
  46. Cloud Native Developers JP Fin. 46

  47. 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