Kubernetes Tools/Kubevirt

[KubeVirt Ep.4] 🚀 VirtualMachine 리소스 실습 | 나만의 VM 만들기

ygtoken 2025. 3. 21. 13:25
728x90

이 글에서는 KubeVirt의 핵심인 VirtualMachine 리소스를 자세히 살펴보고, 기본 템플릿 없이 직접 VM을 생성하는 방법을 알아보겠습니다. VirtualMachine과 VirtualMachineInstance의 관계, 리소스 구조, 그리고 CLI 기반으로 VM을 배포하고 라이프사이클을 관리하는 방법을 실습해 보겠습니다.


📌 VirtualMachine과 VirtualMachineInstance 리소스 이해하기

KubeVirt에는 VM을 정의하고 관리하기 위한 두 가지 주요 리소스가 있습니다: VirtualMachine(VM)과 VirtualMachineInstance(VMI)입니다. 이 두 리소스의 역할과 관계를 명확히 이해하는 것이 중요합니다.

 

VirtualMachine vs VirtualMachineInstance

VirtualMachine(VM) 리소스는:

  • VM의 원하는 상태를 정의하는 선언적 리소스
  • VMI의 라이프사이클을 관리 (생성, 삭제, 재시작 등)
  • VM 설정이 유지되는 영구적 리소스
  • 쿠버네티스 Deployment와 유사한 역할

VirtualMachineInstance(VMI) 리소스는:

  • 실제 실행 중인 VM 인스턴스를 나타내는 리소스
  • 항상 실행 중인 상태만 표현 (Running 또는 생성 중/종료 중 상태)
  • VM이 중지되면 삭제됨
  • 쿠버네티스 Pod와 유사한 역할
# VirtualMachine과 VirtualMachineInstance의 관계
apiVersion: kubevirt.io/v1        # KubeVirt API 버전
kind: VirtualMachine              # 리소스 종류: VM 정의
metadata:
  name: example-vm                # VM 이름
spec:
  running: true                   # true면 VMI가 생성됨, false면 VMI가 삭제됨
  template:                       # VMI를 생성하기 위한 템플릿
    metadata:
      labels:
        kubevirt.io/vm: example-vm  # VMI에 적용될 레이블
    spec:                         # VMI 스펙 정의 시작
      # VM 하드웨어 및 설정... (이 부분은 VMI의 spec과 동일한 구조)
      # 이 부분은 실제 VM 인스턴스의 설정을 정의함

VM은 spec.template에 VMI의 정의를 포함하고 있으며, spec.running 필드를 통해 VMI의 생성 및 삭제를 제어합니다.

 

VM 라이프사이클 상태

VM은 다양한 상태를 가질 수 있으며, 이는 status.printableStatus 필드에서 확인할 수 있습니다:

  • Running: VM이 실행 중이며 VMI가 존재함
  • Stopped: VM이 중지되었으며 VMI가 존재하지 않음
  • Provisioning: VMI가 생성 중이지만 아직 완전히 실행되지 않음
  • Terminating: VMI가 종료 중인 상태
  • Migrating: VM이 한 노드에서 다른 노드로 마이그레이션되는 중
  • Unknown: VM 상태를 확인할 수 없음

▶️ VM과 VMI의 관계 이해: "쿠버네티스에서 Deployment가 Pod의 생명주기를 관리하는 것처럼, KubeVirt에서는 VirtualMachine이 VirtualMachineInstance의 생명주기를 관리합니다. VM을 중지해도 VM 리소스 자체는 계속 존재하므로, 설정이 유지되며 나중에 동일한 구성으로 다시 시작할 수 있습니다."


📌 VM 스펙 상세 분석

VirtualMachine 리소스의 구조를 자세히 살펴보겠습니다. VM 스펙은 하드웨어 리소스, 부팅 옵션, 디스크, 네트워크 등 다양한 설정을 포함합니다.

 

VM 스펙의 주요 구성 요소

apiVersion: kubevirt.io/v1                # KubeVirt API 버전
kind: VirtualMachine                      # 리소스 종류: VM 정의
metadata:
  name: example-vm                        # VM 이름
