kubeadmを使用したKubernetes環境構築

Kubermetes1.17環境をkubeadm(環境構築ツール)を用いて作成していく。
過去何度かkubeadmで環境をセットアップしてきたが、躓くことが多いため
備忘録としても活用していきたい。

1.前提となる環境の作成(UbuntuにDockerインストール)
2.MasterNode、Workerノードの構築
3.MasterNodeのセットアップ
4.WorkerNodeのジョイン
5.最後に

#1.前提となる環境の作成
Kubernetesをセットアップする前に、ゲストOSの準備やDockerのインストールが必要になるので、それらを準備する。

##【Virtualbox】仮想マシン作成
今回、仮想化ソフト：VertualBox、ゲストOS：Ubuntu18.04.3 LTS上でKubernetes環境を構築していく。

まずはホストOSにVirtualBoxをインストールする。
インストール手順は以下を参照
https://eng-entrance.com/virtualbox-install

インストールが完了したら、ゲストOSとなるUbuntuのisoファイルを取得する必要がある。以下のサイトから64-bit PC (AMD64) desktop imageのisoファイルをダウンロードする。
http://releases.ubuntu.com/18.04/

VirtualBoxを起動させて、「新規(N)」をクリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/571290/ffe2c1a8-11ee-4210-dbee-303cb140026a.png)


以下を設定後、作成をクリックする。
・名前:任意(MasterNodeならMaster、WorkerNodeならWorkerなど、、、)
・タイプ(Linux)
・Ubuntu(64-bit)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/571290/9bef2f8a-9fa6-fe6c-59a5-3a509bc6d51e.png)

「仮想ハードディスクの作成」は設定変更せず「作成」をクリックする。
(今後アプリなどをデプロイしていく場合は容量を追加したほうが◎)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/571290/8341d228-deb4-caa0-7abd-de758f96fafa.png)


作成後、以下のように仮想マシンが作成されていることを確認し、
「設定(S)」をクリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/571290/a2a1f6f9-98ec-d36b-4648-079677297954.png)


「システム」→「プロセッサー(P)」でプロセッサー数(P)を2に変更する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/571290/050e6cc2-97f6-5fed-7598-33b6e9346f2b.png)


「ストレージ」で「コントローラー:IDE」下の空のディスクにダウンロードした
isoファイルを割り当て、「OK」をクリックする。※「属性」欄のディスクマークをクリックすることで割り当てるファイルを選択することができる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/571290/56baf01b-a3b4-2d94-888c-8329ce8e75f3.png)


ここまでの作業が完了したら、作成した仮想マシンを選択した状態で「起動(T)」をクリックする。※起動したUbuntuに対する初期設定の変更などは特になし。

##Dockerインストール
実際に仮想マシンにDockerをインストールする。
まずはお決まりのアップデートを実施する。

```
$sudo apt update
$sudo apt upgrade
```

前提ソフトウェアのインストール、docker公式のGPG公開鍵をインストール

```
$sudo apt install apt-transport-https ca-certificates curl software-properties-common
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
```

aptリポジトリの設定の設定。

```
$ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
```

docker-ceのインストール。

```
$sudo apt-get update
$sudo apt-get install docker-ce
```

インストール完了後、docker runコマンドでhello-worldコンテナを実行し、
以下のように出力されれば問題なし。(実行結果は一部割愛)

```
$sudo docker run hello-world
nable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
1b930d010525: Pull complete
Digest: sha256:9572f7cdcee8591948c2963463447a53466950b3fc15a247fcad1917ca215a2f
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
・・・・
```

ここまでをMasterNode、WorkerNode合わせて準備しておく。

#2.MasterNode、Workerノードの構築

ここからKubermetesをインストールしていくための作業に入る。
また、以下の作業はMasterNode、WorkerNode共通の作業となる。

Kubernetesのキーを取得

```
$curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
```

Kubernetesのリポジトリを登録した後、更新を実行する。

```
$sudo apt-add-repository "deb http://apt.kubernetes.io/ kubernetes-xenial main"
$sudo apt-get update
```

swapをオフにする。

```
sudo swapoff -a
```

各パッケージをインストールする。

```
apt-get install -y kubelet kubeadm kubectl
```

パッケージインストール後、/etc/systemd/system/kubelet.service.d/10-kubeadm.confに以下を追記する。

```
$vi 10-kubeadm.conf
Environment="KUBELET_CGROUP_ARGS=--cgroup-driver=cgroupfs"
```
上記を実行することで、Cgroup DriverをDockerとkubeletとの間で一致させている。※この作業を実行しないと、MasterNodeのセットアップ時や、WorkerNodeのjoin時にエラーが出力される。(対処にはkubeadmのresetが必要)


