6
4

More than 3 years have passed since last update.

Kubernetes the hard way on Raspberry Pi

Last updated at Posted at 2021-07-25

PXL_20210725_085200448.jpg

以下の動機でKubernetes the hard way on Raspberry Piを実施。その際のメモ。

  • CKAの勉強を兼ねて
  • いざという時に備えて家に1つクラスタを持っておきたい

Key takeaway

  • 事前に注意しておきたいハマる(かもしれない)ポイントが分かる(私の場合、環境設定で躓いた)
    • 本記事内では公式ドキュメントにある手順について1つずつ追うことはしない
  • Controller & Worker 両roleを持つノードをセットアップする方法が分かる(公式ドキュメント等に手順見当たらない)
  • Metallbを使ってLoad Balancerを配備するところまでカバー

環境

  • ハードウェア
    • Controller & Worker
      • Raspberry Pi 4 Model B 8GB RAM
    • Worker
      • Raspberry Pi 4 Model B 8GB RAM
      • Raspberry Pi 3 Model B 1GB RAM
  • OS
    • Ubuntu Server 20.04.2 LTS on Raspberry Pi
  • 作業環境
    • Ubuntu 18.04(WSL2) on Windows 10 21H1

連休前に思い立ち、フリマサイトで本体や冷却ファン等を買い足した。

参考にしたサイト

ハマったとこ

DHCP無効化

ノードのStatic IP設定方法がひと昔前の方法から変わっていてやや躓いたのでメモ。Netplanというものを初めて知る。各Worker上のPOD CIDRへのルーティングもNetplanを使って簡単に不揮発化できた。

Worker node上のswapの恒久的な無効化

swapが有効だとkubeletが動かない記載は何度か見ていたので、 sudo swapoff -a で無効化はしていたが、これだと起動のたびに無効化が必要だったらしい。Worker node起動後、 kubectl get nodeでノードが NotReadyだったので各種コンポーネントのログをチェックしていたら、kubeletのユニットログにswapをoffしろのメッセージを発見して気づく。以下のコマンドで恒久的にswapを無効化する。

sudo systemctl disable dphys-swapfile

Hostnameが重要

当初、controllerにraspberry piを1台、workerを残りの2台に割り当てたが、controllerもworkerとして動かしたく、controllerにworker向けのセットアップを追加で実施した。Controller向けに設定済みノードに対して、他のWorkerノードと同様のセットアップを施してみたがkubeletが動かない。kubeletのログを見ると、controller向けに命名していたhostnameをkubeletが混同して使っていて、API Serverにアクセスできないようで、エラーになっていた。そもそも、kube-controllerkube-worker1のようにノードのロールをHostnameに使っていたのが良くなかった(rpi1,rpi2みたいにしておいた方がいいと思われる)。

以下にWorker 3台構成が正しく動くまでの紆余曲折した構成の変遷を記載しておく。

Worker 2台構成(Hardway開始当初の構成)

HW Node role Hostname
Raspberry Pi 1 Controller kube-controller
Raspberry Pi 2 Worker kube-worker1
Raspberry Pi 3 Worker kube-worker2

Worker 3台構成(3台目のWorker(kubelet)が動かなかった時の構成)

HW Node role Hostname
Raspberry Pi 1 Controller & Worker kube-controller
Raspberry Pi 2 Worker kube-worker1
Raspberry Pi 3 Worker kube-worker2

Worker 3台構成(3台のWorker構成が無事動いた時の構成)

HW Node role Hostname
Raspberry Pi 1 Controller & Worker kube-worker0
Raspberry Pi 2 Worker kube-worker1
Raspberry Pi 3 Worker kube-worker2

読み替えた部分

Bootstrapping the etcd Cluster

etcdは、arm64版のバイナリがリリースされているのでそれを使う

Bootstrapping the Kubernetes Control Plane

  • 各種コンポーネントのバイナリはarm64版に読み替え。wgetするURLはamd64をarm64に置換
  • kube-apiserverの起動引数は本家サイトの最新版とRaspberry Pi向けサイトの情報をマージしたものを利用
cat <<EOF | sudo tee /etc/systemd/system/kube-apiserver.service
[Unit]
Description=Kubernetes API Server
Documentation=https://github.com/kubernetes/kubernetes

