Kubernetes 이야기

KubeVirt로 kubernetes에 Windows VM 생성 본문

Kubernetes/일반

KubeVirt로 kubernetes에 Windows VM 생성

kmaster 2022. 6. 10. 21:00
반응형

 

KubeVirt 는 Kubernetes용 가상 머신 관리 추가 기능이다. KubeVirt의 목표는 Kubernetes 위에 가상화 솔루션을 위한 공통 기반을 제공하는 것이다.

현재까지도 가상 머신이 필요한 작업이 많이 있다. KubeVirt 기술은 Kubernetes 를 채택했거나 채택하기를 원하지만 쉽게 컨테이너화할 수 없는 기존 가상 머신 기반 워크로드를 보유하고 있는 개발 팀의 요구 사항을 해결할 수 있다.

 

이번에는 Kind 클러스터에서 Windows VM을 만들고 실행하는 방법에 대해 알아보자.

 

Kind 클러스터 구성방법은 아래를 참고한다.

 

 

로컬 Kubernetes 클러스터 - kind 설치

Kind Kind 는 Docker Container를 노드로 사용하여 로컬 Kubernetes 클러스터를 실행하기 위한 도구이다. 주로 Kubernetes 자체를 테스트하기 위해 설계되었지만 로컬 개발 또는 CI에 사용될 수 있다. kind의 기.

kmaster.tistory.com

 

KubeVirt 설치

1) KubeVirt 설치

 

KubeVirt는 모든 KubeVirt 핵심 구성 요소의 수명 주기를 관리하는 KubeVirt 연산자를 사용하여 설치할 수 있다.

# export VERSION=$(curl -s https://api.github.com/repos/kubevirt/kubevirt/releases | grep tag_name | grep -v -- '-rc' | sort -r | head -1 | awk -F': ' '{print $2}' | sed 's/,//' | xargs)
# echo $VERSION
# kubectl create -f https://github.com/kubevirt/kubevirt/releases/download/${VERSION}/kubevirt-operator.yaml

이제 KubeVirt에서 사용자 지정 리소스 (CRD)를 설치하자.

# kubectl create -f https://github.com/kubevirt/kubevirt/releases/download/${VERSION}/kubevirt-cr.yaml

 

kube-virt namespace에 설치된 내역은 아래와 같다. 기본적으로 KubeVirt는 7개의 포드, 3개의 서비스, 1개의 데몬셋, 3개의 배포 앱, 3개의 레플리카 세트를 배포된다.

# k get all -n kubevirt
NAME                                   READY   STATUS    RESTARTS   AGE
pod/virt-api-75b9cc686d-4zfh4          1/1     Running   0          8m59s
pod/virt-api-75b9cc686d-lcps2          1/1     Running   0          8m59s
pod/virt-controller-6bfb5db587-chr8s   1/1     Running   0          8m24s
pod/virt-controller-6bfb5db587-j5wfl   1/1     Running   0          8m24s
pod/virt-handler-h2bkq                 1/1     Running   0          8m24s
pod/virt-operator-5c8d67c764-5jcqc     1/1     Running   0          57m
pod/virt-operator-5c8d67c764-l4d8q     1/1     Running   0          57m

NAME                                  TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
service/kubevirt-operator-webhook     ClusterIP   10.96.140.117   <none>        443/TCP   9m1s
service/kubevirt-prometheus-metrics   ClusterIP   10.96.0.11      <none>        443/TCP   9m1s
service/virt-api                      ClusterIP   10.96.173.41    <none>        443/TCP   9m1s

NAME                          DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR            AGE
daemonset.apps/virt-handler   1         1         1       1            1           kubernetes.io/os=linux   8m24s

NAME                              READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/virt-api          2/2     2            2           8m59s
deployment.apps/virt-controller   2/2     2            2           8m24s
deployment.apps/virt-operator     2/2     2            2           57m

