x**3な人生

基本的にはメモ

Ubuntu18.04でKubernetesのクラスタを組んだときのメモ

TL;DR

基本的にはここの通りに従えば良いです。

linuxconfig.org

環境

ノードは3台(masterが1台、slaveが2台)、すべてVMなどは用いずホスト上に構築します。

$ cat /etc/os-release 
NAME="Ubuntu"
VERSION="18.04.1 LTS (Bionic Beaver)"
...

$ docker -v
Docker version 18.09.2, build 6247962

2019/3/21時点でkubernetesはdocker 18.06で動作することを期待するため、後ほどセットアップのときに警告が出力されますが おそらく問題はないと思います。

インストールする前に、すべてのノードでホスト名が設定されていることを確認してください。 もし設定がまだであれば、hostnamectlコマンドを用いてそれぞれのノードで任意のホスト名を設定します。

$ sudo hostnamectl set-hostname HOSTNAME

インストール

すべてのノードにおいて次のインストール手順を行います。

(1) dockerのインストール

$ sudo apt install docker.io
$ sudo systemctl enable docker  # 再起動したときにdockerも起動するよう設定

(2) kubernetesのインストール

最初にgoogleのサイトにあるapt-keyを用いてリポジトリを追加します。 なおxenial(16.04)用のリポジトリのようですが、まだbionicのものがないためこれを用います。 今のところこれで正常に動作しているようです。

$ curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add
$ sudo apt-add-repository "deb http://apt.kubernetes.io/ kubernetes-xenial main"

次にapt installによりkubectlkubeadmおよびkubeletをインストールします。 以下のようにkubeadmだけを指定すれば他もまとめてインストールされます。

$ sudo apt install kubeadm

メモリのswapを無効にしていないのであれば、kubernetesを起動する前にオフにしておきます。 -a--allの省略版です。

$ sudo swapoff -a

kubernetesの起動

(1) Masterノード

masterノードから起動を行います。まずmasterノードでkubeadm initを初期化し、 次にそれぞれのslaveノードでkubeadm joinを実行してクラスタに参加させます。

複数ノード間でコンテナ間通信を行うためにflannelを利用するため、--pod-network-cidrでCIDRを指定します。 指定するアドレス帯は 参考サイト と同じく10.244.0.0/16に設定します。

$ sudo kubeadm init --pod-network-cidr=10.244.0.0/16

もし起動に失敗した場合、エラーの内容に応じて対処を行い再度起動を試みます。 例えばswapoff -aを忘れていたりすると起動に失敗します。 なお再起動の前にkubeadm resetでクリアする必要があります。

# 起動に失敗した場合はresetしてからinit
$ sudo kubeadm reset
...
$ sudo kubeadm init

kubeadm initが成功すると、セットアップの実行ログとともに設定方法のインストラクションが表示されますので これに従います。

まずkubectlコマンドでkubernetesを操作できるようにconfigを用意します。 /etc/kubernetes/admin.confkubeadm initの実行後に生成されるconfigファイルです。

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

この設定が完了すると、kubectl applyでpodをデプロイしたりすることができるようになります。

またインストラクションの最後に、次のようなslaveノードをクラスタに参加させるための方法が表示されます。 後ほどslaveノードでこれを実行する必要があるため、シェルスクリプトとして保存するなどしておきます。

#!/bin/sh

$ sudo kubeadm join IPADDR:PORT --token TOKEN --discovery-token-ca-cert-hash HASH

(2) Flannel podのデプロイ

続いてmasterノードからflannel podをデプロイしてslaveノードとの通信ができるようにします。

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

代わりにURLを直接指定することもできます。

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

flannelがデプロイされたことを確認します。

$ kubectl get pods --all-namespaces
...

(3) Slaveノード

インストールが完了していれば、あとは先ほどのインストラクションに従ってkubeadmからkubernetesを起動するだけです。

# on slave node
$ sudo kubeadm join IPADDR:PORT --token TOKEN --discovery-token-ca-cert-hash HASH

slaveノードがクラスタに参加したかどうかはmasterノードからkubectlで確認出来ます。

# on master node
$ kubectl get nodes
NAME        STATUS      ROLES       AGE      VERSION
master      Ready       master      10m      v1.13.4
slave1      Ready       <none>      3m       v1.13.4
slave2      Ready       <none>      2m       v1.13.4

サービスのデプロイ

最後に参考サイトの 例に従いnginxをデプロイしてみます。

$ kubectl run --image=nginx nginx-server --port=80 --env="DOMAIN=cluster"
$ kubectl expose deployment nginx-server --port=80 --name=nginx-http

デプロイが成功すると、kubectl get servicesもしくはkubectl get svcにより nginx-httpと言う名前のサービスがデプロイされている ことが確認できます。

$ kubectl get services
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP   39h
nginx-http   ClusterIP   10.99.125.225   <none>        80/TCP    37h

またkubectl scaleによりpodのレプリカの数を変更することも出来ます。 まずdeploymentとレプリカ数を確認します。

$ kubectl get deployments
NAME           READY   UP-TO-DATE   AVAILABLE   AGE
nginx-server   1/1     1            1           38h

nginx-serverというdeploymentがレプリカ数1で配置されていることが分かります。 READYがレプリカの状態を示しています。

次にkubectl scaleによりレプリカ数を2に変更します。対象のdeploymentは deployments/nginx-serverのように指定します。

$ kubectl scale deployments/nginx-server --replicas=2
$ kc get deployments
NAME           READY   UP-TO-DATE   AVAILABLE   AGE
nginx-server   1/2     2            1           38h

変更後すぐは2つ目のレプリカが用意されていないためREADY1/2となっていますが、 しばらくするとこれが2/2となり2つのレプリカが配置されたことが分かります。

$ kc get deployments
NAME           READY   UP-TO-DATE   AVAILABLE   AGE
nginx-server   2/2     2            1           38h

以上