---
title: "Kubernetes 클러스터 구축: kubeadm으로 쉽게 시작하는 가이드"
description: "Kubernetes는 컨테이너화된 애플리케이션을 자동으로 배포·확장·관리하는 오픈소스 오케스트레이션 플랫폼으로, kubeadm을 사용해 단일 노드 클러스터를 초기화하고 Calico CNI를 설치해 Pod 네트워크를 구성하면 기본 환경이 완성된다. 설치 과정은 Docker와 containerd 설정, kubeadm·kubectl·kubelet 설치·클러스터 초기화, CIDR 일치 확인 후 Calico 적용, 필요 시 control‑plane taint 제거 등이며, cgroup 드라이버 일치, swap 비활성화, 포트 개방 등 사전 준비가 필수이다."
date: "2024-11-21"
last_modified: "2026-05-15T08:36:00.000Z"
type: "Post"
tags:
  - "DevOps"
  - "orchestration"
categories:
  - "📗 Docs"
series:
  - "k8s"
canonical_url: "https://blog.pieroot.xyz/k8s-cluster-kubeadm"
markdown_url: "https://blog.pieroot.xyz/k8s-cluster-kubeadm.md"
---

# Kubernetes 클러스터 구축: kubeadm으로 쉽게 시작하는 가이드

Kubernetes는 컨테이너화된 애플리케이션을 자동으로 배포·확장·관리하는 오픈소스 오케스트레이션 플랫폼으로, kubeadm을 사용해 단일 노드 클러스터를 초기화하고 Calico CNI를 설치해 Pod 네트워크를 구성하면 기본 환경이 완성된다. 설치 과정은 Docker와 containerd 설정, kubeadm·kubectl·kubelet 설치·클러스터 초기화, CIDR 일치 확인 후 Calico 적용, 필요 시 control‑plane taint 제거 등이며, cgroup 드라이버 일치, swap 비활성화, 포트 개방 등 사전 준비가 필수이다.

연구실에서 GPU 서버 여러 대에 컨테이너 기반 서비스를 올리기 시작하면서, 컨테이너들을 체계적으로 관리할 도구가 필요해졌다. Docker 하나로 컨테이너를 띄우는 건 어렵지 않지만, 노드가 늘어나고 서비스가 복잡해질수록 **배포, 스케일링, 장애 복구**를 수동으로 처리하는 건 한계가 있다.

그래서 선택한 것이 Kubernetes다. 이번 글에서는 Kubernetes가 뭔지부터 시작해서, kubeadm으로 단일 노드 클러스터를 구축하고 Calico CNI까지 설치하는 전체 과정을 기록했다. 

> **이 글에서 다루는 내용**
> 
> - Kubernetes란 무엇인가, 왜 필요한가
> 
> - Kubernetes의 주요 특징과 구성요소
> 
> - Docker, containerd, kind, kubeadm 설치
> 
> - 클러스터 초기화 및 Calico CNI 구성

---

### 🤔 쿠버네티스(Kubernetes)란?

Kubernetes(K8s)는 컨테이너화된 애플리케이션의 **배포, 확장, 관리를 자동화**하는 오픈소스 컨테이너 오케스트레이션 플랫폼이다. 구글이 내부에서 15년 이상 운영하던 Borg 시스템의 경험을 바탕으로 2014년에 오픈소스로 공개했으며, 현재는 CNCF(Cloud Native Computing Foundation)에서 관리하고 있다.

쉽게 말하면, Docker로 만든 컨테이너들을 여러 서버에 걸쳐 **자동으로 배치하고, 장애 시 복구하고, 트래픽에 따라 확장/축소**해주는 도구다. ~~Docker만으로 컨테이너 10개쯤 관리하다 보면 왜 필요한지 절실히 느끼게 된다~~

> Kubernetes라는 이름은 그리스어로 "키잡이(helmsman)" 또는 "파일럿"을 뜻한다. K와 s 사이에 8글자가 있어서 **K8s**라는 약칭으로도 불린다.

### ✨ 주요 특징

- **자동 스케일링(Auto Scaling)**: 트래픽이 몰리면 Pod를 자동으로 늘리고, 줄어들면 다시 축소한다