[Service]
ExecStart=/usr/local/bin/kube-apiserver \\
  --advertise-address=${INTERNAL_IP} \\
  --allow-privileged=true \\
  --apiserver-count=1 \\
  --audit-log-maxage=30 \\
  --audit-log-maxbackup=3 \\
  --audit-log-maxsize=100 \\
  --audit-log-path=/var/log/audit.log \\
  --authorization-mode=Node,RBAC \\
  --bind-address=0.0.0.0 \\
  --client-ca-file=/var/lib/kubernetes/ca.pem \\
  --enable-admission-plugins=NamespaceLifecycle,NodeRestriction,LimitRanger,ServiceAccount,DefaultStorageClass,ResourceQuota \\
  --etcd-cafile=/var/lib/kubernetes/ca.pem \\
  --etcd-certfile=/var/lib/kubernetes/kubernetes.pem \\
  --etcd-keyfile=/var/lib/kubernetes/kubernetes-key.pem \\
  --etcd-servers=https://${CONTROLLER0_IP}:2379 \\
  --event-ttl=1h \\
  --encryption-provider-config=/var/lib/kubernetes/encryption-config.yaml \\
  --kubelet-certificate-authority=/var/lib/kubernetes/ca.pem \\
  --kubelet-client-certificate=/var/lib/kubernetes/kubernetes.pem \\
  --kubelet-client-key=/var/lib/kubernetes/kubernetes-key.pem \\
  --runtime-config='api/all=true' \\
  --service-account-key-file=/var/lib/kubernetes/service-account.pem \\
  --service-account-signing-key-file=/var/lib/kubernetes/service-account-key.pem \\
  --service-account-issuer=https://${INTERNAL_IP}:6443 \\
  --service-cluster-ip-range=10.32.0.0/24 \\
  --service-node-port-range=30000-32767 \\
  --tls-cert-file=/var/lib/kubernetes/kubernetes.pem \\
  --tls-private-key-file=/var/lib/kubernetes/kubernetes-key.pem \\
  --v=2
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target
EOF

Bootstrapping the Kubernetes Worker Nodes

runcとcontainerdは本家にarm64版のリリースがなかったのでLaunchpadからarm64版debパッケージをダウンロードして利用した。

metallbのセットアップ

公式ドキュメントに従って特に躓くこともなく設定できた。

まず以下のマニフェストをインストールする。

kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.10.2/manifests/namespace.yaml
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.10.2/manifests/metallb.yaml

metallb用のconfigmapをapplyするまでアイドル状態とのこと。以下のconfigmapをapplyする。あらかじめホームネットワークのDHCPリース範囲を確認し、使われる予定のないIPアドレスの範囲を確認しておく(私の場合、192.168.2.100-192.168.2.200がDHCPのリース範囲内だった)。

{
  cat << EOF | kubectl apply -n metallb-system -f -
  apiVersion: v1
  kind: ConfigMap
  metadata:
    namespace: metallb-system
    name: config
  data:
    config: |
      address-pools:
      - name: default
        protocol: layer2
        addresses:
        - 192.168.2.2-192.168.2.99
EOF
}

以上である。以下のサンプルdeploymentで動作確認だけしておく。

{
  kubectl create namespace kube-verify
  cat <<EOF | kubectl create -f -
  apiVersion: apps/v1
  kind: Deployment
  metadata:
    name: kube-verify
    namespace: kube-verify
    labels:
      app: kube-verify
  spec:
    replicas: 3
    selector:
      matchLabels:
        app: kube-verify
    template:
      metadata:
        labels:
          app: kube-verify
      spec:
        containers:
        - name: nginx
          image: nginx:1.21.1
EOF
}

このdeploymentをLoadBalancer typeでサービス公開する。

kubectl expose deployment kube-verify -n kube-verify --type=LoadBalancer --target-port=80 --port=80
service/kube-verify exposed
kubectl get service kube-verify -n kube-verify
NAME          TYPE           CLUSTER-IP    EXTERNAL-IP   PORT(S)        AGE
kube-verify   LoadBalancer   10.32.0.205   192.168.2.2   80:31865/TCP   4s

configで指定した範囲内のIPアドレスがさっそく払い出されていることがわかる。 http://192.168.2.2 にアクセスするとクラスタ上のサービスにアクセスできることがわかる。

image.png

最後に

Kubernetes the hard wayは思っていたより、簡単にできた。オリンピックを観ながら設定していたのでミスが色々あったが、そのおかげでトラブルシューティングをやるチャンスができ、理解をより深めることができたと思う。物理的な構築にはあまりこだわらなかったが、あまり広げて散らかすと家庭内からクレームがでる恐れがあるので、それなりにこじんまりさせることも重要と思う。

6
4
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
6
4