自宅Kubernetesクラスターを構築しました

はじめに

自宅サーバー上にKubernetesクラスターを構築したので、手順などを記録しておこうと思います。
やったことは公式のドキュメントほぼそのままで、躓いた点などのポイントだけを書いていこうと思います。
kubernetes.io

クラスターを動かすVMを建てる

Hyper-V上に以下の設定でVMを建てました。

  • masterノード
    • CPU: 2Core
    • RAM: 2GB
    • Disk: 16GB
  • workerノード x3
    • CPU: 1Core
    • RAM: 1GB
    • Disk: 16GB

OSは全てUbuntu 18.04 LTSで統一しています。

ホスト名 IPアドレス ロール
truss 192.168.0.15 master
kibo 192.168.0.16 worker
zvezda 192.168.0.17 worker
unity 192.168.0.18 worker

ホスト名は国際宇宙ステーションのモジュール名から取りました。masterノードはKubernetesの鍵となる部分なので、ISSの背骨とも言えるtrussの名前をつけました。
これらのVMDNSなり/etc/hostsなりで名前解決できるようにしておいてください。

VMの設定をする(ノード共通)

ファイアウォールの設定をする

ファイアウォールにはufwを使用しました。
masterノードは以下のように設定しました。

To                         Action      From
--                         ------      ----
22                         ALLOW       192.168.0.0/24
9100                       ALLOW       999.999.999.999
6443/tcp                   ALLOW       192.168.0.0/24
10250/tcp                  ALLOW       192.168.0.0/24
10251/tcp                  ALLOW       192.168.0.0/24
10252/tcp                  ALLOW       192.168.0.0/24
2379:2380/tcp              ALLOW       192.168.0.0/24
Anywhere                   ALLOW       10.244.0.0/16

開けているポートはSSHとPrometheusのnode_exporter、Kubernetes関連のポートです。
最後の行の設定は、後述するPodネットワークアドオン、Flannelのためのものです。この設定を忘れると、CoreDNSでPod接続できないというエラーログが出力されます。
workerノードの設定はこちらです。

To                         Action      From
--                         ------      ----
22                         ALLOW       192.168.0.0/24
9100                       ALLOW       999.999.999.999
10250                      ALLOW       Anywhere
30000:32767/tcp            ALLOW       Anywhere
Anywhere                   ALLOW       10.244.0.0/16
10250 (v6)                 ALLOW       Anywhere (v6)
30000:32767/tcp (v6)       ALLOW       Anywhere (v6)

こちらも、SSHとPrometheusのnode_exporter、Kubernetes関連のポートを開けてあります。
また、公式のドキュメントには「iptablesがnftablesバックエンドを使用しないようにする」という設定項目がありますが、これは飛ばしても大丈夫でした。
Ubuntu 18.04ではnftablesは使われていないらしいので、無視しても大丈夫っぽいです。

swapをOFFにする

以下のコマンドでswapをOFFにできます。

sudo swapoff -a

しかし、再起動後には再度swapが有効になるので、/etc/fstab中のswapの設定をしている行を削除するなりコメントアウトするなりしてください。

コンテナランタイムをインストールする

今回はコンテナランタイムとしてDockerを使用しました。
インストール方法はドキュメントそのままです。
kubernetes.io

masterノードの設定をする

以下のコマンドでクラスターの初期化を行います。

kubeadm init --pod-network-cidr=10.244.0.0/16 --apiserver-advertise-address=192.168.0.15

pod-network-cidrはPodに割り当てられるIPアドレスの範囲で、後述するFlannelを使用する場合は、10.244.0.0/16に設定する必要があります。
apiserver-advertise-addressはmasterノードのIPアドレスです。
このコマンドを実行すると、最後にkubeadm join <control-plane-host>:<control-plane-port> --token <token> --discovery-token-ca-cert-hash sha256:<hash>という出力が表示されるので、これをコピーして保存しておいてください。

Podネットワークアドオンのインストール

今回はPodネットワークアドオンとしてFlannelを使用しました。その際、以下のコマンドを実行して、カーネルパラメータの値を設定しました。

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

その後、kubectl applyコマンドでFlannelをインストールしました。

workerノードの設定をする

kubeadm initコマンドを実行した際に出力されたkubeadm join <control-plane-host>:<control-plane-port> --token <token> --discovery-token-ca-cert-hash sha256:<hash>のコマンドを、各workerノードで実行します。

クラスターの動作状況の確認

以下のコマンドでクラスターの動作状況を確認できます。

kubectl get nodes -o wide

今回は以下の出力が得られました。

NAME     STATUS   ROLES    AGE    VERSION   INTERNAL-IP    EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION      CONTAINER-RUNTIME
kibo     Ready    <none>   5d1h   v1.17.4   192.168.0.16   <none>        Ubuntu 18.04.4 LTS   4.15.0-91-generic   docker://18.6.2
truss    Ready    master   5d1h   v1.17.4   192.168.0.15   <none>        Ubuntu 18.04.4 LTS   4.15.0-91-generic   docker://18.6.2
unity    Ready    <none>   5d1h   v1.17.4   192.168.0.18   <none>        Ubuntu 18.04.4 LTS   4.15.0-91-generic   docker://18.6.2
zvezda   Ready    <none>   5d1h   v1.17.4   192.168.0.17   <none>        Ubuntu 18.04.4 LTS   4.15.0-91-generic   docker://18.6.2

何も動かしていない状態では、masterノードは常時CPU使用率20%、メモリ使用率50%弱くらいの負荷です。workerノードは常時CPU使用率2%、メモリ使用率50%強くらいでした。

おわりに

自宅Kubernetesクラスターは前からやってみたかったのですが、なかなか手を付けていませんでした。今回、春休み&外出自粛ということで思い切ってやってみました。
構築は3時間ほどでできたのですが、ufw10.244.0.0/16からのアクセスを許可するのを忘れていて、CodeDNSのエラー解決に時間がかかりました。
とりあえず、クラスター構築はできたので、いろいろ触って勉強していこうと思います。
最後に、「入門 Kubernetes」がとても分かりやすかったのでおすすめです。(情報は少し古いですが…)
www.amazon.co.jp