- **자동 복구(Self-Healing)**: 컨테이너가 죽으면 자동으로 재시작하고, 노드가 죽으면 다른 노드에 컨테이너를 재배치한다

- **서비스 디스커버리 & 로드밸런싱**: DNS 이름이나 IP를 통해 컨테이너를 노출하고, 트래픽을 자동 분산한다

- **자동 롤아웃 & 롤백**: 새 버전 배포 시 점진적으로 교체하고, 문제 발생 시 이전 버전으로 자동 롤백한다

- **스토리지 오케스트레이션**: 로컬 스토리지, 클라우드 스토리지, NFS 등 다양한 스토리지를 자동으로 마운트한다

### **선언적 구성(Declarative Configuration)**: YAML 파일로 원하는 상태를 선언하면, Kubernetes가 알아서 그 상태를 유지한다🧩 구성요소

Kubernetes 클러스터는 크게 **Control Plane(마스터)**과 **Worker Node**로 나뉜다.

> **Control Plane (마스터 노드)**
> 
> - **kube-apiserver**: 클러스터의 API 엔드포인트. `kubectl` 명령어를 포함한 모든 요청이 여기를 통한다
> 
> - **etcd**: 클러스터의 모든 상태 데이터를 저장하는 분산 키-값 저장소
> 
> - **kube-scheduler**: 새로운 Pod를 어떤 노드에 배치할지 리소스 상태를 고려하여 결정한다
> 
> - **kube-controller-manager**: ReplicaSet, Deployment 등 각종 컨트롤러를 실행한다
> 
> - **cloud-controller-manager**: 클라우드 프로바이더와의 연동을 담당한다 (온프레미스에선 없을 수 있음)

> **Worker Node**
> 
> - **kubelet**: 각 노드에서 실행되며, Pod의 컨테이너가 정상적으로 동작하는지 관리한다
> 
> - **kube-proxy**: 네트워크 규칙을 관리하여 Pod 간 통신 및 외부 트래픽 라우팅을 담당한다
> 
> - **Container Runtime**: 실제 컨테이너를 실행하는 엔진 (containerd, CRI-O 등)

#### 🛠️ Kubernetes 배포 도구

---

Kubernetes를 설치하는 방법은 여러 가지가 있다. 환경과 목적에 따라 적절한 도구를 선택하면 된다.