spec:
  running: true                           # VM 실행 여부: true면 시작, false면 중지
  runStrategy: Always                     # 실행 전략(Optional): 
                                          # - Always: 항상 실행 유지
                                          # - Manual: 수동 제어
                                          # - RerunOnFailure: 실패 시 재시작
                                          # - Halted: 항상 중지 상태 유지
  
  template:                               # VMI 템플릿 정의 시작
    metadata:
      labels:                             # VMI에 적용될 레이블
        kubevirt.io/vm: example-vm        # VM 식별 레이블
    spec:
      domain:                             # VM 도메인(하드웨어) 설정 시작
        cpu:
          cores: 2                        # CPU 코어 수
          sockets: 1                      # CPU 소켓 수 
          threads: 1                      # 코어당 스레드 수 (총 vCPU = cores*sockets*threads)
        
        memory:
          guest: 2Gi                      # VM에 할당할 메모리 크기
        
        devices:                          # 디바이스 정의 섹션
          disks:                          # 디스크 장치 설정
          - name: rootdisk                # 디스크 이름 (volumes 섹션과 매핑됨)
            disk:
              bus: virtio                 # 디스크 버스 유형: 성능 최적화된 virtio 사용
          - name: cloudinitdisk           # cloud-init 설정용 디스크
            disk:
              bus: virtio                 # 디스크 버스 유형
          
          interfaces:                     # 네트워크 인터페이스 설정
          - name: default                 # 인터페이스 이름 (networks 섹션과 매핑됨)
            masquerade: {}                # NAT 네트워킹 사용 (외부 통신 가능)
        
        # 선택적 설정
        features:                         # 하드웨어 기능 설정
          acpi: {}                        # ACPI 지원 활성화
        
        firmware:                         # 부팅 설정
          bootloader:
            efi: {}                       # UEFI 부팅 사용
        
        machine:
          type: q35                       # 머신 유형: 최신 PC 아키텍처 에뮬레이션
      
      networks:                           # VM 네트워크 정의
      - name: default                     # 인터페이스 이름과 일치해야 함
        pod: {}                           # Pod 네트워크 사용 (기본 쿠버네티스 네트워크)
      
      volumes:                            # VM 볼륨 정의
      - name: rootdisk                    # 디스크 이름과 일치해야 함
        persistentVolumeClaim:
          claimName: my-vm-rootdisk       # PVC 이름: 미리 생성된 PVC 사용
      - name: cloudinitdisk               # cloud-init 디스크 이름
        cloudInitNoCloud:                 # cloud-init 설정 유형
          userData: |                     # VM 초기화 스크립트
            #cloud-config
            password: password            # 기본 비밀번호 설정
            chpasswd: { expire: False }   # 비밀번호 만료 비활성화

 

도메인(domain) 섹션 상세 분석

spec.template.spec.domain 섹션은 VM의 하드웨어 스펙을 정의하는 부분으로, libvirt 도메인 XML과 유사한 구조를 가집니다:

  1. CPU 설정:
    • cores, sockets, threads: VM에 할당되는 CPU 리소스 구성
    • dedicatedCpuPlacement: CPU 핀닝 (전용 CPU 코어 할당)
    • model: CPU 모델 (host-model, host-passthrough 등)
  2. 메모리 설정:
    • guest: VM에 할당되는 메모리 양
    • hugepages: 대용량 페이지 사용 여부
  3. 디바이스 설정:
    • disks: VM의 디스크 장치 설정
    • interfaces: 네트워크 인터페이스 설정
    • inputs: 마우스, 키보드 등의 입력 장치
    • graphics: VNC, SPICE 등의 그래픽 디스플레이
    • gpu: GPU 장치 설정
  4. 기능(features) 설정:
    • acpi: ACPI 지원
    • apic: APIC 지원
    • hyperv: Hyper-V 기능 지원 (Windows VM용)
    • smm: 시스템 관리 모드 지원

볼륨(volumes)과 네트워크(networks) 섹션

volumes 섹션은 VM에 연결할 스토리지를 정의하며, 다양한 유형이 있습니다:

  • persistentVolumeClaim: 쿠버네티스 PVC 사용
  • containerDisk: 컨테이너 이미지에 포함된 디스크 이미지
  • cloudInitNoCloud: cloud-init 설정 데이터
  • dataVolume: CDI(Containerized Data Importer)를 통한 데이터 볼륨
  • emptyDisk: 임시 빈 디스크

