[CKA] kubeadm으로 Kubernetes 클러스터 구성하기
노드 준비부터 control plane 초기화, CNI 설치, worker node 연결까지 kubeadm 클러스터 구성 흐름을 정리합니다.
kubeadm은 Kubernetes 클러스터의 인증서와 핵심 컴포넌트 구성을 자동화하는 부트스트랩 도구입니다. 전체 흐름은 모든 노드 준비, control plane 초기화, Pod 네트워크 설치, worker node 연결 순서입니다.
모든 노드 준비
컨테이너 런타임과 kubelet, kubeadm, kubectl을 설치하기 전에 커널 모듈과 패킷 포워딩을 설정합니다.
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
sudo modprobe overlay
sudo modprobe br_netfilter
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
sudo sysctl --system
먼저 각 노드에 containerd를 설치하고 기본 설정을 생성합니다. 이 실습은 Ubuntu 패키지의 containerd를 사용했습니다.
sudo apt-get update
sudo apt-get install -y containerd
sudo mkdir -p /etc/containerd
sudo containerd config default | sudo tee /etc/containerd/config.toml > /dev/null
/etc/containerd/config.toml에서 CRI plugin이 disabled_plugins에 포함되지 않았는지 확인합니다. containerd 1.x에서는 runc 설정의 SystemdCgroup을 true로 바꾼 뒤 서비스를 다시 시작합니다.
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
SystemdCgroup = true
sudo systemctl restart containerd
sudo systemctl status containerd
containerd 2.x는 설정 경로가 다르므로 설치된 major 버전에 맞는 Kubernetes container runtime 문서를 확인합니다.
Kubernetes 패키지 저장소는 설치하려는 minor 버전에 맞춰야 합니다. 아래 예시는 v1.31 계열입니다.
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl gpg
sudo mkdir -p /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
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
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl
sudo systemctl enable --now kubelet
sudo swapoff -a
컨테이너 런타임의 cgroup driver와 kubelet의 설정도 일치해야 합니다.
control plane 초기화
Pod 네트워크가 사용할 CIDR을 CNI 설정과 맞춰 초기화합니다. 노드에 여러 주소가 있다면 API server가 광고할 주소도 명시합니다.
sudo kubeadm init \
--apiserver-advertise-address <control-plane-ip> \
--pod-network-cidr 10.244.0.0/16 \
--upload-certs
일반 사용자로 kubectl을 사용하려면 생성된 관리자 kubeconfig를 복사합니다.
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
초기화 직후 CoreDNS가 Pending이고 노드가 NotReady일 수 있습니다. 아직 CNI가 설치되지 않았다면 정상적인 중간 상태입니다.
Pod 네트워크 설치
이 실습에서는 Pod CIDR을 10.244.0.0/16으로 잡고 Flannel을 적용했습니다. 다른 CIDR을 사용했다면 manifest의 네트워크 설정도 같은 값으로 바꿔야 합니다. 아래 URL은 당시 실습에 사용한 설치 경로이므로 다시 실행할 때는 Kubernetes 버전과 Flannel release의 호환성을 먼저 확인합니다.
kubectl apply -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml
kubectl get pods -A
kubectl get nodes
Flannel DaemonSet과 CoreDNS가 Running, 노드가 Ready인지 확인합니다. CNI가 올라오지 않으면 br_netfilter와 net.ipv4.ip_forward부터 다시 확인합니다.
worker node 연결
control plane에서 join 명령을 새로 발급할 수 있습니다.
kubeadm token create --print-join-command
출력된 명령을 worker node에서 관리자 권한으로 실행합니다. join token과 CA hash는 자격 정보이므로 공개 문서나 저장소에 그대로 남기지 않습니다.
sudo kubeadm join <control-plane-host>:6443 \
--token <token> \
--discovery-token-ca-cert-hash sha256:<hash>
마지막으로 각 노드에 CNI와 kube-proxy Pod가 배치되었는지 확인하고 간단한 Pod를 생성해 기본 동작을 점검합니다.
kubectl get nodes
kubectl get pods -A -o wide
kubectl run web --image=nginx
kubectl get pod web
kubectl delete pod web
설치 절차의 기준은 Kubernetes 공식 문서의 kubeadm 설치와 kubeadm 클러스터 생성에서 확인할 수 있습니다.