Kubernetes 1.16 アルファ機能を先取り!
エフェメラルコンテナ / Kubernetes 1.16 Ephemeral Containers (alpha)

9f9df80ab6551776b49c4ad9432ba1b7?s=47 Kazuki Suda
October 24, 2019

Kubernetes 1.16 アルファ機能を先取り!
エフェメラルコンテナ / Kubernetes 1.16 Ephemeral Containers (alpha)

Kubernetes Meetup Tokyo #24 (2019/10/24) - https://k8sjp.connpass.com/event/149872/

Kubernetes には kubectl exec や port-forward といったアプリケーションのデバッグに必要な機能が用意されていますが、scratch イメージをベースとした最小イメージではコマンドがインストールされておらずデバッグが困難という課題がありました。

Kubernetes 1.16 でアルファ機能として実装されたエフェメラルコンテナは、実行中の Pod に一時的にデバッグ用のコンテナを差し込む機能です。このセッションでは、エフェメラルコンテナの概要と PoC 実装である kubectl-debug プラグインを使ったデモを通じて、将来来る Kubernetes でのデバッグ方法を先取りで紹介します。

9f9df80ab6551776b49c4ad9432ba1b7?s=128

Kazuki Suda

October 24, 2019
Tweet

Transcript

  1. Kubernetes Meetup Tokyo #24 (2019/10/24) Kazuki Suda <ksuda@zlab.co.jp>, @superbrothers Kubernetes

    1.16 アルファ機能を先取り!
 エフェメラルコンテナ
  2. Kazuki Suda / @superbrothers ▶ ゼットラボ株式会社 ソフトウェアエンジニア ▶ ヤフー株式会社 「Kubernetes」黒帯

    ▶ Kubernetes Meetup Tokyo, Cloud Native Deep Dive 共同主催者 ▶ Kubernetes Active Contributor ▶ CNCF Ambassador ▶ 「Kubernetes実践⼊⾨」、「みんなのDocker/Kubernetes」共著書 ▶ 「⼊⾨ Prometheus」監訳
  3. アジェンダ 1. Kubernetes でアプリケーションをトラブルシュート/デバッグする 2. エフェメラルコンテナ 3. エフェメラルコンテナ、もっと詳しく 4. 今後のマイルストーン

    5. まとめ
  4. Kubernetes でアプリケーションを
 トラブルシュート/デバッグする

  5. デバッグに使える kubectl のサブコマンド kubectl run Pod を作成する kubectl logs コンテナのログを出⼒する

    kubectl exec コンテナ内で任意のコマンドを実⾏する kubectl port-forward コンテナ内のポートをローカルに転送する kubectl cp コンテナとローカル間でファイルを転送する kubectl top Pod やノードのリソース状況を表⽰する Debugging Applications in Kubernetes - Kubernetes Meetup Tokyo #10
  6. kubectl exec の課題 ▶ コンテナ内で任意のコマンド(プロセス)を実⾏する ▶ つまり、コンテナに含まれるコマンドしか実⾏できない $ kubectl exec

    -it myapp -- /bin/sh OCI runtime exec failed: exec failed: container_linux.go:345: starting container process caused "exec: \"/bin/sh\": stat / bin/sh: no such file or directory": unknown command terminated with exit code 126
  7. kubectl exec の課題 開発者は、コンテナイメージのベストプラクティスであるところの scratch や distroless* をベースイメージに使いたい。 ▶ 最⼩イメージは、運⽤上の負担が⼩さく(セキュリティスキャナのノイズの


    削減)、アタックサーフェス(攻撃対象領域)が狭い ▶ サイズが⼩さいイメージは、ダウンロードから実⾏されるまでの時間が最⼩化さ れ、ディスクの使⽤量も少なくて済む * Google が公開する ランタイムのみを含むコンテナイメージです
  8. kubectl exec の課題 ⼀⽅で、ディストリビューションから提供されるデバッグユーティリティが含まれな いため、実⾏中のコンテナのトラブルシューティングが困難になる。 ▶ デバッグ⽤のサイドカーコンテナを仕込んでおけば解消できるが、全ての Pod に ⼊れておくのはリソースの無駄

    ▶ 最低限のユーティリティを仕込んでおく場合も、デバッグする⼈が必ずしも
 イメージを作成した⼈とは限らないことがある + 特に他社が⽤意したイメージにわざわざ⼿を⼊れるのは⾯倒 デバッグは自分が慣れ親しんだ環境で実施したい!
  9. エフェメラルコンテナ Kubernetes 1.16 からの最新機能です!

  10. エフェメラルコンテナ(Ephemeral Containers) 実⾏中の Pod にトラブルシュートやデバッグを⽬的としてエフェメラルな
 (はかない/⼀時的な)コンテナを追加する ▶ Kubernetes 1.16 でアルファとして機能提供

    + デフォルトで無効(FeatureGate EphemeralContainers) ▶ 現時点では、Pod.spec.shareProcessNamespace を有効にする必要がある まだ実験的機能です。
 本番での使用はまだやめましょう。 Pod コンテナ コンテナ エフェメラル
 コンテナ
  11. エフェメラルコンテナのユースケース ▶ オペレーション: ネットワークに不具合があるかどうかの調査 ▶ デバッグ: 再現の難しいトリッキーな問題を解決するために、既存のコンテナで
 直接デバッグする ▶ ⾃動化:

    共通のベースイメージを使⽤していない組織において、セキュリティ監査 スクリプトを全ての Pod で実⾏する ▶ テクニカルサポート: ノードへのアクセス権限がなく、アプリケーションコンテナ の作成に関わっていない場合にできることは、⽤意した調査スクリプトを顧客に まず最初に実⾏してみてもらうこと
  12. エフェメラルコンテナの制約 デバッグ以外の⽤途で使わせないために通常のコンテナとは異なる部分がある ▶ 実⾏に必要なリソースの確保できる保証がなく、また再起動されない ▶ 通常のコンテナで使⽤できる多くのフィールドが使⽤できない + ports, resources, livenessProbe,

    readinessProbe, etc なにか別の用途にべんりに使われてしまわないようになってます
  13. # Create a debugging container in pod myapp using defaults

    (a busybox image named "debugger") # and immediately attach to it using "kubectl attach". $ kubectl debug mypod --attach ▶ エフェメラルコンテナを作成するための kubectl debug コマンドが提供予定 + 現時点では PoC 実装である kubectl-debug kubectl プラグイン*がある ▶ このコマンド提供後も、kubectl exec は継続して提供される + kubectl exec: コンテナ内でコマンド(プロセス)を実⾏する + kubectl debug: Pod 内で⼀時的なコンテナを実⾏する *https://github.com/verb/kubectl-debug デモします!
  14. エフェメラルコンテナ、もっと詳しく 「Kubernetes API + kubelet」と「kubectl」の
 2つの実装から構成されます! 取り扱い注意
 アルファ時点での情報で、今後仕様が⼤きく変更される可能性があります

  15. Pod の変更(2つフィールドの追加) apiVersion: v1 kind: Pod metadata: name: myapp spec:

    (...) ephemeralContainers: - image: busybox imagePullPolicy: IfNotPresent name: debugger resources: {} stdin: true terminationMessagePolicy: File tty: true (...) status: ephemeralContainerStatuses: - containerID: docker://0a5bce… image: busybox:latest imageID: docker-pullable://busyb… lastState: {} name: debugger ready: false restartCount: 0 v1.Container に加えて、 TargetContainerName フィールドを持つ v1.EphemeralContainer の配列 v1.ContainerStatus の配列 PIDネームスペースをあとから共有するコンテナを
 明示的に指定するためのフィールドで、
 1.16時点では未サポート
  16. API Server の変更 Pod ephemeralcontainers サブリソースの追加 /api/v1/namespaces/{namespace}/pods/{pod}/ephemeralcontainers ▶ サブリソースとすることで、クラスタ管理者は、Pod の他の操作と独⽴して


    エフェメラルコンテナの操作をアクセス制御できる ▶ サブリソース attach, log などはエフェメラルコンテナに対して有効なことか ら、kubectl attach, logs などがエフェメラルコンテナに対して実⾏できる ▶ エフェメラルコンテナに依存する Pod を避けるために、 Pod スペックの
 定義による作成時の設定を許可しない すでに存在するPodに対してエフェメラルコンテナを
 追加することしかできないということです。
  17. ▶ エフェメラルコンテナをリストする ▶ エフェメラルコンテナを更新する kubectl get --raw /api/v1/namespaces/default/pods/myapp/ephemeralcontainers cat <<EOL

    | kubectl replace --raw /api/v1/namespaces/default/pods/myapp/ephemeralcontainers -f- { "apiVersion": "v1", "kind": "EphemeralContainers", "metadata": { "name": "myapp" }, "ephemeralContainers": [ { "name": "debugger2", "image": "busybox",
  18. kubelet の変更(エフェメラルコンテナの起動) Pod をウォッチして、spec.ephemeralContainers に変更があれば
 エフェメラルコンテナを起動する ▶ エフェメラルコンテナの起動は、CRI(Container Runtime Interface)を使⽤して

    ⾏われるため、CRI を実装しているすべてのコンテナランタイムで
 エフェメラルコンテナが使⽤できる
  19. *https://github.com/verb/kubectl-debug PoC 実装時点での仕様なことに注意してください。 $ kubectl debug -h Attach a debug

    container to a running pod Usage: debug [pod] [flags] Flags: --attach kubectl attach Exec kubectl attach to attach to container after creation. -c, --container string Container name. If omitted, a default will be chosen. (default "debugger") -m, --image string Container image. (default "busybox")
  20. // Run lists all available debugs on a user's KUBECONFIG

    or updates the // current context based on a provided debug. func (o *DebugOptions) Run() error { (...) err := r.Visit(func(info *resource.Info, err error) error { (...) pods := o.clientset.CoreV1().Pods(info.Namespace) ec, err := pods.GetEphemeralContainers(info.Name, metav1.GetOptions{}) klog.V(2).Infof("existing ephemeral containers: %v", ec.EphemeralContainers) ec.EphemeralContainers = append(ec.EphemeralContainers, o.debugContainer) ec, err = pods.UpdateEphemeralContainers(info.Name, ec) (...) https://github.com/verb/kubectl-debug/blob/v0.1.1/pkg/cmd/debug.go
  21. 今後のマイルストーン

  22. 今後のマイルストーン ✅ Core API へのエフェメラルコンテナの追加(1.16) ✅ 基本的なエフェメラルコンテナの作成を kubelet がサポート(1.16) ✅

    エフェメラルコンテナを起動するための kubectl コマンド(1.17) ⬜ container namespace targeting を kubelet がサポート(1.17) ⬜ アルファステージでのフィーチャコンプリート(1.18) 2019年10月7日時点の
  23. まとめ

  24. まとめ 1. Kubernetes でアプリケーションをトラブルシュート/デバッグする + kubectl exec にはコンテナに含まれるコマンドしか実⾏できない課題があります 2. エフェメラルコンテナ

    + トラブルシュートやデバッグを⽬的として実⾏中の Pod に⼀時的なコンテナを 追加する機能です 3. エフェメラルコンテナ、もっと詳しく + 「Kubernetes API、kubelet」と「kubectl」の2つの実装から構成されます 4. 今後のマイルストーン + 本番で使⽤できるまでにはもう少し時間がかかりそうです
  25. Question? ▶ Kazuki Suda <ksuda@zlab.co.jp>, @superbrothers ▶ Slide: https://speakerdeck.com/superbrothers/

  26. Appendix ▶ Ephemeral Containers · Issue #277 · kubernetes/enhancements +

    https://github.com/kubernetes/enhancements/issues/277 ▶ Add Ephemeral Containers to the Kubernetes core API #59416 + https://github.com/kubernetes/kubernetes/pull/59416 ▶ Ephemeral Containers - Kubernetes + https://kubernetes.io/docs/concepts/workloads/pods/ephemeral-containers/ ▶ Kubernetes 1.16: Ephemeral Containers (alpha) - Qiita + https://qiita.com/superbrothers/items/85edec4d0232e0bbe2c0