쿠버네티스 클러스터 구축하는 법, kubeadm 5단계
- 쿠버네티스 클러스터는 kubeadm·관리형 클라우드·kOps 중 목적에 맞게 선택합니다
- 컨트롤 플레인 노드는 최소 2vCPU·2GB RAM 이상을 확보해야 합니다
- 컨테이너 런타임 설치부터 워커 노드 조인까지 5단계로 진행합니다
- NotReady나 조인 실패 같은 흔한 오류는 원인별로 점검하면 해결됩니다
쿠버네티스 클러스터, 어떻게 구축해야 할까?

쿠버네티스(Kubernetes, K8s)는 여러 대의 서버에 흩어진 컨테이너를 자동으로 배치·복구·확장해주는 컨테이너 오케스트레이션 도구입니다. 클러스터를 구축하는 가장 표준적인 방법은 kubeadm이라는 공식 CLI 도구로 컨트롤 플레인(마스터) 노드를 초기화한 뒤, 워커 노드를 하나씩 조인(join)시키는 방식입니다. 실습이나 소규모 온프레미스 환경이라면 kubeadm이 가장 널리 쓰이고, 운영 부담을 줄이고 싶다면 AWS EKS·GCP GKE 같은 관리형 서비스를, 클라우드 인프라까지 자동 프로비저닝하고 싶다면 kOps를 선택합니다. 아래에서는 실무에서 가장 많이 쓰는 kubeadm 기준으로 사전 준비부터 실제 명령어, 자주 발생하는 오류까지 순서대로 정리합니다.
클러스터 구축 방식 3가지 비교
구축 방식마다 난이도와 운영 부담이 크게 다르므로, 프로젝트 성격에 맞춰 선택하는 것이 중요합니다.
| 방식 | 난이도·특징 | 적합한 경우 |
|---|---|---|
| kubeadm | 온프레미스·가상머신에 직접 설치, 구성요소를 세밀하게 통제 가능 | 학습·테스트, 사내 서버 직접 운영 |
| 관리형 서비스(EKS·GKE·AKS) | 컨트롤 플레인을 클라우드 업체가 관리, 설치 부담 최소 | 운영 인력이 적은 프로덕션 환경 |
| kOps | 클라우드 인프라(VPC·인스턴스)까지 코드로 자동 생성 | AWS 등에서 셀프 매니지드 클러스터를 자동화하려는 경우 |
온프레미스 vs 클라우드, 무엇이 다른가
온프레미스에서 kubeadm으로 구축하면 네트워크·스토리지 구성을 원하는 대로 설계할 수 있지만, 장애 발생 시 컨트롤 플레인 복구까지 직접 책임져야 합니다. 반대로 관리형 서비스는 컨트롤 플레인 가용성을 클라우드 업체가 보장해주는 대신 노드 구성 자유도가 다소 제한됩니다. 학습 목적이거나 사내 폐쇄망 환경이면 kubeadm, 서비스 운영이 목적이면 관리형 서비스가 합리적입니다.
어떤 방식을 골라야 실수가 적을까
처음 쿠버네티스를 다뤄본다면 소규모 가상머신 3~4대로 kubeadm 클러스터를 직접 구축해보는 것을 권합니다. 컨트롤 플레인·워커 노드·CNI(Container Network Interface, 파드 간 네트워크를 연결해주는 플러그인)가 어떻게 맞물려 동작하는지 체득해야, 이후 관리형 서비스를 쓰더라도 장애 상황을 훨씬 빠르게 진단할 수 있습니다. 쿠버네티스 클러스터가 클라우드 네이티브 아키텍처의 핵심 구성요소이므로, 클라우드 네이티브 아키텍처 핵심 개념 5가지를 함께 읽어두면 전체 그림을 잡는 데 도움이 됩니다.
클러스터 구축 전 준비 사항

