본문 바로가기
AI Journey/클라우드

[k8s] Vagrant 설정파일 분석

by 보눔비스타 2026. 1. 30.

Vagrantfile은 VirtualBox를 기반으로 쿠버네티스(Kubernetes) 클러스터 환경을 자동으로 구축하기 위한 설정 파일이다.

파일의 내용은 변수 정의, 공통 설정, 마스터 노드 설정, 그리고 워커 노드 설정의 4단계로 구성된다.

1. 전역 변수 설정

파일의 최상단에는 클러스터 구축에 필요한 핵심 정보들이 변수로 선언되어 있다.

# [1] 전역 변수 설정 구역
domain = "kubernetes.lab"
control_plane_endpoint = "k8s-master." + domain + ":6443"
pod_network_cidr = "10.244.0.0/16"
master_node_ip = "192.168.57.100"
version = "v1.29"

 

  • 네트워크 및 도메인: 클러스터 내부에서 사용할 도메인(kubernetes.lab)과 마스터 노드의 고정 IP(192.168.57.100)를 지정한다.
  • 쿠버네티스 설정: API 서버가 사용할 엔드포인트 주소와 포트(6443), 그리고 Pod 간 통신에 사용될 네트워크 대역인 pod_network_cidr을 정의한다.
  • 버전 관리: 설치할 쿠버네티스의 버전을 v1.29로 명시하여 환경의 일관성을 유지한다.

 

 

2. 공통 환경 설정: 모든 노드에 적용되는 기반

Vagrant.configure("2") 블록 내부에서 모든 가상 머신(VM)에 공통으로 적용될 인프라 설정을 수행한다.

Vagrant.configure("2") do |config|
    # [2] 공통 환경 및 프로바이더 설정
    config.ssh.insert_key = false
    config.vm.provision :shell, path: "kubeadm/bootstrap.sh", env: { "VERSION" => version }

    config.vm.provider "virtualbox" do |vb|
      vb.memory = "3072"
      vb.cpus = "1"
      vb.customize ["modifyvm", :id, "--nic1", "nat"]
    end

 

  • SSH 키 관리: config.ssh.insert_key = false를 통해 Vagrant가 기본으로 제공하는 공용 키를 그대로 사용하도록 설정한다.
  • 공통 프로비저닝: 모든 노드는 생성 직후 kubeadm/bootstrap.sh 파일을 실행한다. 이때 앞서 정의한 version 변수를 환경 변수로 넘겨주어 전 노드에 동일한 버전의 런타임과 도구(Docker, kubeadm, kubelet 등)가 설치되도록 한다.
  • 리소스 할당: virtualbox 프로바이더 설정을 통해 각 노드에 CPU 1개와 메모리 3,072MB를 할당하고, 외부 통신을 위한 NAT 인터페이스를 구성한다.

🟢부트스트랩(bootstrap.sh)의 역할

Vagrantfile에서 kubeadm/bootstrap.sh가 하는 역할:

가상 머신이 갓 생성되었을 때는 아무것도 없는 상태이므로, 쿠버네티스 노드로 동작하기 위해 필요한 공통 필수 구성 요소를 설치하는 과정이다.

  • Docker/Containerd 설치: 컨테이너를 실행할 엔진이 필요하다.
  • Kubeadm, Kubelet, Kubectl 설치: 쿠버네티스 명령어를 이해하고 실행할 핵심 도구들이다.
  • 시스템 설정: 스왑(Swap) 메모리를 비활성화하거나, 커널 파라미터를 수정하여 네트워크 통신이 가능하게 만든다.

 

3. 마스터 노드(Control Plane) 설정

