0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Vagrant使ってkubeadmとcontainerdでkubernetes1.31を構築する

Posted at

はじめに

kubernetesをkubeadm使って構築する際、Vagrant環境だとNATアドレスが優先されてしまう。
それに対処する個別の設定方法はネットで探すと出てくるものの、毎回探すのが大変。
さらにkubernetesの本家の手順はVagrant環境意識していないので手順通りにやるとハマったり、いろんな情報が混在して、結局何を設定すればいいのかわかりにくかったため、自分の備忘録用に整理。

前提

  • Vagrantで作ったVM2台にインストール(Master用とWorker用にそれぞれ一つ)
    • Masterノード:192.168.56.53
    • Workerノード:192.168.56.54
  • VMはUbuntu20.04を利用
  • kubernetes構築はkubeadmを利用
  • Container Runtimeはcontainerdを利用
  • cgroupドライバはsystemdを利用
  • CNIプラグイン実装はcalicoを利用
  • calicoで使うアドレス帯192.168.0.0/16がVagrantのアドレス帯192.168.56.0/24と重複しているので、calicoのアドレス帯を172.168.0.0/16に変更

手順

以下の手順で進めた。VagrantでのVMはすでにある前提で省略。

  1. Masterノードの構築
    1. Container Runtime(containerd)をインストール
    2. kubeadm, kubelet, kubectlのインストール
    3. kubernetesクラスタの作成(Masterノード側)
    4. CNIプラグインのインストール
  2. Workerノードの構築
    1. Container Runtime(containerd)をインストール
    2. kubeadm, kubeletのインストール
    3. kubernetesクラスタを作成(Workerノード側)

Masterノードの構築

最初Masterノードから。

Container Runtimeのインストール

swapをoffにする

/etc/fstabのswapをコメントアウト

sudo vi /etc/fstab

# コメントアウトしてswap を永続的にOFFにする
# /swap.img  none  swap  sw  0 0

シャットダウン後、swap確認

# shutdown
sudo shutdown -r now

# 起動後に再度ログインしてswap確認
free -m

パケットforward設定

昔の手順見ると他にも設定項目があったが、kubernetes1.31ではこれだけでいいらしい。

# sysctl params required by setup, params persist across reboots
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.ipv4.ip_forward = 1
EOF

# Apply sysctl params without reboot
sudo sysctl --system
sysctl net.ipv4.ip_forward
[結果:設定されているなら1]
net.ipv4.ip_forward = 1

cgroupドライバをどれにするか決める。

cgroupfs driversystemd cgroup driver の2種類のドライバがあるが、
systemd起動しているシステムではsystemd cgroup driverを使えとあるのでsystemdにする。
kubernetesインストール時に指定するので、今は何もしない。

containerdのインストール

containerdの説明ページから辿れるcontainerdのインストールページには公式のバイナリでのインストールする方法と、Dockerでインストールする方法があり、ネットで調べてもDockerでインストールする方法が多く紹介されている。
ここでは公式のバイナリでのインストールにする。(Dockerインストール試したけどうまくいかなかったので諦めた・・)

containerdインストールの大まかな流れは以下のとおり。

  • Step1. containerdインストール
  • Step2. runcインストール
  • Step3. CNIプラグインインストール

Step1.containerdインストール

ダウンロードページから取得。
2.x系もあったが、最近出たばっかりでハマりそうだったので1.7系をインストールする。
この後インストールするruncのバージョン1.2.2に対応しているとのこと。

# 資材をdownloadしてインストール
curl -OL https://github.com/containerd/containerd/releases/download/v1.7.24/containerd-1.7.24-linux-amd64.tar.gz
sudo tar Cxzvf /usr/local containerd-1.7.24-linux-amd64.tar.gz

# service起動用スクリプトもdownlodして設定する
curl -OL https://raw.githubusercontent.com/containerd/containerd/main/containerd.service
sudo cp ./containerd.service /lib/systemd/system/containerd.service
sudo systemctl daemon-reload
sudo systemctl enable --now containerd

## 起動していることを確認
systemctl status containerd

Step2. runcインストール

containerdに対応しているrunc v1.2.2をダウンロード。

curl -OL https://github.com/opencontainers/runc/releases/download/v1.2.2/runc.amd64
sudo install -m 755 runc.amd64 /usr/local/sbin/runc

Step3. CNIプラグインインストール

どのバージョンが適切か不明だったので最新バージョンにする。

curl -OL https://github.com/containernetworking/plugins/releases/download/v1.6.1/cni-plugins-linux-amd64-v1.6.1.tgz
sudo mkdir -p /opt/cni/bin
sudo tar Cxzvf /opt/cni/bin cni-plugins-linux-amd64-v1.6.1.tgz

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

