Ubuntu 20.04 に kubeadm で Kubernetes をインストールする

Ubuntu 20.04  に kubeadm で Kubernetes をインストールする

勉強を兼ねて kubeadm で Kubernetes をインストールする際の手順をまとめます。巷に出回っている v1.18.0 くらいの手順だと最新のバージョンでうまくインストールできなかったので、手順を調査しました。

前提条件

今回は次の環境を対象にインストールを実施する手順を記載します。最新バージョンが更新された場合でも、インストール時に次のバージョンを指定すれば同様の動作になると思います。

  • Ubuntu 20.04
  • kubeadm: v1.22.2
  • kubelet: v1.22.2
  • kubectl: v1.22.2
  • containerd: 1.4.9

また、用意する仮想マシンは ESXi 上で動作しますが、クラウドサービス上で IaaS VM を動かした場合でもほぼ同様かと思います。クラウドサービスの用意するイメージによっては手順が異なる場合があるのでご注意ください。

使用した仮想マシンのスペックは次の通りです。それぞれの仮想マシンはネットワーク的に疎通できるようにしておく必要があります。クラウドサービスの場合は ACL の設定などを後述するファイアウォールの設定に従って別途設定してください。

  • Master ノード
    • CPU: 2 core
    • RAM: 4 GB
  • Worker ノード
    • CPU: 1 core
    • RAM: 2 GB

インストール手順

インストールは次の手順で行います。Master ノードと Worker ノードで途中から手順が異なります。

  1. root ユーザーへの切り替え
  2. スワップディスクの無効化
  3. iptables のブリッジトラフィック有効化
  4. ファイアウォールルールの設定
  5. containerd のインストール
  6. kubeadm のインストール
  7. kubeadm の初期化 (Master ノードのみ)
  8. kubejoin でのノード参加 (Worker ノードのみ)
  9. クレデンシャルの取得 (Master ノードのみ)
  10. Flannel のインストール

1. root ユーザーへの切り替え

インストールに際してシステム設定の変更を行うことが多いため、一般ユーザーから root ユーザーへ切り替えます。以降は指定ない限り root ユーザーでの操作を前提とします。

sudo su

2. スワップディスクの無効化

kubelet が動作するためにスワップディスクを無効化しておく必要があります。

次のコマンドでスワップディスクを無効にします。

swapoff -a

永続的にスワップディスクを無効化するためには、次のように /etc/fstab のスワップディスクをコメントアウトします。

sed -i -e 's/\/swap.img/#\/swap.img/g' /etc/fstab

3. iptables のブリッジトラフィック有効化

Kubernetes ノードの iptables がブリッジを通過するトラフィックを処理するように必要なモジュールの読み込みと設定ファイルを作成します。

modprobe br_netfilter
cat <<EOF > /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF

設定したらシステムに反映します。

sysctl --system

4. ファイアウォールルールの設定

Kubernetes に必要な通信を許可するファイアウォールルールを構成します。Master ノードと Worker ノードでそれぞれ必要な通信ルールは次の通りです。

Master ノード

プロトコル通信の向きポート範囲目的使用者
TCPInbound6443*Kubernetes API server全て
TCPInbound2379-2380etcd server client APIkube-apiserver、etcd
TCPInbound10250Kubelet API自身、コントロールプレーン
TCPInbound10251kube-scheduler自身
TCPInbound10252kube-controller-manager自身

ufw で設定する場合は次のようにします。

ufw allow 22/tcp
ufw allow 443/tcp
ufw allow 6443/tcp
ufw allow 2379/tcp
ufw allow 2380/tcp
ufw allow 10250/tcp
ufw allow 10251/tcp
ufw allow 10252/tcp
ufw allow 30000:32767/tcp
ufw enable

Worker ノード

プロトコル通信の向きポート範囲目的使用者
TCPInbound10250Kubelet API自身、コントロールプレーン
TCPInbound30000-32767NodePort Service†全て

ufw で設定する場合は次のようにします。

ufw allow 22/tcp
ufw allow 10250/tcp
ufw allow 30000:32767/tcp
ufw enable

5. containerd のインストール

