ラズパイ4でKubernetesクラスタを再構築したときに様々詰まった話

いつもGKEでやっていたのだけど、おうちで好き勝手に動かせるクラスタが欲しいと思い、構築

元々勤務している学校のサーバー室に、こっそりk8sクラスタとして仕掛けていたのだが、回収して自宅で再度構築し直した

その時に、様々つまづいたので、備忘録として

OSのインストール

OSはUbuntu 22.04 LTSを使用

Raspbery Pi Imagerを使用したところ、このようなメッセージが

「検証に失敗しているだけで、動かせはするやろ」と思ったのだが、動かず

ラズパイのACTランプが4回点滅を繰り返しているので、調べてみたところ

緑色のACTライトが4回点滅する場合は、コード「start.elf」が見つからなかったことを示しています。Start.elfは、ブートフォルダの先頭にある関数です。この機能が見つからない場合、RaspberryPiは起動しません。

Raspberry pi インジケーターランプ(ACTライト)の意味 - Qiitaより

どうやら本当に書き込めていないらしい。

別のmicro SDカードを刺してみたところ、問題なく動いたので、純粋にmicro SDが壊れていたみたい。

試しに使ったmicro SDがシリコンパワー製のもので、読み書き速度に難があったことから、あきばお〜でサンディスクの64GB micro SDカードを新規調達した。

gpgキー?

Dockerのインストールで、

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

をやったところ、

Warning: apt-key is deprecated. Manage keyring files in trusted.gpg.d instead (see apt-key(8)).

と出てきた。

どうやら、最近のaptでは、apt-key が非推奨らしい。

www.clear-code.com

ただ、一応動いているといえば動いているので、一旦無視して、気が向いたら対応する。

kubeletが動いてくれない

クラスタ構築後、Worker nodeを kubeadm join で追加したはいいのだが、nodeがいつまでも Ready にならず、 NotReady のままになってしまう。

clusteradmin@master:~$ kubectl get nodes
The connection to the server 10.0.100.1:6443 was refused - did you specify the right host or port?

それどころか、kubectl が時たま Connection Refused で使えなくなる始末。

なんでやと思ったのだけど、似たような感じの事例で困っている人の記事を発見。

tech.virtualtech.jp

最近のUbuntuでは、cgroupsがv1からv2になった関係で、containerd周りでコケているらしい?

とりあえず、記事に書いてある通り、cgroupsをv1に戻す対応をした。

Raspberry Pi + Ubuntuな環境でcrgoupsのバージョンを指定する際は、/boot/firmware/cmdline.txtsystemd.unified_cgroup_hierarchy=0を追記して、再起動

参考: raspberry pi os - Enable cgroups v1 in RaspberryPi OS - Raspberry Pi Stack Exchange

公式Docsを見てみると、/etc/containerd/config.tomlSystemdCgroupという項目をTrueにするとのこと。

確かに、現状の設定ファイルはこのようになっている

clusteradmin@master:~$ cat /etc/containerd/config.toml | grep Systemd
            SystemdCgroup = false

これ直すと、普通に動いたのかしら

追記:動いた

flannelのPodが立ち上がらない

コンテナ間通信のプラグインとして、flannelを使っているのだが、flannelのpodがいつまでもcrashしてしまう

clusteradmin@master:~$ kubectl get pods --all-namespaces
NAMESPACE      NAME                             READY   STATUS              RESTARTS         AGE
kube-flannel   kube-flannel-ds-bzqn6            0/1     Error               2 (20s ago)      27s
kube-system    coredns-787d4945fb-97f5n         0/1     ContainerCreating   0                10m
kube-system    coredns-787d4945fb-qbdc7         0/1     ContainerCreating   0                10m
kube-system    etcd-master                      1/1     Running             27 (2m53s ago)   11m
kube-system    kube-apiserver-master            1/1     Running             8 (2m15s ago)    10m
kube-system    kube-controller-manager-master   1/1     Running             10 (3m11s ago)   11m
kube-system    kube-proxy-d6jld                 1/1     Running             5 (3m37s ago)    10m
kube-system    kube-scheduler-master            1/1     Running             25 (3m4s ago)    9m38s