基本的にkubernetesのインストール手順に従って実施する。

必要なパッケージのインストール

sudo apt-get update
# apt-transport-https may be a dummy package; if so, you can skip that package
sudo apt-get install -y apt-transport-https ca-certificates curl gpg

とりあえず、マニュアルに書かれている通りに・・・

sudo mkdir -p /etc/apt/keyrings
# If the directory `/etc/apt/keyrings` does not exist, it should be created before the curl command, read the note below.
# sudo mkdir -p -m 755 /etc/apt/keyrings
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.31/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg

技術者として理解することを放棄し・・・

# This overwrites any existing configuration in /etc/apt/sources.list.d/kubernetes.list
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.31/deb/ /' | 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

自動起動を有効にしてkubeletサービス起動

sudo systemctl enable --now kubelet

この段階ではkubeletサービスは再起動を繰り返して正常に起動しないが問題ないとインストールガイドに書いている。確かにactivating状態のままであり、まともに立ち上がっていない。

$ systemctl status kubelet

## 結果
vagrant@kubeadm:/etc/containerd$ systemctl status kubelet
● kubelet.service - kubelet: The Kubernetes Node Agent
     Loaded: loaded (/lib/systemd/system/kubelet.service; enabled; vendor preset: enabled)
    Drop-In: /usr/lib/systemd/system/kubelet.service.d
             └─10-kubeadm.conf
     Active: activating (auto-restart) (Result: exit-code) since Mon 2024-12-30 21:47:54 JST; 7s ago
       Docs: https://kubernetes.io/docs/
    Process: 14992 ExecStart=/usr/bin/kubelet $KUBELET_KUBECONFIG_ARGS $KUBELET_CONFIG_ARGS $KUBELET_KUBEADM_ARGS $KUBELET_EXTRA_ARG>
   Main PID: 14992 (code=exited, status=1/FAILURE)

kubernetesクラスタの作成(Masterノード側)

事前準備

cgroup driverでsystemdを利用する宣言と、node-ipを設定する。
--node-ipオプションをつけないとkubectl get node -o wideで出力されるINTERNAL_IPがVagrantのNAT IP(10.2.0.15)が優先的に割り当てられる。

cat << EOF | sudo tee /etc/default/kubelet
KUBELET_EXTRA_ARGS=--cgroup-driver=systemd --node-ip=192.168.56.53
EOF

sudo systemctl daemon-reload
sudo systemctl restart kubelet

Masterノードのクラスタ作成

--apiserver-advertise-addressでクラスタ構成のIPを指定。--node-nameはノード名を変更したい場合のみに指定。指定しない場合はホスト名がノード名となる。

sudo kubeadm init --pod-network-cidr=172.16.0.0/16 --apiserver-advertise-address=192.168.56.53 --node-name=master
[出力結果]
sudo kubeadm init --pod-network-cidr=172.16.0.0/16 --apiserver-advertise-address=192.168.56.53 --node-name=master
I0102 10:54:02.171604    5513 version.go:261] remote version is much newer: v1.32.0; falling back to: stable-1.31
[init] Using Kubernetes version: v1.31.4
[preflight] Running pre-flight checks
        [WARNING Hostname]: hostname "master" could not be reached
        [WARNING Hostname]: hostname "master": lookup master on 127.0.0.53:53: server misbehaving
・・・

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 192.168.56.53:6443 --token z8vnl0.lugg1c3jvihk2dg6 \
        --discovery-token-ca-cert-hash sha256:7c41629dc4f0ac5abaea5b1712dbb3264842ea71580203be607875367685599d 

正常終了後の出力結果をそのまま実行

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

このタイミングでkubeletサービスが正常に起動される。
またkubeletサービスにcgroup driverでsystemd、node-ipが設定されていることがわかる。

# kubeletサービスがactive, オプションにsystemdとnode-ipの引数が設定されている
systemctl status kubelet

[出力(抜粋)]
● kubelet.service - kubelet: The Kubernetes Node Agent
     Loaded: loaded (/lib/systemd/system/kubelet.service; enabled; vendor preset: enabled)
    Drop-In: /usr/lib/systemd/system/kubelet.service.d
             └─10-kubeadm.conf
     Active: active (running) since Thu 2025-01-02 10:59:08 JST; 8min ago
       Docs: https://kubernetes.io/docs/
   Main PID: 6384 (kubelet)
      Tasks: 11 (limit: 2274)
     Memory: 33.5M
     CGroup: /system.slice/kubelet.service
             └─6384 /usr/bin/kubelet --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf --config=/var/lib/kubelet/config.yaml --container-runtime-endpoint=unix:///var/run/containerd/containerd.sock --hostname-override=master --pod-infra-container-image=registry.k8s.io/pause:3.10 --cgroup-driver=systemd --node-ip=192.168.56.53

