본문 바로가기
IT/k8s

[K8s] 맨땅에 쿠버네티스 구축하기 Day 1: VM 구성부터 Containerd 튜닝까지 (완벽 가이드)

by 수누다 2026. 1. 26.

들어가며

안녕하세요, 13년 차 시스템 엔지니어 수누다입니다.

이번 주는 저와 함께 '쿠버네티스(Kubernetes) 클러스터'를 내 손으로 직접 구축해보는 프로젝트를 진행하려 합니다. 클라우드(EKS, GKE)를 쓰면 편하지만, 온프레미스 환경에서 바닥부터 직접 깔아봐야 비로소 "K8s가 어떻게 돌아가는지" 뼈저리게 이해할 수 있기 때문이죠.

오늘은 그 대장정의 첫 번째 날, [Day 1] 기초 공사 편입니다. 건물을 올리기 전에 땅을 다지듯, 쿠버네티스가 실행될 수 있는 완벽한 리눅스 환경을 만들어보겠습니다.

1. 인프라 개요 (Infrastructure Specs)

가장 먼저 우리가 구축할 환경의 '설계도'입니다. 3대의 가상 머신(VM)을 하나의 클러스터로 묶을 예정입니다.

  • 가상화 도구: VMware Workstation (네트워크: Bridged Mode 권장)
  • OS: Ubuntu Server 22.04 LTS
  • 노드 구성:
역할 (Role) 호스트네임 (Hostname) IP 주소 (Static) 비고
Control Plane k8s-master 192.168.20.141 클러스터의 두뇌
Worker Node k8s-worker1 192.168.20.142 실제 파드 실행 1
Worker Node k8s-worker2 192.168.20.143 실제 파드 실행 2

2. 고정 IP 및 호스트 설정 (필수)

쿠버네티스 컴포넌트들은 서로 통신할 때 IP보다는 호스트네임을 주로 사용합니다. DNS 서버를 따로 구축하기 번거로운 소규모 홈랩에서는 /etc/hosts 파일에 족보를 등록하는 게 가장 확실한 방법입니다.

설정 파일 수정 (3대 노드 모두 동일하게 적용)

sudo nano /etc/hosts

추가할 내용:

192.168.20.141 k8s-master
192.168.20.142 k8s-worker1
192.168.20.143 k8s-worker2

💡 엔지니어의 Tip: 설정 후 ping k8s-worker1 명령어를 날려보세요. IP가 아닌 이름으로 핑이 간다면 성공입니다.

3. 스왑(Swap) 메모리 비활성화 (가장 중요 ⭐)

많은 초심자가 여기서 실패합니다. 쿠버네티스는 스왑 메모리를 싫어합니다.
쿠버네티스의 스케줄러가 파드(Pod)에 메모리를 할당할 때, 스왑이 켜져 있으면 정확한 자원 관리가 불가능하기 때문입니다. 반드시 꺼야 합니다.

# 1. 현재 실행 중인 스왑 즉시 끄기
sudo swapoff -a

# 2. 재부팅 후에도 다시 켜지지 않게 영구 설정 (fstab 주석 처리)
sudo sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
  • swapoff -a: 당장 현재 세션의 스왑을 끕니다.
  • sed ...: /etc/fstab 파일 안의 swap 관련 줄 앞에 #을 붙여 주석 처리합니다. (vi로 직접 수정해도 됩니다.)

4. 컨테이너 런타임 (Containerd) 설치

이제 도커(Docker)의 시대는 갔습니다. 쿠버네티스 표준 인터페이스(CRI)를 준수하는 가벼운 런타임, Containerd를 설치합니다.

4-1. 필수 패키지 설치

sudo apt update
sudo apt install -y containerd.io

4-2. 설정 파일 생성 및 수정

기본 설정 파일을 생성하고, Cgroup 관리자를 Systemd로 변경하는 것이 핵심입니다.

# 1. 설정 디렉토리 생성
sudo mkdir -p /etc/containerd

# 2. 기본 설정 파일 생성
sudo containerd config default | sudo tee /etc/containerd/config.toml

# 3. SystemdCgroup 활성화 (핵심 ⭐)
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/g' /etc/containerd/config.toml

# 4. 서비스 재시작
sudo systemctl restart containerd

⚠️ 엔지니어의 '삽질 방지' 분석: 왜 SystemdCgroup을 켜나요?

이 설정을 안 하면 나중에 kubelet이 실행되지 않고 에러를 뿜습니다.
리눅스에는 자원을 관리하는 대장인 systemd가 있습니다. 그런데 컨테이너 런타임이 독자적인 cgroupfs 관리자를 쓰면, 자원 관리 주체가 둘(systemd vs cgroupfs)이 되어 충돌이 발생합니다.
이를 막기 위해 SystemdCgroup = true 설정을 통해 "야, 자원 관리는 systemd 형님이 하시는 걸로 통일해!" 라고 교통정리를 해주는 겁니다.

요약 (Summary)

  1. IP & 호스트: 3대 노드의 IP를 고정하고 /etc/hosts에 서로의 이름을 등록했습니다.
  2. 스왑 끄기: K8s의 정확한 자원 관리를 위해 스왑 메모리를 영구 비활성화했습니다.
  3. Containerd: 도커 대신 Containerd를 설치하고, SystemdCgroup을 켜서 안정성을 확보했습니다.

내일(Day 2)은 이 기반 위에 Kubeadm을 설치하고 실제 클러스터를 초기화(Init) 하는 과정을 진행하겠습니다. 준비되셨나요?