- 책 또는 웹사이트의 내용을 복제하여 다른 곳에 게시하는 것을 금지합니다.
- 책 또는 웹사이트의 내용을 발췌, 요약하여 강의 자료, 발표 자료, 블로그 포스팅 등으로 만드는 것을 금지합니다.
로컬에서 Kubernetes 클러스터 구축하기
Vagrant와 kubeadm으로 가상머신에 클러스터 구축하기
VirtualBox와 Vagrant 설치가 끝났으면 본격적으로 쿠버네티스 클러스터를 구축해보겠습니다. 이번에 구축할 클러스터의 형태는 다음과 같습니다.
- Vagrant로 VirtualBox 가상머신 생성
- Vagrant로 containerd 및 kubeadm 설치
- master 노드에 worker 노드를 수동으로 연결
노드
클러스터를 구성하는 서버(머신)를 노드(node)라고 부릅니다. 노드는 물리서버일 수도 있고, 가상머신일 수도 있습니다.
Vagrantfile 작성하기
이제 Vagrant 코드를 작성해보겠습니다. 다음 내용을 Vagrantfile
로 저장합니다.
Vagrant.configure("2") do |config|
config.vm.boot_timeout = 3000
config.vm.define "master" do |master|
master.vm.box = "ubuntu/jammy64"
master.vm.network "private_network", ip: "192.168.56.10"
master.vm.hostname = "master"
master.vm.provider "virtualbox" do |v|
v.memory = 4096
v.cpus = 4
end
master.vm.provision "0", type: "shell", preserve_order: true, privileged: true, inline: <<-EOC
cat <<-'EOF' >/etc/modules-load.d/kubernetes.conf
br_netfilter
EOF
sudo modprobe br_netfilter
cat <<-'EOF' >/etc/sysctl.d/kubernetes.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
sudo sysctl --system
sudo apt update
sudo apt install -y curl gnupg2 software-properties-common apt-transport-https ca-certificates
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmour -o /etc/apt/trusted.gpg.d/docker.gpg
sudo add-apt-repository -y "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
sudo apt update
sudo apt install -y containerd.io
containerd config default | sudo tee /etc/containerd/config.toml >/dev/null 2>&1
sudo sed -i 's/SystemdCgroup \= false/SystemdCgroup \= true/g' /etc/containerd/config.toml
sudo systemctl restart containerd
sudo systemctl enable containerd
cat <<-'EOF' >/etc/default/kubelet
KUBELET_EXTRA_ARGS=--node-ip=192.168.56.10
EOF
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-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl
OUTPUT_FILE=/vagrant/join.sh
rm -rf $OUTPUT_FILE
rm -rf /vagrant/.kube
sudo kubeadm init --pod-network-cidr=10.244.0.0/16 --control-plane-endpoint=192.168.56.10 --apiserver-advertise-address=192.168.56.10
sudo kubeadm token create --print-join-command > $OUTPUT_FILE
chmod +x $OUTPUT_FILE
mkdir -p $HOME/.kube
sudo cp /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
cp -R $HOME/.kube /vagrant/.kube
cp -R $HOME/.kube /home/vagrant/.kube
sudo chown -R vagrant:vagrant /home/vagrant/.kube
kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml
kubectl completion bash >/etc/bash_completion.d/kubectl
echo 'alias k=kubectl' >>/home/vagrant/.bashrc
EOC
end
(1..3).each do |i|
config.vm.define "worker#{i}" do |worker|
worker.vm.box = "ubuntu/jammy64"
worker.vm.network "private_network", ip: "192.168.56.1#{i}"
worker.vm.hostname = "worker#{i}"
worker.vm.provider "virtualbox" do |v|
v.memory = 2048
v.cpus = 2
end
worker.vm.provision "0", type: "shell", preserve_order: true, privileged: true, inline: <<-EOC
cat <<-'EOF' >/etc/modules-load.d/kubernetes.conf
br_netfilter
EOF
sudo modprobe br_netfilter
cat <<-'EOF' >/etc/sysctl.d/kubernetes.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
sudo sysctl --system
sudo apt update
sudo apt install -y curl gnupg2 software-properties-common apt-transport-https ca-certificates
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmour -o /etc/apt/trusted.gpg.d/docker.gpg
sudo add-apt-repository -y "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
sudo apt update
sudo apt install -y containerd.io
containerd config default | sudo tee /etc/containerd/config.toml >/dev/null 2>&1
sudo sed -i 's/SystemdCgroup \= false/SystemdCgroup \= true/g' /etc/containerd/config.toml
sudo systemctl restart containerd
sudo systemctl enable containerd
cat <<-'EOF' >/etc/default/kubelet
KUBELET_EXTRA_ARGS=--node-ip=192.168.56.1#{i}
EOF
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-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl
EOC
end
end
end
애플 실리콘 M 시리즈
맥의 CPU가 인텔이 아닌 애플 실리콘 M 시리즈라면 다음 Vagrantfile
을 사용합니다.
Vagrant.configure("2") do |config|
config.vm.boot_timeout = 3000
config.vm.define "master" do |master|
master.vm.box = "jharoian3/ubuntu-22.04-arm64"
master.vm.box_version = "0.3"
master.vm.network "private_network", ip: "192.168.56.10"
master.vm.hostname = "master"
master.vm.provider "parallels" do |v|
v.memory = 4096
v.cpus = 4
end
master.vm.provision "0", type: "shell", preserve_order: true, privileged: true, inline: <<-EOC
swapoff -a
sed -i '/swap/ s/^/#/' /etc/fstab
cat <<-'EOF' >/etc/modules-load.d/kubernetes.conf
br_netfilter
EOF
sudo modprobe br_netfilter
cat <<-'EOF' >/etc/sysctl.d/kubernetes.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
sudo sysctl --system
sudo apt update
sudo apt install -y curl gnupg2 software-properties-common apt-transport-https ca-certificates
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmour -o /etc/apt/trusted.gpg.d/docker.gpg
sudo add-apt-repository -y "deb [arch=arm64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
sudo apt update
sudo apt install -y containerd.io
containerd config default | sudo tee /etc/containerd/config.toml >/dev/null 2>&1
sudo sed -i 's/SystemdCgroup \= false/SystemdCgroup \= true/g' /etc/containerd/config.toml
sudo systemctl restart containerd
sudo systemctl enable containerd
cat <<-'EOF' >/etc/default/kubelet
KUBELET_EXTRA_ARGS=--node-ip=192.168.56.10
EOF
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-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl
OUTPUT_FILE=/vagrant/join.sh
rm -rf $OUTPUT_FILE
rm -rf /vagrant/.kube
sudo kubeadm init --pod-network-cidr=10.244.0.0/16 --control-plane-endpoint=192.168.56.10 --apiserver-advertise-address=192.168.56.10
sudo kubeadm token create --print-join-command > $OUTPUT_FILE
chmod +x $OUTPUT_FILE
mkdir -p $HOME/.kube
sudo cp /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
cp -R $HOME/.kube /vagrant/.kube
cp -R $HOME/.kube /home/vagrant/.kube
sudo chown -R vagrant:vagrant /home/vagrant/.kube
kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml
kubectl completion bash >/etc/bash_completion.d/kubectl
echo 'alias k=kubectl' >>/home/vagrant/.bashrc
EOC
end
(1..3).each do |i|
config.vm.define "worker#{i}" do |worker|
worker.vm.box = "jharoian3/ubuntu-22.04-arm64"
worker.vm.box_version = "0.3"
worker.vm.network "private_network", ip: "192.168.56.1#{i}"
worker.vm.hostname = "worker#{i}"
worker.vm.provider "parallels" do |v|
v.memory = 2048
v.cpus = 2
end
worker.vm.provision "0", type: "shell", preserve_order: true, privileged: true, inline: <<-EOC
swapoff -a
sed -i '/swap/ s/^/#/' /etc/fstab
cat <<-'EOF' >/etc/modules-load.d/kubernetes.conf
br_netfilter
EOF
sudo modprobe br_netfilter
cat <<-'EOF' >/etc/sysctl.d/kubernetes.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
sudo sysctl --system
sudo apt update
sudo apt install -y curl gnupg2 software-properties-common apt-transport-https ca-certificates
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmour -o /etc/apt/trusted.gpg.d/docker.gpg
sudo add-apt-repository -y "deb [arch=arm64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
sudo apt update
sudo apt install -y containerd.io
containerd config default | sudo tee /etc/containerd/config.toml >/dev/null 2>&1
sudo sed -i 's/SystemdCgroup \= false/SystemdCgroup \= true/g' /etc/containerd/config.toml
sudo systemctl restart containerd
sudo systemctl enable containerd
cat <<-'EOF' >/etc/default/kubelet
KUBELET_EXTRA_ARGS=--node-ip=192.168.56.1#{i}
EOF
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-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl
EOC
end
end
end
Parallels를 사용하므로 다음 명령으로 가상머신을 생성합니다.
$ vagrant up --provider=parallels
Minikube 클러스터
Minikube 클러스터를 생성했다면 다음 명령으로 먼저 Minikube 클러스터를 삭제합니다.
$ minikube delete
Avast Antivirus 감시 제어 문제
Avast Antivirus 등 안티바이러스 프로그램이 설치되어 있는 경우 vagrant up
명령을 실행했을 때 다음과 같은 메시지가 출력되면서 에러가 발생할 수 있습니다. 따라서 Avast 감시 제어 기능을 반드시 끄도록 합니다.
Bringing machine 'master' up with 'virtualbox' provider...
Bringing machine 'worker1' up with 'virtualbox' provider...
Bringing machine 'worker2' up with 'virtualbox' provider...
Bringing machine 'worker3' up with 'virtualbox' provider...
==> master: Box 'ubuntu/jammy64' could not be found. Attempting to find and install...
master: Box Provider: virtualbox
master: Box Version: >= 0
The box 'ubuntu/jammy64' could not be found or
could not be accessed in the remote catalog. If this is a private
box on HashiCorp's Vagrant Cloud, please verify you're logged in via
`vagrant login`. Also, please double-check the name. The expanded
URL and error message are shown below:
URL: ["https://vagrantcloud.com/ubuntu/jammy64"]
Error: schannel: next InitializeSecurityContext failed: Unknown error (0x80092012) - 해당 함수에서 인증서에 대한 파기 여부를 검사하지 못했습니다.
vagrant up
명령으로 가상머신을 생성합니다. 시간이 꽤 오래 걸리므로 느긋하게 기다립니다.
$ vagrant up
SSH auth method: Private Key에서 멈추는 경우
vagrant up
명령으로 가상머신을 생성할 때 SSH auth method: Private Key
에서 멈추는 경우가 많습니다. 따라서 VirtualBox GUI 앱인 Oracle VM VirtualBox을 반드시 실행해 놓은 상태로 vagrant up
명령을 실행합니다.
vagrant up
명령 실행이 끝났으면 vagrant status
명령을 입력하여 가상머신의 상태를 확인합니다. 다음과 같이 표시되면 정상적으로 생성된 것입니다.
$ vagrant status
Current machine states:
master running (virtualbox)
worker1 running (virtualbox)
worker2 running (virtualbox)
worker3 running (virtualbox)
This environment represents multiple VMs. The VMs are all listed
above with their current state. For more information about a specific
VM, run `vagrant status NAME`.
마스터 노드 확인하기
Vagrantfile
안에 내장된 스크립트로 kubeadm
실행에 필요한 설정을 하고 패키지들을 설치했습니다. master 노드에는 제어 플레인(Control Plane)이 구축된 상태고, worker1, 2, 3 노드에는 kubeadm
만 설치된 상태입니다.
다음 명령을 실행하여 master 노드 안으로 들어갑니다.
$ vagrant ssh master
Welcome to Ubuntu 22.04.1 LTS (GNU/Linux 5.15.0-52-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
System information as of Sun Nov 6 17:35:51 UTC 2022
System load: 0.5947265625 Users logged in: 0
Usage of /: 9.0% of 38.70GB IPv4 address for cni0: 10.244.0.1
Memory usage: 37% IPv4 address for enp0s3: 10.0.2.15
Swap usage: 0% IPv4 address for enp0s8: 192.168.56.10
Processes: 124
11 updates can be applied immediately.
10 of these updates are standard security updates.
To see these additional updates run: apt list --upgradable
Last login: Sun Nov 6 11:51:31 2022 from 10.0.2.2
vagrant@master:~$
윈도우에서 vagrant ssh master 실행 시 Permission denied (publickey) 에러 발생 문제
윈도우에서 vagrant ssh master
명령을 실행했을 때 vagrant@127.0.0.1: Permission denied (publickey).와 같은 에러가 발생하는 경우가 있습니다. 이때는 $env:VAGRANT_PREFER_SYSTEM_BIN += 0
명령을 실행한 뒤 vagrant ssh master
명령을 실행하면 됩니다.
$env:VAGRANT_PREFER_SYSTEM_BIN += 0
vagrant ssh master
master 노드 안으로 들어왔습니다. kubectl
도 설치해놓았으므로 kubectl get node
명령으로 노드 목록을 출력해봅니다.
$ kubectl get node
NAME STATUS ROLES AGE VERSION
master Ready control-plane 7m40s v1.28.4
master 노드 하나만 생성되어 있고 롤은 제어 플레인(control-plane)인 것을 볼 수 있습니다. 앞으로 vagrant ssh
로 들어간 노드에서 빠져나올 때는 Ctrl + D 키를 입력하면 됩니다.
쿠버네티스 클러스터 구축하기
이제 worker1, 2, 3 노드를 master 노드에 연결(join) 해보겠습니다. 먼저 worker1부터 들어갑니다.
$ vagrant ssh worker1
vagrant@worker1:~$ cd /vagrant/
vagrant@worker1:/vagrant$ sudo ./join.sh
[preflight] Running pre-flight checks
[WARNING SystemVerification]: missing optional cgroups: blkio
[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.
join.sh
파일은 master 노드를 생성한 뒤 kubeadm join
명령을 미리 저장해둔 파일입니다. 이 부분은 뒤에서 자세히 설명하겠습니다.
위 명령들을 worker2, worker3에도 똑같이 실행합니다.
쿠버네티스 클러스터 확인하기
vagrant ssh master
명령을 실행하여 다시 master 노드로 들어갑니다. 그리고 kubectl get node
명령을 실행해봅니다.
$ vagrant ssh master
vagrant@master:~$ kubectl get node
NAME STATUS ROLES AGE VERSION
master Ready control-plane 19m v1.28.4
worker1 Ready <none> 5m18s v1.28.4
worker2 Ready <none> 68s v1.28.4
worker3 Ready <none> 31s v1.28.4
master, worker1, 2, 3 노드가 모두 Ready
상태인 것을 확인할 수 있습니다. 이렇게 쿠버네티스 클러스터 구축이 끝났습니다.
.kube 디렉터리 설정하기
Vagrantfile
이 들어있는 폴더를 보면 join.sh
파일 말고도 .kube
폴더가 들어있는 것을 볼 수 있습니다. 이 폴더를 호스트의 사용자 계정 폴더(디렉터리로) 복사하면 노드 바깥에서도 kubectl
로 클러스터를 제어할 수 있습니다.
.kube 디렉터리 백업
아래 명령을 실행하면 기존 .kube/config
파일을 삭제하거나 덮어쓰게 됩니다. 따라서 기존 .kube
디렉터리는 백업해주시기 바랍니다.
Copy-Item -Force -Recurse .\.kube C:\Users\${env:UserName}\
cp -R ./.kube ~/
이제 kubectl
명령이 잘 실행되는지 테스트해봅니다.
$ kubectl get node
NAME STATUS ROLES AGE VERSION
master Ready control-plane 23m v1.28.4
worker1 Ready <none> 91s v1.28.4
worker2 Ready <none> 60s v1.28.4
worker3 Ready <none> 31s v1.28.4
윈도우에서 Unable to connect to the server: net/http: TLS handshake timeout 에러 발생
윈도우에서 kubectl get node
명령을 실행했을 때 Unable to connect to the server: net/http: TLS handshake timeout 에러가 발생한다면, $env:VAGRANT_PREFER_SYSTEM_BIN += 0
을 실행한 뒤 kubectl get node
명령을 실행해줍니다.
$env:VAGRANT_PREFER_SYSTEM_BIN += 0
kubectl get node
저작권 안내
이 웹사이트에 게시된 모든 글의 무단 복제 및 도용을 금지합니다.- 블로그, 게시판 등에 퍼가는 것을 금지합니다.
- 비공개 포스트에 퍼가는 것을 금지합니다.
- 글 내용, 그림을 발췌 및 요약하는 것을 금지합니다.
- 링크 및 SNS 공유는 허용합니다.