인프라

[K8s] Proxmox VE 위에 K8S 설정하기

하루이2222 2025. 6. 1. 19:56

[단계 1] 가상 머신(VM) 준비 및 기본 설정

클러스터를 구성할 각 노드에 대한 가상 머신을 준비하고, 네트워크에서 식별 가능하도록 고유한 호스트 이름을 설정하는 단계이다.

  1. 가상 머신 생성
    Proxmox VE의 템플릿 복제 기능을 사용하여 아래 사양으로 VM을 생성한다.

    • 컨트롤 플레인: k8s-master (CPU: 2코어, RAM: 6GB)
    • 워커 노드: k8s-worker-01 ~ k8s-worker-06 (CPU: 2코어, RAM: 4GB)
  2. 호스트 이름 설정
    생성된 모든 VM에 각각 SSH로 접속하여, hostnamectl 명령어를 통해 사전에 계획된 호스트 이름을 설정한다. Kubernetes 클러스터에서 각 노드는 고유한 이름으로 식별되어야 한다.

    sudo hostnamectl set-hostname <각 노드의 이름>

[단계 2] 모든 노드 공통 사전 설정

Kubernetes가 올바르게 작동하기 위해 필요한 시스템 환경을 모든 노드(마스터, 워커 포함)에 동일하게 구성한다.

  1. 시스템 업데이트 및 스왑 비활성화
    패키지를 최신 상태로 업데이트하고, Kubelet의 정상적인 작동을 위해 스왑(Swap) 메모리를 비활성화한다. 스왑이 활성화되어 있으면 Kubelet이 리소스 사용량을 정확히 계산하지 못해 성능 및 안정성 문제가 발생할 수 있다.

    sudo apt-get update && sudo apt-get upgrade -y
    sudo swapoff -a
    # 재부팅 후에도 스왑이 비활성화되도록 fstab 파일에서 해당 라인을 주석 처리한다.
    sudo sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
  2. 방화벽 비활성화 (테스트 환경)
    클러스터 노드 간 통신에 필요한 모든 포트를 개방하기 위해, 이 가이드에서는 방화벽(ufw)을 비활성화한다. 운영 환경에서는 보안을 위해 필요한 포트(예: 6443, 2379-2380, 10250-10252 등)만 선별적으로 허용해야 한다.

    sudo systemctl stop ufw
    sudo systemctl disable ufw
  3. Kubernetes를 위한 커널 모듈 및 네트워크 설정
    컨테이너의 네트워크 트래픽이 iptables에 의해 올바르게 처리되도록 필요한 커널 모듈을 로드하고, IP 포워딩을 활성화한다.

    cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
    br_netfilter
    EOF
    
    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
  4. 컨테이너 런타임(containerd) 설치 및 설정
    Kubernetes는 컨테이너를 직접 실행하지 않으며, containerd와 같은 컨테이너 런타임이 그 역할을 대신한다. containerd를 설치하고, Kubelet과 Cgroup 드라이버를 일치시키기 위해 SystemdCgroup 옵션을 true로 변경한다. 이는 클러스터 안정성을 위한 필수 설정이다.

    sudo apt-get install -y containerd
    sudo mkdir -p /etc/containerd
    sudo containerd config default | sudo tee /etc/containerd/config.toml > /dev/null
    sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
    sudo systemctl restart containerd
    sudo systemctl enable containerd
  5. Kubernetes 패키지(kubelet, kubeadm, kubectl) 설치
    Kubernetes 공식 저장소를 추가하고 세 가지 핵심 패키지를 설치한다.

    • kubelet: 각 노드에서 실행되는 에이전트로, Pod의 라이프사이클을 관리한다.
    • kubeadm: 클러스터의 부트스트래핑(초기 설정 및 노드 추가)을 자동화하는 도구이다.
    • kubectl: Kubernetes 클러스터와 상호작용하기 위한 커맨드 라인 인터페이스(CLI)이다.
    sudo apt-get install -y apt-transport-https ca-certificates curl
    sudo 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
    # apt에 의한 자동 업데이트를 방지하여 클러스터 버전의 일관성을 유지한다.
    sudo apt-mark hold kubelet kubeadm kubectl

[단계 3] 컨트롤 플레인(마스터 노드) 초기화

k8s-master 노드에서만 다음 명령을 실행하여 클러스터의 핵심부인 컨트롤 플레인을 구성한다.

  1. kubeadm으로 클러스터 초기화
    kubeadm init 명령을 사용하여 클러스터를 초기화한다. --pod-network-cidr 옵션은 Pod 간 통신을 위한 CNI 플러그인이 사용할 IP 대역을 지정하는 것으로, Flannel을 사용할 것이므로 10.244.0.0/16으로 설정한다.

    sudo kubeadm init --pod-network-cidr=10.244.0.0/16

    초기화 완료 후 출력되는 kubeadm join ... 명령어는 워커 노드를 클러스터에 참여시키는 데 사용되므로 반드시 별도로 복사해 두어야 한다.

  2. kubectl 환경 설정
    생성된 클러스터를 kubectl로 제어할 수 있도록 설정 파일을 사용자의 홈 디렉터리로 복사하고 권한을 설정한다.

    mkdir -p $HOME/.kube
    sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
    sudo chown $(id -u):$(id -g) $HOME/.kube/config
  3. CNI(Container Network Interface) 플러그인 설치
    기본적으로 Kubernetes 클러스터는 Pod 간의 네트워크 통신을 제공하지 않는다. Flannel과 같은 CNI 플러그인을 설치하여 Pod들이 서로 통신할 수 있는 가상 네트워크 환경을 구성한다.

    kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml

[단계 4] 워커 노드 클러스터 참여

모든 워커 노드(k8s-worker-01 ~ 06)에서, [단계 3]에서 복사해 둔 kubeadm join 명령어를 실행하여 컨트롤 플레인에 참여시킨다.

sudo kubeadm join 192.168.0.9:6443 --token <토큰값> \
  --discovery-token-ca-cert-hash sha256:<해시값>

[단계 5] 클러스터 상태 검증

마스터 노드에서 kubectl 명령어를 통해 클러스터가 정상적으로 구성되었는지 최종 확인한다.

  1. 노드 상태 확인
    모든 노드가 Ready 상태로 표시되는지 확인한다.

    kubectl get nodes -o wide
  2. 전체 파드 상태 확인
    kube-system 네임스페이스의 coredns, etcd, kube-proxy 등 모든 시스템 파드가 Running 상태인지 확인한다.

    kubectl get pods -A

모든 노드가 Ready 상태이고 시스템 파드들이 정상적으로 실행 중이라면, Proxmox VE 기반의 Kubernetes 클러스터 구축이 성공적으로 완료된 것이다.


[참고] Join 토큰 재생성

만약 kubeadm join 명령어를 분실했거나 토큰이 만료된 경우, 마스터 노드에서 아래 명령어를 실행하여 새로운 join 명령어를 생성할 수 있다.

kubeadm token create --print-join-command