MatchBox + PXEでOpenShift用のOS、RHEL CoreOSを全自動で起動する(KVM)

Red HatでOpenShiftのサポートエンジニアをしている林です。

OpenShift 4をベアメタル、KVMなどで構築(UPI)するには、RHEL CoreOS(RHCOS)のマシンを起動する必要があります。そのための方法は大雑把に言って以下の二つです。

  • RHCOSのインストーラーイメージを起動し、インストールメニューでIgnitionやカーネルイメージのURLを指定する
  • PXEブートで、Ignitionやカーネルイメージの場所が指定されたブート構成ファイルを使用する

どちらにしても、Ignitionやカーネルイメージなどの資源をホストする環境を用意する必要があります。

MatchBoxは、RHCOSをネットワークブートする際に必要なIgnitionやカーネルイメージ、iPXEスクリプトなどをホストしてくれるWebアプリケーションです。

github.com

MACアドレスなどのマシン属性を引数にして様々なIgnitionやスクリプトを返してくれるので、例えばKVMでMACアドレスを指定して起動すれば、ユーザー入力なしでRHCOSの起動が完了します。

この記事では、MatchBoxを使って、KVM上でRHCOSを自動インストールして起動する手順を紹介します。

ちなみに、マッチ箱(MatchBox)でRHCOSを点火(Ignition)して起動する、的なアナロジーみたいですね。センスに溢れすぎてて震える。

マシン構成

今回紹介するマシン構成は以下の通りです。

  • KVMホスト / base.examle.com
  • PXEインフラ用VM / pxe.example.com
    • dnsmasq(tftp)
    • MatchBox
  • RHCOSのVM / coreos.example.com

PXE環境としてdnsmasqでDHCP Proxy / tftpサーバーを立てて、さらにMatchBoxも同居している構成ですね。

なお、KVMの各VMはブリッジネットワークで起動しています。

MatchBox環境のセットアップ

大体はGitHub上の手順に従えばセットアップできます。

https://github.com/poseidon/matchbox/blob/v0.8.0/Documentation/deployment.md

MatchBoxのインストール、起動

まず、PXEインフラVMにMatchBoxをインストールして起動します。

## MatchBoxのダウンロードとインストール
[cloud-user@pxe.example.com ~]$ curl -OL https://github.com/poseidon/matchbox/releases/download/v0.8.0/matchbox-v0.8.0-linux-amd64.tar.gz
[cloud-user@pxe.example.com ~]$ tar -xzf matchbox-v0.8.0-linux-amd64.tar.gz
[cloud-user@pxe.example.com ~]$ cd matchbox-v0.8.0-linux-amd6
[cloud-user@pxe.example.com ~]$ sudo cp matchbox /usr/local/bin
[cloud-user@pxe.example.com ~]$ sudo cp contrib/systemd/matchbox-local.service /etc/systemd/system/matchbox.service

## MatchBoxの起動に必要なディレクトリとユーザーを作成
[cloud-user@pxe.example.com ~]$ sudo mkdir /etc/matchbox
[cloud-user@pxe.example.com ~]$ sudo mkdir -p /var/lib/matchbox/{assets,groups,ignition,profiles}
[cloud-user@pxe.example.com ~]$ sudo useradd -U -r matchbox

## MatchBoxの起動
[cloud-user@pxe.example.com ~]$ sudo systemctl daemon-reload
[cloud-user@pxe.example.com ~]$ sudo systemctl enable --now matchbox.service
[cloud-user@pxe.example.com ~]$ systemctl status matchbox 

## ipxeのブートスクリプトを取得できることを確認
[cloud-user@pxe.example.com ~]$ curl http://localhost:8080/boot.ipxe

#!ipxe
chain ipxe?uuid=${uuid}&mac=${mac:hexhyp}&domain=${domain}&hostname=${hostname}&serial=${serial}

MatchBoxにRHCOS起動用のリソースを配置する

次に、MatchBoxでホストする、RHCOSの起動に必要なリソースをダウンロードしてMatchBoxから取得できるようにします。

