Apple Silicon搭載MacにシングルノードOpenShiftをインストールする(UPI編)

Red Hatでソリューションアーキテクトをしている田中司恩(@tnk4on)です。

ついにこの時が来ました!Apple Silicon搭載Mac(以下、ARM Mac)でOpenShiftが動くようになりました!本記事では誰でも実行可能なインストール手順を解説します。 さぁ、全世界OpenShiftインストール愛好家の皆さん、レッツトライ!

(お約束。本記事の内容は検証を目的としており、本番環境での使用や公式なサポートを保証するものではありません。)

-目次-


Hello, Apple Silicon

2020年11月にM1チップが発表されて以降、ARM Macは高性能、高効率なコンピューターとして注目を集めています。 ところが、このARM Mac上でOpenShiftを動かす取り組みにはこれまで問題がありました。

関連するKCSとしては下記があります。

Can I run RHEL virtualized in a Mac using the Apple M1 processor? - Red Hat Customer Portal

要約すると、

  • Apple M1チップ(後継のM2も同様)は4Kまたは16Kのページサイズを使用している
  • aarch64版RHEL 7/8は64Kページサイズ用にコンパイルされている

この違いによりARM MacではRHEL 7/8 を仮想マシンとして実行できないという問題が発生しています。

現行のOpenShift 4は2019年にリリースされて以降、ベースOSのRed Hat Enterprise Linux CoreOS(以下、RHCOS) はRHEL 8をベースとしてリリースされてきました。そのため、ARM Macではaarch64版RHCOSであっても仮想マシンとして起動できない状況がこれまで続いています。

その後リリースされたaarch64版RHEL 9ではページサイズが4Kに変更されたため、ARM MacでRHEL 9の実行が可能になりました。そしてようやく、OpenShift 4.13のリリースと合わせてRHEL 9ベースのRHCOS(実際は9.2)がリリースされることになり、ARM MacでOpenShiftを動かせるようになったのです。

以降はOpenShift 4.13のRC版を使ってARM MacにシングルノードのOpenShiftをインストールする方法をご紹介します。

SNO on ARM Macの構成概要

構成図

Single Node OpenShift on ARM Mac(UPI)のアーキテクチャー
Single Node OpenShift on ARM Mac(UPI)のアーキテクチャー

構成の特徴

1台のARM Mac上で全て完結できるように下記のような特徴があります。

  • ホストネットワーク上の静的IPアドレスを使用可能
  • インストールに必要なインフラ要件はDNSサーバーのみ
  • インストール時にBootstrapノードが不要
  • コンテナを活用し、Macホストの設定変更を最小限にする

前提条件

  • Macホストからインターネットにアクセスできること
    • Proxy経由、非接続環境も対応可能だと思いますが動作確認はしていません
  • Macホストに仮想マシンを実行できる空きリソースがあること
    • 最小リソース:8 vCPU, 16GB RAM, Disk 100 GB
  • Apple Virtialization Frameworkに対応した仮想環境アプリを用意すること
  • "Podman Love"
    • コンテナの実行にPodmanを使うのでPodman Desktopの導入を推奨*1

他には、OpenShiftのインストール方法に多少の理解があることが望ましいですが、本記事で省略している内容は製品ドキュメントや赤帽エンジニアブログの記事などを参考にしてください

パラメーター一覧

インストールに必要なパラメータの一覧です。

ネットワーク

項目 内容 サンプル値
静的IPアドレス1 MacホストのIPアドレス 192.168.1.150
静的IPアドレス2 OpenShiftノードのIPアドレス 192.168.1.40
ネットワークアドレス CIDR 表記の IP ネットワークブロック 192.168.1.0/24
デフォルトゲートウェイ パブリックネットワークへのゲートウェイ 192.168.1.1

ドメイン、クラスター名

項目 内容 サンプル値
ドメイン <base_domain> home.lab
クラスター名 <cluster_name> sno

必要なDNSレコード