![image](https://blog.pieroot.xyz/api/image-proxy?id=6824d166-6f05-46f9-8acb-0d47db8250f2&kind=s3&pageId=30d067c0-15d0-801c-ae2d-d2676f60a1c7&source=block&blockId=30d067c0-15d0-8016-8cbc-f7e5b7dacaac)

이 글에서는 **kubeadm**을 사용하여 클러스터를 구축한다. Kubernetes 공식 홈페이지에서 권장하는 도구이며, 프로덕션 환경에서 가장 범용적으로 사용된다.

---

## ⚙️ 환경 구성

### docker 설치

---

Container runtime을 사용하기 위해 우선 Docker 설치가 필요하다.

```shell
# Add Docker's official GPG key:
sudo apt-get update
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

# Add the repository to Apt sources:
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update

sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
```

유저를 docker 그룹에 추가하면 docker 명령어를 sudo 권한 없이 사용할 수 있다.

```shell
sudo usermod -a -G docker $USER

sudo systemctl restart docker.service

# 계정 로그아웃 후 재 로그인 필요
```

docker daemon 파일을 수정해주어야 하는데 `/etc/docker/daemon.json` 파일을 아래와 같이 수정해준다

```json
{
    "exec-opts": ["native.cgroupdriver=systemd"],
    "default-runtime": "nvidia",
    "runtimes": {
        "nvidia": {
            "args": [],
            "path": "nvidia-container-runtime"
        }
    }
}
```

docker 명령어가 정상적으로 동작하는지 확인

```shell
docker run hello-world
```

> 혹시라도 만약에 이 명령어가 안된다면 버그니까 pc 재부팅해서 한번 해보고, 또 안되면 그냥 재설치 하면 된다.

### containerd 설정

containerd 의 설정을 생성해준 후 cgroup 을 systemd 로 바꾸어주어야 한다.

```shell
mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml

sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/g' /etc/containerd/config.toml

sudo systemctl restart containerd
```

### kind 설치

x86 아키텍처의 경우 아래와 같이 kind 를 바이너리 파일로 받아서 환경변수에 옮겨주면 된다.

```shell
curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.23.0/kind-linux-amd64

chmod +x ./kind
sudo mv ./kind /usr/local/bin/kind
```

### kubeadm 설치

Kubernetes 공식 홈페이지에서는 클러스터 생성 관리를 위해 kubeadm을 권장한다. 다른 선택지로 kubespray, kops 등이 있다.

```bash
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl gpg

curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.30/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.30/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
```

앞서 kubectl 을 설치하지 않았다면 kubelet, kubeadm 설치할 때 같이 설치해준다.

## 🚀 Kubernetes 초기화

---

Kubernetes를 사용하기 위해서는 마스터 노드 생성과 초기화가 필요하다.

> **초기화 전 필수 확인사항**
> 
> - swap 비활성화: `sudo swapoff -a` (영구 적용은 `/etc/fstab`에서 swap 라인 주석 처리)
> 
> - 필요한 포트(6443, 10250, 2379-2380 등)가 방화벽에서 열려 있는지 확인
> 
> - `br_netfilter` 모듈 로드: `sudo modprobe br_netfilter`
> 
> - IP 포워딩 활성화: `echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward`

아래 명령어를 통해 초기화를 진행한다.

```shell
sudo kubeadm init --pod-network-cidr=172.20.0.0/16
```

초기화를 진행하면 아래와 같은 출력문이 나온다.

```shell
Your Kubernetes control-plane has initialized successfully!

To start using your cluster, you need to run the following as a regular user:

  mkdir -p $HOME/.kube
  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  sudo chown $(id -u):$(id -g) $HOME/.kube/config

Alternatively, if you are the root user, you can run:

  export KUBECONFIG=/etc/kubernetes/admin.conf

You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
  https://kubernetes.io/docs/concepts/cluster-administration/addons/

Then you can join any number of worker nodes by running the following on each as root:
```

일반 사용자(sudo 권한 있음) 로 진행할 때는 아래 명령어를 통해 kubectl 권한을 취득한다

```shell
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
```

root 사용자라면 환경변수로 곧장 연결이 가능하다

```shell
export KUBECONFIG=/etc/kubernetes/admin.conf
```

### 🌐 CNI(Container Network Interface) 설치 - Calico

---

Kubernetes 클러스터가 초기화되면 노드 상태가 `NotReady`로 표시된다. 이는 Pod 간 네트워크 통신을 담당하는 **CNI(Container Network Interface)** 플러그인이 아직 설치되지 않았기 때문이다.

> **CNI란?**
> 
> CNI는 Kubernetes에서 Pod의 네트워크 인터페이스를 생성하고 관리하는 표준 규격이다. 대표적인 CNI 플러그인으로는 **Calico**, Flannel, Cilium, Weave 등이 있다. Calico는 BGP 기반 라우팅을 사용하며, NetworkPolicy를 기본 지원하여 보안성이 뛰어나다.

나는 Calico를 선택했다. 설치는 매니페스트 파일을 받아서 적용하는 방식이다.

```shell
curl https://raw.githubusercontent.com/projectcalico/calico/v3.28.1/manifests/calico.yaml -O
```

calico 파일을 받은 후 **반드시** `CALICO_IPV4POOL_CIDR` 값을 확인해야 한다. 기본값은 `192.168.0.0/16`이지만, 우리는 `kubeadm init`에서 `--pod-network-cidr=172.20.0.0/16`으로 지정했으므로 이 값을 맞춰줘야 한다.

```shell
# calico.yaml에서 CIDR 수정
sed -i 's/192.168.0.0\/16/172.20.0.0\/16/g' calico.yaml
```

> **CIDR 불일치 주의!**
> 
> `kubeadm init`의 `--pod-network-cidr` 값과 Calico의 `CALICO_IPV4POOL_CIDR` 값이 다르면 Pod 간 통신이 되지 않는다. ~~이거 안 맞춰서 삽질하는 사람이 정말 많다~~

수정을 완료한 후 적용한다.

```shell
kubectl apply -f calico.yaml
```

Calico가 정상적으로 배포되면 `kube-system` 네임스페이스에 `calico-node`와 `calico-kube-controllers` Pod가 생성된다.

```shell
# Calico Pod 상태 확인
kubectl get pods -n kube-system

# 노드 상태 확인 - Ready로 전환되어야 정상
kubectl get nodes
```

모든 Pod가 `Running` 상태가 되면 노드도 `Ready` 상태로 전환된다. ~~여기까지 오면 거의 다 온 거다~~

---

### 🔓 Control Plane에서 Pod 스케줄링 허용

기본적으로 Kubernetes는 보안상의 이유로 Control Plane(마스터 노드)에 일반 워크로드 Pod를 스케줄링하지 않는다. 하지만 **단일 노드 환경**에서 테스트하거나, Control Plane에서도 Pod를 올리고 싶을 때는 taint를 제거해야 한다.

```shell
kubectl taint nodes --all node-role.kubernetes.io/control-plane-
```

> **프로덕션 환경에서는 주의!**
> 
> 프로덕션 환경에서는 Control Plane과 워크로드를 분리하는 것이 권장된다. 이 설정은 테스트 및 단일 노드 환경에서만 사용하자.

---

## 끝

이상으로 Kubernetes의 기본 개념부터 kubeadm을 이용한 단일 노드 클러스터 구축, 그리고 Calico CNI 설치까지의 전체 과정을 살펴보았다.

정리하면, Docker와 containerd를 설치하고 → kubeadm으로 클러스터를 초기화하고 → Calico로 Pod 네트워크를 구성하면 기본적인 Kubernetes 환경이 완성된다. 여기까지가 "Hello, Kubernetes!" 단계라고 보면 된다.

다음 글에서는 이 클러스터 위에 실제 워크로드를 배포하고 Deployment, Service, Ingress 등 핵심 오브젝트를 다뤄볼 예정이다. ~~삽질은 계속된다~~

---

## ✅ 핵심 정리

✅ **Kubernetes**: 컨테이너 오케스트레이션 플랫폼. 배포, 확장, 관리를 자동화

✅ **Control Plane + Worker Node**: kube-apiserver, etcd, scheduler, kubelet 등으로 구성

✅ **kubeadm**: 공식 부트스트래핑 도구로 프로덕션 수준의 클러스터 생성 가능

✅ **containerd**: Kubernetes의 컨테이너 런타임. cgroup을 systemd로 설정 필수

✅ **Calico CNI**: Pod 네트워크를 담당하는 CNI 플러그인. CIDR 값이 kubeadm init과 일치해야 함

✅ **Control Plane taint 제거**: 단일 노드 테스트 시 `control-plane` taint를 제거해야 Pod 스케줄링 가능

### ⚠️ 주의사항

⚠️ **cgroup 드라이버 일치**: Docker와 containerd 모두 `systemd`를 cgroup 드라이버로 사용해야 한다

⚠️ **Pod Network CIDR**: `kubeadm init` 시 지정한 CIDR과 Calico 설정이 반드시 일치해야 한다

⚠️ **swap 비활성화**: Kubernetes는 기본적으로 swap이 켜져 있으면 동작하지 않는다. `sudo swapoff -a`로 비활성화하자

⚠️ **방화벽 포트**: 6443(API Server), 10250(kubelet), 2379-2380(etcd) 등 필요한 포트가 열려 있어야 한다

### 📚 참고 자료

- [Kubernetes 공식 문서](https://kubernetes.io/ko/docs/)

- [kubeadm 설치 가이드](https://kubernetes.io/ko/docs/setup/production-environment/tools/kubeadm/install-kubeadm/)

- [Calico 공식 문서](https://docs.tigera.io/calico/latest/getting-started/kubernetes/)

- [Docker 공식 설치 문서](https://docs.docker.com/engine/install/ubuntu/)

- [containerd 설정 가이드](https://kubernetes.io/docs/setup/production-environment/container-runtimes/#containerd)
