kubeadmインストール構成とthe-hard-wayインストール構成の違い

[kubeadm](https://kubernetes.io/docs/setup/independent/install-kubeadm/)を使ってk8sをインストールした場合と、[kubernetes-the-hard-way](https://github.com/kelseyhightower/kubernetes-the-hard-way)の手順に沿ってインストールした場合の構成の違いについて調べてみた。


## kubeadmを使用した場合

kubeadmを簡単に説明すると、Linuxサーバーにdockerエンジンが稼働している状態で、kubeadm init を実行することで、マスターノードが構成される。そして、その実行結果を利用して、kubeadm join とすることで、ノードを追加することができる。

kubeadm コマンドの働きによって、k8sクラスタの認証局の構築、APIサーバー(kube-apiserver)、スケジューラー(kube-scheduler)、コントローラーマネージャー(kube-controller-manager)、データベース(etcd)が、自動的に構成される。


### マスターノードの設定

kubeletがsystemdによって起動されることで、k8sのコンポーネントも起動する。 
systemdの設定は、/etc/systemd/system/kubelet.service.d のディレクトリに置かれ、kubeletが起動する。
kubeletは、/etc/kubernetes/manifestsのマニフェストを使用して、ポッド（コンテナ）として、APIサーバー(kube-apiserver)、スケジューラー(kube-scheduler)、コントローラーマネージャー(kube-controller-manager)、データベース(etcd)を起動する。

設定ファイルが格納されたディレクトリ

~~~shell:bash
root@master:/etc/kubernetes# tree .
.
├── admin.conf
├── controller-manager.conf
├── kubelet.conf
├── manifests
│   ├── etcd.yaml
│   ├── kube-apiserver.yaml
│   ├── kube-controller-manager.yaml
│   └── kube-scheduler.yaml
├── 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
└── scheduler.conf
~~~


### ワーカーノードの設定

ノードにおいても、systemdからkubeletが起動される。 kube-proxyやflannelはデーモンセットのため、クラスタのジョインすることで、マスターからの指令により、起動される。

~~~shell:bash
root@node1:/etc/kubernetes# tree
.
├── bootstrap-kubelet.conf
├── kubelet.conf
├── manifests
└── pki
    └── ca.crt
~~~

systemdの設定で、kubeletがenableに成っていなければ、クラスタのメンバーに加わることができない。




## the-hard-wayの手順に沿って、インストールした場合

the-hard-wayは、kubeadmコマンドを使用することなく、全てを手作業で設定する。 the-hard-wayの手順を利用すると、kube-apiserve, kube-controller-manager, kube-scheduler, etcd, etcdctl は、実行形式のファイルとして、/usr/local/bin の下に置かれ、systemdの制御下で起動されることになる。

次は、kube-apiserverのデーモンを起動するためのsystemdの設定ファイルの例です。

~~~file:/etc/systemd/system/kube-apiserver.service
[Unit]
Description=Kubernetes API Server
Documentation=https://github.com/kubernetes/kubernetes

[Service]
ExecStart=/usr/local/bin/kube-apiserver \\
  --advertise-address=${INTERNAL_IP} \\
  --allow-privileged=true \\
  --apiserver-count=3 \\
  --audit-log-maxage=30 \\
  --audit-log-maxbackup=3 \\
  --audit-log-maxsize=100 \\
  --audit-log-path=/var/log/audit.log \\
  --authorization-mode=Node,RBAC \\
  --bind-address=0.0.0.0 \\
  --client-ca-file=/var/lib/kubernetes/ca.pem \\
  --enable-admission-plugins=Initializers,NamespaceLifecycle,NodeRestriction,LimitRanger,ServiceAccount,DefaultStorageClass,ResourceQuota \\
  --enable-swagger-ui=true \\
  --etcd-cafile=/var/lib/kubernetes/ca.pem \\
  --etcd-certfile=/var/lib/kubernetes/kubernetes.pem \\
  --etcd-keyfile=/var/lib/kubernetes/kubernetes-key.pem \\
  --etcd-servers=https://10.240.0.10:2379,https://10.240.0.11:2379,https://10.240.0.12:2379 \\
  --event-ttl=1h \\
  --experimental-encryption-provider-config=/var/lib/kubernetes/encryption-config.yaml \\
  --kubelet-certificate-authority=/var/lib/kubernetes/ca.pem \\
  --kubelet-client-certificate=/var/lib/kubernetes/kubernetes.pem \\
  --kubelet-client-key=/var/lib/kubernetes/kubernetes-key.pem \\
  --kubelet-https=true \\
  --runtime-config=api/all \\
  --service-account-key-file=/var/lib/kubernetes/service-account.pem \\
  --service-cluster-ip-range=10.32.0.0/24 \\
  --service-node-port-range=30000-32767 \\
  --tls-cert-file=/var/lib/kubernetes/kubernetes.pem \\
  --tls-private-key-file=/var/lib/kubernetes/kubernetes-key.pem \\
  --v=2
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target
~~~

the-hard-wayでは、マスターをコントローラーと表記し、ノードをワーカーとして表記している点も、面白いと思います。


### etcdのデータバックアップ

the-hard-wayの手順でインストールした場合、Linuxのコントローラー上で、etcdctlコマンドが利用できるので、以下の手順でバックアップ（スナップショット）が取得できます。

~~~
root@controller-0:~# ETCDCTL_API=3 etcdctl --endpoints=https://172.16.40.10:2379   --cacert=/etc/etcd/ca.pem   --cert=/etc/etcd/kubernetes.pem   --key=/etc/etcd/kubernetes-key.pem snapshot save snapshotdb
Snapshot saved at snapshotdb
root@controller-0:~# ETCDCTL_API=3 etcdctl --endpoints=https://172.16.40.10:2379   --cacert=/etc/etcd/ca.pem   --cert=/etc/etcd/kubernetes.pem   --key=/etc/etcd/kubernetes-key.pem --write-out=table snapshot status snapshotdb
+----------+----------+------------+------------+
|   HASH   | REVISION | TOTAL KEYS | TOTAL SIZE |
+----------+----------+------------+------------+
| 72358df4 |        0 |          5 |      16 kB |
+----------+----------+------------+------------+
~~~~


## まとめ

kubeadmを利用した場合は、kubelet以外の主要なコンポーネントは、ポッドとして構成されます。 the-hard-wayの手順では、kubelet以外のコンポーネントも、マスターノード上で、デーモンとして動作します。