おうちクラスタにCDIをデプロイしてUbuntuを動かす

前回の続きでContainerized Data Importer(以下、CDI)を導入してUbuntu仮想マシンを動かします。

khasegawa.hatenablog.com

マニフェストを用意する

マニフェストの取得コマンドは省きしますが、マニフェストをkustomization.yamlから参照するように定義しておきます。

---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: cdi
resources:
  - https://github.com/kubevirt/containerized-data-importer/releases/download/v1.57.0/cdi-operator.yaml
  - https://github.com/kubevirt/containerized-data-importer/releases/download/v1.57.0/cdi-cr.yaml

クラスタにデプロイする

前回同様にArgo CD Applicationを定義して、CDIをデプロイします。
マニフェストは以下のようになります。

---
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: cdi
  finalizers:
    - resources-finalizer.argocd.argoproj.io
spec:
  project: default
  sources:
    - path: manifests/cdi/base
      repoURL: https://github.com/corrupt952/home
  destination:
    server: "https://kubernetes.default.svc"
    namespace: cdi
  syncPolicy:
    syncOptions:
      - CreateNamespace=true
    automated:
      prune: true
      selfHeal: true

ボリュームの定義をする

PVCを定義する方法もありますが、今回はDataVolumeを定義してUbuntuのイメージをベースとしたデータボリュームを定義しておきます。
今回はUbuntu 22.04を使うので以下のような書き方にしました。
urlstorageClassNameは環境に合わせて変更してください。

---
apiVersion: cdi.kubevirt.io/v1beta1
kind: DataVolume
metadata:
  name: ubuntu-volume
spec:
  source:
    http:
      url: "https://cloud-images.ubuntu.com/jammy/20231027/jammy-server-cloudimg-amd64.img"
  pvc:
    storageClassName: nfs
    accessModes:
      - ReadWriteOnce
    resources:
      requests:
        storage: 8Gi

Argo CDでデプロイしても良いのですが、動作確認のためだけなのでkubectl applyを直接実行して反映します。
この方法でもPVCは作成されるので作成されたかどうかは、以下のコマンドで確認できます。

# DataVolumeの確認
kubectl get dv

# PersistentVolumeClaimの確認
kubectl get pvc

DataVolumeの方でSuccessedと出ていれば問題ありません。
PVCがPendingのままの場合は、storageClassNameクラスタ内で利用可能なStorageClass`になっているのかは確認しましょう。

仮想マシンを定義する

VirtualMachineを定義します。
DataVolumeであるubuntu-volumedisk0という名前でマウントして使います。
また今回はbeestrapというISUCON向けのBootstrappingレポの動作確認も行いたいので Serviceを定義してCockpitやNetdataのポートを解放しておきました。

---
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
  name: ubuntu
  labels:
    kubevirt.io/os: linux
spec:
  running: true
  template:
    metadata:
      labels:
        kubevirt.io/size: small
        kubevirt.io/domain: ubuntu
    spec:
      domain:
        cpu:
          cores: 2
        devices:
          disks:
            - name: disk0
              disk:
                bus: virtio
            - name: cloudinitdisk
              cdrom:
                bus: sata
                readonly: true
          interfaces:
            - name: default
              masquerade: {}
        machine:
          type: q35
        resources:
          requests:
            memory: 2048M
      networks:
        - name: default
          pod: {}
      volumes:
        - name: disk0
          persistentVolumeClaim:
            claimName: ubuntu-volume
        - name: cloudinitdisk
          cloudInitNoCloud:
            userData: |
              #cloud-config
              hostname: ubuntu
              ssh_pwauth: true
              password: ubuntu
              chpasswd:
                expire: false

---
apiVersion: v1
kind: Service
metadata:
  name: ubuntu
  labels:
    kubevirt.io/os: linux
spec:
  ports:
    - name: ssh
      port: 22
      targetPort: 22
    - name: cockpit
      port: 9090
      targetPort: 9090
    - name: netdata
      port: 19999
      targetPort: 19999
  selector:
    kubevirt.io/domain: ubuntu

こちらもDataVolumeと同様にkubectl applyで直接反映します。
1分ほど起動に時間がかかるかもしれませんが、起動できればsshで接続することもできます。

kubectl virt ssh --local-ssh ubuntu@ubuntu 

またVNCで接続したい場合はプロキシーとしてコマンドを実行するか、VNCクライアントを直接起動することもできます。
以下の例では、tigervncのクライアントがインストールされているWSL2の環境でクライアントを起動します。

kubectl virt vnc ubuntu

これで諸々の動作確認が終わりました。 Serviceで定義したポートに関しては仮想マシン内にCockpitなどをインストール後にport-forwardなどで動作確認すると接続できます。