콘텐츠로 이동






08. VM템플릿 구성

Proxmox VE VM 템플릿과 Cloud-Init

VM을 수동으로 설치하면 OS 버전, 사용자, SSH 설정, 패키지, 보안 정책, DNS·NTP, 모니터링 에이전트 구성이 VM마다 달라지기 쉽습니다.

VM 수가 늘어날수록 수작업 설치는 운영 편차, 배포 시간, 장애 대응 비용을 키웁니다. Proxmox VE의 VM 템플릿과 Cloud-Init을 사용하면 기준 이미지를 만들고, Clone마다 사용자·SSH Key·IP·호스트명을 자동으로 주입할 수 있습니다.

Base OS Image
        │
Golden Image VM
├── OS Update
├── qemu-guest-agent
├── cloud-init
├── Internal Repository / CA
├── NTP / DNS
└── Security Baseline
        │
Proxmox VE Template
        │
Clone + Cloud-Init
├── Hostname
├── User / SSH Key
├── IP / Gateway / DNS
└── Custom Initial Configuration
        │
Ready-to-use VM

템플릿과 Golden Image

VM 템플릿은 VM을 반복 생성하기 위한 기준 이미지입니다. Golden Image는 조직의 운영 표준을 적용한 기준 VM 이미지라는 의미로 사용합니다.

Normal VM
        │
Convert to Template
        │
VM Template
├── 직접 실행하지 않음
├── Clone의 기준 이미지
├── Full Clone 생성
└── Linked Clone 생성

좋은 템플릿은 패키지가 많은 이미지가 아니라, 공통 기준은 포함하고 서비스별 설정은 분리한 이미지입니다.

템플릿에 포함 템플릿에 남기지 않을 정보
검증된 OS와 공통 패키지 고정 Hostname과 IP
qemu-guest-agent, cloud-init SSH Host Key, machine-id
내부 Repository, DNS, NTP 비밀번호, Private Key, API Token
내부 CA 인증서 서비스 인증서 Private Key
공통 보안 기준 DB, Git, Registry 등 애플리케이션 데이터
공통 운영·모니터링 에이전트 기존 로그, Agent ID, Kubernetes Join 정보
Template
├── Reusable Standard Configuration
└── No Machine-specific Identity

Clone VM
├── Unique Hostname
├── Unique IP
├── Unique SSH Host Key
├── Unique machine-id
└── Unique Service Configuration

처음에는 OS별 Base Template부터 시작하는 것이 좋습니다.

Minimum Template Set
├── rocky-9-base
├── ubuntu-24-base
└── debian-12-base

Kubernetes, CI Runner, 보안 강화 템플릿은 반복 요구가 확인된 뒤 추가합니다.

기준 VM 만들기

템플릿은 ISO 설치 기반, Cloud Image 기반, 기존 검증 VM 기반, Packer 같은 이미지 빌드 도구로 만들 수 있습니다.

방식 장점 고려사항
ISO 설치 파티션·보안·패키지 정책을 직접 통제 초기 제작 시간이 필요
Cloud Image 빠른 배포, Cloud-Init 기본 지원 이미지·datasource 정책 검증 필요
기존 VM 이미 검증한 구성 재사용 고유 정보·서비스 데이터 제거 필요
Packer 재현성과 자동화에 유리 빌드 파이프라인 구축 필요

기본 템플릿 VM은 최소 사양으로 만듭니다.

Template VM Example
├── VM ID: 801
├── Name: rocky-9-base-v1
├── CPU: 2 vCPU
├── Memory: 2~4GB
├── Disk: 30~50GB
├── SCSI Controller: VirtIO SCSI single
├── Disk: SCSI + Discard + IO Thread
├── NIC: VirtIO
├── QEMU Guest Agent: Enabled
└── Cloud-Init Drive: Enabled

Clone 후 VM별 CPU, 메모리, 디스크는 필요에 맞게 조정합니다.

기준 VM에는 OS와 공통 운영 기준만 적용합니다.

Base Template
├── OS Update
├── qemu-guest-agent
├── cloud-init
├── chrony 또는 조직 NTP 설정
├── 내부 DNS·Repository·CA
├── 공통 보안 기준
└── 공통 모니터링·로그 에이전트

Service Configuration
├── GitLab / Harbor 설치
├── DB 데이터 초기화
├── Kubernetes Join
├── 애플리케이션 Secret
└── 서비스별 인증서 Private Key

서비스별 구성과 Secret은 Ansible, Vault, CI/CD, 별도 Secret 관리 체계에서 주입하는 것이 좋습니다.

Guest Agent와 Cloud-Init

템플릿에는 QEMU Guest Agent를 설치하고 Proxmox VM 옵션에서도 Agent를 활성화합니다.

Rocky Linux·AlmaLinux·RHEL 계열 예시입니다.