[cloud-user@pxe.example.com ~]$ sudo su -
[root@pxe.example.com ~]# cd /var/lib/matchbox/assets
[root@pxe.example.com ~]# RHCOS_BASEURL=https://mirror.openshift.com/pub/openshift-v4/dependencies/rhcos/
[root@pxe.example.com ~]# curl -OL ${RHCOS_BASEURL}/4.1/latest/rhcos-4.1.0-x86_64-installer-initramfs.img
[root@pxe.example.com ~]# curl -OL ${RHCOS_BASEURL}/4.1/latest/rhcos-4.1.0-x86_64-installer-kernel
[root@pxe.example.com ~]# curl -OL ${RHCOS_BASEURL}/4.1/latest/rhcos-4.1.0-x86_64-metal-bios.raw.gz

## 確認
[root@pxe.example.com ~]# curl -O http://localhost:8080/assets/rhcos-4.1.0-x86_64-installer-initramfs.img
[root@pxe.example.com ~]# curl -O http://localhost:8080/assets/rhcos-4.1.0-x86_64-installer-kernel
[root@pxe.example.com ~]# curl -O http://localhost:8080/assets/rhcos-4.1.0-x86_64-metal-bios.raw.gz

MatchBoxにRHCOS起動用のプロファイルを作成する

MatchBoxは、URLの引数にMACアドレスなどを渡すことで、RHCOS起動に必要な様々な情報を返してくれるWebサーバーです。 そのために、まず起動構成やIgnitionの情報などを記載したプロファイルを作成します。

[root@pxe.example.com ~]# cat <<'EOF' > /var/lib/matchbox/profiles/playground.json
{
    "id": "playground",
    "name": "RHCOS - Playground",
    "ignition_id": "playground.ign",
    "boot": {
        "kernel": "/assets/rhcos-4.1.0-x86_64-installer-kernel",
        "initrd": [
            "/assets/rhcos-4.1.0-x86_64-installer-initramfs.img"
        ],
        "args": [
            "ip=dhcp",
            "rd.neednet=1",
            "console=tty0",
            "console=ttyS0",
            "coreos.inst=yes",
            "coreos.inst.install_dev=vda",
            "coreos.inst.image_url=http://pxe.example.com:8080/assets/rhcos-4.1.0-x86_64-metal-bios.raw.gz",
            "coreos.inst.ignition_url=http://pxe.example.com:8080/ignition?mac=${mac:hexhyp}"
        ]
    }
}
EOF

そして、上記のプロファイルで指定したIgnitionファイルを、ignition_idと同名のファイル名で作成します。

[root@pxe.example.com ~]# cat <<EOF > /var/lib/matchbox/ignition/playground.ign
{
  "ignition": {
    "version": "2.2.0"
  },
  "passwd": {
    "users": [
      {
        "name": "core",
        "sshAuthorizedKeys": [
          "ssh-rsa AAAAB3NzaC <ログインで使用するSSH公開鍵>"
        ]
      }
    ]
  },
  "storage": {
    "files": [
      {
        "filesystem": "root",
        "group": {},
        "path": "/etc/hostname",
        "user": {},
        "contents": {
          "source": "data:text/plain;charset=utf-8,coreos.example.com",
          "verification": {}
        },
        "mode": 420
      }
    ]
  }
}
EOF

最後に、MACアドレスとプロファイルを紐付けるgroup設定を作成します。MACアドレスは、KVMでVMを起動する時に任意のものを指定できるので、ここでは02:1a:4a:16:01:9cを使用することにします。

[root@pxe.example.com ~]# cat <<EOF > /var/lib/matchbox/groups/playground.json
{
  "id": "playground-1",
  "name": "RHCOS - Playground 1",
  "profile": "playground",
  "selector": {
    "mac": "02:1a:4a:16:01:9c"
  }
}
EOF

さて、ここまでの設定ができていれば、以下のようにURLを叩くことで必要なIginitionを取得できることを確認できるかと思います。

[cloud-user@pxe.example.com ~]$ curl http://localhost:8080/ignition?mac=02-1a-4a-16-01-9c

