Rancherでラズパイk8sクラスタ構築

前回ラズパイで構築したRancher で ラズパイKubernetesクラスターを構築してみました。
構築はうまくいったのですが、 ARM64は正式サポートされていない ようなのでご注意ください。

ノード準備

Dockerが必要なのでインストールします。
RancherがDockerのインストールスクリプト を準備してくれているのでそれを使います。

$ git clone https://github.com/rancher/install-docker.git
$ cd install-docker/dist/
$ ./20.10.sh

20.10.12がインストールされました。

Rancherサーバーと通信するのでhostsで名前解決します。

192.168.10.202 rancher.tsuchinokometal.com

事前準備はこれくらいだったと思います。
ちなみにOSはUbuntu server 20.04です。

クラスタ構築

Createでクラスターを作成します。

rancher_downstream_cluster_on_raspberrypi_01.png

色々選択できますが、今回はCustomを選択します。

rancher_downstream_cluster_on_raspberrypi_02.png

Network ProviderはFlannelを選択します。
なぜならドキュメント にFlannelにしろと書いてあるから!
Kubernetesバージョンは最新にしてみます。

rancher_downstream_cluster_on_raspberrypi_03.png

ちなみにEdit as YAMLでGUIではできないカスタマイズできるようです。
FlannelだとPodネットワークって10.244.0.0/16じゃなかったっけ?って思って調べたら
以下の画像のようにすれば設定変更できました。
ドキュメントはこの辺 です。

rancher_downstream_cluster_on_raspberrypi_04.png

表示されたコマンドでコンテナを起動します。

rancher_downstream_cluster_on_raspberrypi_05.png

無事ノードがアクティブになりました。
おや?Conditionsに何か出ていますね。

rancher_downstream_cluster_on_raspberrypi_06.png

おやおやおや
「[Disconnected] Cluster agent is not connected」と表示されていますね。

rancher_downstream_cluster_on_raspberrypi_07.png

クラスタがうまく構築できない原因調査

せっかくなので調査した流れを書いてみます。
まず調査するために「Related Resources」にある「Mgmt Cluster」からKubeConfigを取得します。
これ取得できる場所もうちょっとわかりやすくしてほしいですね。

rancher_downstream_cluster_on_raspberrypi_08.png

取得したKubuConfigの内容で.kube/configを作成してkubectlが実行できるか試します。
kubectlは入れた覚えがないので勝手に入る気がします。

root@k8s1:~# kubectl get nodes
NAME   STATUS   ROLES               AGE   VERSION
k8s1   Ready    controlplane,etcd   17m   v1.24.4
k8s2   Ready    worker              10m   v1.24.4

確かにcluster-agentがダメっぽいですね。

root@k8s1:~# kubectl get pod -A -o wide
NAMESPACE       NAME                                      READY   STATUS             RESTARTS        AGE     IP              NODE   NOMINATED NODE   READINESS GATES
cattle-system   cattle-cluster-agent-59cbcd769f-gr2tj     0/1     CrashLoopBackOff   6 (4m25s ago)   10m     10.244.0.5      k8s1   <none>           <none>
cattle-system   cattle-cluster-agent-7c5f86475f-lsw2l     0/1     CrashLoopBackOff   6 (4m49s ago)   10m     10.244.0.4      k8s1   <none>           <none>
cattle-system   cattle-node-agent-kpdjc                   1/1     Running            0               10m     192.168.10.51   k8s1   <none>           <none>
cattle-system   cattle-node-agent-wfx2l                   1/1     Running            0               5m58s   192.168.10.52   k8s2   <none>           <none>
cattle-system   kube-api-auth-crc9w                       1/1     Running            0               10m     192.168.10.51   k8s1   <none>           <none>
ingress-nginx   ingress-nginx-admission-create-2z6mh      0/1     Completed          0               11m     10.244.0.3      k8s1   <none>           <none>
ingress-nginx   ingress-nginx-admission-patch-sc9mh       0/1     Completed          2               11m     10.244.0.2      k8s1   <none>           <none>
ingress-nginx   nginx-ingress-controller-wxpzw            1/1     Running            0               5m58s   10.244.1.3      k8s2   <none>           <none>
kube-system     coredns-59499769fb-t8ts4                  1/1     Running            0               11m     10.244.1.4      k8s2   <none>           <none>
kube-system     coredns-autoscaler-67cbd4599c-lbjms       1/1     Running            0               11m     10.244.1.5      k8s2   <none>           <none>
kube-system     kube-flannel-pphm7                        2/2     Running            0               12m     192.168.10.51   k8s1   <none>           <none>
kube-system     kube-flannel-rdg6d                        2/2     Running            0               5m58s   192.168.10.52   k8s2   <none>           <none>
kube-system     metrics-server-585b7cc746-gk855           1/1     Running            0               11m     10.244.1.2      k8s2   <none>           <none>
kube-system     rke-coredns-addon-deploy-job-bwr6g        0/1     Completed          0               12m     192.168.10.51   k8s1   <none>           <none>
kube-system     rke-ingress-controller-deploy-job-xqgfm   0/1     Completed          0               11m     192.168.10.51   k8s1   <none>           <none>
kube-system     rke-metrics-addon-deploy-job-qhhqq        0/1     Completed          0               11m     192.168.10.51   k8s1   <none>           <none>
kube-system     rke-network-plugin-deploy-job-m9xqb       0/1     Completed          0               12m     192.168.10.51   k8s1   <none>           <none>