하드웨어·OS 요구사항
kubeadm 공식 문서 기준 컨트롤 플레인 노드는 최소 사양을 충족해야 합니다.
컨트롤 플레인 노드는 최소 2vCPU·2GB RAM 이상, 워커 노드는 1vCPU·1GB RAM 이상을 권장합니다. 사양이 부족하면 kubeadm init 단계에서 사전점검(preflight check)이 경고를 띄우거나 파드가 정상적으로 스케줄링되지 않을 수 있습니다.
- 운영체제: Ubuntu 22.04/24.04 또는 CentOS/RHEL 계열 (커널 스왑 제어 가능해야 함)
- 네트워크: 노드 간 고유한 호스트명·MAC 주소·product_uuid 필요
- 포트: 6443(API 서버), 2379~2380(etcd), 10250(kubelet API)·10257(kube-controller-manager)·10259(kube-scheduler) 개방 — 쿠버네티스 공식 포트 목록 기준
방화벽·스왑 등 사전 설정
kubelet은 기본적으로 스왑(swap)이 켜진 상태에서 정상 동작하지 않으므로, 모든 노드에서 스왑을 비활성화해야 합니다. 또한 컨테이너 네트워크가 정상 통신하려면 브릿지 트래픽이 iptables를 거치도록 커널 파라미터를 조정해야 합니다.
# 스왑 비활성화 (재부팅 후에도 유지하려면 /etc/fstab에서 swap 라인 주석 처리)
sudo swapoff -a
# 브릿지 네트워크 트래픽에 필요한 커널 모듈 로드
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
sudo modprobe overlay
sudo modprobe br_netfilter
# 브릿지 트래픽이 iptables를 거치도록 커널 파라미터 설정
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
kubeadm으로 클러스터 구축하는 5단계
사전 준비가 끝났다면 실제 클러스터를 구축합니다. 모든 노드(마스터·워커 공통)에서 1~2단계를 수행하고, 3~4단계는 마스터 노드에서만, 5단계는 워커 노드에서 수행합니다.
1단계 컨테이너 런타임 설치
쿠버네티스는 1.24 버전부터 dockershim을 제거했기 때문에 containerd나 CRI-O처럼 CRI(Container Runtime Interface) 규격을 지원하는 런타임을 별도로 설치해야 합니다. 일반적으로 containerd를 가장 많이 사용합니다.
sudo apt-get update
sudo apt-get install -y containerd
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml
# SystemdCgroup을 true로 변경 후 재시작
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
sudo systemctl restart containerd
2단계 kubeadm·kubelet·kubectl 설치
공식 apt 저장소를 등록한 뒤 세 가지 핵심 패키지를 설치합니다. 이 패키지들은 마스터·워커 노드 모두에 필요합니다. 저장소 경로의 마이너 버전은 쿠버네티스 공식 릴리스 지원 현황을 확인해 지원 종료되지 않은 최신 버전(2026년 8월 기준 v1.36)으로 맞춰야 합니다.
sudo apt-get install -y apt-transport-https ca-certificates curl gpg
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.36/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.36/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
3단계 마스터 노드 초기화
마스터로 사용할 노드에서 kubeadm init을 실행해 컨트롤 플레인을 초기화합니다. --pod-network-cidr는 이후 설치할 CNI 플러그인이 요구하는 대역과 일치시켜야 합니다(Calico는 보통 192.168.0.0/16, Flannel은 10.244.0.0/16).
sudo kubeadm init --pod-network-cidr=192.168.0.0/16
# 일반 사용자로 kubectl 사용 설정
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
명령이 끝나면 마지막에 kubeadm join ... 형태의 조인 명령어가 토큰과 함께 출력됩니다. 이 값을 반드시 별도로 저장해두어야 5단계에서 사용할 수 있습니다.
4단계 네트워크 플러그인(CNI) 설치
CNI를 설치하지 않으면 노드가 계속 NotReady 상태로 남습니다. 대표적인 CNI 플러그인은 다음과 같습니다.
- Calico: 네트워크 정책(NetworkPolicy) 기능이 풍부해 보안 요구가 있는 환경에 적합 — 아래 매니페스트 버전은 공식 릴리스 페이지에서 최신 버전을 확인해 사용하세요
- Flannel: 구성이 단순해 학습·소규모 클러스터에 적합
- Cilium: eBPF 기반으로 대규모 트래픽 처리와 관측성에 강점
kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.32.1/manifests/calico.yaml
5단계 워커 노드 조인
각 워커 노드에서 3단계에서 저장해둔 조인 명령어를 실행합니다. 토큰은 기본적으로 24시간이 지나면 만료되므로, 시간이 지났다면 마스터 노드에서 kubeadm token create --print-join-command로 새 명령을 발급받아야 합니다.
sudo kubeadm join <마스터IP>:6443 --token <토큰값> \
--discovery-token-ca-cert-hash sha256:<해시값>
클러스터 구축 후 확인 및 흔한 오류 해결

