Closed10

kubeadmを用いてUbuntu22.04上で検証用k8sクラスタをシュッと立てる

JunyaJunya

背景

検証用で作る/壊すを簡単にできるk8sクラスタを作りたくなった。今までは適当に降ってきたクラスタを使ったり、minikube on docker desktop on M1 macでことを済ませていたけど、いくつかの理由により、kubeadm on ubuntu にしたかった。

やること

k8sクラスタ(とりあえずコントロールプレーン)をkubeadmを使ってubuntu上に構築する

やらないこと

各種初期化の自動化

JunyaJunya

初期化

kubeadmのインストール を済ませた上でkubeadmを使用したクラスターの作成を見ながら初期化する。Dockerから10.244...、そもそもマシンには固定のIPを当てていて 192.168... がすでに降ってきているため、DNSの設定で干渉しなさそうな 172.16.0.0/12 を使う

$ sudo kubeadm init --pod-network-cidr=172.16.0.0/12
[init] Using Kubernetes version: v1.28.4
(中略)
...
Then you can join any number of worker nodes by running the following on each as root:

kubeadm join <your_ip>:6443 --token <token>
$ mkdir -p $HOME/.kube && sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config && sudo chown $(id -u):$(id -g) $HOME/.kube/config
JunyaJunya

動作確認

とりあえずコントロールプレーンを覗いてみる

$ k get po -n kube-system
NAME                             READY   STATUS             RESTARTS         AGE
coredns-5dd5756b68-lmrjl         1/1     Running            1 (2m47s ago)    2m54s
coredns-5dd5756b68-rb8sc         1/1     Running            1 (2m48s ago)    2m54s
etcd-hitode                      1/1     Running            294 (91s ago)    3m28s
kube-apiserver-hitode            1/1     Running            268 (76s ago)    3m28s
kube-controller-manager-hitode   0/1     CrashLoopBackOff   2 (5s ago)       3m28s
kube-proxy-884d7                 0/1     CrashLoopBackOff   2 (8s ago)       2m53s
kube-scheduler-hitode            1/1     Running            281 (102s ago)   4m2s

やばそう

JunyaJunya

問題

  • k8sのコントロールプレーンのほとんどのコンポーネントが正常に動作していない
    • CrashLoopBackOff になっている、あるいは多くの回数のRESTARTが発生している

当たり前と言えば当たり前だけど、APIサーバが動かないとそもそもkubectlコマンドを発行することができない(のでデバッグがかなりしんどい)

$ k get po -n kube-system
The connection to the server 192.168.1.61:6443 was refused - did you specify the right host or port?
$ curl -k 192.168.1.61:6443
curl: (7) Failed to connect to 192.168.1.61 port 6443 after 0 ms: Connection refused
JunyaJunya

前提の確認

kubeadmのインストール#始める前に で書かれている条件を満たしているか確認する

マシンスペック

超余裕ある

swapがオフになっている

なっている

$ free -h
               total        used        free      shared  buff/cache   available
Mem:            62Gi       961Mi        49Gi       4.0Mi        11Gi        61Gi
Swap:             0B          0B          0B

MACアドレスのユニーク性

ハードウェアデバイスではユニークなアドレスが割り当てられる可能性が非常に高いですが、VMでは同じになることがあります

実機を使っている && 検証が若干面倒なので一旦割愛。

ネットワークアダプタの確認

複数のネットワークアダプターがあり、Kubernetesコンポーネントにデフォルトで到達できない場合

少なくとも一度は k get po -n kube-system の発行に成功していたので、問題なさそう

ポート開放

6443はあいている

$ sudo ufw status verbose
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), deny (routed)
New profiles: skip

To                         Action      From
--                         ------      ----             
...
6443/tcp                   ALLOW IN    Anywhere                     
6443/tcp (v6)              ALLOW IN    Anywhere (v6)  

kubeadm, kubelet, kubectl のバージョン

全てのマイナーバージョンまで一致しているので、k8sのバージョニングポリシー(マイナーひとつ分までサポート)的にも問題ない

$ kubeadm version  
kubeadm version: &version.Info{Major:"1", Minor:"28", GitVersion:"v1.28.2", GitCommit:"89a4ea3e1e4ddd7f7572286090359983e0387b2f", GitTreeState:"clean", BuildDate:"2023-09-13T09:34:32Z", GoVersion:"go1.20.8", Compiler:"gc", Platform:"linux/amd64"}

$ kubelet --version
Kubernetes v1.28.2

$ kubectl version
Client Version: v1.28.2
Kustomize Version: v5.0.4-0.20230601165947-6ce0bf390ce3
Server Version: v1.28.4

