kubeadm をつかって kubernetes v1.21.0 のクラスタをつくる

9 min read読了の目安(約8700字

はじめに

kubeadm をつかって kubernetes v1.21 のクラスタを作ってみました。

基本的に kubeadmを使ってクラスターを構築する の手順に従っています。

使用した環境

コントロールプレーン 1台、ワーカーノード 1台の小さなクラスタを作成しました。
これらのマシンは vSphere の上で動いています。

env コントロールプレーン ワーカーノード
CPU 4 2
Memory 4GB 4GB
OS Ubuntu 20.04 Ubuntu 20.04

node の準備

kubeadmのインストール

kubeadm のインストールを行う前に、必要なコンポーネントの準備をします。

以下の手順はすべての マシンで実行します。

swap の無効化

kubeadmのインストール#始める前に

Swapがオフであること。kubeletが正常に動作するためにはswapは必ずオフでなければなりません。

以下のコマンドを使って swap を無効にします。

swapoff -a

このままだと再起動したときに消えてしまうため、永続化する必要があります。
今回は /etc/fstab を編集して swap をコメントアウトしました。

# /etc/fstab: static file system information.
#
# Use 'blkid' to print the universally unique identifier for a
# device; this may be used with UUID= as a more robust way to name devices
# that works even if disks are added and removed. See fstab(5).
#
# <file system> <mount point>   <type>  <options>       <dump>  <pass>
# / was on /dev/ubuntu-vg/ubuntu-lv during curtin installation
/dev/disk/by-id/dm-uuid-LVM-2xFeMDORvUuXGcybg2e2NsvnCxKu8pd1uoLLLjJIHr6S5tmx0F9pNjkYs74hB7ad / ext4 defaults 0 0
# /boot was on /dev/sda2 during curtin installation
/dev/disk/by-uuid/d2e3fd89-0437-4235-9a79-f506fec162b4 /boot ext4 defaults 0 0
- /swap.img     none    swap    sw      0       0
+ # /swap.img     none    swap    sw      0       0

iptables がブリッジを透過するトラフィックを処理できるようにする

今回使用した OS である Ubuntu 20.04 では、 br_netfilter モジュールがロードされていなかったので、事前にロードしておきます。

また、今回はコンテナランタイムとして CRI-O を使用します。そのために必要なモジュールも同時にロードしておきます。

kubeadmのインストール#iptablesがブリッジを通過するトラフィックを処理できるようにする の手順ではマシンを再起動すると設定が消えてしまうので、永続化しておきます。

# カーネルモジュールをロードする設定
cat <<EOF > /etc/modules-load.d/crio.conf
overlay
br_netfilter
EOF

# カーネルパラメータの設定
cat <<EOF > /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward                 = 1
EOF

再起動後に有効にはなりますが、今回のセッションでは有効にならないので手動で有効にします。

modprobe overlay
modprobe br_netfilter

sysctl --system

iptables が nftables バックエンドを使用しないようにする

kubeadmのインストール#iptablesがnftablesバックエンドを使用しないようにする の手順に従い、レガシーバイナリを利用します。

# レガシーバイナリをインストール
sudo apt-get install -y iptables arptables ebtables

# レガシーバージョンに切り替える
sudo update-alternatives --set iptables /usr/sbin/iptables-legacy
sudo update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy
sudo update-alternatives --set arptables /usr/sbin/arptables-legacy
sudo update-alternatives --set ebtables /usr/sbin/ebtables-legacy

ランタイムのインストール

CRIのインストール/#cri-o

CRI-O をコンテナランタイムとしてインストールします。

環境変数の設定

今回は Ubuntu 20.04 なので OS=xUbuntu_20.04 を指定します。

また、kubernetes 1.21 をインストールしたいので、 VERSION=1.21 を指定します。

インストール

export OS=xUbuntu_20.04
export VERSION=1.21

echo "deb https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/$OS/ /" > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list
echo "deb http://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable:/cri-o:/$VERSION/$OS/ /" > /etc/apt/sources.list.d/devel:kubic:libcontainers:stable:cri-o:$VERSION.list

curl -L https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable:cri-o:$VERSION/$OS/Release.key | apt-key add -
curl -L https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/$OS/Release.key | apt-key add -

apt-get update
apt-get install cri-o cri-o-runc

CRI-Oの起動

systemctl daemon-reload
# CRI-O を永続化する
systemctl enable crio
# CRI-O を起動
systemctl start crio

kubeadm, kubelet, kubectl のインストール

インストールの準備を行います。

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 kubelet=1.21.0-00 のような形式で実行する必要があります。

例えば、 1.19 のバージョンを検索するには、以下のようにすることができます。

$ apt-cache show kubelet | grep Version | grep 1.19
Version: 1.19.11-00
Version: 1.19.10-00
Version: 1.19.9-00
Version: 1.19.8-00
Version: 1.19.7-00
Version: 1.19.6-00
Version: 1.19.5-00
Version: 1.19.4-00
Version: 1.19.3-00
Version: 1.19.2-00
Version: 1.19.1-00
Version: 1.19.0-00

今回は 1.21.1-00 をインストールしました。

sudo apt-get install -y kubelet=1.21.1-00 kubeadm=1.21.1-00 kubectl=1.21.1-00

# apt update などしてバージョンが勝手に上がらないようにする
sudo apt-mark hold kubelet kubeadm kubectl

クラスタの作成

ここまでで、クラスタのノードとして動作させる準備が整いました。

これから、コントロールプレーンとワーカーノードの設定を行います。

コントロールプレーンノードの初期化

コントロールプレーンにしたいマシンで作業します。

config の設定

kubeadm init すると いろいろエラーが出たので config ファイルを作成しました。

$ cat kubeadm/kubeadm-config.yaml
kind: ClusterConfiguration
apiVersion: kubeadm.k8s.io/v1beta2
kubernetesVersion: v1.21.0
# CNI として Calico をつかうため、 pod-network-cidr を指定する必要がある
# https://docs.projectcalico.org/getting-started/kubernetes/quickstart
networking:
	podSubnet: "192.168.0.0/16" 
---
kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
cgroupDriver: systemd

エラー 1

7023 kuberuntime_sandbox.go:69] CreatePodSandbox for pod "kube-controller-manager-taka_kube-system(a42637cbc70a7156d41541b562e7e2a9)" failed: rpc error: code = Unknown desc = cri-o configured with systemd cgroup manager, but did not receive slice as parent:

