HarvesterはRancher社が管理しているKubernetes上でHCIを構築するツールです
自宅で若干持て余している計算資源を使ってHarvesterをインストールし、Hyper-Converged Infrastructureをおうちに構築してみます
Hyper-Converged Infrastructure
通称HCI、これはサーバーの仮想化技術のひとつで、計算資源やネットワーキング、ストレージなどをソフトウェアベースで管理できるようにした製品のことを指すらしいです。
いろいろなアプライアンス製品があるそうですが、残念ながら自分はHCI製品に触れたことがないので細かい解説ができないため詳細はWiki先生を参照ください。 詰まるところ、HCI製品を利用すると簡易なオレオレAWS/GCPが作れるといったところでしょうか?
Harvester
冒頭に話をした通り、HarvesterはRancher社がメンテナンスしているHCI製品です。Kubernetesのエコシステムをフルに活用しながら、Rancher製品をうまく組み合わせてHCIを実現しています。
Harbesterが利用しているツールとしては
- 計算資源管理: KubeVirt
- ネットワーク管理: Multus CNI, VLAN Plugin
- ストレージ管理: Longhorn
が挙げられます。
Harvesterを使ってみる
実際にHarvesterをインストールして仮想マシンを作成してみます。今回の検証環境は下記の通りです。
- 物理サーバー
- 第6世代 Intel NUC NUC6i5SYH
- Harvester
- 0.2.0
ISOインストール
Harvesterはインストール方法にISOによるフルインストール(直接インストールとPXEインストールが選択可能)と既存のKubernetesにインストールするRun as Appの2種類があります。今回はまず動かしてみるということでISOを直接物理サーバーにインストールしていきます。
ISOダウンロード〜インストール完了
GithubのreleaseからISOをダウンロードしてきます。
ダウンロードしてきたISOを適当なUSBメモリに焼き込み、物理サーバーにインストールしていきます。インストール中いくつかオプションの指定ができますが、今回はすべてデフォルト値のまま進みます。
トラブルなくスムーズにインストールが完了するとHarvesterのコンソールが表示されます。
仮想マシンの起動
さっそく仮想マシンを起動してみます。コンソールに指定されているアドレスにアクセスしてダッシュボードを開きます。
仮想マシンを作成するには、事前にインストールするISOファイルとネットワークの設定が必要です。
今回はお試しにUbuntu20.04のISOを用意することに。ISOのURLを指定することになるので、ubuntu.comのURLをそのまま指定します。 ImagesタブのCreateボタンからImageの作成をします。
次に仮想ネットワーク、VLANを作成します。NetworksタブのCreateボタンからNetworkの作成をします。
これで仮想サーバーを作成する準備できました。実際に仮想マシンを作成してみます。 Virtual MachinesタブのCreateボタンから仮想マシンを作成します。今回はお試しということで、先ほど登録したUbuntuのISOとVLANを利用することにします。
Createボタンを押すと実際にサーバーが起動し、HarvesterのWebConsoleからUbuntuのインストール画面へアクセスすることができました。 いやーこれは非常に楽ですね!
少し覗いてみる
少し動きについてみてみます。とりあえずPodの状態を確認。
~ ❯ kubectl get pods NAME READY STATUS RESTARTS AGE virt-launcher-vlan-sample-4bssz 1/1 Running 0 23h
Podの名前から見て、どうもこのPodが先ほど作成した仮想マシン本体のようです。KubeVirtの文字が輝いてますね。
でこのPodのownerReference
を見てみると下記の通り
❯ kubectl get pods -o json virt-launcher-vlan-sample-4bssz | jq .metadata.ownerReferences [ { "apiVersion": "kubevirt.io/v1", "blockOwnerDeletion": true, "controller": true, "kind": "VirtualMachineInstance", "name": "vlan-sample", "uid": "d3cab107-362b-4dfa-a0e7-122457f719ac" } ]
なるほど、この仮想マシンはkubevirt.io/v1のVirtualMachineInstanceで作成されているとのこと。
Harvesterの領域ではなくKubeVirtの領域になりますがもう少し深掘りしてみます。このVirtualMachineInstanceのownerReference
を覗いてみると下記の通り
❯ kubectl get VirtualMachineInstance -o json vlan-sample | jq .metadata.ownerReferences [ { "apiVersion": "kubevirt.io/v1", "blockOwnerDeletion": true, "controller": true, "kind": "VirtualMachine", "name": "vlan-sample", "uid": "b6d42e46-0004-47a3-a86d-78411d878cfc" } ]
つまりVirtualMachineを作成することでVirtualMachineInstanceが作成され、そのVirtualMachineInstanceに合わせてPodが起動する感じでしょうか?
kubectl explain
で覗いてみる限り
- VirtualMachineは仮想マシンのテンプレートとそのステータス(起動中かどうか)を管理
- VirtualMachineInstanceは仮想マシンそのものを管理
- Podは物理的な(?)仮想マシン
という関係性っぽいですね。なるほどー
コードを読んでみると、どうもHarvesterはどんなVirtualMachineオブジェクトでも管理対象とするみたいですね。つまりマニュアルで仮想マシンを作ることができそうかな……?
ためしに下記のようなマニフェストで作成してみます。(ちょっと長い)
apiVersion: kubevirt.io/v1 kind: VirtualMachine metadata: name: manual-vm spec: running: true dataVolumeTemplates: - apiVersion: cdi.kubevirt.io/v1beta1 kind: DataVolume metadata: annotations: harvesterhci.io/imageId: default/image-9dk4s name: manual-vm-cdrom-disk spec: pvc: accessModes: - ReadWriteMany resources: requests: storage: 10Gi storageClassName: longhorn-image-9dk4s volumeMode: Block source: blank: {} - apiVersion: cdi.kubevirt.io/v1beta1 kind: DataVolume metadata: name: manual-vm-rootdisk spec: pvc: accessModes: - ReadWriteMany resources: requests: storage: 10Gi storageClassName: longhorn volumeMode: Block source: blank: {} template: metadata: annotations: harvesterhci.io/diskNames: '["manual-vm-rootdisk","manual-vm-cdrom-disk"]' harvesterhci.io/sshNames: '["github.com"]' labels: harvesterhci.io/creator: RyuSA harvesterhci.io/vmName: manual-vm spec: domain: cpu: cores: 1 devices: disks: - bootOrder: 2 cdrom: bus: sata name: cdrom-disk - bootOrder: 1 disk: bus: virtio name: rootdisk - disk: bus: virtio name: cloudinitdisk interfaces: - macAddress: 52:54:00:57:4c:53 #適当 masquerade: {} model: virtio name: default - bridge: {} macAddress: 2e:61:8d:3d:35:4c #適当 model: virtio name: vlan machine: type: q35 resources: requests: memory: 2Gi evictionStrategy: LiveMigrate hostname: manual-vm networks: - name: default pod: {} - multus: networkName: example-vlan name: vlan volumes: - dataVolume: name: manual-vm-cdrom-disk name: cdrom-disk - dataVolume: name: manual-vm-rootdisk name: rootdisk - cloudInitNoCloud: userData: | #cloud-config ssh_authorized_keys: - >- ssh-rsa (snip) name: cloudinitdisk
これでkubectl create
でオブジェクトを作成してみると
一部の部分(labelやannotation)のお作法さえ守れば、しっかり動きますね。まぁできたからと言ってなにか良いことがあるわけではないのですが……w
まとめ
Harvesterを利用して、Kubernetesクラスタ上にHCIを構築して仮想マシンをKubernetesリソースベースで作成してみました。HarvesterのGUIで指定できる項目がまだ少なかったりしましたが、簡単な用途であれば現在のバージョンでもいい感じに動かせると思います。
本当は既存のKubernetes上にデプロイすることまでやりたかったのですが、手元にあるKuberenetesクラスターはRaspberry Piで構築していたため今回は断念。 というのもKubeVirtのARM64のサポートはまだ完成しておらず、それに引きずられてHarvesterのARM64サポートはこれからの状態です。
なので、気長に待ちつつ、可能なら貢献して行こうかなと思います。