Ubuntu 리눅스 쿠버네티스 클러스터 구축하기

hee·2026년 3월 14일

Cloud

목록 보기
6/6

0. 쿠버네티스란?

쿠버네티스 클러스터는 컨테이너화 된 애플리케이션을 실행하는 컴퓨팅 노드이다.

컨테이너화 된 애플리케이션의 대규모 배포, 스케일링 및 관리를 간편하게 만들어주며, 오픈 소스 기반의 컨테이너 오케스트레이션이다.

오케스트레이션(Orchestration)은 
컨테이너, 서버, 애플리케이션, 데이터 파이프라인 등 
여러 IT 구성 요소와 자동화된 태스크들을 연동하여 
복잡한 워크플로우를 효율적으로 관리 및 조율하는 기술을 의미한다.

도커는 애플리케이션의 프로세스 격리 기술을 사용해 컨테이너로 관리할 수 있는 도구라면,

쿠버네티스는 그런 컨테이너를 간편하게 관리할 수 있게 도와준다고 보면 된다.

1. 준비사항

Ubuntu 24.04.1 LTS / VMware workstation Pro

  • Master Node 1대 (CPU 2 Core, RAM 2GB)

  • Worker Node 2대 (CPU 1 Core, RAM 1GB)

사양 확인

  • 코어 nproc

  • 메모리 free -h

  • ifconfig -a

  • uuid sudo cat /sys/class/dmi/id/product_uuid

모든 명령어 입력은 root 계정에서 진행한다.

  • sudo su

2. 순서

  1. 쿠버네티스 설치 준비

  2. 컨테이너 런타임 설치

  3. 쿠버네티스 설치

  4. Master Node 설정

  5. Worker Node 등록

  6. 최종 확인

3. swap 비활성화

쿠버네티스의 대표적인 역할은 스케줄링(어느 노드에 어떤 컨테이너 (=Pod)를 배치할까)

스케줄러는 각 노드의 가용자원(CPU, Memory)를 정확히 파악해서 Pod를 배치함

만약 swap이 켜져있으면, 노드의 실제 물리 메모리가 부족할 때 디스크의 일부를 메모리처럼 사용하게 됨

이럴 경우, Pod를 계속 보낼 수 있지만, 실제로는 디스크 I/O 성능이 급격히 저하될 수 있음

따러서, 스케줄러가 자원 상태를 100% 예측 가능하게 관리하기 위해서 변수가 되는 스왑을 제거하는 것임.

# 영구 비활성화
sudo sed -i '/swap/s/^/#/' /etc/fstab

# 메모리 상태확인
sudo free -m

# swap 메모리 상태 확인 (출력값 없으면 비활성화 상태)
sudo swapon -a

4. 방화벽 설정

쿠버네티스 포트만 개방 / 방화벽 비활성화 두가지 방법 중 하나를 선택해서 진행함.

필자의 경우 전자를 선택해서 진행.

# 방화벽 설치 및 예외 설정 
sudo apt-get install -y firewalld
sudo systemctl start firewalld
sudo systemctl enable firewalld
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https


Master node 인 경우

TCP

  • 6443 Kubernetes API Server

  • 2379-2380 etcd server API (DB)

  • 10250 Kubernetes API

  • 10251 kube-scheduler

  • 10252 kube-controller-manager

UDP

  • CNI (Container network interface) 용도

  • 8285 Flannel (UDP)

  • 8472 Flannel (VXLAN)

sudo firewall-cmd --permanent --add-port=6443/tcp
sudo firewall-cmd --permanent --add-port=2379-2380/tcp
sudo firewall-cmd --permanent --add-port=10250-10252/tcp
sudo firewall-cmd --permanent --add-port=8285/udp
sudo firewall-cmd --permanent --add-port=8472/udp
sudo firewall-cmd --reload

Worker node 인 경우