networks 섹션은 VM 네트워크 연결을 정의합니다:

  • pod: 기본 Pod 네트워크 사용
  • multus: Multus CNI를 통한 다중 네트워크 인터페이스

▶️ VM 구성 팁: "VM 구성에서 devices.disks와 volumes의 이름이 일치해야 하며, 마찬가지로 devices.interfaces와 networks의 이름도 일치해야 합니다. 이는 장치와 해당 리소스를 연결하는 방식입니다."


📌 나만의 VM 직접 생성하기

이제 기본 템플릿 없이 VM을 직접 정의하고 생성해 보겠습니다. 알파인 리눅스 기반의 간단한 VM을 만들어 보겠습니다.

 

Alpine Linux VM 정의

먼저 alpine-vm.yaml 파일을 만들어 다음 내용을 작성합니다:

apiVersion: kubevirt.io/v1              # KubeVirt API 버전
kind: VirtualMachine                    # 리소스 종류
metadata:
  name: alpine-vm                       # VM 이름
  annotations:
    description: "Alpine Linux VM"      # VM 설명(메타데이터)
spec:
  running: true                         # 생성 즉시 VM 실행
  template:
    metadata:
      labels:
        kubevirt.io/vm: alpine-vm       # VM 식별 레이블
    spec:
      domain:                           # VM 하드웨어 정의 시작
        cpu:
          cores: 1                      # 1개의 CPU 코어 할당
        devices:
          disks:                        # 디스크 장치 정의
          - name: containerdisk         # 컨테이너 디스크(OS 이미지)
            disk:
              bus: virtio               # virtio 버스 사용(성능 최적화)
          - name: cloudinitdisk         # cloud-init 설정 디스크
            disk:
              bus: virtio
          interfaces:                   # 네트워크 인터페이스 정의
          - name: default
            masquerade: {}              # NAT 모드 네트워킹(외부 통신 가능)
          rng: {}                       # 난수 발생기 추가(부팅 속도 향상)
        resources:
          requests:
            memory: 256Mi               # 256MB 메모리 요청
      networks:                         # 네트워크 정의
      - name: default                   # 인터페이스 이름과 일치
        pod: {}                         # 기본 Pod 네트워크 사용
      volumes:                          # 볼륨 정의
      - name: containerdisk             # 컨테이너 디스크 정의
        containerDisk:
          image: quay.io/kubevirt/alpine-container-disk-demo:latest  # Alpine Linux 이미지
      - name: cloudinitdisk             # cloud-init 볼륨 정의
        cloudInitNoCloud:
          userData: |-                  # cloud-init 설정
            #cloud-config
            password: alpine            # 기본 비밀번호 설정
            chpasswd: { expire: False } # 비밀번호 만료 비활성화
            ssh_pwauth: True            # SSH 비밀번호 인증 허용

 

VM 배포 및 상태 확인

# VM 생성
$ kubectl apply -f alpine-vm.yaml
virtualmachine.kubevirt.io/alpine-vm created
# YAML 파일을 적용하여 VM 리소스 생성

# VM 상태 확인
$ kubectl get vm
NAME        AGE   STATUS    READY
alpine-vm   10s   Running   True
# VM이 Running 상태이고 Ready가 True인지 확인
# STATUS: VM의 현재 상태, READY: VM이 정상적으로 실행 중인지 여부

# 상세 정보 확인
$ kubectl describe vm alpine-vm
# VM 리소스의 상세 정보 확인
# 이벤트, 상태, 구성 등 모든 정보가 표시됨

주목할 만한 부분:

  • containerdisk: 컨테이너 이미지로 패키징된 Alpine Linux 디스크 이미지
  • cloudinitdisk: cloud-init 설정으로 기본 사용자 비밀번호 설정
  • masquerade: NAT 네트워킹 모드 (Pod 외부와 통신 가능)
  • rng: 난수 발생기 추가 (VM 부팅 시 필요한 엔트로피 제공)

VM 콘솔 접속

# VM 콘솔 접속
$ virtctl console alpine-vm
# virtctl 명령을 사용하여 VM의 직렬 콘솔에 접속
# 이 명령은 VM의 직렬 콘솔 출력을 표시하고 입력을 VM으로 전달함