sudo dnf install -y qemu-guest-agent cloud-init
sudo systemctl enable --now qemu-guest-agent

Ubuntu·Debian 계열 예시입니다.

sudo apt update
sudo apt install -y qemu-guest-agent cloud-init
sudo systemctl enable --now qemu-guest-agent

Cloud-Init 패키지를 설치한 뒤에는 VM에 Cloud-Init Drive를 추가해야 합니다.

qm set 801 --agent enabled=1
qm set 801 --ide2 local-lvm:cloudinit
qm set 801 --boot order=scsi0

Cloud-Init Drive는 OS 부팅 디스크가 아니라 사용자·네트워크·메타데이터를 전달하는 설정 디스크입니다.

VM Hardware
├── scsi0: OS Disk
├── net0: VirtIO NIC
└── ide2: Cloud-Init Drive

Cloud-Init은 일반적으로 Clone VM의 첫 부팅 시 사용자, SSH Key, IP, Gateway, DNS, 호스트명을 적용합니다. 실제 적용 여부는 Guest OS의 Cloud-Init datasource와 hostname 정책을 템플릿별로 검증해야 합니다.

템플릿 일반화

템플릿으로 전환하기 전에는 VM 고유 정보를 제거해야 합니다.

Generalization
├── 서비스별 Hostname 제거
├── SSH Host Key 제거
├── machine-id 초기화
├── Cloud-Init 실행 상태 정리
├── Shell History 정리
├── 임시 파일·패키지 캐시 정리
└── Agent별 고유 ID 정리 또는 Clone 후 재등록 정책 적용

예시 명령입니다.

sudo cloud-init clean --logs --seed || true

sudo rm -f /etc/ssh/ssh_host_*
sudo truncate -s 0 /etc/machine-id
sudo rm -f /var/lib/dbus/machine-id

sudo rm -f /root/.bash_history
rm -f "${HOME}/.bash_history"