#3.MasterNodeのセットアップ

MasteNodeの初期化(init)を実行する。
podネットワークプロバイダにflannelを使用するため、 --pod-network-cidr=10.244.0.0/16を指定する。

```
$ kubeadm init --pod-network-cidr=10.244.0.0/16 --apiserver-advertise-address=<kube-apiserverがリクエストを待ち受けるIPアドレス>
```

実行後、以下が表示されればMasterNodeの初期化は成功となる。

```
Your Kubernetes control-plane has initialized successfully!

To start using your cluster, you need to run the following as a regular user:

  mkdir -p $HOME/.kube
  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  sudo chown $(id -u):$(id -g) $HOME/.kube/config

You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
  https://kubernetes.io/docs/concepts/cluster-administration/addons/

Then you can join any number of worker nodes by running the following on each as root:

kubeadm join XXX.XXX.XXX.XXX:6443 --token 7jpywr.uck1h30a1r9rfh2s \
    --discovery-token-ca-cert-hash sha256:18cfec05b9caac750cee77fb162db5f675db3f5ea2031da2030caa209e2eee06
```

この際、表示されている「kubeadm join～」の値は後程使用するので、メモしておくこと。

以下コマンドを実行する。

```
$mkdir -p $HOME/.kube
$sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
$sudo chown $(id -u):$(id -g) $HOME/.kube/config
```

MasterNodeの状態を確認する。
(STATUSはNotReadyで問題ない)

```
$kubectl get nodes

NAME                STATUS   ROLES    AGE    VERSION
master-virtualbox   NotReady    master   5h6m   v1.17.2
```


flannelのインストール前にiptablesを編集する。

```
sudo sysctl net.bridge.bridge-nf-call-iptables=1
```

flannelをインストールする。

```
$kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
```

ノードの状態を確認し、「Ready」になっていればセットアップは完了。

```
$kubectl get nodes

NAME                STATUS   ROLES    AGE    VERSION
master-virtualbox   Ready    master   5h6m   v1.17.2
```

#4.WorkerNodeのジョイン

workerNodeにてMasterNodeのinit時に発行されたコマンド(kubeadm join~)を実行する。

```
$kubeadm join XXX.XXX.XXX.XXX:6443 --token 7jpywr.uck1h30a1r9rfh2s --discovery-token-ca-cert-hash sha256:18cfec05b9caac750cee77fb162db5f675db3f5ea2031da2030caa209e2eee06
```

実行後、以下が表示されればMasterNodeへの追加が完了となる。

```
This node has joined the cluster:
* Certificate signing request was sent to apiserver and a response was received.
* The Kubelet was informed of the new secure connection details.

Run 'kubectl get nodes' on the control-plane to see this node join the cluster.
```
時間が経過すると、トークンが無効になるので以下コマンドで再発行を適宜実施する。

```
#token
$kubeadm token create
```

```
#discovery-token-ca-cert-hash
$openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'
```

MasterNodeでクラスタに参加しているか確認する。

```
$kubectl get nodes

NAME                STATUS   ROLES    AGE    VERSION
master-virtualbox   Ready    master   5h6m   v1.17.2
node-virtualbox     Ready    <none>   5h4m   v1.17.2
```

MasterNodeでROLESのラベルを編集する。(MasterNode、WorkerNodeがわかるように)

```
$kubectl label node node-virtualbox node-role.kubernetes.io/node=
$kubectl get nodes

NAME                STATUS   ROLES    AGE    VERSION
master-virtualbox   Ready    master   5h6m   v1.17.2
node-virtualbox     Ready    node     5h4m   v1.17.2
```

#5.最後に
kubeadmの構築は簡単そうに見えてとにかく穴が多い。。。
(特にMasterの初期化、Workerのjoin)
今後もKubernetesのアップデートの度に何かしら手順が変わったりすると思うので、アンテナを張っておかないと、、、

####参考文献
[Ubuntu 18.04 LTS にKubernetes環境をインストールする [Master / Worker]][link-1] 
[link-1]:https://qiita.com/soumi/items/7736ac3aabbbe4fb474a
[kubeadmでKubernetes1.9.3のClusterを構築したメモ][link-2]
[link-2]:http://yasu7ri.hatenablog.com/entry/2018/03/31/231139#4-Cgroup-Driver%E3%81%AE%E8%A8%AD%E5%AE%9A
[Ubuntuにdockerをインストールする][link-3]
[link-3]:https://qiita.com/tkyonezu/items/0f6da57eb2d823d2611d