kubeadmに学ぶクラスター構築/implementation of kubeadm init

3499a1d71fa70b8ee44816ca9e7329fe?s=47 bells17
September 29, 2020

kubeadmに学ぶクラスター構築/implementation of kubeadm init

Kubernetes Novice Tokyo #5 (#k8snovice)
https://k8s-novice-jp.connpass.com/event/187873/
で発表したLT資料です。

配信アーカイブのURLは
https://youtu.be/Qxn8aQTUZuo
になります。

3499a1d71fa70b8ee44816ca9e7329fe?s=128

bells17

September 29, 2020
Tweet

Transcript

  1. kubeadmに学ぶクラスター構築 Kubernetes Novice Tokyo #5(2020/09/09) @bells17

  2. ▶ @bells17 ▶ Software Engineer ▶ 主に Kubernetes 関連コンポーネントの開発など ▶

    Kubernetes #sig-docs-ja-reviews ▶ CNBF実⾏委員 ▶ @bells17_
  3. 今⽇話すこと ▶ kubeadm init時にどんなことが⾏われているのかについて ▶ Kubeadm initによるクラスター構築処理で使われている機能・技術に ついて

  4. 注意点 ▶ 僕⾃⾝はkubeadmにあまり詳しいわけではないです + (現時点で調べてわかったことを共有するだけになります) ▶ 説明は基本的にkubeadmに特に設定値を渡していないケースを想定し てるつもりです ▶ コードべースはv1.19です(release-1.19タグ)

  5. アジェンダ 1. kubeadmとは? 2. kubeadm initによるクラスター構築

  6. kubeadmとは?

  7. Kubeadm ▶ Kubernetesコミュニティ公式のKubernetesクラスター構築ツール ▶ Kubernetesクラスター構築の「ベストプラクティス」を提供 ▶ Kubeadmはクラスターのブートストラップにフォーカスした機能を提供 する + コンテナランタイムやkubeletのインストールはkubeadmのスコープ外

    ▶ Kubesprayやkindなどその他のKubernetesクラスター構築ツールの内部 で使われていることがある ▶ kubeadmが⾏うクラスター構築処理を1(サブ)フェーズ単位で実⾏できる ようになっている ▶ KubernetesコミュニティのSig Cluster Lifecycleによって開発されている
  8. https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/ 1コマンドでKubernetesクラスターを構築できる

  9. Kubeadmの様々なサブコマンド ▶ kubeadm init: Kubernetesクラスターの構築 ▶ kubeadm join: 構築したクラスターへの参加 ▶

    kubeadm upgrade: Kubernetesバージョンのアップグレード ▶ kubeadm config: kubeadmの設定管理 ▶ etc この中で今回はkubeadm initの処理にフォーカスした内容です
  10. kubeadmはサブコマンド内で実⾏される処理がphaseという単位によって分割
 されており、各phase単位でコマンドから処理が実⾏可能になっている

  11. https://github.com/kelseyhightower/kubernetes-the-hard-way

  12. kubeadm initの実装を読むことで、 Kubernetesクラスター構築のベストプラク ティスを提供してくれるツールはどのように クラスターを構築しているのかを知ることが できる

  13. https://github.com/kubernetes/kubeadm/blob/master/docs/design/design_v1.10.md Implementation design for kubeadm
 を読むとなんとなくはkubeadmの処理の流れが理解できる

  14. kubeadm initによるクラスター構築

  15. kubeadm initでやってくれること ▶ 設定に基づいたKubernetesクラスターの構築 ▶ クラスターへの接続情報ファイル(kubeconfig)の⽣成 ▶ その他のマシンが構築したクラスターへ参加するためのコマンドの提⽰ ▶ kubeadm

    joinコマンド
  16. kubeadm initのフェーズ⼀覧 ▶ preflight ▶ certs ▶ kubeconfig ▶ kubelet-start

    ▶ control-plane ▶ etcd ▶ wait-control-plane ▶ upload-config ▶ upload-certs ▶ mark-control-plane ▶ bootstrap-token ▶ kubelet-finalize ▶ addon •チェック処理 •クラスター構築 •Kubeadmによるクラスター管理
  17. https://github.com/kubernetes/website/blob/master/static/images/docs/components-of-kubernetes.png

  18. preflight ▶ Kubeadmによるクラスター構築のための各種チェックを⾏う ▶ Kubeadmの実⾏ユーザーのチェック ▶ kubeletのバージョンチェック ▶ etc

  19. certs ▶ Kubernetesクラスターのための各種証明書の⽣成を⾏う ▶ CA証明書 ▶ APIサーバー証明書 ▶ etc

  20. kubeconfig ▶ 各種control plane/管理者のためのkubeconfigファイルの⽣成を⾏う ▶ 以下の4者のためのkubeconfigを⽣成 ▶ 管理者 ▶ kubelet

    ▶ kube controller manger ▶ kube scheduler ▶ kubernetes/kubernetesのcmd/kubeadm/app/util/kubeconfig
 パッケージにあるCreateBasic関数を使ってkubeconfigファイルのデータを⽣ 成 ▶ その後CreateBasic関数の呼び出し元であるCreateWithCerts関数内でクライ アント証明を埋め込んでいる ▶ クライアント証明書は前のステップで⽣成したファイルを読み込んでいる
  21. https://github.com/kubernetes/kubernetes/blob/release-1.19/cmd/kubeadm/app/util/kubeconfig/kubeconfig.go#L30-L51  CreateBasic

  22. https://github.com/kubernetes/kubernetes/blob/release-1.19/cmd/kubeadm/app/util/kubeconfig/kubeconfig.go#L53-L61   CreateWithCerts

  23. kubelet-start ▶ kubeadmの設定に基づいたkubelet設定ファイルを⽣成し、kubeletの (再)起動を⾏う ▶ systemctl/openrcを利⽤していることが前提となっているよう ▶ 内部的にはsystemctlコマンドなどを実⾏しているだけ ▶ 内部的な処理は以下のようになっている

    ▶ systemctlなどで起動されているkubeletを⼀時停⽌ ▶ 環境変数設定を⽣成~ファイルを⽣成 ▶ 設定を⽣成~ファイルを作成 ▶ systemctlなどでkubeletを起動
  24. control-plane ▶ Static Podで各種control planeのpodを起動するためのpod specマニフェスト ファイルを⽣成する ▶ 以下のコンポーネントのためのyamlを⽣成する ▶

    kube apiserver ▶ kube controller manger ▶ kube scheduler ▶ 内部処理は以下の様になっている ▶ ベースとなるpodのspecを⽣成 ▶ 設定に応じたkustomize/patchファイルによるspecの書き換えを⾏う ▶ ⽣成したspecをstatic pod⽤のファイルとして書き込む ▶ specの書き換えについてはドキュメントについては記載が⾒当たらない(気が する)
  25. https://github.com/kubernetes/kubernetes/blob/release-1.19/cmd/kubeadm/app/phases/controlplane/manifests.go#L46-L91   ベースとなるpod specの⽣成

  26. https://github.com/kubernetes/kubernetes/blob/release-1.19/cmd/kubeadm/app/util/staticpod/utils.go#L153-L183   Kustomizeによるpod specの書き換え

  27. https://github.com/kubernetes/kubernetes/blob/release-1.19/cmd/kubeadm/app/util/staticpod/utils.go#L185-L225 Patchによるpod specの書き換え

  28. 補⾜: Static Pod ▶ Static Podの設定ディレクトリ(デフォルト: /etc/kubelet.d)以下にpod specのマニフェストファイルを設置するとkubeletがPodを起動してくれ る機能 ▶

    Static Podはapi serverからの操作ができないという特徴をがある → kubectlなどで削除したりできない ▶ Static Podの設定ディレクトリはstaticPodPathで設定可能 ▶ また—manifest-urlで指定したURLから定期的に情報取得を⾏い、Static Podを起動することも可能 ▶ Static Podは起動にkube apiserverを必要としないため、kube apiserver を含むcontrol planeの起動ができるということだと思う
  29. etcd ▶ Static Podでetcdのpodを起動するためのpod specマニフェストファイル を⽣成する ▶ 内部処理は以下の様になっている ▶ etcdのデータ⽤のディレクトリを⽣成

    ▶ ベースとなるpodのspecを⽣成 ▶ 設定に応じたkustomize/patchファイルによるspecの書き換えを⾏う ▶ ⽣成したspecをstatic pod⽤のファイルとして書き込む
  30. wait-control-plane ▶ Static Podでetcdのpodを起動するためのpod specマニフェストファイル を⽣成する ▶ 内部処理は以下の様になっている ▶ kubeletが正常に起動していることのチェックを⾏う

    ▶ kubelet のヘルスチェック⽤のエンドポイント(http://localhost: 10248/healthz)へのリクエストによって判断する ▶ kube apiserverが正常に起動していることのチェックを⾏う ▶ kube apiserverの /healthz へのリクエストによって判断する ▶ kube apiserverが正常にレスポンスを返す = etcdも正常という判断? ▶ kube controller manger/kube schedulerのチェックはここでは⾏ってい ないよう
  31. https://github.com/kubernetes/website/blob/master/static/images/docs/components-of-kubernetes.png

  32. upload-config ▶ Kubeadm/kubeletの設定値をConfigMapに作成する ▶ kubeadm側内部処理 ▶ kubeadmの設定と構築したクラスター情報をkubeadm-configという ConfigMapに保存 ▶ kubeadmが?ConfigMapを取得するためのRole/RoleBindingの作成

    ▶ kubelet側内部処理 ▶ kubeletの設定値をConfigMapに作成 ▶ 各種ノードがConfigMapを取得するためのRole/RoleBindingの作成 ▶ ⾃⾝のNodeリソースのCRIソケットを⽰すアノテーションの設定
  33. upload-certs ▶ 各種証明書情報をSecretに書き込む ▶ 内部処理 ▶ 短命(2時間)なブートストラップトークンを作成する ▶ 各種証明書情報をファイルから読み取り暗号化する ▶

    kubeadm-certsというSecretに暗号化された各種証明書情報の書き込みを⾏ う ▶ このSecretはOwnerReferenceでブートストラップトークンと紐付けられ る ▶ kubeadmが?kubeadm-certsを取得するためのRole/RoleBindingの作成を⾏ う ▶ これらのブートストラップトークン・証明書情報はkubeadm joinの際に利⽤ されるよう
  34. mark-control-plane ▶ control planeノードにnodeRegistration.taintsで渡したtaintを設定する ▶ control planeノードのラベルに
 node-role.kubernetes.io/master: ""の付与も⾏う ▶

    “Implementation design for kubeadm”を⾒る限り
 node-role.kubernetes.io/master:NoScheduleというtaintも設定される
 らしいが、実装を⾒る限りそういった箇所はなさそうだった
  35. bootstrap-token ▶ Kubeadm joinでノードをクラスターに参加させるためのブートストラッ プトークンSecretの⽣成を⾏う ▶ 元となるブートストラップトークンはkubeadm initの各フェーズ前の初 期化処理の段階で予め1つ⽣成されている ▶

    ブートストラップを⾏うための各種(Cluster)RoleBindingの設定をブート ストラップトークンの所属グループである system:bootstrappers:kubeadm:default-node-tokenに⾏う ▶ kube-systemのcluster-info ConfigMapにブートストラップ⽤の設定ファ イルを設置する ▶ system:anonymousに対してkube-systemのcluster-info ConfigMapの取 得権限を付与する
  36. 補⾜: system:anonymous ▶ system:anonymousはKubernetesの匿名リクエストに与えられるユー ザー ▶ kube apiserver側の認証⽅法で拒否されなかった場合には匿名リクエス ト扱いになるらしい ▶

    詳細は https://kubernetes.io/docs/reference/access-authn-authz/ authentication/ をチェック
  37. 補⾜: Bootstrap Token ▶ 新しいクラスターを作成する、または新しいノードを既存のクラスター に結合するときに使⽤することを⽬的としたBearerトークンとのこと ▶ 詳細は https://kubernetes.io/docs/reference/access-authn-authz/ bootstrap-tokens/

    をチェック
  38. kubelet-finalize ▶ kubeletが使⽤するkubeconfigに使われる証明書情報の更新を⾏う ▶ 更新に使われる証明書はkubeletの証明書設定ディレクトリのkubelet- client-current.pemとなる ▶ この証明書ファイルが存在する場合、このファイルを使ってkubeconfig が更新される ▶

    この証明書の設定ディレクトリのデフォルトは/etc/kubernetes/pkiの
 よう
  39. addon ▶ DNS(coreDNS or kubeDNS)とkube-proxyがアドオンとしてデプロイされ る ▶ それぞれDeployment/DaemonSetと合わせてService Accountや (Cluster)Role、(Cluster)RoleBinding、ConfigMapなど諸々が⾃動⽣成さ

    れる ▶ Control planeのstatic podのようにkustomizeなどを使ってパッチを当て るといったことはできないっぽい
  40. https://github.com/kubernetes/website/blob/master/static/images/docs/components-of-kubernetes.png

  41. まとめ

  42. まとめ ▶ kubeadm initでどのようにKubernetesクラスターが作られているのか紹介しました ▶ control plane/etcdの管理にstatic podを使っている、ブートストラップトークンという仕 組みを使って新しいノードがクラスターに参加できるようになっている、addonは kubeadmで直接設定ファイルなどを⽣成してデプロイしているなど、Kubernetse

    The Hard Wayをやるのとはまた違ったやり⽅になっていて⾯⽩かったです ▶ ある程度同じようなことはドキュメントに書いてあるとはいえ、コードレベルで追ってい くとドキュメントには書いてないことも把握することができて勉強になりました
  43. もっと詳しく知りたい⽅は ▶ 『解体kubeadm フェーズから読み解くKubernetesクラスタ構築ツール の全貌』という書籍が今⽉(9⽉)はじめに発売されていたらしいので、こ ちらにより詳しく書いて有りそうです
 (僕も昨⽇この本がリリースされていることを知りました)

  44. 参考資料 ▶ A Stronger Foundation for Creating and Managing Kubernetes

    Clusters https://kubernetes.io/blog/2017/01/stronger-foundation-for- creating-and-managing-kubernetes-clusters/ ▶ Implementation details https://kubernetes.io/docs/reference/setup-tools/kubeadm/implementation-details/#mark-the-node-as-control- plane ▶ Installing kubeadm https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/ ▶ Creating a cluster with kubeadm https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/ ▶ Implementation design for kubeadm https://github.com/kubernetes/kubeadm/blob/master/docs/design/design_v1.10.md ▶ kubernetes/kubernetes/cmd/kubeadm https://github.com/kubernetes/kubernetes/tree/release-1.19/cmd/kubeadm ▶ kubernetes/kubeadm https://github.com/kubernetes/kubeadm ▶ Using Kustomize with Kubeadm Configuration Files https://blog.scottlowe.org/2019/10/16/using-kustomize-with-kubeadm- configuration-files/ ▶ Create static Pods https://kubernetes.io/docs/tasks/configure-pod-container/static-pod/ ▶ Authenticating with Bootstrap Tokens https://kubernetes.io/docs/reference/access-authn-authz/bootstrap-tokens/ ▶ Super Simple Discovery API https://github.com/kubernetes/community/blob/master/contributors/design-proposals/cluster-lifecycle/ bootstrap-discovery.md ▶ Authenticating https://kubernetes.io/docs/reference/access-authn-authz/authentication/ ▶ Kubernetes The Hard Way https://github.com/kelseyhightower/kubernetes-the-hard-way
  45. Thanks / Question? ▶ @bells17 ▶ Slide: https://speakerdeck.com/bells17 ▶ @bells17_