# 로그인 (사용자: root, 비밀번호: alpine)
alpine-vm login: root
Password: alpine
# VM 내부에 로그인 (cloud-init에서 설정한 인증 정보 사용)

# 시스템 정보 확인
# hostname -f
alpine-vm
# VM의 호스트명 확인

# uname -a
Linux alpine-vm 5.15.0-generic #1 SMP Alpine 5.15 x86_64 Linux
# 커널 버전 및 시스템 정보 확인

# 네트워크 정보 확인
# ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP
    link/ether 52:54:00:XX:XX:XX brd ff:ff:ff:ff:ff:ff
    inet 10.X.X.X/24 brd 10.X.X.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::XX:XX:XX:XX/64 scope link
       valid_lft forever preferred_lft forever
# 네트워크 인터페이스 정보 확인
# eth0: Pod 네트워크로부터 IP 주소를 할당받은 인터페이스

# 종료
# exit

▶️ 기본 Alpine VM 특징: "Alpine Linux는 매우 가벼운 리눅스 배포판으로, 컨테이너 이미지 크기가 작고 부팅이 빠르기 때문에 테스트용 VM으로 적합합니다. 기본적인 패키지 관리는 apk 명령어를 사용합니다."


📌 다양한 VM 구성 예제

이제 다양한 사용 사례에 맞는 VM 구성 예제를 살펴보겠습니다.

 

Ubuntu VM 직접 생성하기

Ubuntu VM을 위한 ubuntu-vm.yaml 파일을 만들어 보겠습니다:

apiVersion: kubevirt.io/v1              # KubeVirt API 버전
kind: VirtualMachine                    # 리소스 종류
metadata:
  name: ubuntu-vm                       # VM 이름
  annotations:
    description: "Ubuntu Server VM"     # VM 설명
spec:
  running: true                         # 생성 즉시 실행
  template:
    metadata:
      labels:
        kubevirt.io/vm: ubuntu-vm       # VM 식별 레이블
    spec:
      domain:
        cpu:
          cores: 2                      # 2개 CPU 코어 할당(Ubuntu는 리소스가 더 필요함)
        devices:
          disks:
          - name: containerdisk
            disk:
              bus: virtio               # virtio 버스 사용(성능 최적화)
          - name: cloudinitdisk
            disk:
              bus: virtio
          interfaces:
          - name: default
            masquerade: {}              # NAT 모드 네트워킹
          rng: {}                       # 난수 발생기 추가(부팅 속도 향상)
        resources:
          requests:
            memory: 1Gi                 # 1GB 메모리 할당(Ubuntu는 더 많은 메모리 필요)
      networks:
      - name: default
        pod: {}                         # 기본 Pod 네트워크 사용
      volumes:
      - name: containerdisk
        containerDisk:
          image: quay.io/kubevirt/ubuntu-container-disk-demo:22.04  # Ubuntu 22.04 이미지
      - name: cloudinitdisk
        cloudInitNoCloud:
          userData: |-                  # cloud-init 설정
            #cloud-config
            hostname: ubuntu-vm         # 호스트명 설정
            user: ubuntu                # 사용자 이름
            password: ubuntu            # 사용자 비밀번호
            chpasswd: { expire: False } # 비밀번호 만료 비활성화
            ssh_pwauth: True            # SSH 비밀번호 인증 허용
            package_update: true        # 패키지 저장소 업데이트
            packages:                   # 자동 설치할 패키지 목록
              - qemu-guest-agent        # VM 모니터링 및 관리를 위한 에이전트
            runcmd:                     # 초기 실행 명령어
              - systemctl enable qemu-guest-agent  # 에이전트 활성화
              - systemctl start qemu-guest-agent   # 에이전트 시작

이 Ubuntu VM은:

  • 2개의 CPU 코어와 1GB 메모리 할당 (Alpine보다 많은 리소스)
  • cloud-init을 통한 사용자 및 패키지 설정
  • QEMU 게스트 에이전트 설치 및 활성화 (VM 모니터링 및 관리 개선)

개인화된 VM 구성: 스토리지와 SSH 키

지속적인 데이터 스토리지와 SSH 키 인증을 사용하는 VM 예제입니다:

apiVersion: kubevirt.io/v1              # KubeVirt API 버전
kind: VirtualMachine                    # 리소스 종류
metadata:
  name: personal-vm                     # VM 이름