ログを確認してみると、名前解決に失敗しているようです。
ノードのhostsに書きましたがPodは使ってくれないんですね。

root@k8s1:~# kubectl -n cattle-system logs cattle-cluster-agent-59cbcd769f-gr2tj
INFO: Environment: CATTLE_ADDRESS=10.244.0.5 CATTLE_CA_CHECKSUM=5daf191809df24f6f766c4d3ce9f42c943b79cf69817f983ec108aaff059880d CATTLE_CLUSTER=true CATTLE_CLUSTER_AGENT_PORT=tcp://10.43.145.52:80 CATTLE_CLUSTER_AGENT_PORT_443_TCP=tcp://10.43.145.52:443 CATTLE_CLUSTER_AGENT_PORT_443_TCP_ADDR=10.43.145.52 CATTLE_CLUSTER_AGENT_PORT_443_TCP_PORT=443 CATTLE_CLUSTER_AGENT_PORT_443_TCP_PROTO=tcp CATTLE_CLUSTER_AGENT_PORT_80_TCP=tcp://10.43.145.52:80 CATTLE_CLUSTER_AGENT_PORT_80_TCP_ADDR=10.43.145.52 CATTLE_CLUSTER_AGENT_PORT_80_TCP_PORT=80 CATTLE_CLUSTER_AGENT_PORT_80_TCP_PROTO=tcp CATTLE_CLUSTER_AGENT_SERVICE_HOST=10.43.145.52 CATTLE_CLUSTER_AGENT_SERVICE_PORT=80 CATTLE_CLUSTER_AGENT_SERVICE_PORT_HTTP=80 CATTLE_CLUSTER_AGENT_SERVICE_PORT_HTTPS_INTERNAL=443 CATTLE_CLUSTER_REGISTRY= CATTLE_FEATURES=embedded-cluster-api=false,fleet=false,monitoringv1=false,multi-cluster-management=false,multi-cluster-management-agent=true,provisioningv2=false,rke2=false CATTLE_INGRESS_IP_DOMAIN=sslip.io CATTLE_INSTALL_UUID=cb60f240-c981-4988-a357-f584f0a5bac8 CATTLE_INTERNAL_ADDRESS= CATTLE_IS_RKE=true CATTLE_K8S_MANAGED=true CATTLE_NODE_NAME=cattle-cluster-agent-59cbcd769f-gr2tj CATTLE_SERVER=https://rancher.tsuchinokometal.com CATTLE_SERVER_VERSION=v2.6.7
INFO: Using resolv.conf: nameserver 10.43.0.10 search cattle-system.svc.cluster.local svc.cluster.local cluster.local options ndots:5
ERROR: https://rancher.tsuchinokometal.com/ping is not accessible (Could not resolve host: rancher.tsuchinokometal.com)

KubernetesにDNSデバッグのためのドキュメント がありますので使ってみます。

dnsutilsをデプロイします。

kubectl apply -f https://k8s.io/examples/admin/dns/dnsutils.yaml

Podでnslookupしてみると外部のDNS名前解決に失敗しているようですね。

