라즈베리 파이로 쿠버네티스 클러스터를 만들어보자.

1. 시작!
!!!!!!!침대에 누워 유튜브의 알고리즘을 탐험하다가 하나의 영상을 보게 되었는데, 결국 카드 결제까지 가는 건 한순간이었다. 이 영상을 보고 갑자기 공대생의 피가 끓는 너낌이 들었달까? 바로 침대 위에서 맥북을 펴고 조사에 착수했다.
2. 구상
하드웨어


사실 대단한 구상은 없다. 위 그림대로 잘 설치하면 된다.
소프트웨어
다들 라즈베리 파이에 Debian 기반 OS에 K3s를 설치하던데, 나는 그렇게 하고싶지 않았다. 일반적인 Ubuntu & K8s 를 설치하고 싶었다. EKS 와 테라폼이 잘 차려준 클러스터만 이용해봤으니 Kubeadm을 써보기로 했다.
3. 지름신 강림

라즈베리 파이4 Model B (4GB) 4개 + 기타 부속품 - 607,200원

가장 핵심인 컴퓨터, ARM 아키텍쳐의 Coretex-A72 쿼드코어 SoC와 4GB램을 갖추고 있는 모델을 4개 구매했다. 1개는 Master Node로, 나머지 3개는 Worker Node로 구성하기 위해서였다. 물론 Master Node도 이중화하고싶지만 예산초과이므로 넘어간다. (연말정산 채고시다!)
반도체 대란인 것을 실감하였다. 최근에 자동차를 구매했을 때도 반도체 대란때문에 꽤 스트레스가 있었는데, 라즈베리파이도 모든 판매 사이트에 인당 구매 제한 또는 품절이 걸려있었다. 여러 판매처에 전화를 해 운이 좋게도 한 번에 4개를 살 수 있는 곳을 찾았다. 해외 가격보단 약간 비쌌지만 나는 지금 당장 내 방에 쿠버네티스가 돌아가는 모습을 보고싶은걸?
방열판, 케이스, 충전기, 성능 좋은 SD카드까지 포함된 패키지 4개 607,200원이다.
Netgear GS308 이더넷 스위칭 허브 - 58,000원

어짜피 로컬에서 돌릴거, 갖고있는 공유기 제조사랑 같은 NETGEAR의 GS308 8포트 스위치 허브를 구매했다. AMGN.(=아무거나) 라즈베리 파이는 추가 파츠 "PoE HAT"을 달면 PoE (Power over ethernet) 기능을 지원하기 때문에 USB-C 충전기를 줄일 수 있다. 하지만, 나는 PoE HAT을 달지 않을 것이다. 그 가격에 라즈베리 파이를 하나 더 살 수 있었기 때문에!
30cm 랜케이블 4개 - 12,400원
PoE를 하지 않을꺼면서 또 케이블은 PoE 까지 생각해서 비싼 케이블을 샀다. 공대 덕후의 심리란..
4. 조립

조립은 그냥 이렇게 심플하게 했다. 다만 충전기 꼽는 순서와 랜케이블 꼽는 순서는 라즈베리파이 케이스 숫자 순서에 맞게 싱크를 했다. IP는 공유기의 DHCP설정에서 static하게 잡아줬다.
5. 설치
OS이미지를 라즈베리 파이에 굽기

이 소프트웨어 하나만 있으면 라즈베리파이에 설치할 수 있는 OS는 클릭질 몇 번으로 사용할 수 있다. Ubuntu 20.04 LTS 64bit 을 설치했다.
첫부팅
이제 이미지가 입혀진 SD카드를 라즈베리파이 안에 넣고 랜 연결 후 부팅한다. 어떤 노드가 어떤 IP를 갖고있는지 확인하려면 DHCP의 도움을 받을 수 있겠다. nmap같은 도구를 사용해도 좋다. (MacOS의 nmap은 좀 다르니 약간의 구글링을 해보시길.)
tmux 를 통한 동시 작업
4개의 노드를 한꺼번에 세팅해야하다보니 좀 지칠 것 같아서 tmux 의 "synchronize panes" 기능을 사용했다.