またノード名、INTERNAL_IPも正しく設定されている。nodeのSTATUSはNotReadyでよい。またcoredns以外のPodも正常に起動されているのがわかる。
corednsはインストールガイドによるとCNIプラグインをインストールするまでPending状態とのことなので問題なし。

$ kubectl get node -o wide
NAME     STATUS     ROLES           AGE   VERSION   INTERNAL-IP     EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION      CONTAINER-RUNTIME
master   NotReady   control-plane   18m   v1.31.4   192.168.56.53   <none>        Ubuntu 20.04.4 LTS   5.4.0-110-generic   containerd://1.7.24

# dns以外のpodは正常起動
$ kubectl get pod -A
NAMESPACE     NAME                             READY   STATUS    RESTARTS   AGE
kube-system   coredns-7c65d6cfc9-jcfjb         0/1     Pending   0          19m
kube-system   coredns-7c65d6cfc9-zjlgw         0/1     Pending   0          19m
kube-system   etcd-master                      1/1     Running   0          20m
kube-system   kube-apiserver-master            1/1     Running   0          20m
kube-system   kube-controller-manager-master   1/1     Running   0          20m
kube-system   kube-proxy-tddbf                 1/1     Running   0          20m
kube-system   kube-scheduler-master            1/1     Running   0          20m

CNIプラグインのインストール

CNIプラグインのcalicoをインストールする。
基本的にインストールガイドの通りやるだけ。

Calicoオペレータを追加

# install Calico operator
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.29.1/manifests/tigera-operator.yaml

Calicoではcidrとして192.168.0.0/16を使っている。これはVagrantと被るので、Masterノード作成時に指定した172.16.0.0/16へ修正する。

# cidrを記載しているので、修正して適用するため一旦ダウンロード
curl -OL https://raw.githubusercontent.com/projectcalico/calico/v3.29.1/manifests/custom-resources.yaml

# cidrを修正
vi custom-resources.yaml
      cidr: 192.168.0.0/16
      ↓
      cidr: 172.16.0.0/16

# 修正したyamlファイルを適用しCalicoをインストール
kubectl apply -f ./custom-resources.yaml

# Podの正常起動を確認(全Podが起動するまで数分程度かかる)
kubectl get pod -A
[結果]
NAMESPACE          NAME                                       READY   STATUS    RESTARTS   AGE
calico-apiserver   calico-apiserver-697587c558-2ltzq          1/1     Running   0          2m2s
calico-apiserver   calico-apiserver-697587c558-v5fkh          1/1     Running   0          2m2s
calico-system      calico-kube-controllers-6dbdfd75fd-ccf42   1/1     Running   0          2m2s
calico-system      calico-node-b45wn                          1/1     Running   0          2m2s
calico-system      calico-typha-7d7889b79-bdvhw               1/1     Running   0          2m2s
calico-system      csi-node-driver-7fwr2                      2/2     Running   0          2m2s
kube-system        coredns-7c65d6cfc9-jcfjb                   1/1     Running   0          56m
kube-system        coredns-7c65d6cfc9-zjlgw                   1/1     Running   0          56m
kube-system        etcd-master                                1/1     Running   0          56m
kube-system        kube-apiserver-master                      1/1     Running   0          56m
kube-system        kube-controller-manager-master             1/1     Running   0          56m
kube-system        kube-proxy-tddbf                           1/1     Running   0          56m
kube-system        kube-scheduler-master                      1/1     Running   0          56m
tigera-operator    tigera-operator-76c4976dd7-rk7qm           1/1     Running   0          2m44s

Masterノードのtaint削除

taint削除してPodのSchedulingを可能とする。

kubectl describe node master |grep -i taint
[結果]
Taints:             node-role.kubernetes.io/control-plane:NoSchedule

kubectl taint nodes --all node-role.kubernetes.io/control-plane-
[結果]
node/master untainted

Masterノード、Podが正常に動作しているなら構築完了。

kubectl get node -o wide
kubectl get pod -A

Workerノードの構築

Container Runtimeのインストール(Workerノード)

containerdのインストールはMasterノードと同様のためそちらを参照

kubeadm, kubeletのインストール

Masterノードのインストール手順とほぼ同様。唯一の違いはkubectl設定がないだけ。手順だけ記載。

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