logにも、それっぽいエラーが出力されていた

clusteradmin@master:~$ kubectl logs kube-flannel-ds-bzqn6 --namespace=kube-flannel
Defaulted container "kube-flannel" out of: kube-flannel, install-cni-plugin (init), install-cni (init)
I0102 14:14:59.696494       1 main.go:204] CLI flags config: {etcdEndpoints:http://127.0.0.1:4001,http://127.0.0.1:2379 etcdPrefix:/coreos.com/network etcdKeyfile: etcdCertfile: etcdCAFile: etcdUsername: etcdPassword: version:false kubeSubnetMgr:true kubeApiUrl: kubeAnnotationPrefix:flannel.alpha.coreos.com kubeConfigFile: iface:[] ifaceRegex:[] ipMasq:true ifaceCanReach: subnetFile:/run/flannel/subnet.env publicIP: publicIPv6: subnetLeaseRenewMargin:60 healthzIP:0.0.0.0 healthzPort:0 iptablesResyncSeconds:5 iptablesForwardRules:true netConfPath:/etc/kube-flannel/net-conf.json setNodeNetworkUnavailable:true}
W0102 14:14:59.696794       1 client_config.go:617] Neither --kubeconfig nor --master was specified.  Using the inClusterConfig.  This might not work.
I0102 14:14:59.733776       1 kube.go:126] Waiting 10m0s for node controller to sync
I0102 14:14:59.733890       1 kube.go:431] Starting kube subnet manager
I0102 14:15:00.734163       1 kube.go:133] Node controller sync successful
I0102 14:15:00.734886       1 main.go:224] Created subnet manager: Kubernetes Subnet Manager - master
I0102 14:15:00.735003       1 main.go:227] Installing signal handlers
I0102 14:15:00.736299       1 main.go:467] Found network config - Backend type: vxlan
I0102 14:15:00.736395       1 match.go:206] Determining IP address of default interface
I0102 14:15:00.739258       1 match.go:259] Using interface with name eth0 and address 10.0.100.1
I0102 14:15:00.739424       1 match.go:281] Defaulting external address to interface address (10.0.100.1)
I0102 14:15:00.739649       1 vxlan.go:138] VXLAN config: VNI=1 Port=0 GBP=false Learning=false DirectRouting=false
E0102 14:15:00.748235       1 main.go:327] Error registering network: operation not supported
W0102 14:15:00.748933       1 reflector.go:347] github.com/flannel-io/flannel/subnet/kube/kube.go:432: watch of *v1.Node ended with: an error on the server ("unable to decode an event from the watch stream: context canceled") has prevented the request from succeeding
I0102 14:15:00.749578       1 main.go:447] Stopping shutdownHandler...

vxlanなるものが悪さをしているらしい。

vxlanとは?も含めて、この記事が参考になった。

qiita.com

podは複数のnode上にあるため、それらを同一のネットワーク内で接続するのに、vxlanという機能を使用しているらしいが、Ubuntu21.10あたりから含まれなくなったらしいので、ネットワークを作成できないみたい

ラズパイに関しては、linux-modules-extra-raspiというパッケージをインストールすることで、解決した。

それでも立ち上がらないflannel

またしてもflannelのpodが立ち上がらないので、再びログを洗った