config.vm.define "master" 블록은 클러스터의 두뇌 역할을 하는 마스터 노드를 정의한다.

    # [3] 마스터 노드(Control Plane) 정의
    config.vm.define "master" do |master|
      master.vm.box = "ubuntu/focal64"
      master.vm.hostname = "k8s-master.#{domain}"
      master.vm.network "private_network", ip: "#{master_node_ip}"
      
      # 호스트 이름 등록 (DNS 대용)
      master.vm.provision "shell", env: {"DOMAIN" => domain, "MASTER_NODE_IP" => master_node_ip} ,inline: <<-SHELL 
      echo "$MASTER_NODE_IP k8s-master.$DOMAIN k8s-master" >> /etc/hosts 
      SHELL
      
      (1..2).each do |nodeIndex|
        master.vm.provision "shell", env: {"DOMAIN" => domain, "NODE_INDEX" => nodeIndex}, inline: <<-SHELL 
        echo "192.168.57.10$NODE_INDEX k8s-worker-$NODE_INDEX.$DOMAIN k8s-worker-$NODE_INDEX" >> /etc/hosts 
        SHELL
      end
      
      # 쿠버네티스 초기화 실행
      master.vm.provision "shell", path:"kubeadm/init-master.sh", env: {"K8S_CONTROL_PLANE_ENDPOINT" => control_plane_endpoint, "K8S_POD_NETWORK_CIDR" => pod_network_cidr,  "MASTER_NODE_IP" => master_node_ip}
    end

 

  • 운영체제 및 호스트네임: Ubuntu 20.04(focal64) 이미지를 사용하며, 호스트네임은 k8s-master.kubernetes.lab으로 설정된다.
  • 네트워크: 호스트 머신과 통신하기 위해 192.168.57.100이라는 고정 IP를 할당한다.
  • 호스트 파일(/etc/hosts) 업데이트: 쉘 스크립트를 통해 자기 자신(master)과 2개의 워커 노드 정보를 /etc/hosts에 기록한다. 이는 별도의 DNS 서버 없이도 클러스터 내 노드들이 서로의 이름을 통해 통신할 수 있게 하기 위함이다.
  • 클러스터 초기화: kubeadm/init-master.sh 스크립트를 실행하여 쿠버네티스 마스터를 초기화(kubeadm init)하고 control plane을 구성한다. 이때 앞서 설정한 Pod 네트워크 대역(10.244.0.0/16)이 적용된다.

 

4. 워커 노드(Worker Node) 설정: 반복문을 통한 확장

Ruby의 반복문((1..2).each)을 사용하여 똑같은 설정을 가진 워크 노드 두 개를 효율적으로 정의한다.

 

 

    # [4] 워커 노드(Worker Nodes) 정의 (반복문)
    (1..2).each do |nodeIndex|
      config.vm.define "worker-#{nodeIndex}" do |worker|
        worker.vm.box = "ubuntu/focal64"
        worker.vm.hostname = "k8s-worker-#{nodeIndex}.#{domain}"
        worker.vm.network "private_network", ip: "192.168.57.10#{nodeIndex}"
        
        # 마스터 및 워커 노드 정보 등록
        worker.vm.provision "shell", env: {"DOMAIN" => domain, "MASTER_NODE_IP" => master_node_ip} ,inline: <<-SHELL 
        echo "$MASTER_NODE_IP k8s-master.$DOMAIN k8s-master" >> /etc/hosts 
        SHELL
        
        (1..2).each do |hostIndex|
            worker.vm.provision "shell", env: {"DOMAIN" => domain, "NODE_INDEX" => hostIndex}, inline: <<-SHELL 
            echo "192.168.57.10$NODE_INDEX k8s-worker-$NODE_INDEX.$DOMAIN k8s-worker-$NODE_INDEX" >> /etc/hosts 
            SHELL
        end
        
        # 클러스터 조인 및 Kubelet 설정
        worker.vm.provision "shell", path:"kubeadm/init-worker.sh"
        worker.vm.provision "shell", env: { "NODE_INDEX" => nodeIndex}, inline: <<-SHELL 
            echo ">>> FIX KUBELET NODE IP"
            sudo systemctl daemon-reload
            sudo systemctl restart kubelet
        SHELL
      end
    end
end

 

 

  • 동적 네이밍 및 IP 할당: 반복 인덱스(nodeIndex)를 활용해 각 워커 노드에 고유한 호스트네임과 IP(192.168.57.101, 102)를 순차적으로 부여한다.
  • 네임 서버 등록: 마스터 노드와 마찬가지로 모든 노드의 정보를 /etc/hosts에 등록하여 통신 환경을 조성한다.
  • 클러스터 조인: kubeadm/init-worker.sh 스크립트가 실행되면서 마스터 노드에서 생성된 토큰을 이용해 워커 노드들이 클러스터에 join한다.
  • 네트워크 인터페이스 교정: 마지막 단계로, 가상 머신 환경에서 네트워크 인터페이스가 여러 개일 때 발생할 수 있는 IP 인식 문제를 해결하기 위해 kubelet 서비스를 재시작한다.

이 Vagrantfile이 실행되면 (1) 공통 패키지 설치(Bootstrap) -> (2) 노드별 네트워크 설정 -> (3) 마스터 노드 초기화 -> (4) 워커 노드 조인의 순서로 동작한다. 결과적으로 사용자는 명령어 한 줄로 3대의 가상 머신이 유기적으로 연결된 쿠버네티스 1.29 버전의 클러스터를 즉시 확보할 수 있다.