윈도우에서 쿠버네티스 구축하기
0. 개요
윈도우에서 kubeadm을 사용해 쿠버네티스(k8s, kubernetes) v1.31를 구축하겠습니다.
두 대의 가상 머신을 만들어 한 대는 마스터 노드로 사용하고, 한 대는 워커 노드로 사용하겠습니다.
가상 머신을 띄우기 위해 Vagrant와 VirtualBox는 아래 공식 홈페이지를 통해 다운로드 받으시길 바랍니다.
https://www.virtualbox.org/wiki/Downloads
1. Vagrant로 가상머신 만들고 접속하기
파워쉘을 이용해 원하는 위치에 Vagrantfile 파일을 만듭니다.
저는 “C:\Kang\k8s\kubeadm”에 만들었습니다.
vi Vagrantfile
내용은 아래와 같습니다.
BOX_IMAGE = "bento/ubuntu-18.04"
$pre_install = <<-SCRIPT
echo ">>>> pre-install <<<<<<"
sudo apt-get update
SCRIPT
Vagrant.configure("2") do |config|
# 첫 번째 가상 머신
config.vm.define "ubuntu1804-1" do |subconfig| # 가상 머신 이름
subconfig.vm.box = BOX_IMAGE
subconfig.vm.hostname = "ubuntu1804-1"
subconfig.vm.network :private_network, ip: "192.168.104.2"
subconfig.vm.provider "virtualbox" do |v|
v.memory = 2024
v.cpus = 2
end
subconfig.vm.provision "shell", inline: $pre_install
end
# 두 번째 가상 머신
config.vm.define "ubuntu1804-2" do |subconfig| # 가상 머신 이름
subconfig.vm.box = BOX_IMAGE
subconfig.vm.hostname = "ubuntu1804-2"
subconfig.vm.network :private_network, ip: "192.168.104.3"
subconfig.vm.provider "virtualbox" do |v|
v.memory = 2024
v.cpus = 2
end
subconfig.vm.provision "shell", inline: $pre_install
end
end
파일이 만들어진 위치에서 아래 명령어를 통해 가상 머신을 만들면 됩니다.
vagrant up
조금만 기다리시면 가상 머신이 만들어집니다.
이제 만들어진 가상 머신의 이름을 통해 두 개의 터미널로 각각 접속하겠습니다.
vagrant ssh ubuntu1804-1
vagrant ssh ubuntu1804-2
2. 환경 설정
스왑 메모리로 쿠버네티스 클러스터에 문제가 발생될 수 있으므로 스왑 메모리를 해제해야 합니다.
swapoff -a
sed -i '/swap/s/^/#/' /etc/fstab # 재부팅 시에도 스왑 메모리 off 적용
또, 쿠버네티스 클러스터에서 6443 포트를 사용해 통신하므로 해당 포트를 개방합니다.
ufw allow 6443
3. 컨테이너 런타임 설치
이제 컨테이너 런타임을 설치해야 합니다.
쿠버네티스 1.23에서 부터 도커 런타임을 지원하지 않게 되어, containerd와 같은 다른 컨테이너 런타임을 설치해야 합니다.
아래 명령어를 통해 편하게 containerd를 설치할 수 있습니다.
apt install docker.io
설치 완료가 되면 containerd 설정을 합니다.
# 환경설정 파일 초기화
mkdir -p /etc/containerd
containerd config default > /etc/containerd/config.toml
# config.toml 파일에서 cgroup 설정 변경
sed -i 's/SystemdCgroup = false/SystemdCgroup = true/g' /etc/containerd/config.toml
# 재시작
sudo systemctl restart containerd
4. kubelet kubeadm kubectl 설치
쿠버네티스에서 인증에 필요한 라이브러리를 다운받습니다.
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl gpg
공개키를 다운 받습니다.
mkdir /etc/apt/keyrings
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.31/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
쿠버네티스 apt 저장소를 지정합니다.
# This overwrites any existing configuration in /etc/apt/sources.list.d/kubernetes.list
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.31/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list
kubelet, kubeadm, kubectl을 설치합니다.
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl
kubelet를 활성화합니다.
sudo systemctl enable --now kubelet
5. 마스터 노드 초기화
이 부분은 1번 터미널인 ubuntu1804-1에서만 진행하면 됩니다.
초기화 하기 전에, 초기화에 필요한 라이브러리를 다운 받습니다.
apt install ebtables ethtool
apt install socat
아래 명령어를 통해 초기화 합니다.
# --apiserver-advertise-address에는 마스터 노드의 ip 주소를 기입하면 됩니다.
kubeadm init --apiserver-advertise-address=192.168.104.2 --pod-network-cidr=10.244.0.0/16
이제 워커 노드에서 쓰일 토큰과 해시 코드를 알아내야 합니다.
토큰을 알아내는 방법은 아래 명령어를 사용하면 됩니다.
kubeadm token list
해시 코드를 알아내는 방법은 아래와 같습니다.
openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'
6. 워커 노드를 마스터 노드에 Join
이 부분은 1번 터미널인 ubuntu1804-2에서만 진행하면 됩니다.
여기 역시 필요한 라이브러리를 다운 받습니다.
apt install ebtables ethtool
apt install socat
위에서 알아낸 마스터의 토큰과 해시코드를 사용해야 합니다.
kubeadm join 192.168.104.2:6443 --token <token값> --discovery-token-ca-cert-hash sha256:<hash 코드 값>
7. kubectl get nodes 오류 - Master Node
이 부분은 1번 터미널인 ubuntu1804-1에서만 진행하면 됩니다.
클러스터 구축이 완료되었으니 정상적으로 워커 노드가 Join 되었는지 마스터 노드에서 확인해봤습니다.
kubectl get nodes
하지만 위 사진과 같이 오류가 발생했습니다.
검색 결과 아래의 명령어를 사용하시면 됩니다.
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
그러니 정상적으로 ubuntu1804-1에 ubuntu1804-2가 Join된 것을 확인할 수 있었습니다.
8. kubectl get nodes 오류 - Worker Node
이 부분은 2번 터미널인 ubuntu1804-2에서만 진행하면 됩니다.
워커 노드에서도 마스터 노드와 똑같은 오류가 발생했습니다.
워커 노드의 경우 아래 명령어를 실행하면 됩니다.
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/kubelet.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
9. CNI 설치
이 부분은 1번 터미널인 ubuntu1804-1에서만 진행하면 됩니다.
쿠버네티스에서 컨테이너가 통신하기 위해서는 CNI가 필요합니다.
CNI 오픈소스 중 하나인 칼리코(Calico)를 설치하겠습니다.
kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml
10. 잘못된 사설 ip 수정하기
이 부분은 1번, 2번 둘 다 진행하면 됩니다.
아래 명령어를 통해 노드의 사설ip를 확인할 수 있습니다.
kubectl get nodes -o wide
두 노드의 사설 ip가 같고, 잘못된 ip가 할당되어 있습니다.
ubuntu1804-1의 사설 ip는 192.168.104.2이어야 합니다.
ubuntu1804-2의 사설 ip는 192.168.104.3이어야 합니다.
아래 명령어를 확인하면 kubelet의 상태 정보를 볼 수 있습니다.
service kubelet status
위 사진에서 Drop-In 쪽을 보면 /lib/systemd/system/kubelet.service.d/10-kubeadm.conf가 kubelet이 초기화될 때 사용되는 파일입니다.
해당 파일의 내용 마지막 —node-ip를 적절히 추가하면 됩니다.
# Note: This dropin only works with kubeadm and kubelet v1.11+
[Service]
Environment="KUBELET_KUBECONFIG_ARGS=--bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf"
Environment="KUBELET_CONFIG_ARGS=--config=/var/lib/kubelet/config.yaml"
# This is a file that "kubeadm init" and "kubeadm join" generates at runtime, populating the KUBELET_KUBEADM_ARGS variable dynamically
EnvironmentFile=-/var/lib/kubelet/kubeadm-flags.env
# This is a file that the user can use for overrides of the kubelet args as a last resort. Preferably, the user should use
# the .NodeRegistration.KubeletExtraArgs object in the configuration files instead. KUBELET_EXTRA_ARGS should be sourced from this file.
EnvironmentFile=-/etc/default/kubelet
ExecStart=
ExecStart=/usr/bin/kubelet $KUBELET_KUBECONFIG_ARGS $KUBELET_CONFIG_ARGS $KUBELET_KUBEADM_ARGS $KUBELET_EXTRA_ARGS --node-ip <node-ip>
ip 값 추가 후 아래 명령어로 kubelet을 재시작합니다.
systemctl daemon-reload && systemctl restart kubelet
그러면 아래 사진과 같이 정상적으로 바뀐 모습을 볼 수 있습니다.
11. Nginx 띄워보기
이 부분은 1번 터미널인 ubuntu1804-1에서만 진행하면 됩니다.
nginx.yaml 파일을 만듭니다.
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: nginx-app
spec:
containers:
- name: nginx-container
image: nginx
ports:
- containerPort: 80
아래 명령어로 pod를 생성합니다.
kubectl apply -f nginx.yaml
nginx 접속을 위해 port를 노출합니다.
kubectl port-forward nginx-pod 8080:80
새로운 터미널을 띄워 curl 명령을 보냅니다.
curl localhost:8080
host에서 웹 서버로 접속하지 않은 이유는, 쿠버네티스 클러스터 환경이 가상환경 이기 때문입니다.