Raspberry Pi 4 で簡単にx86対応Kubernetesクラスタを作ろう
はじめに
サイバーエージェントの7days インフラ向け 開発型インターン ONLINEに参加しました。
色々と新しい学びがありましたが躓いたことなどもあったので、自分なりに簡単にクラスタを作れる手順をまとめました。
構築手順
OSセットアップ
今回利用したOSはubuntu20.04です。sshが接続できるような状態にします。
以下の作業をすべての端末で行ってください。
アップデート
以下のコマンドを実行しシステムを更新します。
sudo apt update sudo apt upgrade -y
E: Unable to lock the administration directory /var/lib/dpkg/lock?
上記のようなメッセージが出る場合は自動更新が動いているのでしばらく放置しましょう。
ホストネームの設定
同じ端末が複数あるとどの端末を操作しているかわからなくなるので、名前をつけましょう。
とりあえず各端末を以下のようにします。
- rpi4-node1
- rpi4-node2
- rpi4-node3
sudo hostnamectl set-hostname rpi4-node1
上記コマンド実行後に再度ログインすればホストネームは変更されています。
IPアドレスの固定
Ubuntu 20.04 LTSで固定IPアドレスの設定のようにすればアドレスを固定にできます。
本例では以下のようになっています。
- rpi4-node1 192.168.1.21
- rpi4-node2 192.168.1.22
- rpi4-node3 192.168.1.23
- デフォルトゲートウェイ 192.168.1.1
rpi4-node1であれば以下のようなファイルを「/etc/netplan/99_config.yaml」に作成します。
network: version: 2 renderer: networkd ethernets: eth0: dhcp4: false dhcp6: false addresses: [192.168.1.21/24] gateway4: 192.168.1.1 nameservers: addresses: [192.168.1.1, 8.8.8.8, 8.8.4.4]
その後以下のコマンドで設定を適応します。
この際sshが切れる場合があるので、変更後のIPアドレスに再接続してください。
sudo netplan apply
魔法の設定
以下のコマンドを実行すると、memoryが0となっています。これを1にする必要があります。
ubuntu@rpi4-node1:~$ cat /proc/cgroups #subsys_name hierarchy num_cgroups enabled cpuset 10 1 1 cpu 3 1 1 cpuacct 3 1 1 blkio 4 1 1 memory 0 48 0 devices 2 40 1 freezer 6 2 1 net_cls 5 1 1 perf_event 8 1 1 net_prio 5 1 1 pids 9 45 1 rdma 7 1 1
「/boot/firmware/cmdline.txt」を以下のように編集してください。
ビフォー
net.ifnames=0 dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=LABEL=writable rootfstype=ext4 elevator=deadline rootwait fixrtc
アフター
net.ifnames=0 dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=LABEL=writable rootfstype=ext4 elevator=deadline rootwait fixrtc cgroup_enable=memory
x86エミュレータの設定
以下のコマンドを貼り付け実行してください。
wget https://raw.githubusercontent.com/penM000/qemu-binfmt-setup/main/qemu-binfmt-setup.sh chmod +x ./qemu-binfmt-setup.sh ./qemu-binfmt-setup.sh rm ./qemu-binfmt-setup.sh
上記ではqemu 4.2が入りますが、割とコアダンプが多発するので以下のように無理やり新しいバージョンを入れることを推奨します。
qemu 5.0
wget http://ports.ubuntu.com/pool/universe/q/qemu/qemu-user-static_5.0-5ubuntu9_arm64.deb sudo dpkg -i qemu-user-static_5.0-5ubuntu9_arm64.deb rm qemu-user-static_5.0-5ubuntu9_arm64.deb
qemu 5.1
wget http://ftp.jp.debian.org/debian/pool/main/q/qemu/qemu-user-static_5.1+dfsg-4+b1_arm64.deb sudo dpkg -i qemu-user-static_5.1+dfsg-4+b1_arm64.deb rm qemu-user-static_5.1+dfsg-4+b1_arm64.deb
再起動
このタイミングで一旦再起動します。
sudo reboot
microk8sのインストール
以下のコマンドでインストールします。
sudo snap install microk8s --classic --channel=1.19/stable
kubectlの別名を設定します。
sudo snap alias microk8s.kubectl kubectl
sudo 無しで利用できるようにします。次回ログインで適応されます。
sudo usermod -a -G microk8s ubuntu sudo chown -f -R ubuntu ~/.kube
正しくインストールできれば以下のような表示になります。
sudo microk8s.status microk8s is running high-availability: no datastore master nodes: 127.0.0.1:19001 datastore standby nodes: none addons: enabled: ha-cluster # Configure high availability on the current node disabled: dashboard # The Kubernetes dashboard dns # CoreDNS helm # Helm 2 - the package manager for Kubernetes helm3 # Helm 3 - Kubernetes package manager host-access # Allow Pods connecting to Host services smoothly ingress # Ingress controller for external access metallb # Loadbalancer for your Kubernetes cluster metrics-server # K8s Metrics Server for API access to service metrics rbac # Role-Based Access Control for authorisation registry # Private image registry exposed on localhost:32000 storage # Storage class; allocates storage from host directory
以下のような表示になる場合は「魔法の設定」を行っていない可能性があります。
また、起動直後は処理中の場合があります。
sudo microk8s.status microk8s is not running. Use microk8s inspect for a deeper inspection.
クラスタの作成
下記作業は、すべてのノードでmicrok8sが利用可能なものとして進行します。
rpi4-node1で以下のコマンドを実行します。すると以下のような情報が出るのでこれをrpi4-node2で実行します。
joinにはsudoが必要です。
ubuntu@rpi4-node1:~$ microk8s add-node From the node you wish to join to this cluster, run the following: microk8s join 192.168.1.21:25000/1d40b640b06cf019f1f4b47bf2a8e42e
ubuntu@rpi4-node1:~$ sudo microk8s join 192.168.1.21:25000/1d40b640b06cf019f1f4b47bf2a8e42e Contacting cluster at 192.168.1.21 Waiting for this node to finish joining the cluster. ..
戻ってきたら再度rpi4-node1でコマンドを実行し、同様にして、rpi4-node3で実行します。
ubuntu@rpi4-node1:~$ microk8s add-node From the node you wish to join to this cluster, run the following: microk8s join 192.168.1.21:25000/373ed6c9036180b5906348a8657e78c5
ubuntu@rpi4-node3:~$ sudo microk8s join 192.168.1.21:25000/373ed6c9036180b5906348a8657e78c5 Contacting cluster at 192.168.1.21 Waiting for this node to finish joining the cluster. ..
すべて参加できると以下のように3台がマスターノードで認識されます。
ubuntu@rpi4-node1:~$ microk8s.status microk8s is running high-availability: yes datastore master nodes: 192.168.1.21:19001 192.168.1.23:19001 192.168.1.22:19001 datastore standby nodes: none
もし以下のように参加できない場合は参加できないノードで「sudo microk8s.leave」などをでリセットしてから再度参加しましょう。
ubuntu@rpi4-node1:~$ microk8s.status microk8s is running high-availability: no datastore master nodes: 192.168.1.21:19001 192.168.1.23:19001 datastore standby nodes: none
Kubernetes設定
上記でKubernetesクラスターが完成しました。
ここからは実際に使えるようにKubernetesの設定を行います。
helm有効化
ubuntu@rpi4-node1:~$ sudo microk8s.enable helm3
sudo snap alias microk8s.helm3 helm helm repo add stable https://kubernetes-charts.storage.googleapis.com/
DNS有効化
以下のコマンドでポッドがDNSを利用できるようになります
ubuntu@rpi4-node1:~$ sudo microk8s.enable dns
ubuntu@rpi4-node1:~$ kubectl run test --image busybox:1.28 --restart Never -it --rm -- nslookup google.com Server: 10.152.183.10 Address 1: 10.152.183.10 kube-dns.kube-system.svc.cluster.local Name: google.com Address 1: 2404:6800:4004:808::200e nrt20s08-in-x0e.1e100.net Address 2: 172.217.175.238 nrt12s29-in-f14.1e100.net pod "test" deleted
MetalLB有効化
以下のコマンドでMetalLBが利用できます
アドレス範囲は192.168.1.30~192.168.1.40とします。
ubuntu@rpi4-node1:~$ sudo microk8s.enable metallb Enabling MetalLB Enter each IP address range delimited by comma (e.g. '10.64.140.43-10.64.140.49,192.168.0.105-192.168.0.111'): 192.168.1.30-192.168.1.40
ダッシュボード有効化
以下のコマンドでダッシュボードが利用できます。
ubuntu@rpi4-node1:~$ sudo microk8s.enable dashboard
ダッシュボードを8443ポートで見れるようにします。
ubuntu@rpi4-node1:~$ kubectl expose deployment kubernetes-dashboard --name=kubernetes-dashboard-lb --port 8443 --target-port=8443 --type LoadBalancer -n kube-system
以下のコマンドでhttps://192.168.1.30:8443にアクセスすれば良いことがわかります。
ubuntu@rpi4-node1:~$ kubectl get svc -n kube-system NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kube-dns ClusterIP 10.152.183.10 <none> 53/UDP,53/TCP,9153/TCP 9m24s metrics-server ClusterIP 10.152.183.225 <none> 443/TCP 2m15s kubernetes-dashboard ClusterIP 10.152.183.105 <none> 443/TCP 2m6s dashboard-metrics-scraper ClusterIP 10.152.183.178 <none> 8000/TCP 2m5s kubernetes-dashboard-lb LoadBalancer 10.152.183.118 192.168.1.30 8443:31650/TCP 27s
アクセスするとトークンを求められます。以下のコマンドでトークンを取得する事ができます。
ubuntu@rpi4-node1:~$ kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep default-token | a wk '{print $1}') Name: default-token-gqfr7 Namespace: kube-system Labels: <none> Annotations: kubernetes.io/service-account.name: default kubernetes.io/service-account.uid: 650450a4-16f4-42e7-9092-11e77d6e91dd Type: kubernetes.io/service-account-token Data ==== ca.crt: 1103 bytes namespace: 11 bytes token: eyJhbGciOiJ
Argo CD
kubectl create namespace argocd kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
以下のようにすべて起動するまで待ちましょう。
ubuntu@rpi4-node1:~$ kubectl get pods -n argocd NAME READY STATUS RESTARTS AGE argocd-redis-cccbb8f7-lz59z 1/1 Running 0 65s argocd-application-controller-5bb5bf665c-qnk8b 1/1 Running 0 65s argocd-repo-server-8fbdb95bf-zm2g2 1/1 Running 0 65s argocd-dex-server-5559ccbb9f-rgcw2 1/1 Running 1 65s argocd-server-5bc896856-56sjp 1/1 Running 0 64s
以下のようにpodが受付状態になっていますが、外からアクセスできないのでこれをできるようにします。
ubuntu@rpi4-node1:~$ kubectl get svc -n argocd NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE argocd-dex-server ClusterIP 10.152.183.238 <none> 5556/TCP,5557/TCP,5558/TCP 3m16s argocd-metrics ClusterIP 10.152.183.169 <none> 8082/TCP 3m16s argocd-redis ClusterIP 10.152.183.107 <none> 6379/TCP 3m16s argocd-repo-server ClusterIP 10.152.183.193 <none> 8081/TCP,8084/TCP 3m16s argocd-server-metrics ClusterIP 10.152.183.83 <none> 8083/TCP 3m16s argocd-server ClusterIP 10.152.183.114 <none> 80/TCP,443/TCP 3m16s
上記でロードバランサが使えるようになったので変更します。
ubuntu@rpi4-node1:~$ kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "LoadBalancer"}}' service/argocd-server patched ubuntu@rpi4-node1:~$ kubectl get svc -n argocd NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE argocd-dex-server ClusterIP 10.152.183.238 <none> 5556/TCP,5557/TCP,5558/TCP 4m25s argocd-metrics ClusterIP 10.152.183.169 <none> 8082/TCP 4m25s argocd-redis ClusterIP 10.152.183.107 <none> 6379/TCP 4m25s argocd-repo-server ClusterIP 10.152.183.193 <none> 8081/TCP,8084/TCP 4m25s argocd-server-metrics ClusterIP 10.152.183.83 <none> 8083/TCP 4m25s argocd-server LoadBalancer 10.152.183.114 192.168.1.31 80:31148/TCP,443:30112/TCP 4m25s
192.168.1.31にアクセスするとページが見れます。
ユーザー名はadminで、パスワードは以下のコマンドを実行することで得ることができます。

