Kubernetes 入門 & Ubuntu Server 18.04 *4 で Kubernetes クラスタを建てる

コンテナが増えてきてコンテナ間ネットワークが複雑になり、本番環境と開発環境が乱立するようになってくると Docker では管理が大変になってきます。そこで `コンテナオーケストレーションツール` を使いましょう。今回はコンテナオーケストレーションツールのデファクトスタンダードである `Kubernetes` のクラスタを構築します。

# 今回の環境
- VMware ESXi 上の仮想マシン (Ubuntu Serer 18.04) *4
- Master&etcd *1 + Worker *3 の4台構成
- Kubeadm による構築
- Docker v18.06.2-ce
- Kubernetes v1.17.0
- その他ツール類は 2020/01/06 現在の最新バージョン

|Name|IP|Hostname|
|:--|:--|:--|
|Master|10.0.0.100|master|
|Worker01|10.0.0.101|worker01|
|Worker02|10.0.0.102|worker02|
|Worker03|10.0.0.103|worker03|

```sh
$ sudo sh -c "echo \"master 10.0.0.100\" >> /etc/hosts"
$ sudo sh -c "echo \"worker01 10.0.0.101\" >> /etc/hosts"
$ sudo sh -c "echo \"worker02 10.0.0.102\" >> /etc/hosts"
$ sudo sh -c "echo \"worker03 10.0.0.103\" >> /etc/hosts"
```

# Master の構築

## まずは Docker の構築
4台に行います。

```sh
$ sudo sed -i 's|/swap|#/swap|' /etc/fstab
$ sudo sed -i 's|GRUB_CMDLINE_LINUX=""|GRUB_CMDLINE_LINUX="cgroup_enable=memory swapaccount=1"|' /etc/default/grub
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
$ sudo add-apt-repository -y "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
$ sudo apt update
$ sudo apt install -y docker-ce=18.06.2~ce~3-0~ubuntu
$ sudo sh -c "echo '{\"exec-opts\":[\"native.cgroupdriver=systemd\"],\"log-driver\":\"json-file\",\"log-opts\":{\"max-size\":\"100m\"},\"storage-driver\":\"overlay2\"}' > /etc/docker/daemon.json"
$ sudo mkdir -p /etc/systemd/system/docker.service.d
$ sudo usermod -aG docker $USER
$ sudo systemctl daemon-reload
$ sudo systemctl enable docker
$ sudo systemctl restart docker
```

## Kubernetes の構築
4台に行います。

```sh
$ curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
$ sudo add-apt-repository -y ppa:projectatomic/ppa
$ sudo sh -c "echo 'deb http://apt.kubernetes.io/ kubernetes-xenial main' > /etc/apt/sources.list.d/kubernetes.list"
$ sudo apt update
$ sudo apt install -y kubelet kubeadm kubectl libseccomp2 software-properties-common
$ sudo modprobe overlay
$ sudo modprobe br_netfilter
$ sudo sh -c 'echo "net.bridge.bridge-nf-call-iptables = 1\nnet.ipv4.ip_forward = 1\nnet.bridge.bridge-nf-call-ip6tables = 1" > /etc/sysctl.d/99-kubernetes-cri.conf'
$ sudo sysctl --system
$ sudo systemctl daemon-reload
$ sudo systemctl enable kubelet
$ sudo systemctl restart kubelet
```

ここで一度再起動します。

```sh
$ sudo reboot
```

# クラスタの構築
## Master の構築

```sh
$ sudo kubeadm init

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 10.0.0.100:6443 --token pk20xj.mcasr444m8g4zlq3 \
    --discovery-token-ca-cert-hash sha256:5379d0a290c07bd18d0ba1c9da52aa1a3225fc9f6a1add38ba8c1aa5f3bc78d7
```

`join` 用のコマンドが出力されたら完了です。
`kubectl` コマンドが実行できるように認証情報をコピーします。

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

## Worker の構築

先程出力された `join` コマンドを使います。

```sh
$ sudo kubeadm join 10.0.0.100:6443 --token pk20xj.mcasr444m8g4zlq3 \
    --discovery-token-ca-cert-hash sha256:5379d0a290c07bd18d0ba1c9da52aa1a3225fc9f6a1add38ba8c1aa5f3bc78d7

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.
```

`Run ~` が出力されたら成功です。

## 確認
Master で行います。

```sh
$ kubectl get node
NAME       STATUS     ROLES    AGE     VERSION
master     NotReady   master   5m50s   v1.17.0
worker01   NotReady   <none>   2m7s    v1.17.0
worker02   NotReady   <none>   2m7s    v1.17.0
worker03   NotReady   <none>   2m7s    v1.17.0
```

まだ CNI を入れていないため `NotReady` ですが問題ありません。

## CNI
Kubernetes 本体ではネットワーク機能を提供していないため、ノード間通信のためのネットワークを作る必要があります。
Flannel, Weave, Calico 等がありますが、今回は Weave を使用します。
Master で行います。

```sh
$ kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')"
serviceaccount/weave-net created
clusterrole.rbac.authorization.k8s.io/weave-net created
clusterrolebinding.rbac.authorization.k8s.io/weave-net created
role.rbac.authorization.k8s.io/weave-net created
rolebinding.rbac.authorization.k8s.io/weave-net created
daemonset.apps/weave-net created
```

先程 `NotReady` でしたが、 CNI をインストールしたのでもう一度確認してみましょう。

```sh
$ kubectl get node
NAME       STATUS   ROLES    AGE   VERSION
master     Ready    master   28m   v1.17.0
worker01   Ready    <none>   24m   v1.17.0
worker02   Ready    <none>   24m   v1.17.0
worker03   Ready    <none>   24m   v1.17.0
```

無事に `Ready` になりました。
以上で Kubernetes クラスタの構築は終了です。

# kubectl とは？
>Kubernetesのコマンドラインツールであるkubectlを使用して、Kubernetesクラスターに対してコマンドを実行することができます。kubectlによってアプリケーションのデプロイや、クラスターのリソース管理および検査を行うことができます。
https://kubernetes.io/ja/docs/tasks/tools/install-kubectl/

公式からの引用ですがこういうものです。
各コマンドの詳しい説明は `kubectl help` で確認してください。

`get` `apply` `delete` `edit` 等々 Kubernetes を操作する上で必須となるツールです。

今後の記事では `kubectl` をメインに他のツールも使いながら Kubernetes を使っていきたいと思います。