root@k8s1:~# kubectl exec -i -t dnsutils -- nslookup kubernetes.default
Server:		10.43.0.10
Address:	10.43.0.10#53

Name:	kubernetes.default.svc.cluster.local
Address: 10.43.0.1
root@k8s1:~# kubectl exec -i -t dnsutils -- nslookup rancher.tsuchinokometal.com
Server:		10.43.0.10
Address:	10.43.0.10#53

** server can't find rancher.tsuchinokometal.com: FORMERR

command terminated with exit code 1
root@k8s1:~# kubectl exec -i -t dnsutils -- nslookup google.com
Server:		10.43.0.10
Address:	10.43.0.10#53

** server can't find google.com: FORMERR

command terminated with exit code 1

調べたらCoreDNSのForward設定を「8.8.8.8 8.8.4.4」に変更するとうまくいくようです。

root@k8s1:~# kubectl get configmap -n kube-system coredns -o yaml > coredns.yaml
root@k8s1:~# vi coredns.yaml 
root@k8s1:~# cat coredns.yaml 
apiVersion: v1
data:
  Corefile: |
    .:53 {
        errors
        health {
          lameduck 5s
        }
        ready
        kubernetes cluster.local in-addr.arpa ip6.arpa {
          pods insecure
          fallthrough in-addr.arpa ip6.arpa
        }
        prometheus :9153
        #forward . "/etc/resolv.conf"
        forward . 8.8.8.8 8.8.4.4
        cache 30
        loop
        reload
        loadbalance
    } # STUBDOMAINS - Rancher specific change
kind: ConfigMap
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"v1","data":{"Corefile":".:53 {\n    errors\n    health {\n      lameduck 5s\n    }\n    ready\n    kubernetes cluster.local in-addr.arpa ip6.arpa {\n      pods insecure\n      fallthrough in-addr.arpa ip6.arpa\n    }\n    prometheus :9153\n    forward . \"/etc/resolv.conf\"\n    cache 30\n    loop\n    reload\n    loadbalance\n} # STUBDOMAINS - Rancher specific change\n"},"kind":"ConfigMap","metadata":{"annotations":{},"name":"coredns","namespace":"kube-system"}}
  name: coredns
  namespace: kube-system
root@k8s1:~# kubectl apply -f coredns.yaml 
configmap/coredns configured

Googleの名前解決ができるようになりました!
けどrancher.tsuchinokometal.comは解決できません。
外部DNS公開してないんでそりゃそうですねぇ。

root@k8s1:~# kubectl exec -i -t dnsutils -- nslookup google.com
Server:		10.43.0.10
Address:	10.43.0.10#53

Non-authoritative answer:
Name:	google.com
Address: 142.250.207.14

root@k8s1:~# kubectl exec -i -t dnsutils -- nslookup rancher.tsuchinokometal.com
Server:		10.43.0.10
Address:	10.43.0.10#53

** server can't find rancher.tsuchinokometal.com: NXDOMAIN

command terminated with exit code 1

調べてみるとこちら に CoreDNSにレコード登録する方法が紹介されていたのでやってみました。

root@k8s1:~# cat coredns.yaml 
apiVersion: v1
data:
  Corefile: |
    .:53 {
        errors
        health {
          lameduck 5s
        }
        hosts {
          192.168.10.202 rancher.tsuchinokometal.com
          fallthrough
        }
        ready
        kubernetes cluster.local in-addr.arpa ip6.arpa {
          pods insecure
          fallthrough in-addr.arpa ip6.arpa
        }
        prometheus :9153
        #forward . "/etc/resolv.conf"
        forward . 8.8.8.8 8.8.4.4
        cache 30
        loop
        reload
        loadbalance
    } # STUBDOMAINS - Rancher specific change
...

やっと解決できました。

root@k8s1:~# kubectl exec -i -t dnsutils -- nslookup rancher.tsuchinokometal.com
Server:		10.43.0.10
Address:	10.43.0.10#53

Name:	rancher.tsuchinokometal.com
Address: 192.168.10.202

agentもRUNNINGになりました。

