kubeadm を使ったシングルノードクラスターの作成

2024/01/01に公開

kubeadm を使用して k8s クラスターの構築を行いました。
主に containerd のインストールと Pod ネットワークの設定に嵌ったので備忘録です。
検証環境のため、シングルノードの構成になっています。

以下の公式ドキュメントを参考にしています。

事前情報

バージョン情報

Version
Ubuntu 22.04.3
kubernetes v1.28.2
kubeadm v1.28.2
containerd v1.6.26
calico v3.27.0

ネットワーク情報

種類 IP(CIDR)
node01 192.168.11.110
Node Network 192.168.11.0/24
Pod Network 172.24.0.0/16

手順

以下のコマンドは root ユーザー以外で実行する想定です。

01. 前提条件

# swap を off にする。
sudo swapoff -a

# /etc/fstab の `swap.img` をコメントアウトする
sed -e 's/^\/swap.img/#&/g' /etc/fstab | sudo tee /etc/fstab

02. コンテナランタイムのインストール

# IPv4フォワーディングを有効化し、iptablesからブリッジされたトラフィックを見えるようにする
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
sudo modprobe overlay
sudo modprobe br_netfilter

# この構成に必要なカーネルパラメーター、再起動しても値は永続する
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables  = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward                 = 1
EOF

# 再起動せずにカーネルパラメーターを適用
sudo sysctl --system

# containerd のインストール
# Add Docker's official GPG key:
sudo apt-get update
sudo apt-get install ca-certificates curl gnupg
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

# Add the repository to Apt sources:
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" \
  | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install containerd.io

# 別途 CNI plugins をインストールする
curl -LO https://github.com/containernetworking/plugins/releases/download/v1.4.0/cni-plugins-linux-amd64-v1.4.0.tgz
sudo mkdir -p /opt/cni/bin
sudo tar Cxzvf /opt/cni/bin cni-plugins-linux-amd64-v1.4.0.tgz

# systemd cgroup ドライバーを構成する
# systemd cgroup を使用するように containerd を構成する
# サンドボックス(pause)イメージを変更する
containerd config default | sudo tee /etc/containerd/config.toml
sed \
    -e 's/SystemdCgroup = false/SystemdCgroup = true/g' \
    -e 's/pause:3.6/pause:3.9/g' \
    /etc/containerd/config.toml | sudo tee /etc/containerd/config.toml
sudo systemctl restart containerd

03. kubeadm、kubelet、kubectlのインストール

sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl

curl -fsSL https://dl.k8s.io/apt/doc/apt-key.gpg | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-archive-keyring.gpg

echo "deb [signed-by=/etc/apt/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list

sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl

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

# コントロールプレーンノードの初期化のための設定ファイルを作成する
kubeadm config print init-defaults | tee init_config.yaml
init-config.yaml
apiVersion: kubeadm.k8s.io/v1beta3
bootstrapTokens:
- groups:
  - system:bootstrappers:kubeadm:default-node-token
  token: abcdef.0123456789abcdef
  ttl: 24h0m0s
  usages:
  - signing
  - authentication
kind: InitConfiguration
localAPIEndpoint:
  advertiseAddress: 1.2.3.4
  bindPort: 6443
nodeRegistration:
  criSocket: unix:///var/run/containerd/containerd.sock
  imagePullPolicy: IfNotPresent
  name: node
  taints: null
---
apiServer:
  timeoutForControlPlane: 4m0s
apiVersion: kubeadm.k8s.io/v1beta3
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controllerManager: {}
dns: {}
etcd:
  local:
    dataDir: /var/lib/etcd
imageRepository: registry.k8s.io
kind: ClusterConfiguration
kubernetesVersion: 1.28.0
networking:
  dnsDomain: cluster.local
  serviceSubnet: 10.96.0.0/12
scheduler: {}

編集して以下の内容に更新する

init-config.yaml
localAPIEndpoint:
  advertiseAddress: 192.168.11.110      # kubernetes api server へアクセスする IP アドレスを設定する

nodeRegistration:
  name: node01                          # コントロールプレーンノード名を設定する

networking:
    podSubnet: 172.24.0.0/16            # Pod ネットワーク CIDR を追加する
sudo kubeadm init --config init_config.yaml

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

05. calico のインストール

kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.27.0/manifests/tigera-operator.yaml

# calico custom resource のマニフェストファイルを保存する
curl -LO https://raw.githubusercontent.com/projectcalico/calico/v3.27.0/manifests/custom-resources.yaml
custom-resources.yaml
# This section includes base Calico installation configuration.
# For more information, see: https://docs.tigera.io/calico/latest/reference/installation/api#operator.tigera.io/v1.Installation
apiVersion: operator.tigera.io/v1
kind: Installation
metadata:
  name: default
spec:
  # Configures Calico networking.
  calicoNetwork:
    # Note: The ipPools section cannot be modified post-install.
    ipPools:
    - blockSize: 26
      cidr: 192.168.0.0/16
      encapsulation: VXLANCrossSubnet
      natOutgoing: Enabled
      nodeSelector: all()

---

# This section configures the Calico API server.
# For more information, see: https://docs.tigera.io/calico/latest/reference/installation/api#operator.tigera.io/v1.APIServer
apiVersion: operator.tigera.io/v1
kind: APIServer
metadata:
  name: default
spec: {}

編集して以下の内容に更新する

custom-resources.yaml
      cidr: 172.24.0.0/16     # Pod ネットワーク CIDR
kubectl create -f custom-resources.yaml

# Remove the taints on the control plane so that you can schedule pods on it.
kubectl taint nodes --all node-role.kubernetes.io/control-plane-
kubectl taint nodes --all node-role.kubernetes.io/master-

06. ノードの状態確認

kubectl get nodes -o wide
NAME       STATUS   ROLES           AGE   VERSION   INTERNAL-IP      EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION      CONTAINER-RUNTIME
node01     Ready    control-plane   1d    v1.28.2   192.168.11.110   <none>        Ubuntu 22.04.3 LTS   5.15.0-91-generic   containerd://1.6.26

STATUS が Ready になれば OK

まとめ

事前のネットワーク設計が大事。
検証環境なら minikube で良さそう。
VSCode の drawio integration すごく便利。

Discussion