項目 内容 サンプル値
Kubernetes API api.<cluster_name>. <base_domain> api.sno.home.lab
Kubernetes API(内部クラスター通信) api-int.<cluster_name>. <base_domain> api-int.sno.home.lab
アプリケーションIngressトラフィック *.apps.<cluster_name>. <base_domain> *.apps.sno.home.lab
OpenShiftノード <host_name>. <cluster_name>. <base_domain> m1-ocp.sno.home.lab

インストール方法

参照するインストールドキュメントは下記をベースとしますが、本記事ではARM Mac用に様々なカスタマイズを加えています。

15.2.2. 単一ノードの OpenShift を手動でインストールする

Gitリポジトリのクローン

インストールに必要なファイル類のテンプレートを用意しています。下記URLのリポジトリをクローンしてご利用ください。

GitHub - tnk4on/sno-on-arm-mac: Install Single Node OpenShift on Apple Silicon-based Mac (ARM Mac)

git clone https://github.com/tnk4on/sno-on-arm-mac.git
cd sno-on-arm-mac

インストーラーとOpenShift CLIの入手

インストールに必要な openshift-install とクライアントの oc を入手して実行パスに配置します。

export OCP_VERSION=4.13.0-rc.2
export ARCH=aarch64
mkdir src
cd src
curl -LO https://mirror.openshift.com/pub/openshift-v4/$ARCH/clients/ocp/$OCP_VERSION/openshift-install-mac.tar.gz
curl -LO https://mirror.openshift.com/pub/openshift-v4/$ARCH/clients/ocp/$OCP_VERSION/openshift-client-mac.tar.gz
tar zxf openshift-install-mac.tar.gz
tar zxf openshift-client-mac.tar.gz
sudo cp openshift-install oc /usr/local/bin/
cd ..
  • OCP_VERSION: 「4.13.0-rc.0」以降を指定します
  • ARCH: ARM Macに対応した「aarch64」を指定します*2
  • ダウンロードしたアーカイブはsrcディレクトリに一時保存します
  • 実行バイナリの配置先はPATH環境変数であればどこでも可能です

RHCOS ISOの入手

インストールに使用するRHCOSのISOイメージを入手します。