NAMESPACE             NAME                                      READY   STATUS      RESTARTS       AGE
cattle-fleet-system   fleet-agent-6888d747f-79nrc               1/1     Running     0              5m1s
cattle-system         cattle-cluster-agent-59cbcd769f-gr2tj     1/1     Running     11 (12m ago)   38m
cattle-system         cattle-cluster-agent-59cbcd769f-jhwjv     1/1     Running     0              6m59s

良さそうですね。
全然ラズパイ感はないですが、ノードにはラズパイを使用しています。

rancher_downstream_cluster_on_raspberrypi_09.png

以下は再構築したやつだけど、このバージョンで試しています。

$ kubectl get node -o wide
NAME   STATUS   ROLES               AGE   VERSION    INTERNAL-IP    EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION     CONTAINER-RUNTIME
k8s1   Ready    controlplane,etcd   10d   v1.24.13   192.168.0.51   <none>        Ubuntu 20.04.6 LTS   5.4.0-1089-raspi   docker://20.10.24
k8s2   Ready    worker              10d   v1.24.13   192.168.0.52   <none>        Ubuntu 20.04.6 LTS   5.4.0-1069-raspi   docker://20.10.24
k8s3   Ready    worker              10d   v1.24.13   192.168.0.53   <none>        Ubuntu 20.04.6 LTS   5.4.0-1089-raspi   docker://20.10.24

Load Balancerの導入 ※2023/7/16追記

RancherでもLoad Balancerを使いたい時は自分でインストールしないといけないようですね。
nginxを起動してみましたがEXTERNAL-IPがpendingから進みません。

$ kubectl create deployment nginx --image=nginx:latest
$ kubectl expose deployment/nginx --type LoadBalancer --port 80 --name nginx
$ kubectl get svc nginx
NAME    TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
nginx   LoadBalancer   10.43.128.240   <pending>     80:31744/TCP   14s

手動で構築した時 と同じくMetalLBを使おうと思いますが、せっかくなのでRancherGUIで入れてみます。

EXPLORE CLUSTERからクラスターを選択し、Apps/Chartsを開いてみると、
PartnersのリポジトリにMetalLBがありました。

deploy_metallb_01.png

これを使ってみます。

deploy_metallb_02.png

システム側だと思うのでsystemプロジェクトを選択します。

deploy_metallb_03.png

特にデフォルトから変更せずにインストール。

deploy_metallb_04.png

無事デプロイできたようです。

deploy_metallb_05.png

metallb-systemというnamespaceにデプロイされていますね。

$ kubectl get all -n metallb-system
NAME                                      READY   STATUS    RESTARTS       AGE
pod/metallb-controller-6c46576fd9-p8lrf   1/1     Running   1 (105s ago)   2m36s
pod/metallb-speaker-297wf                 4/4     Running   0              2m36s
pod/metallb-speaker-ksw54                 4/4     Running   0              2m36s

NAME                              TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
service/metallb-webhook-service   ClusterIP   10.43.225.231   <none>        443/TCP   2m36s

NAME                             DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR            AGE
daemonset.apps/metallb-speaker   2         2         2       2            2           kubernetes.io/os=linux   2m36s

NAME                                 READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/metallb-controller   1/1     1            1           2m36s

NAME                                            DESIRED   CURRENT   READY   AGE
replicaset.apps/metallb-controller-6c46576fd9   1         1         1       2m36s

IPアドレス割り当て範囲を設定します。
ドキュメントはこちら

apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  namespace: metallb-system
  name: first-pool
spec:
  addresses:
  - 192.168.0.230-192.168.0.239
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: example
  namespace: metallb-system
spec:
  ipAddressPools:
  - first-pool

EXTERNAL-IPが割り振られました。

ubuntu@k8s1:~$ kubectl get svc nginx
NAME    TYPE           CLUSTER-IP      EXTERNAL-IP     PORT(S)        AGE
nginx   LoadBalancer   10.43.128.240   192.168.0.230   80:31744/TCP   29m

Monitoringのインストール

ついでにAppsからMonitoringをインストールしてPrometheusとGrafanaを入れてみました。

rancher_downstream_cluster_on_raspberrypi_10.png

ちゃんとGrafanaでメトリクスが見れました。

rancher_downstream_cluster_on_raspberrypi_11.png

Pod見ても問題なさそうですね。