NAME                                         DESIRED   CURRENT   READY   AGE
replicaset.apps/virt-api-75b9cc686d          2         2         2       8m59s
replicaset.apps/virt-controller-6bfb5db587   2         2         2       8m24s
replicaset.apps/virt-operator-5c8d67c764     2         2         2       57m

NAME                            AGE     PHASE
kubevirt.kubevirt.io/kubevirt   9m18s   Deployed

 

2) virtctl cli 설치 및 "kubectl krew" 와 "kubectl virt" Plugin 설치

 

2-1) virtctl 설치

VERSION=$(kubectl get kubevirt.kubevirt.io/kubevirt -n kubevirt -o=jsonpath="{.status.observedKubeVirtVersion}")
ARCH=$(uname -s | tr A-Z a-z)-$(uname -m | sed 's/x86_64/amd64/') || windows-amd64.exe
echo ${ARCH}
curl -L -o virtctl https://github.com/kubevirt/kubevirt/releases/download/${VERSION}/virtctl-${VERSION}-${ARCH}
chmod +x virtctl
sudo install virtctl /usr/local/bin

 

2-2) kubectl krew와 kubectl cirt plugin설치

# (
  set -x; cd "$(mktemp -d)" &&
  OS="$(uname | tr '[:upper:]' '[:lower:]')" &&
  ARCH="$(uname -m | sed -e 's/x86_64/amd64/' -e 's/\(arm\)\(64\)\?.*/\1\2/' -e 's/aarch64$/arm64/')" &&
  KREW="krew-${OS}_${ARCH}" &&
  curl -fsSLO "https://github.com/kubernetes-sigs/krew/releases/latest/download/${KREW}.tar.gz" &&
  tar zxvf "${KREW}.tar.gz" &&
  ./"${KREW}" install krew
)

# export PATH="${KREW_ROOT:-$HOME/.krew}/bin:$PATH"

# kubectl krew install virt

 

3) Experiment with the Containerized Data Importer (CDI) 설치

 

CDI는 Kubevirt와 함께 사용할 가상 머신 이미지를 가져오도록 설계된 유틸리티이다.

# kubectl create -f https://github.com/kubevirt/containerized-data-importer/releases/download/v1.50.0/cdi-operator.yaml
# kubectl create -f https://github.com/kubevirt/containerized-data-importer/releases/download/v1.50.0/cdi-cr.yaml

 

설치된 내역은 아래와 같다.

# k get cdi cdi -n cdi
NAME   AGE   PHASE
cdi    61s   Deploying

# k get pods -n cdi
NAME                               READY   STATUS    RESTARTS   AGE
cdi-apiserver-c6cdc9489-ts879      1/1     Running   0          80s
cdi-deployment-7d587548cd-bn7lq    1/1     Running   0          74s
cdi-operator-997bdf879-xzjzd       1/1     Running   0          107s
cdi-uploadproxy-6c64d5cd59-c5m9f   1/1     Running   0          69s

 

4) Windows ISO 파일 다운받기

 

KubeVirt로 설치할 windows ISO 파일을 다운로드 받자. 아래 ms사의 홈페이지로 이동하면 ISO파일을 다운로드 받을 수 있다.

https://www.microsoft.com/en-us/evalcenter/download-windows-server-2016

 

다운로드 링크를 복사한 다음 wget으로 파일을 다운로드 받는다.

# wget -O win2016.iso 'https://go.microsoft.com/fwlink/p/?LinkID=2195174&clcid=0x409&culture=en-us&country=US'

 

5) PVC에 Windows ISO Image 업로드

 

# virtctl image-upload \
   --image-path=/root/download/win2016.iso \
   --pvc-name=iso-win2016 \
   --access-mode=ReadWriteOnce \
   --pvc-size=7G \
   --uploadproxy-url=https://uploadproxy.10.10.100.10.nip.io:443 \
   --insecure \
   --wait-secs=240
PVC default/iso-win2016 not found
PersistentVolumeClaim default/iso-win2016 created
Waiting for PVC iso-win2016 upload pod to be ready...
Pod now ready
Uploading data to https://uploadproxy.10.10.100.10.nip.io:443

 6.49 GiB / 6.49 GiB [==============================================================================================================] 100.00% 3m35s