コントロールプレーンノードのkubeletによって使用されるcgroupドライバーの設定

Dockerを使用した場合、kubeadmは自動的にkubelet向けのcgroupドライバーを検出し、それを実行時に/var/lib/kubelet/kubeadm-flags.envファイルに設定します。

と書いてある。

$ sudo cat /var/lib/kubelet/kubeadm-flags.env
KUBELET_KUBEADM_ARGS="--container-runtime-endpoint=unix:///var/run/containerd/containerd.sock --pod-infra-container-image=registry.k8s.io/pause:3.9"

当該ファイルを確認しても、cgroupに関する記述はなさそうだけど問題ないのか。。??

JunyaJunya

使用されているcgroupを確認する

kubelet

systemdのがもの使われている

$ sudo cat /var/lib/kubelet/config.yaml | yq e '.cgroupDriver' -
systemd

https://kubernetes.io/ja/docs/tasks/administer-cluster/kubeadm/configure-cgroup-driver/ 辺りを見るとこれはデフォルトの挙動っぽい。

v1.22では、ユーザーがKubeletConfigurationのcgroupDriverフィールドを設定していない場合、kubeadmはデフォルトでsystemdを設定するようになりました。

containerdで使用されているcgroupも確認する

containerd

なぜかconfigが生えていない(なんで??)ので、生やす

$ ls /etc/containerd
config.toml.bak
$ containerd config default | sudo tee /etc/containerd/config.toml

これを覗いてみると、SystemdCgroup = false という怪しげな一行が観測できる。

$cat /etc/containerd/config.toml
            ShimCgroup = ""
            SystemdCgroup = false

こいつを true に書き換えて、systemctl restart containerd で再起動させてやる。


参考

めちゃくちゃ参考になる記事が出てきた: Ubuntu 22.04でのKubernetesクラスター構築(ContainerdとSystemdCgroup)

JunyaJunya

kubeadm を再起動させる

削除

別にクラスタを消して困ることもないし、そもそもビルド && スクラップを雑にやりたいのが当初の目的だったので、sudo kubeadm reset && rm -rf ~/.kube で諸々削除する

やり直し

https://zenn.dev/link/comments/0bf8d4b8552f96

をもう一度やる

確認

(RESTARTSの値がやばそうなのがいくつかあるけど)うまく動いていそう :tada:

$ k get po -n kube-system
NAME                             READY   STATUS    RESTARTS   AGE
coredns-5dd5756b68-2vvw4         1/1     Running   0          8m16s
coredns-5dd5756b68-8mnrp         1/1     Running   0          8m16s
etcd-hitode                      1/1     Running   309        8m32s
kube-apiserver-hitode            1/1     Running   282        8m32s
kube-controller-manager-hitode   1/1     Running   19         8m30s
kube-proxy-9ffm5                 1/1     Running   0          8m16s
kube-scheduler-hitode            1/1     Running   294        8m29s

RESTARTS の値は累計値とっているから??(pod NAMEが変わらないものは kubeadm reset によって0にならないから??)

JunyaJunya

シングルノードクラスタ上にpodを展開する

コントロールプレーンが展開されているノードの taint の削除

コントロールプレーンの各種podが正しく展開されたのできちんと動きそうだけど、一応シングルクラスタノードとして動作するか検証する。

k8sはデフォルトでは、コントロールプレーンが展開されているノードにpodをスケジュールしてくれない。これはtaintによって制御されており、確かに確認できる

$ k get node
NAME     STATUS   ROLES           AGE   VERSION
hitode   Ready    control-plane   23m   v1.28.2
$ k describe node hitode | grep -i taint
Taints:             node-role.kubernetes.io/control-plane:NoSchedule

(taintの良い感じの確認方法がわからず、確認方法がすごい荒っぽい。。)

とりあえず外してあげる

$ k taint nodes --all node-role.kubernetes.io/control-plane-
node/hitode untainted

pod を展開する

ようやく hello-world ができる。

$ k run hello-world --image=hello-world --restart=Never
pod/hello-world created
$ k get po
NAME          READY   STATUS      RESTARTS   AGE
hello-world   0/1     Completed   0          3s

めでたい

JunyaJunya

結論

  • Ubuntu 22.04上でkubeadmを用いてk8sクラスタを作成する際には、(デフォルトで??)kubeletとcontainerdで使用しているcgroupが異なるため、動作がものすごい不安定になる
    • コントロールプレーンのほとんどのコンポーネントがCrashLoopBackOffあるいはrestartを繰り返す
  • containerdのconfig(/etc/containerd/config.toml)の設定をいい感じにしてやると解決する
このスクラップは2023/12/04にクローズされました