ubuntu@rpi4-node1:~$ kubectl get pods -n argocd -l app.kubernetes.io/name=argocd-server -o name | cut -d'/' -f 2 argocd-server-5bc896856-56sjp

project: default source: repoURL: 'https://github.com/argoproj/argocd-example-apps.git' path: guestbook targetRevision: HEAD destination: server: 'https://kubernetes.default.svc' namespace: default




コマンドも以下のようにすれば動きます。
wget https://github.com/argoproj/argo-cd/releases/download/v1.7.8/argocd-linux-amd64 chmod +x argocd-linux-amd64 ./argocd-linux-amd64 argocd controls a Argo CD server Usage: argocd [flags] argocd [command] Available Commands: account Manage account settings app Manage applications cert Manage repository certificates and SSH known hosts entries cluster Manage cluster credentials completion output shell completion code for the specified shell (bash or zsh) context Switch between contexts gpg Manage GPG keys used for signature verification help Help about any command login Log in to Argo CD logout Log out from Argo CD proj Manage projects relogin Refresh an expired authenticate token repo Manage repository connection parameters repocreds Manage repository connection parameters version Print version information Flags: --auth-token string Authentication token --client-crt string Client certificate file --client-crt-key string Client certificate key file --config string Path to Argo CD config (default "/home/ubuntu/.argocd/config") --grpc-web Enables gRPC-web protocol. Useful if Argo CD server is behind proxy which does not support HTTP2. --grpc-web-root-path string Enables gRPC-web protocol. Useful if Argo CD server is behind proxy which does not support HTTP2. Set web root. -H, --header strings Sets additional header to all requests made by Argo CD CLI. (Can be repeated multiple times to add multiple headers, also supports comma separated headers) -h, --help help for argocd --insecure Skip server certificate and domain verification --logformat string Set the logging format. One of: text|json (default "text") --loglevel string Set the logging level. One of: debug|info|warn|error (default "info") --plaintext Disable TLS --port-forward Connect to a random argocd-server port using port forwarding --port-forward-namespace string Namespace name which should be used for port forwarding --server string Argo CD server address --server-crt string Server certificate file Use "argocd [command] --help" for more information about a command.
kube-ops-view
kubectl create namespace kube-ops-view