mkdir iso
export ISO_URL=$(openshift-install coreos print-stream-json | grep location | grep $ARCH | grep iso | cut -d\" -f4)
curl -L $ISO_URL -o iso/rhcos-live.iso
  • ダウンロードしたISOはisoディレクトリに保存します。インストールを繰り返す場合はISOの再利用が可能です。
  • ISOの名前は任意で変更しても問題ありません

DNSサーバーの実行

Podmanを使用してDNSサーバーをコンテナで実行します。コンテナイメージはOpenShift Localで使用しているものを利用します。*3

以降はPodman Desktopを導入後の状態からの解説です。Podman Desktopのインストール方法は下記を参考にしてください。 MacOS | Podman Desktop

1. Podman machineをルートモードに変更

Podman machineで1024番以下のポートをバインドするためにルートモード(rootful)に変更します。

podman machine stop
podman machine set --rootful
podman machine start
  • Podman machineの実行前であれば podman machine init --rootful で初期設定する方法でも可

2. Podman machineのsystemd-resolvedを停止

UDPポート53番を使用できるようにPodman machineで実行中のsystemd-resolvedを停止します

podman machine ssh sed -r -i.orig 's/#?DNSStubListener=yes/DNSStubListener=no/g' /etc/systemd/resolved.conf
podman machine ssh systemctl restart systemd-resolved
podman machine ssh ss -ltnup

3. dnsmasq.confの修正

利用する環境に合わせてドメイン名、ホスト名、IPアドレスを修正します。

dnsmasq.confのサンプルを展開

user=root
port= 53
expand-hosts
log-queries
log-facility=-
local=/home.lab/
domain=home.lab
address=/apps.sno.home.lab/192.168.1.40
address=/api.sno.home.lab/192.168.1.40
address=/api-int.sno.home.lab/192.168.1.40
address=/m1-ocp.sno.home.lab/192.168.1.40
ptr-record=40.1.168.192.in-addr.arpa,m1-ocp.sno.home.lab
rev-server=192.168.1.0/24,127.0.0.1

  • log-queriesとlog-facility:デバッグ目的で標準出力にクエリログを出力します。不要であれば削除可能です。
  • ptr-record:OpenShiftノードのみ逆引き設定が必要です。これが無いとインストールが正常に完了しません。*4
  • rev-server:逆引きを行うDNSサーバーは自分自身(127.0.0.1)を指定します。

4. コンテナの実行

Podmanを使いDNSサーバーをコンテナで実行します

podman run -d --rm -p 53:53/udp -v ./dnsmasq.conf:/etc/dnsmasq.conf --name dnsmasq quay.io/crcont/dnsmasq:latest
  • Mac上のdnsmasq.confをバインドマウントしてコンテナ内に読み込みます
  • (注意)Mac上ではpodman system serviceは使用できないので、コンテナを自動実行したい場合はPodman machine内に仕込むなどの工夫が必要です
  • --rmを付けるかどうかはお好みでどうぞ

Macホストの設定変更

Macホスト自身からOpenShiftクラスターへのアクセスに必要なDNS名前解決の設定を行います。

1. /etc/resolver

ブラウザー等からOpenShiftクラスターへ接続する際に<cluster_name>. <base_domain>のDNSクエリはコンテナで実行中のDNSサーバーへ転送するように/etc/resolverを使用します。

sudo tee /etc/resolver/sno.home.lab &>/dev/null <<EOF
nameserver 127.0.0.1
EOF

2. /etc/hosts

ocクライアントは/etc/resolverを通過したDNS名前解決を行わないため、静的に/etc/hostsにOpenShiftクラスターのKubernetes APIのDNSレコードを登録します。

sudo tee -a /etc/hosts &>/dev/null <<EOF
192.168.1.40    api.sno.home.lab
EOF

RHCOS ISOのテスト起動とデバイス名の確認

使用する仮想環境アプリでOpenShiftノード用の仮想マシンを作成します。

[UTMの場合の設定参考値]

項目 サンプル値
CPU(Cores) 8
Memory(MB) 16384
Storage(GB) 100 *5
Use Apple Virtualization オン
Network Mode Bridged
Boot ISO Image <任意のパス>/iso/rhcos-live.iso

仮想マシン作成後、ISOから起動します。ISOの起動手順は仮想環境アプリに準じます。 正常にRHCOSがLiveモードで起動するとcoreユーザーでログインした状態のコンソールが表示されます。 その後、インストールに必要なストレージデバイス名とNIC名を確認します。

sudo fdisk -l
ip a

(参考)

  • NIC: enp0s1(UTM), ens160(VMware Fusion)
  • ストレージデバイス: /dev/vda(UTM), /dev/nvme0n1(VMware Fusion NVMe), /dev/sda(VMware Fusion SATA)

install-config.yamlの更新

ご利用の環境に合わせてinstall-config.yamlの内容を修正します。

install-config.yamlのサンプルを展開

apiVersion: v1
baseDomain: home.lab
compute:
- name: worker
  replicas: 0
controlPlane:
  name: master
  replicas: 1
metadata:
  name: sno
networking:
  clusterNetworks:
  - cidr: 10.128.0.0/14
    hostPrefix: 23
  machineNetwork:
  - cidr: 192.168.1.0/24
  networkType: OVNKubernetes
  serviceNetwork:
  - 172.30.0.0/16
platform:
  none: {}
bootstrapInPlace:
  installationDisk: /dev/vda
pullSecret: '{"auths":...}' 
sshKey: 'ssh-ed25519 AAAA...'

1. インストール先ディスク

前項で確認したストレージデバイス名に合わせて、install-config.yaml内のinstallationDisk: 値を修正します。

bootstrapInPlace:
  installationDisk: /dev/vda

2. プルシークレット

Red Hat Hybrid Cloud Console から入手したプルシークレットをpullSecret:に貼り付けます。

pullSecret: '{"auths":...}' 

3. SSHキー

事前に作成したSSHキーペアの公開鍵をsshKey:に貼り付けます

(参考)25.1.6. クラスターノードの SSH アクセス用のキーペアの生成

sshKey: 'ssh-ed25519 AAAA...'

Ignitionファイルの作成

インストールディレクトリを作成し、Ignitionファイルを作成します。

mkdir ocp
cp install-config.yaml ocp
openshift-install --dir=ocp create single-node-ignition-config
  • (注意)Ignitionファイルを作成すると使用したinstall-config.yaml は失われるので、毎回コピーして元ファイルを残すようにしましょう

Ignitionファイルの作成後のインストールディレクトリ構成は下記のようになります

ocp
├── auth
│   ├── kubeadmin-password
│   └── kubeconfig
├── bootstrap-in-place-for-live-iso.ign
├── metadata.json
└── worker.ign
  • Bootstrap Inplace方式でインストールするため、worker.ignは使用しません

IgnitionファイルをRHCOS ISOへ埋め込む

RHCOS ISOにIgnitionファイルを埋め込むにはcoreos-installerを使用します。しかしながらMac向けのcoreos-installerコマンドは無いため、コンテナで実行して代用します。

1. aliasコマンドの登録

コンテナ実行コマンドをaliasコマンドとして登録します

alias coreos-installer='podman run --privileged --rm \
    -v $PWD:/data \
    -w /data quay.io/coreos/coreos-installer:release'
coreos-installer --version
  • バージョンが表示されればOKです
  • (参考)15.2.2.1. coreos-installer によるインストール ISO の生成
    • ドキュメントのコンテナ実行コマンドはLinux向けで記載されているためMac上のPodmanで実行した場合はエラーになります。そのためバインドマウントオプションをMac向けに修正しています。

2. Ignitionファイルの埋め込み

coreos-installerコマンドを使い、RHCOS ISOにbootstrap-in-place-for-live-iso.ignファイルを埋め込みます

coreos-installer iso ignition embed -fi ocp/bootstrap-in-place-for-live-iso.ign iso/rhcos-live.iso
  • エラーなくコマンドが終了すれば成功です。特にログ出力などはありません。見た目はISOファイルの更新日時が変更されるくらいです。

OpenShiftノードの静的IPアドレス設定

RHCOS ISOイメージに事前にカーネル引数を設定することで、RHCOSライブ環境の起動時に静的IPアドレスを設定します。

(余談)OpenShiftノードに静的IPアドレスを設定する方法はドキュメントやKCSにもいくつか手順がありますが、今回のインストール方法(SNOのBootstrap Inplaceインストール)では下記の理由により後述するISOにカーネル引数を設定する方法しか採用できません。

  • coreos-installer iso ignition embedとcoreos-installer iso customizeが併用できない
  • Ignitionファイルを埋め込んでいるため自動でインストールが始まってしまう(ライブ環境起動後に手動でカーネル引数の設定ができない)

1. 環境変数の設定

カーネル引数に指定する環境変数を設定します

export IP=192.168.1.40
export GATEWAY=192.168.1.1
export NETMASK=255.255.255.0
export INT=enp0s1
export HOSTNAME=m1-ocp.sno.home.lab
export DNS=192.168.1.150

2. ISOにカーネル引数を設定する

coreos-installerコマンドを使い、ISOにカーネル引数を設定します

coreos-installer iso kargs modify -a "console=ttyS0 rd.neednet=1 ip=${IP}::${GATEWAY}:${NETMASK}:${HOSTNAME}:${INT}:none nameserver=${DNS}" iso/rhcos-live.iso

RHCOS ISOの起動

iso/rhcos-live.isoを使用してISOを起動します。ISO起動後は自動でクラスターのインストールが開始されます。 インストールの自動実行中、下記のタイミングで再起動が2回行われます。

  • 1回目:ISO起動→ディスクへ書き込み完了後
  • 2回目:Bootstrap開始→Bootstrap完了後

(余談)4.13.0-rc.0を使用すると、Bootstrapプロセスに移行後にRHCOSからCentOS Stream CoreOSへ切り替わります。4.13.0-rc.2以降はRHCOSに完全移行しました。

(参考)インストール状況のモニタリング

OpenShiftのインストール実行中、ターミナルウィンドウを複数開き下記のコマンドを利用してログのモニタリングができます。

ターミナル1: RHCOSノード上のログ

export IP=192.168.1.40
sed -i -e "/${IP}/d" ~/.ssh/known_hosts
ssh core@${IP} -o "StrictHostKeyChecking=no" journalctl -b -f

ターミナル2:Cluster Operatorの起動状況

export KUBECONFIG=ocp/auth/kubeconfig
watch -n 1 oc get co

ターミナル3:インストールログ

export KUBECONFIG=ocp/auth/kubeconfig
openshift-install --dir=ocp wait-for bootstrap-complete
openshift-install --dir=ocp wait-for install-complete

ターミナル4: DNSサーバーのログ

podman logs -f dnsmasq

環境のリセット

インストールに問題があった場合は下記を実行して環境をリセットします。その後、IgnitionファイルをRHCOS ISOへ埋め込む手順から再開します。

インストールディレクトリの削除

rm -rf ocp

ISOイメージの初期化

coreos-installer iso reset iso/rhcos-live.iso

インストール後の状況

インストール直後のディスク使用量(ディスクイメージのサイズ)は 約23 GBでした。 Activity Monitorで見たCPU、メモリの状況は下記の通りです。ホストはM1 MAX(10コア/64GB RAM)です。

CPUの状況
CPUの状況
Memoryの状況
Memoryの状況

Chrome、VS Code、Podman Desktop、UTMなどを立ち上げた状態でも、特にOSの動作上の重さなどは感じられません。

One more thing ?

OpenShift 4.13のRC版が公開されたことにより、誰でもARM MacにOpenShiftをインストールすることができるようになりました。*6

現時点ではインストールができる状態に辿り着いたところなので、実際の性能面や互換性は未知数です。ですが、普段使いのARM Macで常時動かせるOpenShift環境があるというのはとてもワクワクします。M2 MaxやM1 Ultraなどを搭載した端末ならどこまでできるのか?などと考えるのも楽しいものです。

さらに!今回紹介したUPIをベースとした手動インストール方法の他に、もっとインストールを簡単にする方法があります。支援付きインストーラー(Assisted Installer) とOCP 4.12から登場した エージェントベースのインストーラー(Agent-Based Installer) です。残念ながら本記事執筆時点ではARM Macに対してこれらの方法を用いたインストールができません。インストールの確認ができたらまた別の記事にて紹介したいと思います。

(2023/4/3、追記) エージェントベースのインストール記事を公開しました! rheb.hatenablog.com

(2023/5/10、追記) 支援付きインストーラーの記事を公開しました! rheb.hatenablog.com

*1:他のコンテナ実行環境でも代替えは可能だと思いますが、せっかくなのでPodmanを使いましょう!

*2:ハマりポイントその1。バイナリ名が同じなのでopenshift-install versionを実行してrelease architecture:の出力結果を確認するしかamd64なのかarm64なのか判別できません。

*3:OpenShift Localの中で動いているコンテナについてはこの記事で紹介しています https://rheb.hatenablog.com/entry/crc_remote_connecting

*4:ハマりポイントその2。このPTRレコードが無いとCluster Operatorの起動終盤で進まなくなります。

*5:100GBでもインストール前の検証にパスするようにバグが修正されました https://github.com/openshift/installer/pull/7025

*6:非公開イメージを使ったRed Hat公式ブログの記事はありましたが、誰でもインストールできるようになったのは4.13 RC版公開以降です。 https://cloud.redhat.com/blog/openshift-on-an-apple-m1-vm-with-red-hat-advanced-cluster-management

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