상태 확인 명령어
모든 노드 조인이 끝나면 마스터 노드에서 아래 명령으로 클러스터 상태를 확인합니다. 모든 노드의 STATUS가 Ready로 표시되어야 정상입니다.
kubectl get nodes -o wide
kubectl get pods -A
kubectl describe node <노드이름> # 문제 원인 파악용
자주 발생하는 오류와 해결법
- 노드가 계속 NotReady: CNI 플러그인 미설치이거나, kube-proxy·CNI 파드가 CrashLoopBackOff 상태인 경우가 대부분입니다.
kubectl get pods -n kube-system으로 확인하세요. - kubeadm join 실패(토큰 만료): 마스터 노드에서
kubeadm token create --print-join-command로 새 토큰을 발급받아 재시도합니다. - preflight 오류(스왑 감지):
swapoff -a가 재부팅 후 풀렸을 가능성이 큽니다./etc/fstab의 swap 라인이 주석 처리됐는지 확인하세요. - 파드가 Pending 상태로 멈춤: 워커 노드 리소스 부족이거나 taint(오염 표시)가 남아있어 스케줄링이 안 되는 경우입니다.
kubectl taint nodes --all node-role.kubernetes.io/control-plane-로 마스터 노드도 파드를 받도록 허용할 수 있습니다(단일 노드 실습 환경 한정).
운영 환경에서는 마스터 노드에 애플리케이션 파드를 스케줄링하지 않는 것이 원칙입니다. taint 제거는 학습·테스트 용도로만 사용하고, 프로덕션에서는 반드시 별도 워커 노드를 구성하세요.
자주 묻는 질문
Q. 쿠버네티스 클러스터를 구축하려면 서버가 최소 몇 대 필요한가요?
가상머신 1대에 마스터와 워커 역할을 함께 부여하는 것도 기술적으로는 가능하지만, 실무 감각을 익히려면 마스터 1대와 워커 2대 이상으로 구성하는 것을 권장합니다. 노드 간 통신, 조인 절차, 장애 발생 시 워크로드 재스케줄링 동작을 실제로 관찰할 수 있기 때문입니다.
Q. Docker 대신 다른 컨테이너 런타임을 써도 되나요?
가능합니다. 오히려 필수에 가깝습니다. 쿠버네티스 1.24 버전부터 dockershim이 제거되어, Docker 엔진을 직접 쓰려면 별도의 cri-dockerd 어댑터가 필요합니다. 별도 요구사항이 없다면 containerd나 CRI-O처럼 CRI 규격을 기본 지원하는 런타임을 사용하는 것이 설치와 유지보수 모두 간단합니다.
Q. 관리형 쿠버네티스 서비스와 kubeadm 직접 구축 중 무엇이 나을까요?
목적에 따라 다릅니다. 쿠버네티스 내부 동작을 배우거나 폐쇄망 환경에서 운영해야 한다면 kubeadm이 적합하고, 컨트롤 플레인 장애 대응·업그레이드 부담을 줄이고 싶다면 EKS·GKE·AKS 같은 관리형 서비스가 유리합니다. 두 방식 모두 kubectl 명령어와 매니페스트 작성법은 동일하므로, kubeadm으로 익힌 지식은 관리형 서비스로 옮겨가도 그대로 활용할 수 있습니다.
Q. 클러스터 구축 시 방화벽 포트는 어떻게 열어야 하나요?
마스터 노드는 API 서버용 6443번, etcd용 2379~2380번, kubelet API용 10250번, kube-controller-manager용 10257번, kube-scheduler용 10259번 포트를 열어야 합니다. 워커 노드는 kubelet용 10250번과 NodePort 서비스 범위(기본 30000~32767번)를 열어두면 대부분의 구성에서 통신 문제가 발생하지 않습니다.
Q. 조인한 워커 노드를 클러스터에서 제거하려면 어떻게 하나요?
마스터 노드에서 kubectl drain <노드이름> --ignore-daemonsets로 파드를 다른 노드로 옮긴 뒤 kubectl delete node <노드이름>로 제거합니다. 이후 해당 워커 노드에서 kubeadm reset을 실행해 로컬에 남은 클러스터 설정을 정리해야 재조인 시 충돌이 없습니다.
