개요
- 목적: K3s 클러스터 VM(Master 1 + Worker 2)을 Terraform으로 자동 생성
- 방식: Proxmox Cloud-Init 템플릿 VM을 clone하여 프로비저닝
- 이전 방식: 베어메탈 PXE → Proxmox VM + Terraform IaC로 전환
아키텍처
| 구분 | VM ID | 역할 | 네트워크 |
|---|---|---|---|
| k3s-master | 200 | Control Plane | vnetsvc (SDN) |
| k3s-worker-1 | 201 | Worker | vnetsvc (SDN) |
| k3s-worker-2 | 202 | Worker | vnetsvc (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.qcow2Tip: 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 Clone | SSH 디스크 import 방식은 Windows SSH Agent 호환 문제 |
| 네트워크 | vnetsvc (SDN VNET) | 격리된 서비스 네트워크, isolated_svc 방화벽 그룹 |
| IP 할당 | DHCP | OPNsense 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 um880iothread 경고
- 증상:
iothread is only valid with virtio disk or virtio-scsi-single controller - 원인: 템플릿의 SCSI 컨트롤러가
virtio-scsi-pci(multi-queue).iothread는virtio-scsi-single에서만 유효. - 영향: 기능 문제 없음. 성능 최적화가 필요하면 템플릿 컨트롤러 변경.
5. 다음 단계
- Proxmox UI 또는 DHCP에서 VM IP 확인
ansible/inventory.yml에 IP 반영- Ansible 플레이북으로 K3s 설치 및 클러스터 조인
kubectl get nodes로 검증