sudo rm -rf /tmp/*
sudo rm -rf /var/tmp/*

if command -v dnf >/dev/null 2>&1; then
  sudo dnf clean all
fi

if command -v apt >/dev/null 2>&1; then
  sudo apt clean
fi

sync

위 명령은 예시입니다. 배포판과 보안·모니터링 에이전트에 따라 일반화 절차가 달라질 수 있습니다.

특히 SSH Host Key를 제거한 뒤 Clone VM의 최초 부팅에서 고유 키가 생성되는지 반드시 확인해야 합니다. 자동 생성되지 않는 이미지라면 Cloud-Init 또는 최초 부팅 절차에서 ssh-keygen -A를 실행하도록 별도 구성합니다.

일반화가 끝나면 VM을 종료합니다.

sudo poweroff
qm status 801

템플릿 전환과 Clone

VM이 종료된 뒤 템플릿으로 변환합니다.

qm template 801

템플릿은 직접 실행하지 않고 Clone의 기준으로 사용합니다.

구분 Full Clone Linked Clone
디스크 독립적인 전체 복사본 Base Template + 변경분
템플릿 의존성 없음 있음
생성 속도 상대적으로 느림 빠름
저장 공간 더 많이 사용 더 적게 사용
적합한 용도 장기 운영·중요 VM 개발·테스트·단기 실습

Full Clone 예시입니다.

qm clone 801 401 \
  --name k8s-cp-prod-01 \
  --full 1 \
  --storage local-lvm

Linked Clone 예시입니다.

# Linked Clone 지원 스토리지에서만 사용
qm clone 801 701 \
  --name k8s-test-01 \
  --full 0

Linked Clone은 템플릿 Base Disk에 접근할 수 있어야 실행됩니다. 지원 여부는 스토리지 유형과 디스크 포맷에 따라 다르므로, 운영 표준으로 사용하기 전 Clone·백업·마이그레이션·복구 시나리오를 검증해야 합니다.

Cloud-Init으로 VM 초기화

Clone 후 첫 부팅 전에 사용자·SSH Key·네트워크를 설정합니다.

qm set 401 \
  --ciuser infraadmin \
  --sshkeys /root/.ssh/infraadmin.pub

qm set 401 \
  --ipconfig0 ip=10.10.30.101/24,gw=10.10.30.1 \
  --nameserver 10.10.10.53 \
  --searchdomain example.internal

qm set 401 \
  --cores 4 \
  --memory 8192 \
  --balloon 0 \
  --onboot 1

qm start 401

DHCP를 사용한다면 다음처럼 설정할 수 있습니다.

qm set 401 --ipconfig0 ip=dhcp

NIC가 여러 개인 VM은 인터페이스별로 ipconfig0, ipconfig1을 설정합니다. 특별한 라우팅 요구사항이 없다면 기본 게이트웨이는 하나의 인터페이스에만 지정합니다.

net0: Service Network
└── Default Gateway 설정

net1: Storage / Backup Network
└── Default Gateway 미설정

Cloud-Init은 일반적으로 첫 부팅 시 한 번 초기화를 수행합니다. 이미 실행된 운영 VM에서 cloud-init clean으로 재초기화하면 사용자·네트워크·파일 설정에 영향을 줄 수 있으므로 신중히 사용합니다.

Custom User Data와 Snippet

기본 Cloud-Init 설정만으로 부족하다면 Custom User Data를 사용할 수 있습니다.

#cloud-config

package_update: false
package_upgrade: false

packages:
  - curl
  - bash-completion
  - qemu-guest-agent

runcmd:
  - systemctl enable --now qemu-guest-agent

Snippet에 저장한 Custom User Data는 cicustom으로 연결합니다.

qm set 401 \
  --cicustom "user=local:snippets/user-data-base.yaml"

Cloud-Init 설정은 다음 명령으로 확인할 수 있습니다.

qm cloudinit dump 401 user
qm cloudinit dump 401 network

클러스터 환경에서는 snippet 파일이 VM이 이동할 수 있는 모든 노드에서 접근 가능해야 합니다. 그렇지 않으면 해당 VM이 시작하지 못할 수 있습니다.

Custom User Data에는 비밀번호, API Token, Private Key 같은 Secret을 넣지 않습니다. Secret은 Vault, CI/CD Secret, Ansible Vault, 조직의 Secret 관리 시스템 등으로 별도 관리합니다.

템플릿 검증

새 템플릿은 바로 운영에 사용하지 않고 Clone 테스트를 수행합니다.

Proxmox VE 확인

  • 템플릿이 정상적으로 변환되었는가
  • Cloud-Init Drive와 Guest Agent 옵션이 활성화되었는가
  • Full Clone 또는 Linked Clone이 의도대로 생성되는가
  • CPU, 메모리, 디스크, NIC 설정을 변경할 수 있는가
  • Cloud-Init user·network 설정이 정상적으로 생성되는가

Guest OS 확인

  • Clone VM이 정상 부팅되는가
  • Cloud-Init이 성공 상태인가
  • Hostname, IP, Gateway, DNS가 VM별로 올바른가
  • SSH Public Key로 로그인할 수 있는가
  • SSH Host Key와 machine-id가 VM마다 고유한가
  • QEMU Guest Agent가 실행 중인가
  • 내부 Repository, CA, NTP, 모니터링·로그 에이전트가 정상인가
  • 템플릿에 불필요한 계정, 로그, Token, Private Key가 남아 있지 않은가
cloud-init status --long
systemctl status qemu-guest-agent
hostnamectl
ip -br addr
cat /etc/machine-id

템플릿 버전 관리

템플릿은 수정해서 덮어쓰기보다 새 버전을 만드는 방식이 좋습니다.

rocky-9-base-v1
rocky-9-base-v2
rocky-9-k8s-v1
ubuntu-24-base-v1

권장 수명주기는 아래와 같습니다.

Build
→ Test
→ Approve
→ Publish
→ Use
→ Patch
→ New Version
→ Deprecate
→ Retire

템플릿 변경 이력에는 OS 패치 수준, Guest Agent·Cloud-Init 버전, CA 변경, Repository 변경, 보안 정책 변경, 검증 결과를 남깁니다.

핵심 정리

  • VM 템플릿은 반복 배포를 위한 기준 이미지이며, Golden Image는 조직 표준을 반영한 템플릿입니다.
  • 템플릿에는 OS·공통 패키지·보안 기준·Guest Agent·Cloud-Init·내부 Repository·CA를 넣고, Hostname·IP·Host Key·machine-id·Secret·데이터는 남기지 않습니다.
  • Cloud-Init은 Clone VM의 첫 부팅 시 사용자, SSH Key, IP, Gateway, DNS, 호스트명을 주입하는 도구입니다.
  • Cloud-Init 패키지 설치 외에도 Proxmox VM에 Cloud-Init Drive를 추가해야 합니다.
  • 템플릿 변환 전에는 Cloud-Init 상태, SSH Host Key, machine-id, 로그·히스토리·임시 파일을 정리합니다.
  • Full Clone은 독립성이 높아 장기 운영 VM에 적합하고, Linked Clone은 빠르고 공간 효율적이지만 Base Template 의존성을 관리해야 합니다.
  • Custom User Data와 Snippet은 강력하지만 Secret 저장소로 사용해서는 안 됩니다.
  • 템플릿은 새 버전으로 관리하고, Clone·Cloud-Init·Guest Agent·네트워크·보안 검증을 거친 뒤 운영에 배포합니다.

참고 자료




작성일: 2026년 9월 10일 ,  마지막 업데이트: 2026년 9월 10일