root@k8s1:~# kubectl get pod -A
NAMESPACE                  NAME                                                      READY   STATUS      RESTARTS       AGE
cattle-fleet-system        fleet-agent-6888d747f-79nrc                               1/1     Running     0              60m
cattle-monitoring-system   alertmanager-rancher-monitoring-alertmanager-0            2/2     Running     0              2m21s
cattle-monitoring-system   prometheus-rancher-monitoring-prometheus-0                3/3     Running     0              2m19s
cattle-monitoring-system   pushprox-kube-controller-manager-client-8sblh             1/1     Running     0              3m46s
cattle-monitoring-system   pushprox-kube-controller-manager-proxy-64f6dc94c6-k7skc   1/1     Running     0              3m44s
cattle-monitoring-system   pushprox-kube-etcd-client-fwsc2                           1/1     Running     0              3m46s
cattle-monitoring-system   pushprox-kube-etcd-proxy-55544d768d-2kfnf                 1/1     Running     0              3m46s
cattle-monitoring-system   pushprox-kube-proxy-client-hp5pw                          1/1     Running     0              3m45s
cattle-monitoring-system   pushprox-kube-proxy-client-zp8lc                          1/1     Running     0              3m46s
cattle-monitoring-system   pushprox-kube-proxy-proxy-85f89bcc4d-zw9nk                1/1     Running     0              3m46s
cattle-monitoring-system   pushprox-kube-scheduler-client-m8x7m                      1/1     Running     0              3m46s
cattle-monitoring-system   pushprox-kube-scheduler-proxy-6cb664c86b-q28ms            1/1     Running     0              3m46s
cattle-monitoring-system   rancher-monitoring-grafana-586df56bff-f2l6j               3/3     Running     0              3m44s
cattle-monitoring-system   rancher-monitoring-kube-state-metrics-77ddfd789b-jhtws    1/1     Running     0              3m46s
cattle-monitoring-system   rancher-monitoring-operator-79cdfbcf48-jfbfr              1/1     Running     0              3m45s
cattle-monitoring-system   rancher-monitoring-prometheus-adapter-79d8db9697-vjbbv    1/1     Running     0              3m46s
cattle-monitoring-system   rancher-monitoring-prometheus-node-exporter-f626q         1/1     Running     0              3m43s
cattle-monitoring-system   rancher-monitoring-prometheus-node-exporter-nfb6c         1/1     Running     0              3m43s
cattle-system              cattle-cluster-agent-59cbcd769f-gr2tj                     1/1     Running     11 (68m ago)   94m
cattle-system              cattle-cluster-agent-59cbcd769f-jhwjv                     1/1     Running     0              62m
cattle-system              cattle-node-agent-kpdjc                                   1/1     Running     0              95m
cattle-system              cattle-node-agent-wfx2l                                   1/1     Running     0              90m
cattle-system              helm-operation-5jp7p                                      1/2     NotReady    0              7m40s
cattle-system              kube-api-auth-crc9w                                       1/1     Running     0              95m
default                    dnsutils                                                  1/1     Running     1 (20m ago)    81m
ingress-nginx              ingress-nginx-admission-create-2z6mh                      0/1     Completed   0              95m
ingress-nginx              ingress-nginx-admission-patch-sc9mh                       0/1     Completed   2              95m
ingress-nginx              nginx-ingress-controller-wxpzw                            1/1     Running     0              90m
kube-system                coredns-59499769fb-t8ts4                                  1/1     Running     0              96m
kube-system                coredns-autoscaler-67cbd4599c-lbjms                       1/1     Running     0              96m
kube-system                kube-flannel-pphm7                                        2/2     Running     0              96m
kube-system                kube-flannel-rdg6d                                        2/2     Running     0              90m
kube-system                metrics-server-585b7cc746-gk855                           1/1     Running     0              95m
kube-system                rke-coredns-addon-deploy-job-bwr6g                        0/1     Completed   0              96m
kube-system                rke-ingress-controller-deploy-job-xqgfm                   0/1     Completed   0              95m
kube-system                rke-metrics-addon-deploy-job-qhhqq                        0/1     Completed   0              95m
kube-system                rke-network-plugin-deploy-job-m9xqb                       0/1     Completed   0              96m

ドキュメント によるとテストはされていないようですが、インストールはすんなりいきました。

Rancherすんなりいけば便利ですね。すんなりいけば。