TCP

  • 10250 kubelet API

  • 30000-32767 Nodeport services (외부에서 쿠버네티스 내부 서비스에 접속할 때 사용함

UDP

  • 8285/8472 Flannel
sudo firewall-cmd --permanent --add-port=10250/tcp
sudo firewall-cmd --permanent --add-port=30000-32767/tcp
sudo firewall-cmd --permanent --add-port=8285/udp
sudo firewall-cmd --permanent --add-port=8472/udp
sudo firewall-cmd --permanent --add-port=26443/tcp
sudo firewall-cmd --reload

방화벽 오픈 상태 확인

#열린 포트 확인
sudo firewall-cmd --list-all

👆 worker node
👆 master node

5. 네트워크 옵션 설정

리눅스 서버의 네트워크 기능을 쿠버네티스용 (= 컨테이너 통신용)으로 바꾸는 과정

br_netfilter

  • 리눅스 서버는 기본적으로 물리적인 통신을 담당

  • 하지만, 쿠버네티스는 서버 안에 가상 네트워크를 만들고, 그 안에서 Pod들이 통신하도록 함

  • br_netfilter는 리눅스 커널의 bridge 레이어를 통과하는 패킷들을 iptables(방화벽/네트워크 규칙)이 검사할 수 있게 함

k8s.conf

  • 컨테이너 간의 통신이 리눅스 방화벽 규칙을 따르도록 강제하는 설정
# /etc/modules-load.d/k8s.conf 파일 생성
sudo cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
br_netfilter
EOF
# /etc/sysctl.d/k8s.conf 파일 생성
sudo cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
# 시스템 재시작 없이 stysctl 파라미터 반영
sudo sysctl --system

6. 컨테이너 런타임 설치

쿠버네티스는 컨테이너를 관리하는 오케스트레이션 플랫폼이기 때문에, 컨테이너 런타임을 별도로 설치해야한다.

세가지 방법이 존재하는데, 두번째 방법 (containerd만 설치해서 사용하는 방법을 선택했다)

  1. docker 설치 시 Depends로 함께 설치되는 containerd 패키지 사용

  2. containerd만 설치 사용

  3. docker engine + cri-dockerd

Containerd 설치 후 사용

apt 업데이트 후 필수 패키지 설치

sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl gnupg

공개키 다운로드 및 저장소 등록

공개키는 인터넷에서 파일을 다운로드할때, 해커가 심어놓은 악성코드인지 혹은 진짜 Docker인지 확인하기 위해서 사용함

#공개키 다운로드
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
# 저장소 등록
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

containerd 패키지 설치

쿠버네티스의 표준 런타임

sudo apt-get update
#containerd 패키지 설치
sudo apt-get install containerd
#설치 확인
sudo systemctl status containerd

containerd config 설정

리눅스의 주인은 systemd 인데, 쿠버네티스의 kubelet도 자원관리를 위해 이 systemd를 사용하길 바람.

이 설정을 안해주면 컨테이너 런타임과 시스템이 충돌하게 됨.

#containerd 구성 파일 생성
sudo mkdir -p /etc/containerd
#containerd 기본 설정값으로 config.toml 생성
sudo containerd config default | sudo tee /etc/containerd/config.toml
#config.toml 파일 수정 SystemCgroup 설정을 true로 바꿈
vi /etc/containerd/config.toml
#수정사항 적용 및 재실행
sudo systemctl restart containerd



7. 쿠버네티스 클러스터 설치

필수 패키지 설치 및 구글 클라우드 공개키 다운로드 및 쿠버네티스 레포지토리 추가

sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl gnupg
#공개 키 다운로드
curl -fsSLo /etc/apt/keyrings/kubernetes-archive-keyring.gpg https://dl.k8s.io/apt/doc/apt-key.gpg
#apt 저장소에 쿠버네티스 저장소 추가
sudo echo "deb [signed-by=/etc/apt/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list

쿠버네티스 패키지 설치

kubeadm : 클러스터를 구축(init, join)하는 도구

kubelet : 각 노드에서 컨테이너를 실제로 실행/관리함

kubectl : 사용자가 쿠버네티스에 명령을 내리는 도구

#저장소 추가되었기 때문에 apt 업데이트
sudo apt-get update
#쿠버네티스 패키지 설치
sudo apt-get install -y kubelet kubeadm kubectl
#쿠버네티스 패키지 버전 고정
sudo apt-mark hold kubelet kubeadm kubectl
#쿠버네티스 설치 버전 조회
kubelet --version
kubeadm version
kubectl version
#kubelet service 확인
sudo systemctl status kubelet.service


문제 발생

→ kubelet, kubeadm, kubectl 모두 설치됨

→ 하지만 kubelet.services가 안열림

대안책

Docker 저장소 정보 삭제하고 재설치


제대로 작동함을 확인 ! Master Node 구성

8. Control-Plane 구성 및 CNI 설정

Calico 기본 설정값 192.168.0.0/16

# default
kubeadm init
# calico
sudo kubeadm init --pod-network-cidr=192.168.0.0/16



netstat 보냈는데 답이 없음 = API 서버 죽어있음


API 서버가 죽어있어서, kubectl 설정 삭제하고 다시 작성함.

후에, CNI(container network interface) 설정 진행

*CNI (container network interface)

컨테이너 간의 네트워크를 제어할 수 있는 플러그인으로 컨테이너 런타임에서 컨테이너의 네트워크를 사용하게 하는 인터페이스임.

9. 최종 확인

# connection
nc -vz [ip] [port]
# master node의 kubeadm token create --print-join-command
# 알아온 ip, port, token, hash 값을 worker node에서 실행
# master node와 연동됨
sudo kubeadm join [ip] [port] [token] [hash]
# master node에서 연결된 node 확인
hostname -I

👆 worker node
👆 master node

0개의 댓글