Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

▶ @bells17 ▶ Software Engineer ▶ 主に Kubernetes 関連コンポーネントの開発など ▶ Kubernetes #sig-docs-ja-reviews ▶ CNBF実⾏委員 ▶ @bells17_

Slide 3

Slide 3 text

今⽇話すこと ▶ kubeadm init時にどんなことが⾏われているのかについて ▶ Kubeadm initによるクラスター構築処理で使われている機能・技術に ついて

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

kubeadmとは?

Slide 7

Slide 7 text

Kubeadm ▶ Kubernetesコミュニティ公式のKubernetesクラスター構築ツール ▶ Kubernetesクラスター構築の「ベストプラクティス」を提供 ▶ Kubeadmはクラスターのブートストラップにフォーカスした機能を提供 する + コンテナランタイムやkubeletのインストールはkubeadmのスコープ外 ▶ Kubesprayやkindなどその他のKubernetesクラスター構築ツールの内部 で使われていることがある ▶ kubeadmが⾏うクラスター構築処理を1(サブ)フェーズ単位で実⾏できる ようになっている ▶ KubernetesコミュニティのSig Cluster Lifecycleによって開発されている

Slide 8

Slide 8 text

https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/create-cluster-kubeadm/ 1コマンドでKubernetesクラスターを構築できる

Slide 9

Slide 9 text

Kubeadmの様々なサブコマンド ▶ kubeadm init: Kubernetesクラスターの構築 ▶ kubeadm join: 構築したクラスターへの参加 ▶ kubeadm upgrade: Kubernetesバージョンのアップグレード ▶ kubeadm config: kubeadmの設定管理 ▶ etc この中で今回はkubeadm initの処理にフォーカスした内容です

Slide 10

Slide 10 text

kubeadmはサブコマンド内で実⾏される処理がphaseという単位によって分割
 されており、各phase単位でコマンドから処理が実⾏可能になっている

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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によるクラスター管理

Slide 17

Slide 17 text

https://github.com/kubernetes/website/blob/master/static/images/docs/components-of-kubernetes.png

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

kubeconfig ▶ 各種control plane/管理者のためのkubeconfigファイルの⽣成を⾏う ▶ 以下の4者のためのkubeconfigを⽣成 ▶ 管理者 ▶ kubelet ▶ kube controller manger ▶ kube scheduler ▶ kubernetes/kubernetesのcmd/kubeadm/app/util/kubeconfig
 パッケージにあるCreateBasic関数を使ってkubeconfigファイルのデータを⽣ 成 ▶ その後CreateBasic関数の呼び出し元であるCreateWithCerts関数内でクライ アント証明を埋め込んでいる ▶ クライアント証明書は前のステップで⽣成したファイルを読み込んでいる

Slide 21

Slide 21 text

https://github.com/kubernetes/kubernetes/blob/release-1.19/cmd/kubeadm/app/util/kubeconfig/kubeconfig.go#L30-L51  CreateBasic

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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の書き換えについてはドキュメントについては記載が⾒当たらない(気が する)

Slide 25

Slide 25 text

https://github.com/kubernetes/kubernetes/blob/release-1.19/cmd/kubeadm/app/phases/controlplane/manifests.go#L46-L91   ベースとなるpod specの⽣成

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

補⾜: 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の起動ができるということだと思う

Slide 29

Slide 29 text

etcd ▶ Static Podでetcdのpodを起動するためのpod specマニフェストファイル を⽣成する ▶ 内部処理は以下の様になっている ▶ etcdのデータ⽤のディレクトリを⽣成 ▶ ベースとなるpodのspecを⽣成 ▶ 設定に応じたkustomize/patchファイルによるspecの書き換えを⾏う ▶ ⽣成したspecをstatic pod⽤のファイルとして書き込む

Slide 30

Slide 30 text

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のチェックはここでは⾏ってい ないよう

Slide 31

Slide 31 text

https://github.com/kubernetes/website/blob/master/static/images/docs/components-of-kubernetes.png

Slide 32

Slide 32 text

upload-config ▶ Kubeadm/kubeletの設定値をConfigMapに作成する ▶ kubeadm側内部処理 ▶ kubeadmの設定と構築したクラスター情報をkubeadm-configという ConfigMapに保存 ▶ kubeadmが?ConfigMapを取得するためのRole/RoleBindingの作成 ▶ kubelet側内部処理 ▶ kubeletの設定値をConfigMapに作成 ▶ 各種ノードがConfigMapを取得するためのRole/RoleBindingの作成 ▶ ⾃⾝のNodeリソースのCRIソケットを⽰すアノテーションの設定

Slide 33

Slide 33 text

upload-certs ▶ 各種証明書情報をSecretに書き込む ▶ 内部処理 ▶ 短命(2時間)なブートストラップトークンを作成する ▶ 各種証明書情報をファイルから読み取り暗号化する ▶ kubeadm-certsというSecretに暗号化された各種証明書情報の書き込みを⾏ う ▶ このSecretはOwnerReferenceでブートストラップトークンと紐付けられ る ▶ kubeadmが?kubeadm-certsを取得するためのRole/RoleBindingの作成を⾏ う ▶ これらのブートストラップトークン・証明書情報はkubeadm joinの際に利⽤ されるよう

Slide 34

Slide 34 text

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も設定される
 らしいが、実装を⾒る限りそういった箇所はなさそうだった

Slide 35

Slide 35 text

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の取 得権限を付与する

Slide 36

Slide 36 text

補⾜: system:anonymous ▶ system:anonymousはKubernetesの匿名リクエストに与えられるユー ザー ▶ kube apiserver側の認証⽅法で拒否されなかった場合には匿名リクエス ト扱いになるらしい ▶ 詳細は https://kubernetes.io/docs/reference/access-authn-authz/ authentication/ をチェック

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

addon ▶ DNS(coreDNS or kubeDNS)とkube-proxyがアドオンとしてデプロイされ る ▶ それぞれDeployment/DaemonSetと合わせてService Accountや (Cluster)Role、(Cluster)RoleBinding、ConfigMapなど諸々が⾃動⽣成さ れる ▶ Control planeのstatic podのようにkustomizeなどを使ってパッチを当て るといったことはできないっぽい

Slide 40

Slide 40 text

https://github.com/kubernetes/website/blob/master/static/images/docs/components-of-kubernetes.png

Slide 41

Slide 41 text

まとめ

Slide 42

Slide 42 text

まとめ ▶ kubeadm initでどのようにKubernetesクラスターが作られているのか紹介しました ▶ control plane/etcdの管理にstatic podを使っている、ブートストラップトークンという仕 組みを使って新しいノードがクラスターに参加できるようになっている、addonは kubeadmで直接設定ファイルなどを⽣成してデプロイしているなど、Kubernetse The Hard Wayをやるのとはまた違ったやり⽅になっていて⾯⽩かったです ▶ ある程度同じようなことはドキュメントに書いてあるとはいえ、コードレベルで追ってい くとドキュメントには書いてないことも把握することができて勉強になりました

Slide 43

Slide 43 text

もっと詳しく知りたい⽅は ▶ 『解体kubeadm フェーズから読み解くKubernetesクラスタ構築ツール の全貌』という書籍が今⽉(9⽉)はじめに発売されていたらしいので、こ ちらにより詳しく書いて有りそうです
 (僕も昨⽇この本がリリースされていることを知りました)

Slide 44

Slide 44 text

参考資料 ▶ 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

Slide 45

Slide 45 text

Thanks / Question? ▶ @bells17 ▶ Slide: https://speakerdeck.com/bells17 ▶ @bells17_