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

kubectl internal

kubectl internal

Kubernetes の CLI ツールである kubectl がどのようにクラスタとやりとりしているのか、ソースコードからみていきます。 加えて、kubectl のプラグイン機構の紹介とどのように実現されているのか、プラグインの作り方も紹介します。

Kubernetes Internal #8 / https://k8sinternal.connpass.com/event/212249/

9f9df80ab6551776b49c4ad9432ba1b7?s=128

Kazuki Suda

May 26, 2021
Tweet

Transcript

  1. Kubernetes Internal #8(2021/05/26) SUDA Kazuki, Preferred Networks, Inc. @superbrothers kubectl

    internal
  2. @superbrothers SUDA Kazuki / @superbrothers ▶ Preferred Networks, Inc. /

    エンジニア ▶ Kubernetes Meetup Tokyo, Prometheus Meetup Tokyo ほか、共同主催者 ▶ Cloud Native Ambassador (CNCF) ▶ 「Kubernetes実践⼊⾨」、「みんなのDocker/Kubernetes」共著書 ▶ 「⼊⾨ Prometheus」、「Kubernetes で実践するクラウドネイティブ DevOps」監訳書 2
  3. None
  4. 株式会社 Preferred Networks ▶ 深層学習などの最先端の技術を最短路で実⽤化することで、これまで解決が困難であった 現実世界の課題解決を⽬指しています ▶ ⾃動運転、製造、運輸、バイオ、ヘルスケア、ロボットといった多岐に渡る事業領域で、 数多くの分野の研究者が⽇々 Kubernetes

    で構築された GPU クラスタで機械学習を⾏っています 4
  5. @superbrothers なぜ実装レベルに関する知⾒・理解を深めたいのか 単純に業務の役⽴つ ▶ 挙動から想像するより実装を⾒たほうが早いこともある + オープンソースならソースコードが⾒放題 ▶ 壊れていると困るので直ってほしい +

    イシューを作成する次のステップとして⾃分で直しちゃったほうが早いこともある ▶ 使っているソフトウェアに貢献したい + 機能追加は議論が必要だったりお作法も難しいがバグ修正は簡単で貢献度も⾼くてオススメ 5
  6. None
  7. @superbrothers アジェンダ ▶ kubectl の実装を知ろう ▶ ちょっとした不便を kubectl プラグインで解決しよう 7

  8. @superbrothers kubectl delete コマンドを例に kubectl の実装を知ろう

  9. @superbrothers kubectl ▶ Kubernetes の CLI ツール ▶ 主な役割は kube-apiserver

    とやり取りしての Kubernetes オブジェクトの取得、作成、変更、削除 + やり取りには github.com/kubernetes/client-go が使⽤されている ▶ CLI アプリケーションの作成には、github.com/spf13/cobra が使⽤されている ▶ そのほか、github.com/kubernetes/cli-runtime にヘルパ関数がある 9
  10. @superbrothers Worker Node kube-proxy kubelet Container Runtime OS ControlPlane Node

    etcd kube-apiserver kube-controller-manager kube-scheduler kubectl REST
  11. $ kubectl help kubectl controls the Kubernetes cluster manager. Find

    more information at: https://kubernetes.io/docs/reference/kubectl/overview/ Basic Commands (Beginner): create Create a resource from a file or from stdin. expose Take a replication controller, service, deployment or pod and expose it as a new Kubernetes Service run Run a particular image on the cluster set Set specific features on objects Basic Commands (Intermediate): explain Documentation of resources get Display one or many resources edit Edit a resource on the server delete Delete resources by filenames, stdin, resources and names, or by resources and label selector Deploy Commands: rollout Manage the rollout of a resource scale Set a new size for a Deployment, ReplicaSet or Replication Controller autoscale Auto-scale a Deployment, ReplicaSet, StatefulSet, or ReplicationController Cluster Management Commands: certificate Modify certificate resources. cluster-info Display cluster info top Display Resource (CPU/Memory) usage. cordon Mark node as unschedulable uncordon Mark node as schedulable drain Drain node in preparation for maintenance taint Update the taints on one or more nodes Troubleshooting and Debugging Commands: describe Show details of a specific resource or group of resources logs Print the logs for a container in a pod
  12. @superbrothers kubectl delete コマンド ▶ cmd/kubectl/kubectl.go + main 関数 ▶

    staging/src/k8s.io/kubectl/pkg/cmd/cmd.go + ルートコマンド(kubectl)の実装 ▶ staging/src/k8s.io/kubectl/pkg/cmd/delete/delete.go + delete サブコマンドの実装 12
  13. type DeleteOptions struct { ... } func NewCmdDelete(f cmdutil.Factory, streams

    genericclioptions.IOStreams) *cobra.Command { deleteFlags := NewDeleteCommandFlags("containing the resource to delete.") cmd := &cobra.Command{ Use: "delete ([-f FILENAME] | [-k DIRECTORY] | TYPE [(NAME | -l label | --all)])", DisableFlagsInUseLine: true, Short: i18n.T("...."), Long: deleteLong, Example: deleteExample, Run: func(cmd *cobra.Command, args []string) { o, err := deleteFlags.ToOptions(nil, streams) cmdutil.CheckErr(err) cmdutil.CheckErr(o.Complete(f, args, cmd)) cmdutil.CheckErr(o.Validate()) cmdutil.CheckErr(o.RunDelete(f)) }, SuggestFor: []string{"rm"}, } deleteFlags.AddFlags(cmd) cmdutil.AddDryRunFlag(cmd) return cmd } func (o *DeleteOptions) Complete(f cmdutil.Factory, args []string, cmd *cobra.Command) error { ... } func (o *DeleteOptions) Validate() error { ... } func (o *DeleteOptions) RunDelete(f cmdutil.Factory) error { ... } https://github.com/kubernetes/kubernetes/blob/v1.21.1/staging/src/k8s.io/kubectl/pkg/cmd/delete/delete.go
  14. @superbrothers typed client と dynamic client ▶ typed client(型付きクライアント) +

    k8s.io/client-go/kubernetes + map[string]interface{} のようなデータ構造を使⽤せずに各 GVK(GroupVersionKind)に Go の type を使⽤する + 使いやすく、型の安全性があり、簡潔で読みやすい + ⼀⽅でコンパイル時に型を知っておく必要があり柔軟性がない ▶ dynamic client(動的クライアント) + k8s.io/client-go/dynamic + Json.Unmarshal の出⼒をラップする unstructured.Unstructured という type のみを使う + type に関する情報を開発者が提供する必要がある + 様々なリソースを⼀緒くたに扱う場合に有⽤ 14 clientset.AppsV1().Deployments(namespace).Get(context.TODO(), name, metav1.GetOptions{}) gvr := schema.GroupVersionResource{Group: "apps", Version: "v1", Resource: “deployment"} client.Resource(gvr).Namespace(namespace).Get(context.TODO, name, metav1.GetOptions{})
  15. @superbrothers ちょっとした不便を kubectl プラグインで解決しよう

  16. @superbrothers kubectl プラグインとは ▶ kubectl に任意のサブコマンドを追加する機能 ▶ Kubernetes が拡張性を重視するなかで CLI

    ツールの拡張機能として提供されている ▶ ⼀般的に git-style と呼ばれるプラグイン機構を採⽤ + PATH の通ったディレクトリに配置された実⾏ファイルの名前が特定のプレフィックスで 開始しているものを呼び出す + kubectl プラグインの場合はプレフィックスが「kubectl-」 16 $ kubectl plugin list The following compatible plugins are available: /home/ksuda/.krew/bin/kubectl-images /home/ksuda/.krew/bin/kubectl-krew /home/ksuda/.krew/bin/kubectl-open_svc /home/ksuda/.krew/bin/kubectl-rolesum /home/ksuda/.krew/bin/kubectl-tree /home/ksuda/.krew/bin/kubectl-view_secret /home/ksuda/.krew/bin/kubectl-view_serviceaccount_kubeconfig
  17. @superbrothers kubectl プラグインをつくる ▶ kubectl コマンドの出⼒をレインボーにする🌈 17 $ cat <<EOL

    > kubectl-lol #!/usr/bin/env bash exec kubectl "$@" | lolcat EOL $ chmod +x kubectl-lol $ mv kubectl-lol /usr/local/bin/ $ kubectl lol get po -A
  18. @superbrothers kubectl のプラグイン機構 ▶ cmd/kubectl/kubectl.go + main 関数 ▶ staging/src/k8s.io/kubectl/pkg/cmd/cmd.go

    + ルートコマンドが呼び出される前に kubectl に存在しておらず「kubectl-」プレフィックスを つけた名前を持つ実⾏ファイルが存在していれば実⾏ 18
  19. @superbrothers kubectl way なプラグインをつくるのに便利なライブラリ ▶ k8s.io/cli-runtime + —kubeconfig や —context、—output

    などのフラグをサポート ▶ k8s.io/kubectl + kubectl の内部で使われている便利関数などが使える そのほか、https://github.com/kubernetes/sample-cli-plugin が参考になる。 19
  20. @superbrothers kubectl プラグインを配布する ▶ kubectl plugin マネージャ Krew + プラグインマネージャで、インデックスに登録されたプラグインをインストール、管理できる

    + これ⾃体も kubectl プラグインとして実装されている + インデックスリポジトリ: https://github.com/kubernetes-sigs/krew-index + カスタムインデックス機能もある + https://krew.sigs.k8s.io/docs/user-guide/custom-indexes/ ▶ Homebrew + 信頼と実績 20
  21. @superbrothers Thanks / Question? ▶ SUDA Kazuki, @superbrothers ▶ Slide:

    https://speakerdeck.com/superbrothers/ 21