개요

  • 목적: K3s 클러스터 VM(Master 1 + Worker 2)을 Terraform으로 자동 생성
  • 방식: Proxmox Cloud-Init 템플릿 VM을 clone하여 프로비저닝
  • 이전 방식: 베어메탈 PXE → Proxmox VM + Terraform IaC로 전환

아키텍처

구분VM ID역할네트워크
k3s-master200Control Planevnetsvc (SDN)
k3s-worker-1201Workervnetsvc (SDN)
k3s-worker-2202Workervnetsvc (SDN)

1. 사전 작업: Cloud-Init 템플릿 VM 생성

Proxmox 쉘에서 1회만 실행. 이후 Terraform이 이 템플릿을 clone하여 VM 생성.

# Debian 12 Cloud Image 다운로드
wget https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-generic-amd64.qcow2 \
  -O /tmp/debian-12-cloud.qcow2
 
# 템플릿 VM 생성 (ID: 9000)
qm create 9000 --name debian-12-cloud-template \
  --memory 2048 --cores 2 --net0 virtio,bridge=vmbr0
qm importdisk 9000 /tmp/debian-12-cloud.qcow2 app-1
qm set 9000 --scsihw virtio-scsi-pci --scsi0 app-1:vm-9000-disk-0
qm set 9000 --ide2 app-1:cloudinit
qm set 9000 --boot c --bootdisk scsi0
qm set 9000 --serial0 socket --vga serial0
qm set 9000 --agent enabled=1
qm template 9000
 
# 정리
rm /tmp/debian-12-cloud.qcow2

Tip: VGA 콘솔을 선호하면 --vga std로 변경하고 --serial0 생략.


2. Terraform 구성

디렉토리 구조

terraform/k3s-cluster/
├── main.tf              # VM 리소스 정의 (clone 기반)
├── variables.tf         # 변수 선언
├── outputs.tf           # 출력값 (VM ID, IP)
├── terraform.tfvars     # 환경별 값 (API 토큰, SSH 키 등)
└── terraform.tfvars.example

핵심 설계 결정

항목결정이유
VM 생성 방식Template CloneSSH 디스크 import 방식은 Windows SSH Agent 호환 문제
네트워크vnetsvc (SDN VNET)격리된 서비스 네트워크, isolated_svc 방화벽 그룹
IP 할당DHCPOPNsense DHCP Reservation으로 관리
스토리지app-1 (ZFS)VM 디스크용. ISO는 local(파일 기반) 사용
Master 관리Terraform 신규 생성import 방식은 상태 충돌 문제 발생

주요 코드 — main.tf

# 템플릿에서 clone하여 VM 생성
resource "proxmox_virtual_environment_vm" "k3s_worker" {
  for_each = var.workers
 
  node_name = var.proxmox_node
  vm_id     = each.value.vm_id
  name      = each.key
 
  clone {
    vm_id = var.template_vm_id  # 9000
  }
 
  network_device {
    bridge   = var.bridge       # vnetsvc
    model    = "virtio"
    firewall = true             # isolated_svc 방화벽 그룹 적용
  }
 
  initialization {
    ip_config {
      ipv4 { address = "dhcp" }
    }
    user_account {
      username = var.vm_user
      keys     = var.ssh_public_keys
      password = var.vm_password
    }
  }
}

3. 적용

cd terraform/k3s-cluster
terraform init
terraform apply

결과

Apply complete! Resources: 3 added, 0 changed, 0 destroyed.

master_vm_id = 200
worker_vm_ids = {
  "k3s-worker-1" = 201
  "k3s-worker-2" = 202
}

4. 트러블슈팅

storage ‘local-lvm’ does not exist

  • 원인: Proxmox 기본 설치 시 LVM 스토리지로 생성되나, ZFS 환경에서는 미존재. bpg/proxmox provider가 내부적으로 기본값 사용.
  • 해결: Proxmox 쉘에서 alias 생성
pvesm add zfspool local-lvm --pool app-1 --content images,rootdir --nodes um880

iothread 경고

  • 증상: iothread is only valid with virtio disk or virtio-scsi-single controller
  • 원인: 템플릿의 SCSI 컨트롤러가 virtio-scsi-pci (multi-queue). iothreadvirtio-scsi-single에서만 유효.
  • 영향: 기능 문제 없음. 성능 최적화가 필요하면 템플릿 컨트롤러 변경.

5. 다음 단계

  1. Proxmox UI 또는 DHCP에서 VM IP 확인
  2. ansible/inventory.yml에 IP 반영
  3. Ansible 플레이북으로 K3s 설치 및 클러스터 조인
  4. kubectl get nodes로 검증