kubeletsystemdcgroup manager として使うことを伝えないといけないようです。

エラー2

Flag --cgroup-driver has been deprecated, This parameter should be set via the config file specified by the Kubelet's --config flag. See https://kubernetes.io/docs/tasks/administer-cluster/kubelet-config-file/ for more information.

kubelet の 引数として --cgroup-driver を使うのは 廃止されているので、 config ファイル経由で渡す必要があります。

コントロールプレーンの作成

# kubeadm init --config path/to/config
kubeadm init --config kubeadm/kubeadm-config.yaml

この状態で少し待つと、コントロールプレーンが出来上がります。

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

Alternatively, if you are the root user, you can run:

  export KUBECONFIG=/etc/kubernetes/admin.conf

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 <controle-plane-host>:<controle-plane-port> --token some-token \
        --discovery-token-ca-cert-hash sha256:some-discovery-token-ca-cert-hash

出力されているメッセージ通り、 export KUBECONFIG=/etc/kubernetes/admin.conf を実行すると kubectl が使えるようになります。

kubectl get node
NAME         STATUS   ROLES           AGE    VERSION
k8s-master   Ready    control-plane   10s   v1.21.0

ワーカーノードの設定

コントロールプレーンの設定の最後に出てきたコマンドをワーカーノードで入力します。

kubeadm join <controle-plane-host>:<controle-plane-port> --token some-token \
        --discovery-token-ca-cert-hash sha256:some-discovery-token-ca-cert-hash

この表示がでると、ワーカーノードの設定は完了です。

Node join complete:
* Certificate signing request sent to control-plane and response
  received.
* Kubelet informed of new secure connection details.

Run 'kubectl get nodes' on control-plane to see this machine join.
kubectl get node
NAME         STATUS   ROLES           AGE    VERSION
k8s-master   Ready    control-plane   6m     v1.21.0
k8s-node01   Ready                    12s    v1.21.0;

ここまでで コントロールプレーン 1台、node 1台のクラスタができました!

node を増やす場合には、新しいマシンで ノードの準備 を行い、先程のコマンドを入力することで node を増やすことができそうです。