spec:
  running: true                         # 생성 즉시 실행
  template:
    metadata:
      labels:
        kubevirt.io/vm: personal-vm     # VM 식별 레이블
    spec:
      domain:
        cpu:
          cores: 2                      # CPU 코어 수
          sockets: 1                    # CPU 소켓 수
          threads: 1                    # 코어당 스레드 수
        memory:
          guest: 2Gi                    # 2GB 메모리 할당
        devices:
          disks:
          - name: rootdisk              # 루트 디스크(OS)
            disk:
              bus: virtio               # virtio 버스 사용
          - name: datadisk              # 데이터 저장용 추가 디스크
            disk:
              bus: virtio
          - name: cloudinitdisk         # cloud-init 설정 디스크
            disk:
              bus: virtio
          interfaces:
          - name: default
            masquerade: {}              # NAT 모드 네트워킹
      networks:
      - name: default
        pod: {}                         # 기본 Pod 네트워크 사용
      volumes:
      - name: rootdisk                  # 루트 디스크 볼륨 정의
        containerDisk:
          image: quay.io/kubevirt/fedora-container-disk-demo:latest  # Fedora 이미지
      - name: datadisk                  # 데이터 디스크 볼륨 정의
        persistentVolumeClaim:
          claimName: personal-vm-data   # 미리 생성된 PVC 사용
                                        # 이 PVC는 VM이 삭제되어도 유지됨
      - name: cloudinitdisk             # cloud-init 볼륨 정의
        cloudInitNoCloud:
          userData: |-                  # cloud-init 설정
            #cloud-config
            hostname: personal-vm       # 호스트명 설정
            ssh_authorized_keys:        # SSH 공개 키 추가(비밀번호 대신 키 인증)
              - ssh-rsa AAAAB3NzaC1y...YOUR_SSH_PUBLIC_KEY
            runcmd:                     # 초기 실행 명령어
              - mkdir -p /mnt/data      # 데이터 디스크 마운트 포인트 생성
              - echo '/dev/vdb /mnt/data ext4 defaults 0 0' >> /etc/fstab  # 자동 마운트 설정
              - mount -a                # 모든 디스크 마운트

이 VM 구성은:

  • SSH 키 인증을 통한 보안 강화 (비밀번호 대신 키 사용)
  • PVC를 사용한 영구 데이터 디스크 연결 (VM 재시작/삭제 후에도 데이터 유지)
  • cloud-init을 통한 디스크 마운트 자동화 (VM 부팅 시 자동 설정)

고급 VM 설정: 부팅 옵션 및 하드웨어 기능

특수 부팅 옵션과 하드웨어 기능을 사용하는 고급 VM 예제입니다:

apiVersion: kubevirt.io/v1              # KubeVirt API 버전
kind: VirtualMachine                    # 리소스 종류
metadata:
  name: advanced-vm                     # VM 이름
spec:
  running: true                         # 생성 즉시 실행
  template:
    metadata:
      labels:
        kubevirt.io/vm: advanced-vm     # VM 식별 레이블
    spec:
      domain:
        cpu:
          cores: 4                      # 4개 CPU 코어 할당
          model: host-passthrough       # 호스트 CPU 모델 그대로 사용
                                        # 호스트 CPU 기능을 VM에 직접 전달(최상의 성능)
          dedicatedCpuPlacement: true   # CPU 핀닝 활성화
                                        # VM의 vCPU를 특정 물리 CPU에 고정하여 성능 향상
        memory:
          guest: 4Gi                    # 4GB 메모리 할당
        features:                       # 하드웨어 기능 설정
          acpi: {}                      # ACPI 지원 활성화(전원 관리)
          apic: {}                      # APIC 지원 활성화(인터럽트 제어)
          smm:
            enabled: true               # 시스템 관리 모드 활성화
        firmware:                       # 펌웨어/부팅 설정
          bootloader:                   # 부트로더 설정
            efi:                        # UEFI 부팅 사용
              secure: true              # 보안 부팅 활성화(부팅 이미지 검증)
        machine:
          type: q35                     # 머신 타입: 최신 QEMU PC 모델
                                        # 향상된 I/O 및 현대적 디바이스 지원
        devices:
          disks:
          - name: rootdisk
            disk:
              bus: virtio               # virtio 버스 사용
          - name: cloudinitdisk
            disk:
              bus: virtio
          interfaces:
          - name: default
            masquerade: {}              # NAT 모드 네트워킹
      volumes:
      - name: rootdisk
        containerDisk:
          image: quay.io/kubevirt/fedora-container-disk-demo:latest  # Fedora 이미지
      - name: cloudinitdisk
        cloudInitNoCloud:
          userData: |-                  # cloud-init 설정
            #cloud-config
            hostname: advanced-vm       # 호스트명 설정