コンテナーランタイムとして containerd をインストールします。コンテナーランタイムは Docker を使うのが主流でしたが、最近では containerd を使うので十分になっているんじゃないかと思います。

インストールに必要なモジュールの読み込みと設定を行います。

modprobe overlay
cat > /etc/modules-load.d/containerd.conf <<EOF
overlay
br_netfilter
EOF
cat > /etc/sysctl.d/99-kubernetes-cri.conf <<EOF
net.bridge.bridge-nf-call-iptables  = 1
net.ipv4.ip_forward                 = 1
net.bridge.bridge-nf-call-ip6tables = 1
EOF

設定したらシステムに反映します。

sysctl --system

次のコマンドで containerd をインストールします。

apt-get update && apt-get install -y apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -
add-apt-repository \
    "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
    $(lsb_release -cs) \
    stable"
apt-get update && apt-get install -y containerd.io
mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml
systemctl restart containerd

6. kubeadm のインストール

次のコマンドで kubeadm をインストールします。最後のコマンドで意図しないバージョンの更新を防ぎます。

sudo apt-get update && sudo apt-get install -y apt-transport-https curl
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
cat <<EOF | sudo tee /etc/apt/sources.list.d/kubernetes.list
deb https://apt.kubernetes.io/ kubernetes-xenial main
EOF
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl

7. kubeadm の初期化 (Master ノードのみ)

次のコマンドで kubeadm を初期化します。このコマンドは Master ノードのみで実行します。Pod ネットワークの CIDR に指定しているネットワークはこの後の手順で実行する Flannel に合わせたものです。異なるネットワークコンポーネントを利用する場合は適宜環境に合わせてください。

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

コマンドの実行が完了すると Worker ノードで実行するためのコマンドが出力されます。

8. kubejoin でのノード参加 (Worker ノードのみ)

次のようなコマンドが kubeadm 初期化成功時に出力されているので、Worker ノードで実行します。参加コマンドのトークン有効期限は 24 時間なので、初期セットアップは連続して行うと良いと思います。

kubeadm join 192.168.11.48:6443 --token 8ioun5.g2khwdpt5stgaoz8 \
--discovery-token-ca-cert-hash sha256:8d69b1fb4155931ec1d2a6bc68cf4f3b32ba37576cfe7acd1d7d3054a6b20640

9. クレデンシャルの取得 (Master ノードのみ)

kubectl を実行するために必要なクレデンシャル情報を取得します。ここからは一般ユーザーに戻ってコマンドを実行します。

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

現時点では kubectl get nodes を実行しても各ノードの状態は Not Ready になっていると思います。

$ kubectl get nodes
NAME          STATUS     ROLES                  AGE     VERSION
kube-master   NotReady   control-plane,master   4m41s   v1.22.2
kube-worker   NotReady   <none>                 112s    v1.22.2

10. Flannel のインストール

Kubernetes ノード間での Pod 通信をオーバーレイするためのネットワークコンポーネントとして Flannel をインストールします。

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

各 Pod が通信できるようになるとシステム Pod が徐々にセットアップされていきます。

$ kubectl get nodes
NAME          STATUS   ROLES                  AGE    VERSION
kube-master   Ready    control-plane,master   117m   v1.22.2
kube-worker   Ready    <none>                 115m   v1.22.2

$ kubectl get pod -n kube-system
NAME                                  READY   STATUS    RESTARTS   AGE
coredns-78fcd69978-j28wr              1/1     Running   0          117m
coredns-78fcd69978-mwd8t              1/1     Running   0          117m
etcd-kube-master                      1/1     Running   0          117m
kube-apiserver-kube-master            1/1     Running   0          118m
kube-controller-manager-kube-master   1/1     Running   0          117m
kube-flannel-ds-4rjnq                 1/1     Running   0          104m
kube-flannel-ds-vldr6                 1/1     Running   0          104m
kube-proxy-4pb4w                      1/1     Running   0          115m
kube-proxy-6gkq4                      1/1     Running   0          117m
kube-scheduler-kube-master            1/1     Running   0          117m

この状態になればひとまず Kubernetes として利用できる環境が整備できました。