clusteradmin@master:~$ kubectl logs kube-flannel-ds-5cq5f --namespace=kube-flannel
Defaulted container "kube-flannel" out of: kube-flannel, install-cni-plugin (init), install-cni (init)
I0102 14:21:39.663540       1 main.go:204] CLI flags config: {etcdEndpoints:http://127.0.0.1:4001,http://127.0.0.1:2379 etcdPrefix:/coreos.com/network etcdKeyfile: etcdCertfile: etcdCAFile: etcdUsername: etcdPassword: version:false kubeSubnetMgr:true kubeApiUrl: kubeAnnotationPrefix:flannel.alpha.coreos.com kubeConfigFile: iface:[] ifaceRegex:[] ipMasq:true ifaceCanReach: subnetFile:/run/flannel/subnet.env publicIP: publicIPv6: subnetLeaseRenewMargin:60 healthzIP:0.0.0.0 healthzPort:0 iptablesResyncSeconds:5 iptablesForwardRules:true netConfPath:/etc/kube-flannel/net-conf.json setNodeNetworkUnavailable:true}
W0102 14:21:39.663887       1 client_config.go:617] Neither --kubeconfig nor --master was specified.  Using the inClusterConfig.  This might not work.
I0102 14:21:39.700428       1 kube.go:126] Waiting 10m0s for node controller to sync
I0102 14:21:39.700527       1 kube.go:431] Starting kube subnet manager
I0102 14:21:39.707598       1 kube.go:452] Creating the node lease for IPv4. This is the n.Spec.PodCIDRs: [172.16.0.0/24]
I0102 14:21:40.701102       1 kube.go:133] Node controller sync successful
I0102 14:21:40.701695       1 main.go:224] Created subnet manager: Kubernetes Subnet Manager - master
I0102 14:21:40.701743       1 main.go:227] Installing signal handlers
I0102 14:21:40.702648       1 main.go:467] Found network config - Backend type: vxlan
I0102 14:21:40.702964       1 match.go:206] Determining IP address of default interface
I0102 14:21:40.705451       1 match.go:259] Using interface with name eth0 and address 10.0.100.1
I0102 14:21:40.705623       1 match.go:281] Defaulting external address to interface address (10.0.100.1)
I0102 14:21:40.705858       1 vxlan.go:138] VXLAN config: VNI=1 Port=0 GBP=false Learning=false DirectRouting=false
E0102 14:21:40.707784       1 main.go:327] Error registering network: failed to acquire lease: subnet "10.244.0.0/16" specified in the flannel net config doesn't contain "172.16.0.0/24" PodCIDR of the "master" node
I0102 14:21:40.707957       1 main.go:447] Stopping shutdownHandler...

こちらは、あまり情報が見つからなかったのだが、中国語(!?)で記事が見つかった。

blog.csdn.net

flannelのpodを作成するときに使用するyamlファイルの中に、このような設定項目がある

kind: ConfigMap
apiVersion: v1
metadata:
  name: kube-flannel-cfg
  namespace: kube-flannel
  labels:
    tier: node
    app: flannel
data:
  cni-conf.json: |
    {
      "name": "cbr0",
      "cniVersion": "0.3.1",
      "plugins": [
        {
          "type": "flannel",
          "delegate": {
            "hairpinMode": true,
            "isDefaultGateway": true
          }
        },
        {
          "type": "portmap",
          "capabilities": {
            "portMappings": true
          }
        }
      ]
    }
  net-conf.json: |
    {
      "Network": "10.244.0.0/16",
      "Backend": {
        "Type": "vxlan"
      }
    }

この中の"Network": "10.244.0.0/16",という部分で、podのCIDRを指定しているのだが、Kubernetesクラスタを作成した際のオプションで--pod-network-cidr=172.16.0.0/16と指定しており、ここが一致していないのが原因だった。 そのため、合わせた上でapplyし直したところ、うまく動き出した。

clusteradmin@master:~$ kubectl get pods --all-namespaces
NAMESPACE      NAME                             READY   STATUS    RESTARTS   AGE
kube-flannel   kube-flannel-ds-ssg4b            1/1     Running   0          18s
kube-system    coredns-787d4945fb-2bqlx         1/1     Running   0          3m5s
kube-system    coredns-787d4945fb-wx6w8         1/1     Running   0          3m5s
kube-system    etcd-master                      1/1     Running   29         3m21s
kube-system    kube-apiserver-master            1/1     Running   0          3m15s
kube-system    kube-controller-manager-master   1/1     Running   0          3m17s
kube-system    kube-proxy-mvk7d                 1/1     Running   0          3m5s
kube-system    kube-scheduler-master            1/1     Running   27         3m18s

Workerの方はどうなの?

今回、Workerの方もラズパイ4 + Ubuntu22.04という環境のため、cgroupsのバージョンを落とす + linux-modules-extra-raspi のインストールを行った上でkubeadm joinを実行する

感想

バージョンが新しくなったりして、いつまでも同じ情報が使えるわけではないなという所感

Kubernetesのエコシステムは巨大で、エラーの目星をつけるのもとても大変だった・・・