multipass를 이용하여 로컬 환경에 쿠버네티스 클러스터 구축하기
쿠버네티스를 처음 접하는 경우 로컬 환경에 kubernetes 클러스터를 구축하는 것은 다소 복잡하고 어려울 수 있다.
이번 포스팅에서는 multipass 도구를 활용하여 간편하게 로컬 환경에 쿠버네티스 클러스터를 구축하는 방법을 소개하고자 한다.
multipass는 경량의 VM 관리 도구로 간단한 명령어 몇 가지로 다양한 VM을 쉽게 생성하고 관리할 수 있다. 이를 통해 쿠버네티스 클러스터를 로컬 환경에서 쉽고 빠르게 설정할 수 있다.
multipass 사용법 알아보기
multipass를 활용하기 때문에 multipass 사용법에 대해서 알아야 한다.
아래 포스팅을 참고하기 바란다.
2024.07.02 - [ETC] - Multipass 사용법: 간편하게 가상 머신 관리하기
--cloud-init 옵션에 적용할 yaml 작성하기
multipass는 가상 인스턴스를 생성 시에 필요한 여러 명령들을 실행시킬 수 있다.
이를 통해서 쿠버네티스 구성에 필요한 패키지와 관련 파일들을 생성할 것이다.
클러스터 구성 스펙은 다음과 같다.
- 쿠버네티스 클러스터는 control plane 역할을 하는 master 노드와 작업을 수행하는 worker 노드, 두 개의 VM으로 구성할 것이다.
- 각 노드의 OS는 우분투 20.04 버전을 사용할 것이다.
- 쿠버네티스 버전 1.28을 설치할 것이다.
master 노드 cloud-init yaml
# master-init.yaml
package_update: true
package_upgrade: true
packages:
- docker.io
- apt-transport-https
- ca-certificates
- curl
- ntpdate
runcmd:
- sudo ntpdate ntp.ubuntu.com
- sudo systemctl enable docker
- sudo systemctl start docker
- sudo mkdir -p /etc/apt/keyrings
- curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.28/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
- echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.28/deb/ /" | sudo tee /etc/apt/sources.list.d/kubernetes.list
- sudo apt update
- sudo apt install -y kubelet kubeadm kubectl
- sudo apt-mark hold kubelet kubeadm kubectl
- sudo systemctl enable kubelet
- sudo kubeadm init
- mkdir -p /home/ubuntu/.kube
- sudo cp -i /etc/kubernetes/admin.conf /home/ubuntu/.kube/config
- sudo chown -R ubuntu:ubuntu /home/ubuntu/.kube
- sudo kubeadm token create --print-join-command > /home/ubuntu/kubeadm_join_cmd.sh
- sudo chown ubuntu:ubuntu /home/ubuntu/kubeadm_join_cmd.sh
- chmod +x /home/ubuntu/kubeadm_join_cmd.sh
- |
sudo bash -c 'cat <<EOF > /home/ubuntu/k8s-post-init.sh
#!/bin/bash
export KUBECONFIG=/home/ubuntu/.kube/config
sleep 60
kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml
kubectl taint nodes --all node-role.kubernetes.io/control-plane-
EOF'
- sudo chown ubuntu:ubuntu /home/ubuntu/k8s-post-init.sh
- sudo chmod +x /home/ubuntu/k8s-post-init.sh
- sudo -u ubuntu /home/ubuntu/k8s-post-init.sh
위 yaml 파일은 가상 인스턴스에 다음과 같은 작업을 수행한다.
- apt update 수행
- apt upgrade 수행
- docker.io, apt-transport-https, ca-certificates, curl, ntpupdate 패키지 설치
- 쿠버네티스 관련 패키지인 kubeadm, kubectl, kubelet를 설치하기 위한 gpg 키 등록
- 쿠버네티스 관련 apt repository 등록
- kubeadm, kubelet, kubectl 설치
- worker 노드를 쿠버네티스 클러스터에 참여시키기 위한 토큰 생성 및 join 스크립트 파일 생성
- 쿠버네티스 네트워크 구성을 위한 calico CNI 설치 (k8s-post-init.sh 실행)
- master 노드에 pod 스케줄링을 허용하기 위한 명령 실행 (k8s-post-init.sh 실행)
데비안 12와 우분투 22.04 이하 버전의 경우 /ec/apt/keyrings 디렉터리가 없으므로 생성해 줘야 한다.
이제 더이상 쿠버네티스 패키지 레포지토리로 apt.kubernetes.io와 yum.kubernetes.io 는 사용되지 않는다.
대신 pkgs.k8s.io를 사용한다.
관련 내용은 아래 링크를 참고하기 바란다.
Kubernetes Legacy Package Repositories Will Be Frozen
pkgs.k8s.io: Introducing Kubernetes Community-Owned Package
worker 노드 cloud-init yaml
# worker-init.yaml
package_update: true
package_upgrade: true
packages:
- docker.io
- apt-transport-https
- ca-certificates
- curl
- ntpdate
runcmd:
- sudo ntpdate ntp.ubuntu.com
- sudo systemctl enable docker
- sudo systemctl start docker
- sudo mkdir -p /etc/apt/keyrings
- curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.28/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
- echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.28/deb/ /" | sudo tee /etc/apt/sources.list.d/kubernetes.list
- sudo apt update
- sudo apt install -y kubelet kubeadm kubectl
- sudo systemctl enable kubelet
위 yaml 파일은 가상 인스턴스에 다음과 같은 작업을 수행한다.
- apt update 수행
- apt upgrade 수행
- docker.io, apt-transport-https, ca-certificates, curl, ntpupdate 패키지 설치
- 쿠버네티스 관련 패키지인 kubeadm, kubectl, kubelet를 설치하기 위한 gpg 키 등록
- 쿠버네티스 관련 apt repository 등록
- kubeadm, kubelet, kubectl 설치
worker 노드의 경우 관련 패키지 설치만 한다.
master VM 인스턴스 생성
$> multipass launch focal --name master --memory 2G --disk 10G --cpus 2 --cloud-init <master-init.yaml 파일 경로>
위 명령은 master-init.yaml 적용과 함께 memory 2G, disk 10G, 2 cpu core 리소스를 갖는 인스턴스를 생성한다.
물론 memory, disk, cpu core 수는 적절한 값으로 지정하면 되겠다.
master-init.yaml을 적용하면 master 노드 인스턴스의 /home/ubuntu/kubeadm_join_cmd.sh 파일이 생성된다.
kubeadm_join_cmd.sh 파일은 worker 노드에서 실행하여 쿠버네티스 클러스터에 worker 노드를 참여시키는 역할을 할 것이다.
master 인스턴스 생성 후 multipass shell master 명령으로 master 쉘에 접속하여
kubelet, kubeadm, kubectl 이 정상적으로 설치되었는지, 그리고 kubeadm_join_cmd.sh, k8s-post-init.sh 파일이 존재하는지 확인해 보기 바란다.
$> ~/ multipass shell master
Welcome to Ubuntu 20.04.6 LTS (GNU/Linux 5.4.0-187-generic aarch64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/pro
System information as of Thu Jul 4 21:57:48 KST 2024
System load: 0.51
Usage of /: 40.5% of 9.52GB
Memory usage: 45%
Swap usage: 0%
Processes: 161
Users logged in: 0
...
ubuntu@master:~$ ll
total 44
drwxr-xr-x 5 ubuntu ubuntu 4096 Jul 4 20:09 ./
drwxr-xr-x 3 root root 4096 Jul 4 20:06 ../
-rw------- 1 ubuntu ubuntu 114 Jul 4 21:49 .bash_history
-rw-r--r-- 1 ubuntu ubuntu 220 Feb 25 2020 .bash_logout
-rw-r--r-- 1 ubuntu ubuntu 3771 Feb 25 2020 .bashrc
drwx------ 2 ubuntu ubuntu 4096 Jul 4 20:06 .cache/
drwxr-xr-x 3 ubuntu ubuntu 4096 Jul 4 20:09 .kube/
-rw-r--r-- 1 ubuntu ubuntu 807 Feb 25 2020 .profile
drwx------ 2 ubuntu ubuntu 4096 Jul 4 20:06 .ssh/
-rwxr-xr-x 1 ubuntu ubuntu 200 Jul 4 20:08 k8s-post-init.sh*
-rwxr-xr-x 1 ubuntu ubuntu 168 Jul 4 20:08 kubeadm_join_cmd.sh*
ubuntu@master:~$ which kubeadm
/usr/bin/kubeadm
ubuntu@master:~$ which kubelet
/usr/bin/kubelet
ubuntu@master:~$ which kubectl
/usr/bin/kubectl
worker VM 인스턴스 생성
$> multipass launch focal --name worker --memory 2G --disk 10G --cpus 2 --cloud-init <worker-init.yaml 파일 경로>
위 명령 역시 worker-init.yaml 적용과 함께 memory 2G, disk 10G, 2 cpu core 리소스를 갖는 인스턴스를 생성한다.
worker 인스턴스 역시 생성 후 multipass shell worker 명령으로 worker 쉘에 접속하여 kubectl, kubeadm, kubelet 이 설치되었는지 확인해 보기 바란다.
$> multipass shell worker
Welcome to Ubuntu 20.04.6 LTS (GNU/Linux 5.4.0-187-generic aarch64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/pro
System information as of Thu Jul 4 22:00:08 KST 2024
System load: 0.18
Usage of /: 31.9% of 9.52GB
Memory usage: 22%
Swap usage: 0%
Processes: 139
Users logged in: 0
...
ubuntu@worker:~$ which kubectl
/usr/bin/kubectl
ubuntu@worker:~$ which kubelet
/usr/bin/kubelet
ubuntu@worker:~$ which kubeadm
/usr/bin/kubeadm
focal 은 우분투 20.04 버전의 alias 이름으로 multipass find 명령으로 확인할 수 있다.
결국 위 명령은 master, worker 노드 모두 우분투 20.04 버전에 구성하게 된다.
master와 worker 인스턴스를 생성한 뒤 multipass ls(혹은 list) 명령을 통해서 인스턴스 목록을 확인한다.
$> multipass ls
Name State IPv4 Image
master Running 192.168.64.11 Ubuntu 20.04 LTS
172.17.0.1
172.16.219.64
worker Running 192.168.64.12 Ubuntu 20.04 LTS
172.17.0.1
172.16.171.64
각 인스턴스에 표시되는 ip 정보는 호스트마다 다르게 지정될 것이다.
master 노드에서 생성한 kubeadm_join_cmd.sh를 worker 노드에서 실행
앞서 언급했듯이 master 노드에서 생성한 kubeadm_join_cmd.sh 파일을 worker 노드에서 실행시켜 쿠버네티스 클러스터에 worker 노드를 등록해야 한다.
이를 위해서는 master 노드에 있는 kubeadm_join_cmd.sh 파일을 worker 노드에 전달을 해야 하는데 여기서는 multipass transfer 기능을 사용하여 파일을 전송하도록 하겠다.
아래 두 개의 명령을 통해서 손쉽게 파일을 전달할 수 있다.
# master 노드의 /home/ubuntu/kubeadm_join_cmd.sh 파일을 호스트의 현재 디렉토리로 가져옴
$> multipass transfer master:/home/ubuntu/kubeadm_join_cmd.sh ./
# 호스트에서 kubeadm_join_cmd.sh 파일을 worker 노드의 /home/ubuntu 경로에 전송함.
$> multipass transfer kubeadm_join_cmd.sh worker:/home/ubuntu
worker 노드에 전송된 kubeadm_join_cmd.sh 파일을 실행시킨다.
# worker 인스턴스 쉘에 접속
$> multipass shell worker
# kubeadm_join_cmd.sh 실행
ubuntu@worker:~$ sudo ./kubeadm_join_cmd.sh
[preflight] Running pre-flight checks
[preflight] Reading configuration from the cluster...
[preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml'
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[kubelet-start] Starting the kubelet
[kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap...
This node has joined the cluster:
* Certificate signing request was sent to apiserver and a response was received.
* The Kubelet was informed of the new secure connection details.
Run 'kubectl get nodes' on the control-plane to see this node join the cluster.
위와 같이 메시지가 출력되면 실행은 성공한 것이다.
master 노드(control plane) 확인
control plane 역할을 하는 master 노드에 접속하여 node의 상태와 생성된 pod 들을 확인해 보자.
ubuntu@master:~$ kubectl get node -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
master Ready control-plane 113m v1.28.11 192.168.64.11 <none> Ubuntu 20.04.6 LTS 5.4.0-187-generic containerd://1.7.12
worker Ready <none> 51m v1.28.11 192.168.64.12 <none> Ubuntu 20.04.6 LTS 5.4.0-187-generic containerd://1.7.12
node 정보를 확인했을 때 master, worker 두 개가 등록되었고 STATUS가 모두 Ready 상태면 성공이다.
pod를 확인해 보자.
ubuntu@master:~$ kubectl get pod -A
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system calico-kube-controllers-658d97c59c-mhqrf 1/1 Running 0 116m
kube-system calico-node-9vhb9 1/1 Running 0 54m
kube-system calico-node-nkrgb 1/1 Running 0 116m
kube-system coredns-5dd5756b68-cr5cl 1/1 Running 0 117m
kube-system coredns-5dd5756b68-t4nmc 1/1 Running 0 117m
kube-system etcd-master 1/1 Running 0 117m
kube-system kube-apiserver-master 1/1 Running 0 117m
kube-system kube-controller-manager-master 1/1 Running 0 117m
kube-system kube-proxy-ftz22 1/1 Running 0 54m
kube-system kube-proxy-s9btb 1/1 Running 0 117m
kube-system kube-scheduler-master 1/1 Running 0 117m
쿠버네티스 동작에 필요한 pod들이 모두 Running 상태라면 성공이다.
끝.