{
  "ignition": {
    "version": "2.2.0"
  },
  "passwd": {
    "users": [
      {
        "name": "core",
        "sshAuthorizedKeys": [
          "ssh-rsa AAAAB3Nz ..."
        ]
      }
    ]
  },
  "storage": {
    "files": [
      {
        "filesystem": "root",
        ...

PXE環境とブートの流れを確認

ここでは、PXE環境をdnsmasqで構築しています。dnsmasqで以下のように設定し、tftpサーバーを有効にしています。

私の環境では、DHCPサーバーはネットワーク上に既にあったため、ここでは、DHCP Proxyを使って構成します。

基本的に、以下のGitHubドキュメントに記載されているとおりで問題ないかなと思います。

https://github.com/poseidon/matchbox/blob/v0.8.0/Documentation/network-setup.md#proxy-dhcp

[root@pxe.example.com ~]# cat /etc/dnsmasq.conf

# 既存のDHCPサーバーが割り当てているIPレンジ
dhcp-range=192.168.1.1,proxy,255.255.255.0

# TFTP有効化
enable-tftp
tftp-root=/var/lib/tftpboot

# PXEリクエストの場合はTFTPでiPXEをロード(chainload)する
pxe-service=tag:#ipxe,x86PC,"PXE chainload to iPXE",undionly.kpxe
# iPXE user classからのリクエストの場合はipxeタグをセットする
dhcp-userclass=set:ipxe,iPXE
# ipxeタグ付きのリクエストでmatchboxがホストするスクリプトをロードする
pxe-service=tag:ipxe,x86PC,"iPXE",http://pxe.example.com:8080/boot.ipxe

# verbose
log-queries
log-dhcp

TFTPからiPXEをロードできるように、undionly.kpxeをダウンロードしてTFTPのルートに配置します。

[root@pxe.example.com ~]# curl -OL http://boot.ipxe.org/undionly.kpxe
[root@pxe.example.com ~]# mv undionly.kpxe /var/lib/tftpboot/

上記により、iPXEで以下のブートスクリプトが起動するはずです。念のため、ブートスクリプトを確認してみます。

## iPXEブートスクリプト
[root@pxe.example.com ~]# curl http://localhost:8080/boot.ipxe

#!ipxe
chain ipxe?uuid=${uuid}&mac=${mac:hexhyp}&domain=${domain}&hostname=${hostname}&serial=${serial}

## chain先のスクリプト
[root@pxe.example.com ~]# curl http://localhost:8080/ipxe?mac=02-1a-4a-16-01-9c
#!ipxe
kernel /assets/rhcos-4.1.0-x86_64-installer-kernel ip=dhcp rd.neednet=1 console=tty0 console=ttyS0 coreos.inst=yes coreos.inst.install_dev=vda coreos.inst.image_url=http://pxe.example.com:8080/assets/rhcos-4.1.0-x86_64-metal-bios.raw.gz coreos.inst.ignition_url=http://pxe.example.com:8080/ignition?mac=${mac:hexhyp}
initrd /assets/rhcos-4.1.0-x86_64-installer-initramfs.img
boot

RHCOSの起動

これで、ブートの環境ができたので、後はKVMでVMを立ち上げればRHCOSが起動します。

[root@base.example.com ~]# virt-install --name "rhcos-playground" \
  --mac "02:1a:4a:16:01:9c" \
  --memory 2046 --disk size=16 \
  --network bridge=br0,model=virtio \
  --os-variant rhel8.0 \
  --debug --pxe

## 起動したVMのIPを確認するためコンソールにアクセスする
[root@base.example.com ~]# virsh console rhcos-playground
Connected to domain rhcos-playground
Escape character is ^]

Red Hat Enterprise Linux CoreOS 410.8.20190520.0 (Ootpa) 4.1
...
enp1s0: 192.168.1.xx ...

coreos login: 
^]

## 上記で確認したIPにSSHでログインする
[root@base.example.com ~]# ssh -i <ignitionで指定した鍵> core@192.168.1.xx
...
[core@coreos ~]$ 

OpenShift 4でRHCOSを起動する場合

今回は、RHCOSを単独で起動しましたが、RHCOSは、本来、OpenShift専用のOSですので、実際はOpenShift構成時に起動することになります。

以下の記事で田中さんが詳細について記載されているので、ご確認ください。

rheb.hatenablog.com

MatchBoxを使う場合は、openshift-installコマンドで生成されるIgnitionファイルを、MatchBoxのデータディレクトリ/var/lib/matchboxにコピーして、そのIgnitionファイルを参照するようプロファイルを作成すれば、簡単にOpenShift用のノードを起動することができるわけですね。

起動しない場合の確認

  • ファイアウォールが正しく設定されているか
  • DHCPサーバーが、適切なDNSサーバーのIPを配っているか
  • virt-installで起動する時にMACアドレスを正しく指定しているか

* 各記事は著者の見解によるものでありその所属組織を代表する公式なものではありません。その内容については非公式見解を含みます。