はじめに
ここでは、オンプレミス環境でkubernetesプロジェクト推奨構成のクラスタを構築できる構築支援ツール[kubeadm]が、どのような動作でクラスタ環境を自動で構築しているのか、
構築支援ツールを利用せずに手動で構築したK8sクラスタと比較して、内部を見てみようと思います。
手動でK8sクラスタを構築した作業は以下の記事で公開しています。
・Kubernetes(K8s)を仮想環境でHard Wayに構築してみた
Kubernetesのコンポーネント
K8sは以下のコンポーネントで構成されています。
コントロールプレーン
- etcd
クラスタの構成を保存するための分散型キーバリューストア - kube-apiserver
kubectlやほかのコンポーネントとやり取りのためのAPIを提供するコンポーネント - kube-controller-manager
K8s内の様々なコントローラ(DeploymentやDaemonsetなど)を管理しているコンポーネント - kube-scheduler
ポッドをどのノードで起動するか割り当てるコンポーネント
割り当てだけ行い、各ノードのkubeletがそれぞれ割り当てられたポッドを起動する
ワーカノード
- kubelet ( + Container Runtime)
スケジュールされたポッドを起動する - kube-proxy
クラスタ内のサービスと、ポッドネットワーク、クラスタネットワークのルーティングを行う - cni plugin
ワーカノードのポッドネットワークを提供する。
手動で構築したクラスタの場合
Kubernetes The Hard Wayの通りに構築したKubernetesクラスタの場合、各コンポーネントは以下のような構成となっています。
コンポーネント自体は/usr/local/binにバイナリでインストールされていて、systemdのサービスとして起動しています。
コントロールプレーン
# ls -l /usr/local/bin/
total 394456
-rwxr-xr-x 1 1922357897 root 23667040 Aug 30 2019 etcd
-rwxr-xr-x 1 1922357897 root 17513984 Aug 30 2019 etcdctl
-rwxr-xr-x 1 root root 164522400 Aug 19 2019 kube-apiserver
-rwxr-xr-x 1 root root 116421664 Aug 19 2019 kube-controller-manager
-rwxr-xr-x 1 root root 42985504 Aug 19 2019 kubectl
-rwxr-xr-x 1 root root 38786144 Aug 19 2019 kube-scheduler
#
ワーカノード
# ls -l /usr/local/bin/
total 232972
-rwxr-xr-x 1 trnuser trnuser 28655652 Jul 3 2019 crictl
-rwxr-xr-x 1 root root 42985504 Aug 19 2019 kubectl
-rwxr-xr-x 1 root root 119645232 Aug 19 2019 kubelet
-rwxr-xr-x 1 root root 36987488 Aug 19 2019 kube-proxy
-rwxr-xr-x 1 root root 10270256 Apr 25 2019 runc
# ls -l /bin/containerd
-rwxr-xr-x 1 2000 2000 49077568 Sep 6 2019 /bin/containerd
#
設定は、/var/lib配下と、/etc/kubernetes/conf配下にファイルとして配置されています。また、起動オプションは.service ファイルに記載しています。
コントロールプレーン
# ls -l /etc/kubernetes/config/
total 4
-rw-r--r-- 1 root root 198 May 11 06:32 kube-scheduler.yaml
# ls -l /var/lib/kubernetes/ | grep -e kubeconfig
-rw------- 1 root root 6391 Apr 13 02:39 kube-controller-manager.kubeconfig
-rw------- 1 root root 6341 Apr 13 02:39 kube-scheduler.kubeconfig
#
ワーカノード
# ls -l /var/lib |grep -e kube* -e cni
drwxr-xr-x 3 root root 4096 Apr 14 05:32 cni
drwxr-xr-x 8 root root 4096 May 11 08:00 kubelet
drwxr-xr-x 2 root root 4096 May 8 00:45 kube-proxy
drwxr-xr-x 2 root root 4096 Apr 14 00:59 kubernetes
#
これらはすべて、K8sクラスタ構築時に手動でダウンロード・設定ファイルを作成することでインストールしました。(大変だった。。)
kubeadmで構築したクラスタの場合
一方、kubeadmでは、これらの設定ファイルの作成を行った記憶がありません。
作業はkubelet, kubectl, kubeadm, containerdのインストールをパッケージマネージャで行った程度です。
設定ファイルはどこにあるのでしょうか?
コントロールプレーン
# ls -l /etc/kubernetes/ | grep .conf
-rw------- 1 root root 5449 May 13 04:26 admin.conf
-rw------- 1 root root 5489 May 13 04:26 controller-manager.conf
-rw------- 1 root root 1885 May 13 04:27 kubelet.conf
-rw------- 1 root root 5437 May 13 04:26 scheduler.conf
root@controller-0:~#
ワーカノード
# ls -l /var/lib |grep -e kube* -e cni
drwx------ 8 root root 4096 May 13 04:48 kubelet
root@worker-2:~#
少し足りなく見えますが、ありましたね。
具体的にはkubeadm init, kubeadm join実行時に、そのオプションや設定によって自動的に設定が作成されて、新規のノードに配置されるようです。
手動と比べたらとても楽です。
ではコンポーネントはどうでしょうか?
サービスとして起動しているのは、containerdとkubeletくらいです。
実はその他のコンポーネントはkubeadmでは、ポッドで動いていました。
# kubectl get po -n kube-system
NAME READY STATUS RESTARTS AGE
coredns-66bff467f8-sxmg2 1/1 Running 0 131m
coredns-66bff467f8-xjkqv 1/1 Running 0 131m
etcd-controller-0 1/1 Running 0 131m
etcd-controller-1 1/1 Running 0 129m
etcd-controller-2 1/1 Running 0 119m
kube-apiserver-controller-0 1/1 Running 0 131m
kube-apiserver-controller-1 1/1 Running 0 128m
kube-apiserver-controller-2 1/1 Running 0 118m
kube-controller-manager-controller-0 1/1 Running 0 131m
kube-controller-manager-controller-1 1/1 Running 0 128m
kube-controller-manager-controller-2 1/1 Running 0 118m
kube-flannel-ds-amd64-bstfd 1/1 Running 0 119m
kube-flannel-ds-amd64-fbvcm 1/1 Running 1 111m
kube-flannel-ds-amd64-hl5vv 1/1 Running 1 111m
kube-flannel-ds-amd64-hqs9x 1/1 Running 0 127m
kube-flannel-ds-amd64-jxs6m 1/1 Running 0 127m
kube-flannel-ds-amd64-vfvl8 1/1 Running 0 110m
kube-proxy-6b2xl 1/1 Running 0 129m
kube-proxy-9v2jj 1/1 Running 0 131m
kube-proxy-xfssz 1/1 Running 0 110m
kube-proxy-xznsj 1/1 Running 0 111m
kube-proxy-z8q4r 1/1 Running 0 119m
kube-proxy-zxm2v 1/1 Running 0 111m
kube-scheduler-controller-0 1/1 Running 0 131m
kube-scheduler-controller-1 1/1 Running 0 128m
kube-scheduler-controller-2 1/1 Running 0 118m
#
サービスファイルに記述するような起動オプション類は、ポッドのマニフェストに記載されています。
# ll /etc/kubernetes/manifests/
total 24
drwxr-xr-x 2 root root 4096 May 13 04:26 ./
drwxr-xr-x 4 root root 4096 May 13 06:33 ../
-rw------- 1 root root 1862 May 13 04:26 etcd.yaml
-rw------- 1 root root 3225 May 13 04:26 kube-apiserver.yaml
-rw------- 1 root root 3081 May 13 04:26 kube-controller-manager.yaml
-rw------- 1 root root 1120 May 13 04:26 kube-scheduler.yaml
#
また、各ノードで共通の設定内容については、ConfigMapオブジェクトで管理されているようです。
# kubectl get cm -n kube-system
NAME DATA AGE
coredns 1 141m
extension-apiserver-authentication 6 141m
kube-flannel-cfg 2 137m
kube-proxy 2 141m
kubeadm-config 2 141m
kubelet-config-1.18 1 141m
#
[ConfigMap]とは、Kubernetesクラスタ上で管理されているリソースで、内容はクラスタ内のどのコンテナからでも利用可能です。
設定ファイルで管理するよりも遥かに柔軟に管理できます。
これらの配慮によって、ノードのスケーリングに柔軟に対応できるように工夫されていたんですね。
まとめ
構築支援ツール[kubeadm]では、K8sクラスタのコンポーネントが可能な限りポッドとして管理されていることがわかりました。
また共通の設定値は、コンポーネントが起動する際に参照が必要なものなどはさすがにConfigMapでは管理できませんが、それ以外を可能な限り[ConfigMap]で管理しているようです。
kubeadmは、正常でカスタマイズ不要な場合は構築がとても楽ですが、理解していないとトラブルシューティングに手こずってしまいます。
利用する際は、以下を意識して落ち着いて構築することが成功のカギであると思います。
- initコマンドのオプションでどの設定値が変更できるのかを理解する。
- 各コンポーネントの設定がファイルとマニフェストによって管理されているということを意識して、設定値を確認する。
参考
- 公式 「Overview of kubeadm 」https://kubernetes.io/docs/reference/setup-tools/kubeadm/kubeadm/