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/

Kazuki Suda

May 26, 2021
Tweet

More Decks by Kazuki Suda

Other Decks in Technology

Transcript

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

    View Slide

  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

    View Slide

  3. View Slide

  4. 株式会社 Preferred Networks
    ▶ 深層学習などの最先端の技術を最短路で実⽤化することで、これまで解決が困難であった
    現実世界の課題解決を⽬指しています
    ▶ ⾃動運転、製造、運輸、バイオ、ヘルスケア、ロボットといった多岐に渡る事業領域で、
    数多くの分野の研究者が⽇々 Kubernetes で構築された GPU クラスタで機械学習を⾏っています
    4

    View Slide

  5. @superbrothers
    なぜ実装レベルに関する知⾒・理解を深めたいのか
    単純に業務の役⽴つ
    ▶ 挙動から想像するより実装を⾒たほうが早いこともある
    + オープンソースならソースコードが⾒放題
    ▶ 壊れていると困るので直ってほしい
    + イシューを作成する次のステップとして⾃分で直しちゃったほうが早いこともある
    ▶ 使っているソフトウェアに貢献したい
    + 機能追加は議論が必要だったりお作法も難しいがバグ修正は簡単で貢献度も⾼くてオススメ
    5

    View Slide

  6. View Slide

  7. @superbrothers
    アジェンダ
    ▶ kubectl の実装を知ろう
    ▶ ちょっとした不便を kubectl プラグインで解決しよう
    7

    View Slide

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

    View Slide

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

    View Slide

  10. @superbrothers
    Worker Node
    kube-proxy
    kubelet
    Container Runtime
    OS
    ControlPlane Node
    etcd
    kube-apiserver
    kube-controller-manager
    kube-scheduler
    kubectl
    REST

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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{})

    View Slide

  15. @superbrothers
    ちょっとした不便を
    kubectl プラグインで解決しよう

    View Slide

  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

    View Slide

  17. @superbrothers
    kubectl プラグインをつくる
    ▶ kubectl コマンドの出⼒をレインボーにする🌈
    17
    $ cat < 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

    View Slide

  18. @superbrothers
    kubectl のプラグイン機構
    ▶ cmd/kubectl/kubectl.go
    + main 関数
    ▶ staging/src/k8s.io/kubectl/pkg/cmd/cmd.go
    + ルートコマンドが呼び出される前に kubectl に存在しておらず「kubectl-」プレフィックスを
    つけた名前を持つ実⾏ファイルが存在していれば実⾏
    18

    View Slide

  19. @superbrothers
    kubectl way なプラグインをつくるのに便利なライブラリ
    ▶ k8s.io/cli-runtime
    + —kubeconfig や —context、—output などのフラグをサポート
    ▶ k8s.io/kubectl
    + kubectl の内部で使われている便利関数などが使える
    そのほか、https://github.com/kubernetes/sample-cli-plugin が参考になる。
    19

    View Slide

  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

    View Slide

  21. @superbrothers
    Thanks / Question?
    ▶ SUDA Kazuki, @superbrothers
    ▶ Slide: https://speakerdeck.com/superbrothers/
    21

    View Slide