###
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.31/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg

###
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.31/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list

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

###
sudo systemctl enable --now kubelet
systemctl status kubelet

kubernetesクラスタを作成(Workerノード側)

クラスタ作成での事前準備

Masterノード同様、cgroup driverでsystemdを利用する宣言と、node-ipを設定する。
ここで設定変更後、kubeletを再起動してもまだkubeletサービスは正しく起動していないので、kubeadm join後に変更した方がいいかもしれないが未調査。

cat << EOF | sudo tee /etc/default/kubelet
KUBELET_EXTRA_ARGS=--cgroup-driver=systemd --node-ip=192.168.56.54
EOF

sudo systemctl daemon-reload
sudo systemctl restart kubelet

Workerノードのクラスタ作成

Masterノードインストール時に発行されたトークンは有効期限があるため、Tokenを再発行しておく。Masterノードで実行。

# Masterノードで実施すること!
sudo kubeadm token create --print-join-command

kube joinコマンドでMasterノードに参加する。これはWorkerノードで実施。
Masterノードで発行したTokenにアドバタイズするWorkerノード自身のIPアドレス192.168.56.54を追加する。

sudo kubeadm join 192.168.56.53:6443 --token ae23nz.3z2wgkowa4egops7 --discovery-token-ca-cert-hash \
       sha256:690a36f5e45e096d0e0a34bddceae0b6775cbec024cfb26cee0f8cea38ee084e \
       --apiserver-advertise-address=192.168.56.54

Workerノードが作成されたことを確認

Workerノードで確認

まずはWorkerノードでkubeletサービスが正しく起動され、node-ipが設定されていることを確認する

systemctl status kubelet
[結果(抜粋)]
...
Active: active (running) since Thu 2025-01-02 13:02:30 JST; 22min ago
...
     CGroup: /system.slice/kubelet.service
             └─12478 /usr/bin/kubelet (略) --cgroup-driver=systemd --node-ip=192.168.56.54

Masterノードで確認

続いてMasterノードにWorkerノードがクラスタに参加されたことを確認する。またINTERNAL_IPがVagrantのNAT IPでないことを確認する。

kubectl get node -o wide
[結果]
NAME      STATUS   ROLES           AGE    VERSION   INTERNAL-IP     EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION      CONTAINER-RUNTIME
master    Ready    control-plane   155m   v1.31.4   192.168.56.53   <none>        Ubuntu 20.04.4 LTS   5.4.0-110-generic   containerd://1.7.24
worker1   Ready    <none>          27m    v1.31.4   192.168.56.54   <none>        Ubuntu 20.04.4 LTS   5.4.0-110-generic   containerd://1.7.24

うまくいけば、同様の手順でWorkerノードを追加できる。

その他

ノードのリセット

kubeadm initkubeadm joinをやり直す

Masterノードのリセット

sudo kubeadm reset
rm -rf ~/.kube

Workerノードのリセット

Masterノードで実施、クラスタからWorkerノードを切り離す。

kubectl drain worker1 --ignore-daemonsets --force
kubectl delete node worker1

Workerノードで実施、Workerノードのリセット

sudo kubeadm reset
rm -rf ~/.kube

INTERNAL_IPの変更

INTERNAL_IPの変更手順:その1

/etc/default/kubeletKUBELET_EXTRA_ARGSで指定したnode-ipを変更しkubeletを再起動してもINTERNAL_IPに反映されない。
反映させる場合の手順は以下。

  • /etc/default/kubeletからnode-ipを削除してkubelet再起動
    →このタイミングでNATのIPがアドバタイズされている模様(INTERNAL_IPがNATのIPに変わる)
  • 再びnode-ipを設定してkubelet再起動

INTERNAL_IPの変更手順:その2

/etc/default/kubeletにnode-ipを記載しないで、別のファイルに書いてもいいらしい。

sudo vi /lib/systemd/system/kubelet.service.d/10-kubeadm.conf 
# KUBELET_CONFIG_ARGSにnode-ipを追加
Environment="KUBELET_CONFIG_ARGS=--config=/var/lib/kubelet/config.yaml --node-ip=x.x.x.x"

# 再起動
sudo systemctl daemon-reload
sudo systemctl restart kubelet

まとめ

cgroup driverの設定部分がネットで調べていると迷子になってしまい、結果動いてはいるものの設定が設定不足の可能性あります。誤り等あればコメント頂けたらありがたいです。
これまでminikube使っていたけど、これだとクラスタ組めるのでノード停止時の動作とか色々検証できるはず(やる気があれば)

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?