Ubuntu 24.04 환경에서 Kubernetes 클러스터를 구축하고 Container Orchestration 환경을 구성하는 과정을 작성했습니다.
컨테이너 오케스트레이션 플랫폼
- 여러 서버에 분산된 컨테이너들을 자동으로 관리하는 시스템
- 컨테이너의 배포, 확장, 복구를 자동화
- 예시: 웹서버 3개가 필요하면 자동으로 3개 서버에 배포하고, 하나가 죽으면 자동으로 다시 생성
컨테이너를 실제로 실행하는 소프트웨어
- 컨테이너의 생성, 실행, 중지, 삭제를 담당하는 프로그램
- Docker에서 분리되어 나온 경량화된 컨테이너 실행 엔진
- Kubernetes가 "nginx 컨테이너 실행해줘"라고 요청하면 실제로 실행하는 역할
- 예시: 요리사(Kubernetes)가 "라면 끓여줘"라고 하면 실제로 라면을 끓이는 가스레인지(containerd) 역할
컨테이너 간 네트워크 통신을 연결해주는 표준
- 서로 다른 서버에 있는 컨테이너들이 서로 통신할 수 있게 해주는 네트워크 플러그인
- Calico CNI: 각 컨테이너에 IP를 할당하고 라우팅 경로를 설정
- CNI가 없으면 컨테이너들이 서로 통신할 수 없음 (격리된 상태)
- 예시: 서로 다른 건물(서버)에 있는 사람들(컨테이너)이 전화(네트워크)로 통신할 수 있게 해주는 전화망 시스템
여러 서버를 하나로 묶은 컴퓨팅 환경
- 여러 대의 물리적 서버를 하나의 큰 컴퓨터처럼 사용하는 시스템
- Master Node 1개 + Worker Node 여러 개로 구성
- 하나의 서버가 고장나도 다른 서버에서 서비스 계속 운영 (고가용성)
- 예시: 여러 대의 컴퓨터를 연결해서 하나의 강력한 슈퍼컴퓨터처럼 사용
클러스터 내에서 역할이 다른 서버들
Master Node (관리 서버)
- 클러스터 전체를 관리하고 명령을 내리는 서버
- API Server, Scheduler 등 관리 프로그램들이 실행
kubectl명령어를 받아서 전체 클러스터를 제어- 예시: 공장의 관리사무소 (전체 공장 관리)
Worker Node (작업 서버)
- 실제 애플리케이션(Pod)이 실행되는 서버
- Master의 명령을 받아서 컨테이너를 생성하고 실행
- kubelet, kube-proxy 등이 실행되어 Master와 통신
- 예시: 공장의 생산라인 (실제 제품 생산)
Kubernetes에서 가장 작은 배포 단위
- 하나 이상의 컨테이너를 묶은 그룹 (보통 1개 컨테이너 = 1개 Pod)
- 같은 Pod 안의 컨테이너들은 IP 주소와 저장공간을 공유
- Pod는 Worker Node에서 실행됨
- Pod가 죽으면 새로운 Pod가 자동으로 생성됨 (임시적 존재)
- 예시: 택배 상자 (여러 물건을 하나로 묶어서 배송)
┌─────────────── Cluster (클러스터) ───────────────┐
│ │
│ ┌─── Master Node ───┐ ┌─── Worker Node ───┐ │
│ │ │ │ │ │
│ │ • API Server │ │ • kubelet │ │
│ │ • Scheduler │ │ • Pod │ │
│ │ • Controller │ │ └─ Container │ │
│ │ │ │ • Pod │ │
│ └───────────────────┘ │ └─ Container │ │
│ └───────────────────┘ │
│ │
│ CNI (네트워크)로 모든 Pod 연결 │
└─────────────────────────────────────────────────┘
전체 흐름:
- 사용자:
kubectl명령어로 Master Node에 요청 - Master Node: Worker Node들에게 Pod 생성 명령
- Worker Node: Container Runtime으로 Pod 생성
- CNI: 모든 Pod들이 서로 통신할 수 있게 네트워크 연결
┌─────────────────────────────────────────────────────────────────────────┐
│ Kubernetes Cluster │
│ │
│ ┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐ │
│ │ Master Node │ │ Worker Node 1 │ │ Worker Node 2 │ │
│ │ (myserver01) │ │ (myserver02) │ │ (myserver03) │ │
│ │ IP: 10.0.2.21 │ │ IP: 10.0.2.22 │ │ IP: 10.0.2.23 │ │
│ │ │ │ │ │ │ │
│ │ ┌──────────────┐ │ │ ┌──────────────┐ │ │ ┌──────────────┐ │ │
│ │ │ API Server │ │ │ │ kubelet │ │ │ │ kubelet │ │ │
│ │ │ Scheduler │ │ │ │ kube-proxy │ │ │ │ kube-proxy │ │ │
│ │ │ Controller │ │ │ │ containerd │ │ │ │ containerd │ │ │
│ │ │ etcd │ │ │ │ │ │ │ │ │ │ │
│ │ └──────────────┘ │ │ └──────────────┘ │ │ └──────────────┘ │ │
│ └──────────────────┘ └──────────────────┘ └──────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────┘
│
┌──────────────────┐
│ Pod Network │
│ 192.168.0.0/16 │
│ (Calico CNI) │
└──────────────────┘
| 구분 | 버전 |
|---|---|
| OS | Ubuntu 24.04 LTS |
| Kubernetes | v1.30.x |
| Container Runtime | containerd |
| CNI Plugin | Calico |
| 네트워크 | 고정 IP (10.0.2.15,20,25) |
- Host Network:
10.0.2.0/24 - Pod Network:
192.168.0.0/16(Calico) - Service Network:
10.96.0.0/12(기본값)
고가용성과 확장성을 고려하여 1개의 마스터 노드와 2개의 워커 노드로 구성된 클러스터를 설계하였습니다.
| 단계 | 작업 항목 | 세부 내용 | 대상 노드 |
|---|---|---|---|
| 1-1 | 기본 환경 설정 | Ubuntu 22.04 기본 설치 및 업데이트 | 기본 VM |
| 필수 패키지 설치 (tree, curl, openssh-server 등) | |||
| 기본 보안 설정 및 방화벽 구성 | |||
| 1-2 | 네트워크 기본 설정 | Netplan 구성 파일 생성 (템플릿) | 기본 VM |
| SSH 서비스 활성화 및 설정 | |||
| 1-3 | Container Runtime 설치 | containerd 설치 및 기본 구성 | 기본 VM |
| SystemdCgroup 설정으로 Kubernetes 호환성 확보 | |||
| 커널 모듈 및 네트워크 매개변수 사전 구성 | |||
| 1-4 | 공통 구성 요소 설치 | Kubernetes 패키지 저장소 추가 | 모든 노드 |
| kubeadm, kubelet, kubectl 설치 |
| 단계 | 작업 항목 | 세부 내용 | 대상 노드 |
|---|---|---|---|
| 2-1 | VM 복제 | 베이스 VM을 3개로 복제 | |
| (Master 1개, Worker 2개) | Template → 3 Nodes | ||
| 각 노드별 고유 hostname 설정 | |||
| 2-2 | 노드별 네트워크 개별화 | myserver01 (Master): 10.0.2.15/24 | myserver01 |
| myserver02 (Worker1): 10.0.2.20/24 | myserver02 | ||
| myserver03 (Worker2): 10.0.2.25/24 | myserver03 | ||
| 2-3 | SSH Key 기반 인증 구성 | 각 노드에서 SSH 키 페어 생성 | 모든 VM |
| 모든 노드 간 양방향 SSH 접근 설정 |
| 단계 | 작업 항목 | 세부 내용 | 대상 노드 |
|---|---|---|---|
| 3-1 | Master Node 전용 설정 | kubeadm init으로 Control Plane 초기화 | myserver01 |
| kubectl 설정 및 CNI 플러그인(Calico) 설치 | |||
| 클러스터 토큰 생성 및 확인 | |||
| 3-2 | Worker Node 전용 설정 | Master 노드에서 kubeconfig 복사 | myserver02, myserver03 |
| kubeadm join으로 클러스터 참여 | |||
| 노드 상태 검증 및 Pod 스케줄링 테스트 |
# 새로운 네트워크 설정 파일 생성
sudo nano /etc/netplan/01-netcfg.yaml or sudo vi /etc/netplan/01-netcfg.yaml
# 기존 cloud-init 설정 제거
sudo rm /etc/netplan/50-cloud-init.yamlnetwork:
version: 2
renderer: networkd
ethernets:
enp0s3:
addresses:
- 10.0.2.25/24 # 마스터: 15, 워커1: 20, 워커2: 25
routes:
- to: default
via: 10.0.2.1
nameservers:
addresses:
- 8.8.8.8
dhcp4: falsesudo netplan apply
ip a # IP 주소 확인# /etc/hosts 파일 생성
sudo nano /etc/hosts || sudo vi /etc/hosts127.0.0.1 localhost
10.0.2.15 myserver01
10.0.2.20 myserver02
10.0.2.25 myserver03ssh-keygen -t rsa -b 4096
# Enter 키로 기본 설정 사용 (패스프레이즈 없음)ls -l .ssh/
cat .ssh/id_rsa.pub
#를 이용한 ssh id 확인 가능# 마스터 노드(01)에서 실행
ssh-copy-id ubuntu@myserver02
ssh-copy-id ubuntu@myserver03
# 워커 노드(02)에서 실행
ssh-copy-id ubuntu@myserver01
ssh-copy-id ubuntu@myserver03
# 워커 노드(03)에서 실행
ssh-copy-id ubuntu@myserver01
ssh-copy-id ubuntu@myserver02서버도메인을 사용하기 위해서는 위 2단계에서 /etc/hosts에 등록이 필수
ssh ubuntu@해당서버IP or ubuntu@서버네임 # 비밀번호 없이 접속되는지 확인sudo -i
# 커널 모듈 자동 로드 설정
cat <<EOF | tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
# 즉시 모듈 로드
modprobe overlay
modprobe br_netfilter
# sysctl 설정
cat <<EOF | 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
# 설정 적용
sysctl --systemsudo apt update && sudo apt install -y containerd
# 설치 확인
containerd --version
systemctl status containerd# 기본 설정 생성
sudo containerd config default | sudo tee /etc/containerd/config.toml > /dev/null
# SystemdCgroup 활성화 (중요!)
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/g' /etc/containerd/config.toml
# 설정 확인
sudo cat /etc/containerd/config.toml | grep SystemdCgroup
# 서비스 재시작
sudo systemctl restart containerd
sudo systemctl status containerdsudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates# GPG 키 저장 디렉토리 생성
sudo mkdir -p /etc/apt/keyrings
# Kubernetes 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 tee /etc/apt/apt.conf.d/99allow-insecure-repositories <<EOF
APT::Get::AllowUnauthenticated "true";
Acquire::AllowInsecureRepositories "true";
Acquire::AllowDowngradeToInsecureRepositories "true";
EOF
# 패키지 업데이트
sudo apt-get update
****# 패키지 설치 (사용 가능한 버전 찾기)
sudo apt-get install -y --allow-unauthenticated kubelet kubeadm kubectl
# 버전 확인
kubectl version
kubeadm version
kubelet --version
# 필요한 이미지 목록 확인
sudo kubeadm config images list
# 이미지 사전 다운로드
sudo kubeadm config images pull --cri-socket unix:///run/containerd/containerd.sock# Control Plane 초기화
sudo kubeadm init \
--apiserver-advertise-address={**master nod ip**} \
--pod-network-cidr=192.168.0.0/16 \
--cri-socket /run/containerd/containerd.sock# 설정 디렉토리 생성
mkdir -p $HOME/.kube
# 클러스터 접속 설정 복사
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
# 파일 소유권 변경
sudo chown $(id -u):$(id -g) $HOME/.kube/config
# 설정 확인
tree .kube/# Calico 설치
kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml# 노드 상태 확인
kubectl get nodes -o wide
# 토큰 확인 (워커 노드 조인용)
sudo kubeadm token list
# 시스템 Pod 상태 확인
kubectl get pods -n kube-system
# 설정 디렉토리 생성
mkdir -p $HOME/.kube
# 마스터 노드에서 config 복사
scp -p ubuntu@myserver01:~/.kube/config ~/.kube/configmaster node 생성시 발급된 토큰값을 이용해야함
# 마스터 노드 초기화 시 출력된 명령어 실행 (예시)
sudo kubeadm join 10.0.2.15:6443 \
--token uo2u6z.....kf \
--discovery-token-ca-cert-hash sha256:...........9d5ec78# 모든 노드 상태 확인
kubectl get nodes -o wide
# 워커 노드 로그 확인
sudo journalctl -u kubelet -f
# CNI 플러그인 동작 확인
kubectl get pods -n kube-system
# Deployment 생성 - 애플리케이션 배포
kubectl create deployment nginx1 --image=registry.k8s.io/nginx
# 비스 생성 - 외부 접근 가능하도록 노출
kubectl expose deployment nginx1 --type=NodePort --port=8081 --target-port=80
# 클러스터 리소스 전체 상태 확인
kubectl get all
# 서비스 상태 및 접근 정보 확인
kubectl get svc
# pod 실행 node 위치 확인 명령어
kubectl get pods -o wide- ✅ 3-Node Kubernetes 클러스터 구축 (Master 1, Worker 2)
- ✅ 고가용성 Container Orchestration 환경 구성
- ✅ SSH Key 기반 보안 인증 시스템 적용
- ✅ Calico CNI를 활용한 Pod 네트워킹 구현
- ✅ containerd Runtime 최적화 설정
- Helm Chart를 활용한 애플리케이션 배포 자동화
- Ingress Controller 도입으로 외부 트래픽 관리
- Monitoring Stack (Prometheus + Grafana) 구축
- CI/CD Pipeline 연동으로 자동 배포 환경 구성