概要
Terraform Libvirt Provider を用いて、KVM 上に CoreOS + Minikube が導入された1台の仮想マシンをプロビジョニングする。
Prerequisite
- Terraform
- Container engine (docker, podman, or nerdctl, ...)
- KVM 関連パッケージ
- qemu-kvm
- libvirt-clients
- libvirt-daemon
- bridge-utils
- virt-manager
- (OS: Ubuntu 22.04)
サンプルコード
こちらの GitHub repository を参照。
手順
CoreOS image の入手
CoreOS のダウンロードページから、QEMU用のイメージをダウンロードする。本記事では、
https://builds.coreos.fedoraproject.org/prod/streams/testing/builds/37.20230303.2.0/x86_64/fedora-coreos-37.20230303.2.0-qemu.x86_64.qcow2.xz
を使用する。
ダウンロードしたイメージを解凍し、fedora-coreos-37.20230303.2.0-qemu.x86_64.qcow2
を /var/lib/libvirt/images/
に移す (*補足)。
$ unxz -k fedora-coreos-37.20230303.2.0-qemu.x86_64.qcow2.xz
$ sudo mv fedora-coreos-37.20230303.2.0-qemu.x86_64.qcow2 /var/lib/libvirt/images/
Ignition の作成
Ignition は、CoreOS (をはじめとするいくつかの Linux 系 distribution) でサポートされている、OS のセットアップ自動化のための仕組みである。
設定は JSON 形式のファイルで記述される。ただ、人間にとってわかりやすい YAML で記述した後、 Butane (前身:Fedora CoreOS Config Transpiler, FCCT) を用いて JSON に変換するのが一般的である。
(ファイルの拡張子は、慣習的に変換前の YAML を .bu
、変換先の JSON を .ign
にする)。
次のような .bu
ファイルを作成する。
variant: fcos
version: 1.1.0
passwd:
users:
- name: core
groups:
ssh_authorized_keys:
- "<YOUR_SSH_KEY>"
# Docs of ignition storage.files: https://coreos.github.io/butane/examples/#storage-and-files
storage:
files:
# minikube: https://minikube.sigs.k8s.io/docs/start/
- path: /usr/local/bin/minikube
overwrite: true
mode: 0755
contents:
source: https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
# kubectl: https://kubernetes.io/docs/tasks/tools/install-kubectl-linux/
- path: /usr/local/bin/kubectl
overwrite: true
mode: 0755
contents:
source: https://dl.k8s.io/release/v1.26.2/bin/linux/amd64/kubectl
-
passwd
ブロック でcore
ユーザの作成 -
storage.files
ブロックでminikube
およびkubectl
のインストール
を指定する(上記のssh_authorized_keys
は自身の SSH 公開鍵に書き換える)。
上記の ignition.bu
を、Butane を用いて ignition.ign
に変換する。今回は quay.io で配布されている Butane コンテナを利用する。
$ docker run -i --rm quay.io/coreos/butane:release --pretty --strict < ignition.bu > ignition.ign
Terraform libvirt-provider による VM のプロビジョニング
Terraform で libvirt 仮想化環境を管理するために、dmacvicar/libvirt provider を用いる。
事前準備
Libvirt は、デフォルトでは外部のアプリケーションが関連するリソースにアクセスすることを制限している。
そこで、Terraform の libvirt-provider を実行する際に Permission Error にならないよう、権限を与えておく。
/etc/apparmor.d/libvirt/TEMPLATE.qemu
を次のように編集し、関連するリソースに権限を付与する1。
# This profile is for the domain whose UUID matches this file.
#
#include <tunables/global>
profile LIBVIRT_TEMPLATE flags=(attach_disconnected) {
#include <abstractions/libvirt-qemu>
/var/lib/libvirt/images/** rwk,
/tmp/** rwk,
}
libvirt を再起動する。
$ sudo systemctl restart libvirtd
プロビジョニングの実行
下記ような main.tf
を作成し、1台の仮想マシンを作成する。(スペックは、公式ドキュメントに記載されている必要最小の構成にした):
- 2 vCPUs
- 2GB RAM
- 20GB Volume
terraform {
required_providers {
libvirt = {
source = "dmacvicar/libvirt"
version = "0.7.1"
}
}
}
provider "libvirt" {
uri = "qemu:///system"
}
variable coreos_image_uri {
#source: "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/37.20230205.3.0/x86_64/fedora-coreos-37.20230205.3.0-qemu.x86_64.qcow2.xz"
default = "/var/lib/libvirt/images/fedora-coreos-37.20230205.3.0-qemu.x86_64.qcow2"
}
resource "libvirt_ignition" "ignition" {
name = "ignition.ign"
content = "${path.module}/ignition.ign"
}
resource "libvirt_domain" "minikube" {
name = "minikube"
memory = 2000 # in MiB
vcpu = 2
disk {
volume_id = libvirt_volume.coreos_minikube_volume.id
}
coreos_ignition = libvirt_ignition.ignition.id
network_interface {
network_name = "default"
wait_for_lease = true
}
}
resource "libvirt_volume" "coreos_minikube_volume" {
name = "coreos_minikube.qcow2"
pool = "default"
format = "qcow2"
base_volume_id = var.coreos_image_uri
size = 20 * 1024 * 1024 * 1024 # 20 GB
}
Terraform を実行し、仮想マシンをプロビジョニングする。
$ terraform init
$ terraform apply -auto-approve
仮想マシンが作成されたことを確認する。
$ virsh list --all
Id Name State
---------------------------
418 minikube running
仮想マシンへの SSH login
作成した仮想マシンの IP アドレスを調べる。
$ virsh domifaddr minikube
Name MAC address Protocol Address
-------------------------------------------------------------------------------
vnet512 52:54:00:8e:8f:dd ipv4 192.168.122.204/24
core
ユーザで SSH ログインできることを確認する。
$ ssh core@192.168.122.204
Minikube を起動する。
[core@localhost ~]$ minikube start
😄 minikube v1.29.0 on Fedora 37 (kvm/amd64)
...
kubectl が Kubernetes API サーバに接続されていることを確認する。
[core@localhost ~]$ kubectl cluster-info
kubectl cluster-info
Kubernetes control plane is running at https://192.168.49.2:8443
CoreDNS is running at https://192.168.49.2:8443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
補足
/var/lib/libvirt/images/
は libvirt のデフォルトプールで、Terraform Libvirt Provider は通常ここからベースイメージとなる qcow2 ファイルを探す。
base_volume_name - (Optional) The name of the backing volume (CoW) to use for this volume. Note well: when base_volume_pool is not specified the volume is going to be searched inside of pool.
-- libvirt_volume | Resources | dmacvicar/libvirt | Terraform Registry
もしここ以外のプールを指定する場合(たとえば /hoge
下に qcow2 を置く場合)、main.tf
を次のように書き換える:
# `/hoge` 直下の qcow2 ファイルの URI を指定する
variable "coreos_image_uri" {
default = "/hoge/fedora-coreos-37.20230205.3.0-qemu.x86_64.qcow2"
}
# (2) 次の "libvirt_pool" ブロックを追加し、`/hoge` プール を作成する。
resource "libvirt_pool" "image_pool" {
name = "image_pool"
type = "dir"
path = "/hoge"
}
# ...
resource "libvirt_volume" "coreos_minikube_volume" {
name = "coreos_minikube.qcow2"
#(3) base_volume_pool に新たに作成したプールを指定する
base_volume_pool = libvirt_pool.image_pool.id
format = "qcow2"
base_volume_id = var.coreos_image_uri
size = 20 * 1024 * 1024 * 1024 # 20 GB
}