apiVersion: argoproj.io/v1alpha1 kind: Application metadata: name: kube-ops-view spec: destination: name: '' namespace: kube-ops-view server: 'https://kubernetes.default.svc' source: path: deploy repoURL: 'https://codeberg.org/hjacobs/kube-ops-view.git' targetRevision: HEAD project: default





kubectl port-forward service/kube-ops-view 8080:80 --address 0.0.0.0 -n kube-ops-view

Weave Scope
kubectl apply -f "https://cloud.weave.works/k8s/scope.yaml?k8s-version=$(kubectl version | base64 | tr -d '\n')"
kubectl port-forward -n weave "$(kubectl get -n weave pod --selector=weave-scope-component=app -o jsonpath='{.items..metadata.name}')" 4040 --address 0.0.0.0

prometheus
kubectl create namespace prometheus helm install prometheus stable/prometheus-operator --namespace prometheus kubectl port-forward service/prometheus-grafana 3000:80 --address 0.0.0.0 -n prometheus
ユーザ: admin
パスワード: prom-operator

まとめ
CPUがarmであるので、x86のイメージが動かないという問題から、イメージのビルドをしなければならないという問題がありましたが、これである程度はビルドしなくても動かせることがわかりました。でもやっぱり、コアダンプする時はするのでその場合はarm向けのビルドを行わなければいけなさそうです。
ディスカッション
コメント一覧
まだ、コメントがありません