Uploading data completed successfully, waiting for processing to complete, you can hit ctrl-c without interrupting the progress
Processing completed successfully
Uploading /root/download/win2016.iso completed successfully

uploadproxy-url은 아래의 ingress를 추가설정한다.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: uploadproxy-ingress
  namespace: cdi
  annotations:
    cert-manager.io/cluster-issuer: selfsigned-cluster-issuer
    nginx.ingress.kubernetes.io/proxy-body-size: "0"
    nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
spec:
  rules:
  - host: "uploadproxy.10.10.100.10.nip.io"
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: cdi-uploadproxy
            port:
              number: 443
  tls:
  - hosts:
    - uploadproxy.10.10.100.10.nip.io
    secretName: uploadproxy-cert

 

6) virtio 컨테이너 이미지를 로컬로 가져오기

 

# docker pull kubevirt/virtio-container-disk
Using default tag: latest
latest: Pulling from kubevirt/virtio-container-disk
da795872aad4: Pull complete
Digest: sha256:373fae39339fb0b77a101c825b66b5ceadd79397119e46d0c540df26f74fc06a
Status: Downloaded newer image for kubevirt/virtio-container-disk:latest
docker.io/kubevirt/virtio-container-disk:latest

 

7) PVC 및 가상 머신 정의 생성하기

 

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: winhd
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 7Gi
  storageClassName: standard
---
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
  name: iso-win2016
spec:
  running: false
  template:
    metadata:
      labels:
        kubevirt.io/domain: iso-win2016
    spec:
      domain:
        cpu:
          cores: 4
        devices:
          disks:
          - bootOrder: 1
            cdrom:
              bus: sata
            name: cdromiso
          - disk:
              bus: virtio
            name: harddrive
          - cdrom:
              bus: sata
            name: virtiocontainerdisk
        machine:
          type: q35
        resources:
          requests:
            memory: 8G
      volumes:
      - name: cdromiso
        persistentVolumeClaim:
          claimName: iso-win2016
      - name: harddrive
        persistentVolumeClaim:
          claimName: winhd
      - containerDisk:
          image: kubevirt/virtio-container-disk
        name: virtiocontainerdisk

 

# kubectl create -f win2016.yml

 

8) 가상 머신 인스턴스 시작하기

 

# virtctl start iso-win2016

# kubectl get vm,vmi
NAME                                   AGE   STATUS    READY
virtualmachine.kubevirt.io/iso-win2016   33m   Running   True

NAME                                           AGE   PHASE     IP            NODENAME             READY
virtualmachineinstance.kubevirt.io/iso-win2016   26s   Running   10.244.0.39   kind-control-plane   True

 

KVM 지원이 안되는 환경인 경우 아래의 오류가 발생한다.
FailedScheduling 22s default-scheduler 0/1 nodes are available: 1 Insufficient devices.kubevirt.ioo preemption victims found for incoming pod

이런 경우 아래의 내용을 수정한 후 .
# kubectl edit kubevirts.kubevirt.io -n kubevirt kubevirt
...
configuration:
    developerConfiguration:
        useEmulation: true

 

이제 생성한 windows에 접근해보자. vnc모드로 접근하기 위해서 아래와 같이 proxy mode로 실행한다.

# virtctl vnc iso-win2016 --proxy-only --address=0.0.0.0 --port 30050

 

이제 PC의 VNC Viewer에서 <서버주소>:30050으로 접속해보자. 

 

 

 

VNC없이 웹에서 브라우저를 통해 조회할 수 있는 방법도 있다. 자세한 방법은 아래를 참고한다.

https://kubevirt.io/2019/Access-Virtual-Machines-graphic-console-using-noVNC.html

 

Access Virtual Machines' graphic console using noVNC | KubeVirt.io

Demonstrate how to access virtual machines' graphic console using noVNC.

kubevirt.io

 

반응형
Comments