kubeadmのphaseから解るKubernetesクラスタの正体/Phases of kubeadm and Kubernetes Cluster Internal

D3764b33b44dcefd6a453ade0b8fec75?s=47 heriet
September 30, 2020

kubeadmのphaseから解るKubernetesクラスタの正体/Phases of kubeadm and Kubernetes Cluster Internal

Kubernetesクラスタ構築ツールであるkubeadmには、phaseと呼ばれる処理単位があります。通常、kubeadmを利用するうえでphaseを意識する必要はありません。しかし、phaseという観点で各処理を追うことで、標準的なKubernetesクラスタがどのような内部構造となっているのかを明らかにできます。書籍「解体kubeadm」でも着目したこのphaseについての解説と、「解体kubeadm」の執筆の経緯についても紹介します。

Kubernetes Meetup Tokyo #34 https://k8sjp.connpass.com/event/188543/

D3764b33b44dcefd6a453ade0b8fec75?s=128

heriet

September 30, 2020
Tweet

Transcript

  1. heriet / SERA Michio 2020/09/30 Kubernetes Meetup Tokyo #34 kubeadmのphaseから解る

    Kubernetesクラスタの正体 
  2. Kubernetesクラスタ解らない ▶ なんかコンポーネントがいっぱいある ▶ ノードの中⾝はよくしらない ▶ kubeadmを⼿順通り叩いたら よくわからないがクラスタができた  ‎͜ͷεϥΠυͰνϣοτղΔΑ͏ʹͳΔͱࢥ͍·͢

  3. ⾃⼰紹介 ▶ heriet / 世良 迪夫(SERA Michio) • 富⼠通クラウドテクノロジーズ株式会社 >

    昔はニフティって名前の会社でした • Software Developer > ニフクラ Hatobaとか作ってます • 解体kubeadmという本を出しました 
  4. 製品紹介: ニフクラ Hatoba(β) ▶ 法⼈向けパブリッククラウド「ニフクラ」のKubernetes as a Service (KaaS) •

    βのうちは審査に通れば無料で使えます(本番利⽤は⾮推奨)  IUUQTQGTOJGDMPVEDPNTFSWJDFIBUPCBIUN
  5. 本⽇話すこと ▶ どうしてkubeadmの本を書いたか ▶ kubeadmの基本 ▶ kubeadm initの流れ ▶ まとめ

    
  6. どうしてkubeadmの本を書いたか 

  7. 解体kubeadm フェーズから読み解くKubernetesクラスタ構築ツールの全貌 ▶ 世界初のkubeadmの技術書 • 需要がほぼないから世界初なんだと思います ▶ 特にphase(フェーズ)という切り⼝で説明 • phaseはkubeadmにおける処理の単位(後述)

    ▶ ⼤雑把に⾔えば Kubernetes The Hard Wayの kubeadm版みたいな内容 
  8. kubeadmの本を書いた理由 ▶ KaaSであるニフクラHatobaの開発に必要だったから • 公式の構築・運⽤ツールであるkubeadmは特に詳しく把握しておきたかった • 本にしておくとチームメンバーへの共有もかんたん(※) > ※ 作成コストを無視すれば

    ▶ 技術同⼈誌が流⾏っていたから • ニッチすぎて商業誌では出ないであろう技術書を書いてみたい • 仕事でもKubernetesの調査をしてたしチョットまとめれば本になりそう 
  9. 技術同⼈誌から商業誌へ ▶ 技術同⼈誌として「Phases of kubeadm」を頒布 • 技術書同⼈誌博覧会や技術書典 応援祭で頒布 • 累計で約30部ほど頒布

    ▶ インプレスR&Dさんに声をかけてもらって技術の泉シリーズとして出版 • 内容がニッチすぎて売れないと思うんだけど⼤丈夫?  ঎ۀࢽԽ
  10. kubeadmの基本 

  11. kubeadmとは ▶ 公式のKubernetesクラスタ構築・運⽤ツール ▶ Kubernetes + administration でkubeadm(たぶん) • 英語圏ではキューブエーディーエム

    と発⾳されている • わたしは⾃社内で会話するときはクベアダムって発⾳します(発⾳しにくいので…) ▶ 他のツールの内部処理としても使われることを想定 • たとえばCluster API / kubespray / minikube 等の内部で使われている ▶ Kubernetes 1.13(2018/12)でGA 
  12. kubeadmのコアデザインプリンシプル ▶ Secure / セキュア • ベストプラクティスとなるセキュアな構成が構築できる ▶ Easy to

    use / 簡単に使える • ほんの数コマンドでKubernetesクラスタが構築できる ▶ Extendable / 拡張可能 • 設定ファイルで様々なKubernetesクラスタが構築できる  IUUQTLVCFSOFUFTJPEPDTSFGFSFODFTFUVQUPPMTLVCFBENJNQMFNFOUBUJPOEFUBJMTDPSFEFTJHOQSJODJQMFT ৄࡉ͸ެࣜαΠτΛಡ΋͏ʂ
  13. kubeadmによるシングルマスタークラスターの作成例 ▶ 各ノードでkubeadmのインストールと各種準備 • https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/ ▶ マスターノードで kubeadm init ▶

    CNIをインストール ▶ ワーカーノードでkubeadm join  IUUQTLVCFSOFUFTJPEPDTTFUVQQSPEVDUJPOFOWJSPONFOUUPPMTLVCFBENDSFBUFDMVTUFSLVCFBEN # kubeadm init # kubectl apply -f <cni.yaml> # kubeadm join
  14. kubeadmのスコープ  Machine kube-apiserver kube-scheduler kube-controller-manager FUDE kubelet (※最初のインストールのみ利⽤者が実施) Control

    Plane kube-proxy CoreDNS CNI Addon Any Kubernetes Resources kubeadmで 構築・運⽤ 利⽤者が作成 利⽤者が作成 Container Runtime ※kubeadmの世界ではetcdはControl Planeに含まれないので注意(通常はetcdも含まれる事が多い)
  15. kubeadmのサブコマンド⼀覧  サブコマンド 説明 kubeadm init 最初のマスターノードの作成 kubeadm join 2台⽬以降のマスターノードまたはワーカーノードの追加

    kubeadm upgrade Kubernetesバージョンのアップグレード kubeadm reset kubeadmで構築したコンポーネントの初期化 kubeadm config kubeadmのコンフィグ周りの処理つめあわせ kubeadm token kubeadmのブートストラップトークン周りの処理つめあわせ kubeadm version kubeadmのバージョン表⽰ kubeadm alpha 開発中のalpha機能つめあわせ ˞ଠࣈ͸௨ৗΑ͔ͭ͘͏Ͱ͋Ζ͏ίϚϯυ
  16. kubeadmのphaseとは ▶ phaseとはkubeadm で内部的に⾏っている処理の単位 ▶ kubeadm init などのサブコマンドは複数のphaseで構成されている ▶ kubeadm

    XXXX phase A のように 個別のphaseのみを実⾏することも可能 • 実⾏できないphaseやphaseではない処理も⼀部ある ▶ phaseという切り⼝で⼀つずつ追えば 各処理が理解できる  kubeadm XXXX QIBTF" QIBTF# QIBTF$
  17. kubeadm initの流れ 

  18. kubeadm initとは ▶ 最初のマスターノードを作成する操作 • kubeadm initの中⾝を理解すればマスターノードの内部構造を理解できる > マスターノードの内部構造が解ればKubernetesクラスタの中⾝がチョットワカル ▶

    Kubernetes The Hard Wayと似たようなことをやるが、同じではない • ⽐較してみると⾯⽩いと思います 
  19. kubeadm initのphase ▶ kubeadm init は下記13個のphaseが直列に実⾏される(v1.19の場合)  preflight kubelet-start certs

    kubeconfig control-plane etcd wait-control-plane upload-config bootstrap-token upload-certs mark-control-plane kubelet-finalize addon kubeadm init
  20. kubeadm init phase preflight ▶ マシンに関するチェック(InitNodeChecks) • kubeadmが特権ユーザーで実⾏されている • swapがoffになっている

    • …等いろいろ ▶ イメージのPullができるか(PullImagesCheck) • Control Planeやetcd、Addonのイメージを実際にpullする > なので、kubeadm initは初回だけ数分時間がかかったりする  実⾏前のチェックを⾏うphase
  21. kubeadm init phase certs ▶ /etc/kubernetes/pki 以下に証明書を⽣成 • コンポーネント間がmTLSで通信するため ▶

    有効期限は固定 • CA証明書は10年 • サーバー証明書とクライアント証明書は1年 ▶ 既にファイルが有る場合は上書きしない • なので、⾃前の証明書を使いたい場合は 事前に配置しておけば良い  証明書の⽣成を⾏うphase # tree /etc/kubernetes/pki /etc/kubernetes/pki ├── apiserver.crt ├── apiserver-etcd-client.crt ├── apiserver-etcd-client.key ├── apiserver.key ├── apiserver-kubelet-client.crt ├── apiserver-kubelet-client.key ├── ca.crt ├── ca.key ├── etcd │ ├── ca.crt │ ├── ca.key │ ├── healthcheck-client.crt │ ├── healthcheck-client.key │ ├── peer.crt │ ├── peer.key │ ├── server.crt │ └── server.key ├── front-proxy-ca.crt ├── front-proxy-ca.key ├── front-proxy-client.crt ├── front-proxy-client.key ├── sa.key └── sa.pub
  22. kubeadm init phase kubeconfig ▶ kubeconfigとはKubernetes APIに接続するための設定ファイル ▶ 下記のkubeconfigを⽣成 •

    kubeadm管理⽤ • kubeletがKubernetes APIを叩く⽤ • kube-controller-managerがKubernetes APIを叩く⽤ • kube-schedulerがKubernetes APIを叩く⽤ ▶ kubeconfigには証明書が必要なのでcertsの後に実⾏されている  kubeconfigの⽣成を⾏うphase # tree /etc/kubernetes /etc/kubernetes ├── admin.conf ├── controller-manager.conf ├── kubelet.conf └── scheduler.conf
  23. kubeadm init phase kubelet-start ▶ kubeadmの構成ではControl Planeを後述するStatic Podとして起動するため、 マスターノードにもkubeletが必要となる ▶

    kubeadmの実⾏要件としてkubeletがsystemdで管理されている(事前にイン ストールする必要がある)ので、systemdで停⽌と起動を⾏う ▶ kubeletの設定ファイルの出⼒も⾏う • /var/lib/kubelet/kubeadm-flags.env • /var/lib/kubelet/config.yaml  kubeletの設定と起動を⾏うphase
  24. kubeadm init phase control-plane ▶ Static Podとはローカルに配置したmanifestで起動する特別なPodのこと ▶ 下記のStatic Pod

    manifestを⽣成 • kube-apiserver • kube-controller-manager • kube-scheduler ▶ 各起動オプションもStatic Pod manifestに記載されている • 証明書やkubeconfigのパスなども含まれる ▶ kubelet-startで起動したkubeletがStatic Pod manifestからPodの起動を⾏う  Control PlaneのStatic Pod manifestを⽣成するphase # tree /etc/kubernetes/manifests /etc/kubernetes/manifests ├── kube-apiserver.yaml ├── kube-controller-manager.yaml └── kube-scheduler.yaml
  25. kubeadm init phase etcd ▶ 外部のetcdを使う場合はスキップする ▶ 下記のStatic Pod manifestを⽣成

    • etcd  etcdのStatic Pod manifestを⽣成するphase # tree /etc/kubernetes/manifests /etc/kubernetes/manifests └── etcd.yaml
  26. kubeadm init phase wait-control-plane ▶ このphaseは個別に実⾏することはできない(kubeadm init時のみ呼ばれる) ▶ Control Planeが正常に起動するまで待機する

    ▶ 何か設定が間違っていると起動できず、ここでタイムアウトになる • 起動できない要因は様々なので⾃分で調べる必要がある(わりとよくある)  Control Planeの起動を待つphase
  27. kubeadm init phase upload-config ▶ 下記のConfigMapを作成 • kubeadm-config • kubelet-config-X.XX

    > X.XXはKubernetesバージョン ▶ joinやupgrade時にこのConfigMapから設定情報を取得する  kubeadmとkubeletの設定をConfigMapに登録するphase # kubectl get cm kubeadm-config -n kube-system NAME DATA AGE kubeadm-config 2 18d # kubectl get cm kubelet-config-1.19 -n kube-system NAME DATA AGE kubelet-config-1.19 1 18d
  28. kubeadm init phase upload-certs ▶ HA構成が必要な場合(--upload-certs付与時)のみ実⾏される ▶ 証明書をAES256で暗号化したデータをkubeadm-certsというSecretで登録 • 暗号化キーはjoin時に

    —certificate-key として渡す必要がある ▶ kubeadm-certsのownerReferencesとなるbootstrap tokenを作成 • 有効期限が2時間となり、有効期限内に join する必要がある ▶ join時にkubeadm-certsから証明書を 取得して使う  Control Plane構築に必要な証明書をSecretに登録するphase # kubectl get secret kubeadm-certs -n kube-system NAME TYPE DATA AGE kubeadm-certs Opaque 8 36s # kubectl get secret bootstrap-token-au3pw8 -n kube-system NAME TYPE DATA AGE bootstrap-token-au3pw8 bootstrap.kubernetes.io/token 4 71s
  29. kubeadm init phase mark-control-plane ▶ 下記のlabelを付与 • node-role.kubernetes.io/master ▶ 下記のtaintsを付与

    • node-role.kubernetes.io/master:NoSchedule • マスターノード⽤のPod以外はスケジュール されなくなる  マスターノードのlabelとtaintsを付与するphase # kubectl get nodes -o yaml | yq '.items[0].metadata.labels' { "beta.kubernetes.io/arch": "amd64", "beta.kubernetes.io/os": "linux", "kubernetes.io/arch": "amd64", "kubernetes.io/hostname": "master01", "kubernetes.io/os": "linux", "node-role.kubernetes.io/master": "" } # kubectl get nodes -o yaml | yq '.items[0].spec.taints' [ { "effect": "NoSchedule", "key": "node-role.kubernetes.io/master" }, { "effect": "NoSchedule", "key": "node.kubernetes.io/not-ready" } ]
  30. kubeadm init phase bootstrap-token ▶ join時に認証するためのbootstrap tokenを⽣成(有効期限は24時間) • ClusterRole/CluseterRoleBindingの登録やConfigMap cluster-infoの作成など

    もここで⾏う ▶ join時にここで⽣成したbootstrap tokenを使うことで安全にjoinできる  join⽤のbootstrap tokenを⽣成するphase
  31. kubeadm init phase kubelet-finalize ▶ kubeletの⾃動証明書更新の設定 • kubeadmがphase kubeconfigで⽣成したkubelet.confでは、固定のクライアン ト証明書データが埋め込まれている(kubeletの起動にkubelet.confが必要)

    • kubelet起動後に、⾃動証明書更新機能によってクライアント証明書が所定の場 所に保存されるようになる • kubelet.confに埋め込んだ固定のクライアント証明書データを削除し、kubelet の⾃動証明書更新機能によって⽣成されたクライアント証明書の場所に書き換 える ▶ v1.16以前はこのphaseがなかったため、⾃動証明書更新が有効になってなかった  kubeletの設定更新を⾏うphase
  32. kubeadm init phase addon ▶ 下記をインストール • kube-proxy • coredns

     addonのインストールを⾏うphase # kubectl get ds -n kube-system kube-proxy NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE kube-proxy 1 1 1 1 1 kubernetes.io/os=linux 18d # kubectl get deploy -n kube-system coredns NAME READY UP-TO-DATE AVAILABLE AGE coredns 2/2 2 2 18d
  33. kubeadm initから解るKubernetesクラスタの正体(マスターノード)  kube-apiserver kube-scheduler kube-controller-manager FUDE kubelet Control Plane

    (Static Pod) kube-proxy CoreDNS Addon (DaemonSet, Deployment) kubeadm 4UBUJD1PE.BOJGFTU ূ໌ॻ LVCFDPOpH kubeadm-config kubelet-config-x.xx cluste-info ઃఆϑΝΠϧ ConfigMap ※ あくまでkubeadm intで作った場合の構成 Kubernetes Resource ファイル 設定 ⽣成 Ϛελʔϊʔυ ⽣成 ⽣成
  34. 続きは本で! ▶ init以外についても解体kubeadmに書いたので気になる⼈は読んでみてね ▶ 公式ドキュメントにも各phaseの説明はあるのでそれでも⼗分だよ ▶ もっと詳しく知りたい⼈はソースコードを読もう • phaseの概念を頭に⼊れておくとすんなり読めると思います 

  35. まとめ ▶ kubeadmの内部処理が解ると、Kubernetesクラスタの内部がチョット解る • Kubernetesクラスタの内部がわかってると応⽤やトラブルの対処ができるかも ▶ モット解るためには… • Kubernetesのコンポーネントの処理を調べた本とか気軽に書こう! •

    KaaSとかつくってみよう! > ニフクラ Hatobaの開発者も募集してます(We are hiring!!) 
  36. Appendix: kubeadmよもやま話 

  37. kubeadmそのまま運⽤はおすすめはしないよ ▶ kubeadmで運⽤しているとphase単位で処理を呼ぶことはしばしばある • 証明書まわりとかコンポーネントの設定変更とか… • ⼿動でコマンド組み合わせて叩く運⽤ ▶ kubeadmで本番サービス運⽤は⾯倒だからやめたほうがいいとおもうよ •

    クラウドのKaaSを使うのが第⼀の選択肢 • KaaS使えないときかつkubeadmままクラスタを作るならkubesprayを使おう > kubesprayはkubeadmをAnsibleで包んで使いやすくしたツール • 検証⽤途とかならkubeadmでもいいと思います 
  38. kubeadmで困ったとき ▶ kubeadmを使うときバージョンによって⼿順が微妙に変わるケースがあるので公 式サイトのドキュメントはちゃんと読もうね ▶ 公式にトラブルシューティングのページもあるのでそちらも⾒よう • https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/troubleshooting-kubeadm/ 

  39. 直近のkubeadmロードマップ ▶ kubeadm-operator • kubeadmによる操作を宣⾔的にOperatorパターンで実現する ▶ 機械的に読みやすい出⼒(jsonとか)を全コマンドで対応(現在は⼀部のみ) ▶ リトライ性や独⽴性の向上 ▶

    アドオンやetcdの柔軟性向上 ▶ コンポーネント設定管理の簡素化 ▶ kubeadmのGitHubリポジトリを独⽴化  *OUSPEVDUJPOUP4*($MVTUFS-JGFDZDMFIUUQTXXXZPVUVCFDPNXBUDI WY:Q6SW[H ,VCFBEN%FFQ%JWFIUUQTXXXZPVUVCFDPNXBUDI W%IT'G/4*S2 ,&1IUUQTHJUIVCDPNLVCFSOFUFTFOIBODFNFOUTUSFFNBTUFSLFQTTJHDMVTUFSMJGFDZDMFLVCFBEN
  40. あわせて読みたい  ▶ kubeadmに学ぶクラスター構築 https://speakerdeck.com/bells17/implementation-of-kubeadm-init • ちょうど昨⽇のKubernetes Novice Tokyo #5

    の発表 着眼点はこのスライドと同様ですが、このスライドに書いてない話もあるので合わせてどうぞ