- 화면 분할을 4개 한다. (Ctrl + B 누른 후 바로 shift + 5 를 누른다)
- 4개의 화면에 각각 다른 노드들에 접속한다.
- Ctrl + B를 누른 후 : 를 누르면 명령어를 입력하는 창이 나온다.
- 여기에
setw synchronize-pane on
를 입력하고 Enter를 누른다. - 그럼 이후에 모든 입력이 모든 창에 동시 입력됨을 볼 수 있을 것이다.
OS 세팅
일단 데비안 계열 OS에서 설치하고 나서 가장 먼저하는 것이 있다. 아래의 작업을 먼저 해준다.
sudo apt-get update -y
sudo apt-get upgrade -y
sudo reboot
그리고 containerd 컨테이너 런타임을 설치한다.
sudo apt-get install containerd -y
sudo su -
containerd config default /etc/containerd/config.toml
이제 쿠버네티스를 설치한다.
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add
sudo apt-add-repository "deb http://apt.kubernetes.io/ kubernetes-xenial main"
sudo apt-get install kubeadm kubelet kubectl -y
systemd, 컨테이너 런타임, kubelet이 동일한 Cgroup 드라이버를 사용해야 하므로 아래의 설정을 한다.

cgroup="$(head -n1 /boot/firmware/cmdline.txt) cgroup_enable=cpuset cgroup_enable=memory cgroup_memory=1 swapaccount=1"
echo $cgroup | sudo tee /boot/firmware/cmdline.txt
스왑 사용도 비활성화한다.
sudo sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
sudo swapoff -a
cat <<EOF | sudo tee /etc/modules-load.d/containerd.conf
overlay
br_netfilter
EOF
sudo modprobe overlay
sudo modprobe br_netfilter
cat <<EOF | sudo tee /etc/sysctl.d/99-kubernetes-cri.conf
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-ip6tables = 1
EOF
sudo sysctl --system
sudo systemctl restart containerd
공통 설치는 끝났다. 이제 master node를 설정하자. master node만 이 작업을 실행한다.
sudo kubeadm config images pull
sudo kubeadm init --pod-network-cidr=10.244.0.0/16
이 명령어는 kubeadm을 통해 kubernetes cluster 초기화를 진행한다. 아래와 같은 출력이 있는데 접속하기 위한 방법들이 나와있고 이를 실행한다.
Your Kubernetes control-plane has initialized successfully!
To start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
Alternatively, if you are the root user, you can run:
export KUBECONFIG=/etc/kubernetes/admin.conf
You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
https://kubernetes.io/docs/concepts/cluster-administration/addons/
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join 192.168.1.17:6443 --token 657cp0.azs6kcpibalp28tn \
--discovery-token-ca-cert-hash sha256:196fa1770d7dbb181ef874228ee73d3347163ac8a31ac1f9b8dee5775c11b8c8
그리고 가장 밑에 있는 명령어를 잊어버리면 안된다! 이걸 그대로 다른 worker node에 접속하여 붙이면 되는데 --node-name
은 각자 알아서 잘 바꾸도록 한다.
kubeadm join 192.168.1.17:6443 --token 657cp0.azs6kcpibalp28tn \
--discovery-token-ca-cert-hash sha256:196fa1770d7dbb181ef874228ee73d3347163ac8a31ac1f9b8dee5775c11b8c8 --node-name ubuntu1
Flannel은 간단한 CNI (Container Network Interface) 이다. 라즈베리 파이에서 가장 잘 맞아보이는 것이라 설치한다.
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
Lens에서 메트릭을 보기 위해서 Prometheus를 설치한다. 설치한 김에 Grafana까지 같이 설치한다. 사용하는 머신에서 Helm은 먼저 설치한다.
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo add stable https://charts.helm.sh/stable
helm repo update
helm install prometheus prometheus-community/kube-prometheus-stack

6. 설치 완료

열심히 pod을 실행 중인 라즈베리 파이들의 모습을 보고있다. 이제 다양한 Kubernetes 작업들을 직접 해보면서 갖고놀아야겠다. =]