仮想化通信

日本仮想化技術株式会社の公式エンジニアブログ

KubeVirt VMをKubernetes Serviceで公開する

先日の記事でKubernetes + KubeVirtの環境が作れました。

作っただけではちょっともったいない気がしたので、まずKubeVirt VM上でアプリケーションを導入したあと、そのアプリケーションをKubernetes Serviceを使って公開することを試してみます。公式ドキュメント「Virtual machines » Service objects」を参考にしました。

なお、KubernetesとKubeVirtの環境構築までの流れは前回の記事にまとめています。

tech.virtualtech.jp

VMの作成

Containerized Data Importerツールを使って、PVにOSイメージを書き込むところまでできているのが前提です。 以下のようなYAMLを作成してVMを作成します。前回も触れましたが、ssh_authorized_keysにアクセス用のSSH公開鍵を指定します。

[centos@ml110gen9 ~]$ cat testvm1_pvc.yml 
apiVersion: kubevirt.io/v1alpha3
kind: VirtualMachine
metadata:
  creationTimestamp: 2018-07-04T15:03:08Z
  generation: 1
  labels:
    kubevirt.io/os: linux
  name: vm1
spec:
  running: true
  template:
    metadata:
      creationTimestamp: null
      labels:
        kubevirt.io/domain: vm1
    spec:
      domain:
        cpu:
          cores: 2
        devices:
          disks:
          - disk:
              bus: virtio
            name: disk0
          - cdrom:
              bus: sata
              readonly: true
            name: cloudinitdisk
        machine:
          type: q35
        resources:
          requests:
            memory: 1024M
      volumes:
      - name: disk0
        persistentVolumeClaim:
          claimName: fedora
      - cloudInitNoCloud:
          userData: |
            #cloud-config
            hostname: vm1
            ssh_pwauth: True
            disable_root: false
            ssh_authorized_keys:
            - ssh-rsa your-ssh-pubkey
        name: cloudinitdisk

claimName: fedoraというところでPVを指定しています。fedoraというPVにFedora OSのイメージが書き込まれており、そのイメージを仮想マシンで使うイメージです。

YAMLを使って、VMを作成します。

[centos@ml110gen9 ~]$ kubectl create -f testvm1_pvc.yml 

しばらく待つと、KubeVirtによりVMが作成されます。Runningになって、IPアドレスが付与されたことを確認します。

[centos@ml110gen9 ~]$ kubectl get vmi
NAME   AGE   PHASE     IP               NODENAME
vm1    22m   Running   10.244.224.100   ml110gen9.maas

VMへのSSHアクセス

SSHでアクセスします。Fedoraイメージのデフォルトユーザーはfedoraです。

[centos@ml110gen9 ~]$ ssh fedora@10.244.224.100 
Last login: Wed Apr 14 08:12:22 2021 from 172.17.28.125

fedoraというユーザーにパスワードを設定すれば、virtctl console fedoraでコンソール接続も可能ですが、デフォルト状態ではできないので、SSH接続します。

VMでアプリを導入して公開してみる

VMの中でアプリケーションを用意してみましょう。今回はApache2をインストールしてみます。

[fedora@vm1 ~]$ sudo yum install httpd -y
[fedora@vm1 ~]$ sudo systemctl enable --now httpd

サービスがLISTENしていることを確認します。

[fedora@vm1 ~]$ ss -atu|grep http
tcp   LISTEN 0      511                      *:http                *:*  

デフォルトページだと識別しづらいので、サンプルページを作ってみます。

[fedora@vm1 ~]$ cat <<EOF | sudo tee /var/www/html/index.html
hello world on vm1
EOF

まずはVMの中でWebサーバーのコンテンツにアクセスしてみます。

[fedora@vm1 ~]$ curl http://localhost
hello world on vm1

終わったらVMからログアウトします。

[fedora@vm1 ~]$ exit

Kubernetes ServiceでVM上の Webサーバーを公開してみる

Kubernetes ServiceをYAML形式で記述します。今回はNodePortを使ってみます。

[centos@ml110gen9 ~]$ cat testvm1_svc.yml 
apiVersion: v1
kind: Service
metadata:
  name: vm-service
spec:
  externalTrafficPolicy: Cluster
  ports:
  - port: 27013
    protocol: TCP
    targetPort: 80
    name: http
  selector:
    kubevirt.io/domain: vm1
  type: NodePort

selectorでVM作成時と同じドメイン名を指定しています。今回はWebサーバーを公開するため、80ポートを公開して27013ポートからアクセスできるようにしています。その27013ポートに対してNodePortが割り当てられます。

サービスをKubernetesに登録します。

[centos@ml110gen9 ~]$ kubectl apply -f testvm1_svc.yml
service/vm-service created

サービスを確認します。

[centos@ml110gen9 ~]$ kubectl get svc
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)           AGE
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP           163m
vm-service   NodePort    10.105.17.248   <none>        27013:32664/TCP   4m33s

NodePortを使ってVM上のWebサーバーコンテンツにアクセスしてみます。

[centos@ml110gen9 ~]$ curl http://172.17.28.125:32664
hello world on vm1

うまくいきました。対象がVMでもKubernetesのコンテナの運用と同様、KubernetesのServiceを使って公開できることがわかりました。