이 VM은:

  • 호스트 CPU 모델 직접 사용 (최대 성능, 호스트의 모든 CPU 기능 활용)
  • 전용 CPU 코어 할당 (CPU 핀닝, 다른 워크로드와 CPU 공유 없음)
  • EFI 펌웨어 및 보안 부팅 지원 (UEFI 기반 보안 부팅)
  • Q35 머신 타입 사용 (최신 QEMU 머신 모델, PCIe 지원)

▶️ VM 구성 선택 팁: "VM 구성은 워크로드 요구사항에 맞게 조정해야 합니다. 개발/테스트 환경에서는 가벼운 VM과 ContainerDisk가 적합하며, 프로덕션 환경에서는 영구 스토리지와 적절한 리소스 할당이 중요합니다."


📌 VM 라이프사이클 관리

VM의 라이프사이클을 virtctl 명령어와 YAML 수정을 통해 관리하는 방법을 알아보겠습니다.

 

virtctl을 이용한 VM 제어

virtctl CLI 도구를 사용하면 다양한 VM 작업을 쉽게 수행할 수 있습니다:

# VM 시작
$ virtctl start alpine-vm
VM alpine-vm was scheduled to start
# VM을 시작하는 명령어
# VM이 중지 상태에서 실행 상태로 전환됨

# VM 중지
$ virtctl stop alpine-vm
VM alpine-vm was scheduled to stop
# VM을 중지하는 명령어
# VM이 실행 상태에서 중지 상태로 전환됨
# VM 구성은 유지되지만 VMI는 삭제됨

# VM 재시작
$ virtctl restart alpine-vm
VM alpine-vm was scheduled to restart
# VM을 재시작하는 명령어
# 실행 중인 VMI를 삭제하고 새 VMI를 생성함

# VM 일시 중지
$ virtctl pause alpine-vm
VM alpine-vm was scheduled to pause
# VM을 일시 중지하는 명령어
# VM 실행은 유지되지만 CPU 실행이 일시 정지됨

# VM 재개
$ virtctl unpause alpine-vm
VM alpine-vm was scheduled to unpause
# 일시 중지된 VM을 다시 실행하는 명령어

# VM 콘솔 접속
$ virtctl console alpine-vm
# VM의 직렬 콘솔에 접속하는 명령어
# 부팅 메시지 및 텍스트 콘솔 접근 가능

# VNC 콘솔 접속
$ virtctl vnc alpine-vm
# VM의 그래픽 콘솔(VNC)에 접속하는 명령어
# GUI 환경이 있는 VM에 유용

# 포트 포워딩 설정
$ virtctl port-forward alpine-vm 22:22
# VM의 특정 포트를 로컬 포트로 포워딩하는 명령어
# 예: VM의 22번 포트(SSH)를 로컬 22번 포트로 연결

 

YAML 수정을 통한 VM 제어

VM의 실행 상태는 YAML의 spec.running 필드를 수정하여 제어할 수도 있습니다:

# VM 시작 (running: true로 설정)
$ kubectl patch vm alpine-vm --type merge -p '{"spec":{"running":true}}'
virtualmachine.kubevirt.io/alpine-vm patched
# VM의 running 상태를 true로 변경하는 명령어
# 패치(patch) 방식으로 특정 필드만 수정

# VM 중지 (running: false로 설정)
$ kubectl patch vm alpine-vm --type merge -p '{"spec":{"running":false}}'
virtualmachine.kubevirt.io/alpine-vm patched
# VM의 running 상태를 false로 변경하는 명령어
# VM이 중지되고 VMI가 삭제됨

 

runStrategy 설정을 통한 고급 VM 라이프사이클 관리

VM의 라이프사이클을 더 세밀하게 제어하려면 runStrategy 필드를 사용할 수 있습니다:

spec:
  runStrategy: Always     # VM이 항상 실행 상태 유지
                         # 노드 장애나 시스템 재시작 후에도 자동으로 재시작
  # 또는
  runStrategy: RerunOnFailure  # 오류 발생 시 자동 재시작
                              # 정상 종료 시에는 재시작하지 않음
  # 또는
  runStrategy: Manual     # 수동 시작/중지만 허용
                         # virtctl이나 API 호출로만 제어 가능
  # 또는
  runStrategy: Halted     # VM이 항상 중지 상태 유지
                         # VM을 정의만 하고 실행하지 않을 때 사용

 

이 설정을 적용하려면:

# runStrategy 설정 변경
$ kubectl patch vm alpine-vm --type merge -p '{"spec":{"runStrategy":"RerunOnFailure"}}'
# VM의 재시작 정책을 변경하는 명령어
# 'RerunOnFailure'로 설정하면 비정상 종료 시 자동으로 재시작됨

▶️ VM 관리 베스트 프랙티스: "프로덕션 환경에서는 runStrategy: RerunOnFailure를 사용하여 VM이 비정상 종료 시 자동으로 재시작되도록 하는 것이 좋습니다. 또한 리소스 관리를 위해 중요하지 않은 VM은 사용하지 않을 때 중지(virtctl stop)하는 습관을 들이는 것이 좋습니다."

 

VM 삭제 및 정리

실습이 끝난 후 VM 리소스를 정리하는 방법입니다:

# VM 삭제
$ kubectl delete vm alpine-vm
virtualmachine.kubevirt.io "alpine-vm" deleted
# VM 리소스를 완전히 삭제하는 명령어
# VM 구성 및 관련 VMI가 모두 삭제됨
# 주의: PVC 등의 영구 볼륨은 별도로 삭제해야 함

# 모든 VM 삭제
$ kubectl delete vm --all
# 현재 네임스페이스의 모든 VM 삭제
# 대규모 정리 작업 시 유용

📌 VM에 메타데이터 및 태그 추가

VM에 메타데이터와 태그를 추가하여 관리 및 구성을 더 효율적으로 할 수 있습니다.

 

레이블과 어노테이션 추가

apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
  name: labeled-vm                   # VM 이름
  labels:                            # 레이블 정의(검색 및 필터링에 사용)
    environment: development         # 환경 구분 레이블
    app: webserver                   # 애플리케이션 유형 레이블
    team: devops                     # 담당 팀 레이블
  annotations:                       # 어노테이션 정의(비검색용 메타데이터)
    description: "Web server VM for development"  # VM 설명
    owner: "john.doe@example.com"    # 소유자 정보
    version: "1.0.0"                 # 버전 정보
spec:
  # VM 스펙...

 

이런 방식으로 레이블을 추가하면 쿠버네티스의 레이블 셀렉터를 사용하여 VM을 필터링하고 그룹화할 수 있습니다:

# 개발 환경의 VM만 조회
$ kubectl get vm -l environment=development
# 레이블 셀렉터를 사용한 VM 필터링
# environment=development 레이블이 있는 VM만 표시

# 웹 서버 VM만 조회
$ kubectl get vm -l app=webserver
# app=webserver 레이블이 있는 VM만 표시

# 여러 조건 조합
$ kubectl get vm -l 'environment=development,app=webserver'
# 여러 레이블 조건을 조합한 필터링
# 개발 환경의 웹 서버 VM만 표시

 

태그 기반 VM 관리

VM에 설정된 레이블과 어노테이션은 다양한 관리 작업에 활용할 수 있습니다:

# 개발 환경의 모든 VM 중지
$ kubectl get vm -l environment=development -o name | xargs -I {} virtctl stop {}
# 1. 개발 환경 VM 목록 조회
# 2. 이름만 추출(-o name)
# 3. 각 VM에 대해 virtctl stop 명령 실행

# 특정 팀의 VM에 리소스 제한 적용
$ kubectl get vm -l team=devops -o name | xargs -I {} kubectl patch {} --type merge -p '{"spec":{"template":{"spec":{"domain":{"resources":{"requests":{"memory":"1Gi"}}}}}}}}'
# 1. devops 팀 VM 목록 조회
# 2. 이름만 추출
# 3. 각 VM에 메모리 요청을 1Gi로 패치

▶️ 메타데이터 관리 팁: "VM에 환경(dev/staging/prod), 역할(web/db/cache), 소유자, 비용 센터 등의 메타데이터를 일관되게 추가하면 클라우드 네이티브 방식으로 VM을 관리할 수 있습니다. 이는 특히 많은 수의 VM을 관리할 때 유용합니다."


📌 VM 모니터링 및 디버깅

VM의 상태를 모니터링하고 문제를 진단하는 방법을 알아보겠습니다.

 

VM 상태 및 이벤트 확인

VM에 문제가 생겼을 때 첫 번째로 확인해야 할 것은 VM의 상태와 관련 이벤트입니다:

# VM 상태 자세히 확인
$ kubectl get vm alpine-vm -o yaml
# VM 리소스의 전체 YAML 출력
# 모든 설정 및 상태 정보 확인 가능

# VM 상태 요약 확인
$ kubectl get vm alpine-vm -o jsonpath='{.status.printableStatus}'
Running
# jsonpath를 사용하여 특정 필드만 추출
# printableStatus 필드는 VM의 현재 상태를 간결하게 표시

# VM 관련 이벤트 확인
$ kubectl get events | grep alpine-vm
# 쿠버네티스 이벤트 중 VM 이름이 포함된 이벤트만 필터링
# VM 생성, 시작, 오류 등의 이벤트 확인 가능

 

VM 로그 확인

VM을 실행하는 virt-launcher Pod의 로그를 확인하여 문제를 진단할 수 있습니다:

# VM의 virt-launcher Pod 찾기
$ kubectl get pods | grep virt-launcher-alpine-vm
virt-launcher-alpine-vm-abc123   1/1     Running   0          10m
# VM을 실행하는 virt-launcher Pod 조회

# Pod 로그 확인
$ kubectl logs virt-launcher-alpine-vm-abc123
# Pod의 기본 컨테이너 로그 확인
# VM 시작 및 실행 과정의 로그 메시지 확인

# 특정 컨테이너 로그 확인
$ kubectl logs virt-launcher-alpine-vm-abc123 -c compute
# 'compute' 컨테이너의 로그만 확인
# VM 실행과 관련된 세부 로그 확인

 

VM 콘솔 로그 확인

VM의 직렬 콘솔 로그를 확인하면 부팅 과정이나 VM 내부의 문제를 진단하는 데 도움이 됩니다:

# 직렬 콘솔 로그 확인
$ virtctl console alpine-vm
# VM의 직렬 콘솔에 접속
# 부팅 메시지 및 커널 로그 확인 가능

# 이미 실행 중인 VM의 로그 확인
$ virtctl console alpine-vm --follow
# --follow 옵션을 사용하여 실시간 로그 스트림 확인
# 부팅 과정이나 시스템 로그를 실시간으로 모니터링

▶️ 문제 해결 팁: "VM이 시작되지 않거나 예상대로 작동하지 않을 경우, 먼저 VM 이벤트와 virt-launcher Pod 로그를 확인하세요. 가장 흔한 문제로는 리소스 부족, 볼륨 마운트 오류, 네트워크 구성 오류 등이 있습니다."


📌 Summary

이 글에서는 KubeVirt의 핵심인 VirtualMachine 리소스에 대해 알아보고, 직접 VM을 생성하고 관리하는 방법을 실습해보았습니다. 주요 내용을 요약하면:

  • VirtualMachine(VM)과 VirtualMachineInstance(VMI)는 각각 쿠버네티스의 Deployment와 Pod와 유사한 관계를 가집니다.
  • VM 스펙은 CPU, 메모리, 디스크, 네트워크 등 다양한 하드웨어 구성을 정의합니다.
  • ContainerDisk, PersistentVolumeClaim, DataVolume 등 다양한 스토리지 옵션을 활용할 수 있습니다.
  • virtctl을 통해 VM의 시작, 중지, 재시작, 콘솔 접속 등 다양한 작업을 수행할 수 있습니다.
  • 레이블과 어노테이션을 활용하여 VM을 효과적으로 관리하고 그룹화할 수 있습니다.
  • VM 모니터링 및 디버깅을 위해 이벤트, 로그, 콘솔 출력 등 다양한 도구를 활용할 수 있습니다
728x90