エアギャップ(インターネット接続無し)環境での OCP(Openshift Container Platform) の導入/運用手順を紹介するシリーズです。今回は(ただでさえニッチな内容の本シリーズの中では最も需要がありそうな)「エアギャップ環境での OCP インストール」手順を紹介します。アプリデプロイとかアップデートとかも需要あると思ってますが、まずはプラットフォームをインストールしないことには何も始まらないので、エアギャップ環境での OCP システム構築時に必ず通る道ともいえるものです。
【大まかな流れ】
エアギャップ環境で OCP をインストールする場合、大きくは以下の流れを実施することになります:
(0)構成の検討・準備
(1)インターネット接続環境下で必要なインストールに必要なファイル群をダウンロード
(2)(1)でダウンロードしたファイルをエアギャップ環境に持ち込んで OCP を PXE インストール
(3)インストール後の作業
(0)は導入する OCP のバージョンの確定であったり、マスターノード/ワーカーノードの構成(台数)であったり、各ノードサーバーのスペック見積り、といった準備作業です。(1)以降の作業を行う上で RedHat アカウントが必要になるので、その取得なども含まれます。
(1)実際に「OCP をインストールする」と言える作業は(2)で行うことになるのですが、その準備としてインターネット接続環境下でインストールに必要なファイル群をまとめてダウンロードしておく、という作業です。具体的に必要なファイルは(0)で検討したバージョンなどにも依存しますが、単に OCP の導入に必要なファイルだけでなく、前回紹介した周辺環境をまとめてセットアップする OCP4 ヘルパーノードなどもこのタイミングでダウンロードしておきます。
(2)「OCP をインストールする」作業です。これも前回紹介しましたが、本ブログでは PXE インストールによる導入手順を紹介します。各種コマンドを実行することにはなるのですが、いわゆる "setup.exe" や "install.sh" のようなものとは異なり、「インストール自体は PXE で実行されるので、インストール状況を確認するコマンドを実行」することになります。
(3)OCP 導入後にエアギャップ環境特有の設定が必要になります。
ではこの流れで実際に OCP をエアギャップ環境でインストールしてみます。
【(0)構成の検討・準備】
今回構築する OCP は「エアギャップ環境で OCP を作る手順を確認する」ことを目的として(OCP 上で何か重いアプリケーションを動かすことを目的とはせず)、以下のスペックとしました:
・マスターノード3、ワーカーノード3
・ノードは全て仮想サーバー(x86_64)
・仮想サーバーのスペックは vCPU x 4、メモリ 16GB、ディスク 200GB
・各ノードサーバーの NIC は PXE ブートに対応したもの
・OCP バージョンは 4.13.0
ちなみに vCPU x 4 は最小スペックで、メモリはマスターノード 16GB、ワーカーノード 8GB が最小スペック。ディスクは 120 GB が最小で、これらを満たしていないとインストール時のチェックにひっかかります(引っかかった結果、どうなるかは知りません。とりあえず「満たしてない」というメッセージが出ることは確認)。ワーカーノードは(マスターノードにワーカーノードのロールを割り当てれば)0でもいいですが、マスターノードは最低3つ必要です。
これ以外にブートストラップノード(後述)やバスチョンサーバー(後述)も必要なので、1台のデスクトップ PC 内の仮想環境で作ろうとすると、vCPU やディスクはともかく、メモリがかなり厳しいはずで、最低 128GB はないと難しい(スワップしまくり)になると思います。64GB 搭載の PC だとマスターノード3、ワーカーノード0でも厳しいかも。。ちなみに私は(今更 VMWare を使うのもアレなので) VirtualBox を使って今回の作業を実施しています。
改めて、今回の OCP クラスタでは以下表の構成でサーバーを用意することにします:
なお、ドメインは "ocp.xxx.localdomain" を使うことにします(バスチョンサーバーの FQDN は bastion.ocp.xxx.localdomain" となります)。ちょっと細かいことを言うと、この場合、OCP 導入時の「ドメイン」は "xxx.localdomain" で、"ocp" は「クラスターID」と呼ばれます。この辺り慣れていないとわかりにくいのですが、OCP 導入時は OCP 用のサブドメインを使うことが想定されているので、いわゆる一般的なドメインを使うのではなく、クラスター ID が追加されたサブドメインを使って構築する(OCP のドメインは「クラスターID + ドメイン」から成り立っている)、と理解しておくのが分かりやすいのではないかと思いました。
また今回は PXE インストールを行うため、各ノードサーバーの NIC は PXE 対応している必要があります。物理サーバーの場合は PXE に対応した物理 NIC を用意するか、ネットワークブート可能な KVM を用意してください。仮想サーバーの場合は PXE に対応した仮想 NIC を選択することになります。VirtualBox であればデフォルトの Intel PRO/1000 MT Desktop(82540EM) であれば PXE 対応しています:

また各ノードサーバーの起動優先順位を以下のように設定します(上にあるものほど優先順位を高く設定します):
・DVD, USB メモリ
・ディスクストレージ(HDD, SDDドライブ)
・ネットワーク
今回のインストールでは使いませんが、緊急時のメンテナンスなどの目的で DVD や USB メモリから起動したくなるケースが想定されます。そのような時のために DVD や USB メモリでの起動を最優先に設定しておきます。 次にディスクストレージを優先して起動します。今の段階ではディスクには何もインストールされていません(何らかの OS がインストール済みのディスクを使う場合は削除してください。詳しくはこちら)が、この後の作業で CoreOS をインストールします。CoreOS インストール後は CoreOS を起動する、という設定です。 そしてディスクに何もインストールされていない場合は PXE インストールを実施するためネットワークブートも可能になるよう(ディスクよりも低い優先順位で)設定しておく必要があります(下図はサンプル):

また OCP 4.13.0 は今となっては推奨バージョンとはいえないと思いますが、のちの作業で 4.14.0 へアップグレードしたいので、そのために敢えて低めのバージョンで初期インストールします。
【(1)インターネット接続環境下で必要なインストールに必要なファイル群をダウンロード】
では(0)で決めた OCP 4.13.0 をエアギャップ環境でインストールするために必要なファイルを用意します。まずはインターネットに接続できる RHEL(RedHat Enterprise Linux) 9.x を用意します。ディスクの空きは 4.13.0 の初期インストールだけなら 50GB くらい、初期インストール後に実施する 4.14.0 へのアップグレードに必要なファイルまでを同じ環境でダウンロードするつもりであれば 100GB は必要です。このダウンロードを実施するための PC のメモリは 4GB 程度ないと厳しいかも、、そのつもりで環境を準備してください。
では早速必要なファイルのダウンロード・・・なんですが、1つだけ入手方法が他と異なる特殊なファイルがあるので、まずはこれから紹介します。RedHat でアカウントを作成し(個人アカウントでも構いません)、そのアカウントでログインして pull-secret と呼ばれるファイルをダウンロードします。pull-secret は「ダウンロード」と表現していますが、正確には「ログイン済みのユーザー向けに作成されたものをダウンロード」します(つまりログインユーザー毎に内容は異なるファイルです)。ログイン時の RedHat アカウントに紐づいた内容で利用できるものですが、個人アカウントでも開発者サブスクリプションに登録することで無料で利用できるものなので、必要であれば開発者サブスクリプションに登録してください。この辺りの登録手順は前回の内容を参照してください。
pull-secret をダウンロードするには RedHat アカウント作成後にブラウザで https://cloud.redhat.com/openshift/install/pull-secret にアクセスします(ログイン前の場合はここでログインが必要です)。そして "Download pull secret" ボタンをクリックするとダウンロードが始まります:

ダウンロードした pull-secret は "pull-secret" または "pull-secret.txt" というファイル名でダウンロードされます。ファイル名は後者("pull-secret.txt")だった場合は前者("pull-secret")にリネームしておいてください。以降は "pull-secret" という拡張子のないファイル名でダウンロード済みであると仮定して説明を続けます。
このダウンロードした pull-secret ファイル自体もエアギャップ環境に持ち込む必要があるのですが、この後のインターネット接続環境での作業でも必要なファイルです。同 "pull-secret" ファイルを "/root/.docker/config.json" というファイル名で保存します(~/Downloads/pull-secret というファイルとしてダウンロード済みの場合の例です):
次にファイルをダウンロードする準備として、この後の作業の中で必要になるツール類をあらかじめまとめてインストールする、という手順を実施します。具体的には root ユーザーの CLI で以下のコマンドを実行します:
またダウンロードするファイルを保管するためのフォルダ(/data)を作成しておきます:
早速ダウンロードした pull-secret も /data にコピーしておきましょう:
ここからが本格的な「ファイルダウンロード」作業となります。手順は決して短くはないのですが、最初は内容の理解が甘くても構いませんので、以下で紹介されている CLI コマンドを淡々と実行いただくことで済むものです。
ではエアギャップ環境に持ち込む必要があるファイルを順にダウンロードしていきます。まず最初は OCP4 ヘルパーノードを動かすために必要な ansible-galaxy のコレクションモジュールです。以下のコマンドを実行して、~/collections/ というフォルダに community.crypto と ansible-posix モジュールをダウンロードします(ここではインストールは不要で、ダウンロードのみ実行します):
コマンドが正しく実行されると ~/collections/ というフォルダが作られていて、その中に community-crypto-x.x.x.tar.gz と ansible-posix-x.x.x.tar.gz というファイルが存在しているはずです(x.x.x 部分はバージョン番号で、実行したタイミングによって異なります)。上記最後のコマンドでダウンロードしたモジュールを collections/ フォルダごと /data にコピーしています。
続いてこの後バスチョンサーバーで使うことになる OCP4 ヘルパーノード本体と、NFS プロビジョナーを github からダウンロードします:
これらのコマンドが正しく実行されると /data 以下に ocp4-helpernode.tgz と nfs-subdir.tgz という2つのファイルが作られます。
次はいよいよ OCP 4.13.0 の OS 部分である RHCOS(RedHat CoreOS) 4.13.0 本体となるファイル群を RedHat サイトからダウンロードします:
/data/ocp-files/ というフォルダを作成し、その中に6つの RHCOS 4.13.0 インストール用ファイルをダウンロードしました。
OS のイメージをダウンロードした後はいよいよ OCP 本体部分のダウンロードに移ります。次はバスチョンサーバー内に構築する OCP 4.13.0 のミラーレジストリとなるコンテナイメージをダウンロードします。この実体は docker.io から提供されているコンテナイメージなので、上記手順で実行した docker 互換の podman を使い、インターネット接続環境でこのイメージを docker pull (正確には podman pull)して、その結果を tar ファイル(/data/registry.tar)にエクスポートする形でファイルの形でダウンロードします:
そしてこのミラーレジストリに展開する(ミラーリングする)中身となるミラーイメージの準備です。まずはミラーリング実行時のコマンドとなる oc と oc-mirror をダウンロードします。まずは oc-mirror から(この後実際にミラーリングするので /data だけでなく /usr/local/bin にもコピーしています):
同様に oc コマンドを用意します。ダウンロードする必要のあるファイルは上述でダウンロード済みの openshift-client-linux-4.13.0.tar.gz なので、ここから oc コマンドだけを取り出します:
ここからが本作業の中で一番のメインイベントとなるミラーイメージのダウンロードとなります。インターネット接続環境にも依存しますが、最も時間のかかるダウンロード作業で、ダウンロード結果となるファイルのサイズも巨大なもの(1ファイルで 30GB 近く)となるものです。
ミラーイメージダウンロードの準備として、以下の内容で /data/imageset-config-4.13.0.yaml を作成します。このファイルに記載されている内容に従ってミラーレジストリ作成に必要なファイルがダウンロードされるもので、OCP 4.13.0 を初期インストールするための内容になっています。なお同時に local-storage-operator というオペレーターもダウンロードしています。これは今回特に使うわけではないのですが、エアギャップ環境のミラーレジストリでも OperatorHub を有効にできていることを確認する目的で指定しています(今回の OCP 4.13.0 のインストールが完了すると、Local Storage Operator だけが OperatorHub に表示されるようになります)。OCP インストール後に利用することが決まっているオペレーターがある場合はこの imageset-config-4.13.0.yaml ファイル内に記載して、一緒にダウンロードするようにしてください:
上記ファイル内の赤字部分についてコメントしておきます。まず storageConfig.localpath = /data/mirror-ocp という部分でファイルのダウンロード先フォルダを指定しています。 次に mirror.platform.channels で "4.13 の安定板(stable-4.13)" を使うことを明記し、そのバージョンとして 4.13.0 から 4.13.0 まで(つまり 4.13.0)を対象にダウンロードすることを指定しています。 そして mirror.operators 内で local-storage-operator:stable オペレーターを一緒にダウンロードする旨を記載しています。必要に応じて適宜変更してください。
ではこのファイルを使ってミラーイメージを一括ダウンロードします。上述の pull-secret(~/.docker/config.json)がないとダウンロードは失敗するので注意してください:
最後のコマンドを実行すると(正しく実行されると)ファイルのダウンロードが開始されます。ここはかなり時間のかかる作業なので、ずっとこの環境のターミナルを開けない環境などの場合は tmux などでバックグラウンド実行することを推奨します。
コマンドが最後まで正しく実行されると /data/mirror-ocp/mirror_seq1_000000.tar という 30GB 前後の巨大なファイルが作られます。これがミラーイメージと呼ばれるもので、この後エアギャップ環境のミラーレジストリを作る際の中身に相当するものです。
インターネット接続環境を使って最低限ダウンロードしておくべきファイルは以上です。以下はエアギャップ環境によっては必要となるファイルであったり、事前にインターネット接続環境下で(というか、エアギャップ環境では使えるエディタも限られてしまうので、普段使っているテキストエディタが使える環境のうちに使って)用意しておくと便利なファイルです。
この後のエアギャップ環境下では主にバスチョンサーバーと呼ばれる作業マシン内に必要な環境を構築していくことになります。その際に RHEL の(yum/dnf コマンドを実行してパッケージをインストールする際の)パッケージリポジトリが必要になります。 RHEL の DVD(ISO) メディアを用意し、その DVD(ISO) を RHEL に挿入して作業することができる環境の場合はその方法でパッケージリポジトリを構築できるのでいいのですが、例えばバスチョンサーバーが物理サーバーで、かつ DVD ドライブを内蔵していないようなケースだったりすると DVD を挿入するだけでパッケージリポジトリを用意することができなくなります。そのような場合は RHEL ISO ファイルそのものをエアギャップ環境に持ち込む必要があります(サイズの小さい Boot DVD ではなく、フル DVD の ISO が必要です)。以下のサイトから RHEL DVD の ISO ファイル(例えば rhel-9.2-x86_64-dvd.iso)を事前にダウンロードして、/data フォルダに保存しておきます。なおここでもダウンロード時に RedHat アカウントでログインする必要があります:
https://developers.redhat.com/products/rhel/download
またこの ISO を使ってパッケージリポジトリを構築する場合は、以下の内容のリポジトリ構築用の設定ファイル(/data/isorepo.repo)が必要です。エアギャップ環境での作業になるとテキストエディタも自由には選べなくなるので、インターネット接続が使えるうちに設定ファイル類を作っておくことをお勧めします:
このような設定ファイルがいくつか必要なので、インターネット接続環境で作れる範囲で作ってしまうことにします。というわけで次は OCP4 ヘルパーノードを使う際のパラメータファイルである /data/vars.yaml を以下の内容で作っておきます:
ここでも赤字部分についてコメントしておきます。まず2行目に disk = "sda" という記載をしていますが、これは「OCP をインストールする環境ではディスクは /dev/sda として認識されている」ことを示しています。とりあえずこの値を設定していますが、実際の環境はエアギャップ環境内のバスチョンサーバーなどで確認いただきたいのですが、異なる場合はここを編集してください。また6行目で helper.networkifname = "enp0s3" と記載しています。これはバスチョンサーバーのネットワークインターフェース名("ip a" や "ifconfig" コマンドで確認できるインターフェース名)が "enp0s3" であることを意味しています。この値も実際のものと異なる場合は編集してください。 もう1つ、今回は OCP を構築するドメインを "ocp.xxx.localdomain" とする、と書きましたが、このファイルでは dns.domain と dns.clusterip に分けてドメインを設定している点に注意してください(2つを足して <dns.clusterid>.<dns.domain> で実際に利用するドメイン名になるよう指定してください)。
次に数か所で IP アドレスを指定していますが、各ノードサーバーの想定 IP アドレスに加えて、DHCP サーバーや chronyd サーバー(時刻同期サーバー)の IP アドレスも指定しています。今回は OCP4 ヘルパーノードを使って周辺環境を構築するので、DHCP, DNS などは全てバスチョンサーバーと同じ IP アドレスを指定する必要がある点に注意ください。また macaddr が空文字列になっている行が多いですが、これらには各ノードサーバーのネットワークインターフェースが持つ MAC アドレスを指定することになります。各サーバーの MAC アドレスの値を調べて、"xx:xx:xx:xx:xx:xx" 形式で入力する必要があるのですが、今の時点では(まだ使わないので)空文字列にしていても大丈夫です。
ただこの vars.yaml ファイルはとても大事なファイルです。この中で指定する IP アドレスや MAC アドレスが(ちょっとしたミスで間違えやすいものですが)1箇所でも間違えているとうまくインストールできなくなってしまうものなので、注意して入力するよう心掛けてください。
続いて、時刻同期サーバーである chronyd の設定ファイル(/data/chrony.conf)を以下の内容で用意します(10.10.0.0/24 のアドレスからのみリクエストを受け付ける設定をしています):
もう1つ、OCP インストール時の設定ファイル(install-config.yaml)を生成するシェルスクリプト(/data/install-config.sh)を以下の内容で用意します:
上述の vars.yaml 同様、このファイルでも <metadata.name>.<baseDomain> で実際のドメイン名になるよう記載する点に注意が必要です。またこのファイルの中でマスターノードが3つ、ワーカーノードが3つそれぞれ必要になることが記載されている点にも注意してください(OCP が正しくインストールされているかどうかは、ここで指定した値の数だけノードが用意できているかどうかで判断されます)。
ここまでの作業を行うと、/data 以下に以下のファイル/フォルダができているはずです:
上記ファイルを全て(フォルダはフォルダまるごと) USB メモリなどに入れて、この後の作業となるバスチョンサーバーにコピーする必要があります。方法は USB メモリ以外に USB ディスクでも構いません。作業用の PC を持ち込むのであれば、その作業 PC の中に入れて持ち込むのも一つの方法です。1ファイルで 30GB 近くあるものも含まれているので1枚の DVD では無理ですが、ファイルを分割すれば複数枚の DVD で持ち運ぶことはできると思います。 方法はともかく、これらのファイルをなんらかの方法でインターネット接続のないバスチョンサーバーが利用できる状態にする必要があります。場合によってはここがエアギャップ OCP 環境構築の最初の関門になると思います。
ここまでの手順ができればインターネット接続のある環境で行う作業は以上です。ここまでで既にかなり長い説明になっていますが、本番はここから。次からはいよいよインターネット接続がない環境下で実施する作業に入ります。
【(2)OCP を PXE インストール】
ここから先は全てインターネット接続のない環境で実施することになります。これまでにインターネット接続環境で用意したファイルを使って OCP 4.13.0 をインストールします。
ここで構築する OCP は以下のようなサーバー群から構成されます:

このうち、バスチョンサーバー以外のノードは PXE インストールと呼ばれるネットワークインストールで導入します。つまり「ほぼ電源を入れるだけ」の作業です。 OCP をインストールするための作業という意味ではその大半が「バスチョンサーバーを構築する作業」となります。
ではエアギャップ環境でバスチョンサーバーを構築する手順を紹介します。まず前提としてエアギャップ環境内に RHEL がインストールされたサーバーを1台用意します(エアギャップ環境内で RedHat のサブスクリプションを有効にする手順等はこちらを参照してください)。またバスチョンサーバーは SELinux が無効になっていると OCP4 ヘルパーノード実行時にエラーとなってしまうので、SELinux はデフォルトの permissive や enforcing にするなどして無効以外の設定にしてください:

加えてバスチョンサーバーにインストールする RHEL は("Minimum Install" ではなく)"Server with GUI" オプションでインストールしておくことを推奨します。理由はインストールされた OCP のウェブコンソール画面にアクセスする際、このバスチョンサーバーのウェブブラウザからアクセスするしかない可能性があるためです。他の作業用 Windows PC などがある環境であれば、その Windows からウェブアクセスすることも可能ですが、そのような作業マシンがない場合は全てバスチョンサーバーを使って設定する必要があり、ウェブアクセスが必要な場合もバスチョンサーバーのウェブブラウザを使う必要に迫られる可能性があるからでした(以下はバスチョンサーバーが "Server with GUI" でインストールされている前提で説明します)。
そして上述の【1】でダウンロードしたファイル群はバスチョンサーバーの /data/ 以下にコピーされているものと仮定して以下の説明を続けます。つまりバスチョンサーバーにも以下のファイルが存在しているものと仮定して以下を続けます:
またブートストラップノードや各マスターノード/ワーカーノードのサーバーに付属している NIC の MAC アドレスも必要です。MAC アドレスの値は仮想サーバーなどであれば比較的簡単に調べることができますが、物理サーバーだと最悪の場合、実際に OS が動いている状態でないと調べる方法がない可能性もあります。このあたりの OS をインストールしなくても調べる具体的な手順はこちらでも紹介しているので参考にしてください。
改めてここからはエアギャップ環境(インターネット接続のない環境)下での、バスチョンサーバーと呼ばれる作業サーバーの準備手順を紹介します。以下のコマンドは全て root ユーザー権限で実行してください(sudo 権限のある一般ユーザーからは "sudo -i" を実行して root ユーザー権限でターミナルを準備してください)。
事前に確認する情報としてもう1点、これ以降の説明では /usr/local/bin フォルダに実行 PATH が設定されている必要があります。もし設定されていない場合は ~/.bashrc の最後に以下の1行を追加して再ログインしてください:
まずは対象サーバーにインストールした RHEL を起動します。この際に DVD ドライブに RHEL DVD を入れることができる場合は挿入しておきます(これで DVD のローカルリポジトリからパッケージがインストールできるようになります)。その様な環境ではない場合は、上述の手順で rhel-9.2-x86_64-dvd.iso と isorepo.repo ファイルをエアギャップ環境の /data フォルダ以下にコピーしているので、これらを使ってローカルリポジトリを作る作業が必要になります。 ISO ファイルを使ってローカルリポジトリを作成する場合は事前に用意した /data/isorepo.repo ファイルを併用して作成します。その場合、まずは /media/rheliso という空のフォルダを作成します:
このフォルダに ISO ファイルをマウントします。一時的なマウントではなく恒久的にマウントしたいので、/etc/fstab ファイルに以下の1行を追加してバスチョンサーバーを再起動します(再起動後に /media/rheliso に DVD がマウントされているはずです):
マウントされた DVD(ISO) を使ってローカルリポジトリを作成します。/data/isorepo.repo ファイルを /etc/yum.repos.d/ にコピーします。加えてサブスクリプションを無効にしてデフォルトのリポジトリが自動的に復元されないようにします。最後にデフォルトのリポジトリファイルを削除してからリポジトリを更新します(これでローカルリポジトリが作成され、使える状態になります):
ローカルリポジトリが利用可能な状態になったので、ここからこの後の作業に必要なパッケージ類をインストールしていきます。以下のコマンドを実行して、ローカルリポジトリからまとめてインストールします:
上のコマンドで ansible 系のコマンドもインストールしているので、インターネット接続環境でダウンロードした ansible collection コマンドが使えるようになります。以下のコマンドで2つのパッケージをインストールします(x.x 部分は実際にダウンロードしたファイルバージョンに合わせて指定して下さい):
次にネットワークインターフェースを設定します(ネットワーク設定が済んでいる場合、ここは飛ばしてください)。まずはネットワークインターフェース名を確認するため、以下のコマンドを実行します:
コマンドの結果、"lo" のインターフェースに関する情報と、それとは別のインターフェースに関する情報が表示されます。"lo" はローカルホスト用の設定なのでこちらではなく、もう1つのインターフェースに関する情報は実際の通信に使うインターフェースです。この後、そのインターフェース名を使って設定を行うので、インターフェース名を見つけてください。以下の例では "enp0s3" が求めるインターフェース名で、以下この前提でコマンドを実行していきますが、実際に入力するコマンドは自分の環境でのインターフェース名に合わせて変更してください:

今回の前提ではバスチョンサーバーは IP アドレスは "10.10.0.10/24" 、FQDN は "bastion.ocp.xxx.localdomain" として構築するので、そのための設定変更を行います。なおデフォルトゲートウェイが存在する環境の場合はそのアドレスを指定する必要がありますが、特にない環境の場合は自分自身のアドレス(10.10.0.10)を指定します。また DNS はこの後 OCP4 ヘルパーノードが作る環境をそのまま使うので、ここは自分自身のアドレス(10.10.0.10)を指定します:
また、このバスチョンサーバーは "registry.ocp.xxx.localdomain" という名前でもアクセスすることができるようにしておきます。そこで /etc/hosts ファイルを編集し、以下の1行を追加して保存します:
ネットワークの設定ができたら、次はミラーレジストリを作ります。ミラーレジストリとなるコンテナイメージを podman(docker)に展開して、空のミラーレジストリを作成しておきます:
ミラーレジストリの中身をロードするにはいくつかのコマンドを用意する必要があるので、その辺りも含めて OCP4 ヘルパーノードの準備を先にしておきます。あらかじめダウンロードした tgz ファイルをホームディレクトリに展開し、更にあらかじめ用意しておいた設定ファイル(/data/vars.yaml)を上書きします:
OCP4 ヘルパーノードを実行する前に改めて ~/ocp4-helpernode/vars.yaml ファイルの中身を実際の環境に合わせた正しい情報に更新してください。赤字部分はコメントです。実際の環境に合わせて正しく変更してください(ここが間違っていると PXE インストールが正しく実行されなかったり、正しく導入完了を検知できなかったりします。特に MAC アドレスに注意):
OCP4 ヘルパーノードを実行するには(エアギャップ環境ではあるのですが) pull-secret に関する情報が必要です。以下の手順でダミーの pull-secret を作っておきます:
このまま次の処理を続けてもいいはずなんですが、私が実際に試した環境だとここで一度サーバーを再起動しないといけないことがありました。自分でもどちらが正解か自信がないのですが、このまま続けて次の ansible-playbook コマンドが失敗する場合はバスチョンサーバーを再起動してください。
~/ocp4-helpernode/vars.yaml ファイルの準備ができたら OCP4 ヘルパーノードを実行します。コマンドは ansible playbook として用意されているので(その変数部分が vars.yaml に集約されているので)以下のコマンドを実行します。成功すると DNS や DHCP、TFTP、HAPROXY など、この後の PXE インストール時に必要な周辺環境に加え、oc コマンドの準備や ssh で利用する鍵の準備などもまとめて構築してくれます(完了まで数分から数十分かかります)。OCP4 ヘルパーノードを使わない場合、1つ1つこれらの環境を用意する必要があることを考えると、とても便利です:
ここまでできていれば事前環境準備はほぼミラーレジストリの中身をインストールイメージ(今回の例だと OCP 4.13.0 インストール用のイメージ)にするだけなんですが、NTP(時刻同期サーバー)については少し手を加える必要があります。といっても事前に用意した /data/chrony.conf で /etc/chrony.conf を更新して起動するだけです:
このタイミングで OCP インストール時用の設定ファイル(install-config.yaml)を作っておくことにします。これも事前に用意した /data/install-config.sh を実行することで install-config.yaml ファイルを作ります。 なお、/data/install-config.sh を実行する際には ~/.openshift/pull-secret, ~/.ssh/helper_rsa.pub, /opt/registry/certs/domain.crt の3つのファイルが存在している必要がありますが、ここまでのコマンドが成功していれば全て作成されているはずです。
では install-config.yaml ファイルを作成します:
正しく実行されるとカレントディレクトリに install-config.yaml というファイルが生成されています。このファイルは OCP インストール時に利用します(後で使います)。
いよいよ、このバスチョンサーバー構築時におけるメイン作業ともいえる(OCP 4.13.0 用の)ミラーレジストリの構築を行います。構築時の中身となるイメージは /data/mirror_seq1_000000.tar ファイルとして用意されているので、これをレジストリにインポートすればよいのですが、そのためにはもともと用意していた pull-secret と、今回のミラーレジストリにアクセスするための鍵情報をミックスした鍵ファイルを用意する必要があります。順に行っていきます。
まずはインターネット接続環境でダウンロードした pull-secret ファイル(/data/pull-secret)を JSON 変換したものを /data/config.json というファイルで書き出しておきます:
次に(ansible-playbook 実行時に作成された)~/.openshift/pull-secret-update というファイルを "# cat ~/.openshift/pull-secret-update" などで表示します(赤枠部分をこの後使います):

そして /data/config.json をテキストエディタで開きます。以下のような内容が表示されます:

この2行目と3行目の間に先ほど確認した ~/.openshift/pull-secret-update ファイルの赤枠部分をコピー&ペーストなどで挿入し、最後に ","(カンマ)を入力して保存します:

こうして出来上がった /data/config.json を ~/.docker/config.json としてコピーします。これでミラーレジストリイメージをインポートする際に必要な鍵ファイルの準備ができました:
そしてミラーレジストリのインポート実行時に必要な oc-mirror バイナリを /data/oc-mirror から /usr/local/bin にコピーします:
ここまでに準備した環境を使って(OCP 4.13.0 用の)ミラーイメージをミラーレジストリにインポートします(上述の ansible-playbook を実行した時と比較しても、終了まで更に長い時間がかかるコマンドです):
正常に終了していると ~/oc-mirror-workspace/ というフォルダが作られ、その中に results-xxxxxxxxxx といった名称のフォルダが作られているはずです(このフォルダはインストール後の調整時に使います):

以下のコマンドを使ってミラーレジストリが正しくインポートされ、動作していることを確認します(例のように "4.13.0-" で始まるタグ行がたくさん表示されることが確認できれば成功です):

ここまでできればバスチョンサーバーとしての準備は完了です(OCP インストールの大きな山を1つ越えた、くらいに考えてください)。後は実際に OCP をインストールする際の PXE インストール用のファイルを準備する必要がありますが、周辺環境の準備は完了した、くらいに理解していただいて大丈夫です。
PXE インストール用に用意するファイルの中にはイグニッションファイルと呼ばれるものが含まれます。これは CoreOS インストール時に必要な鍵ファイルですが、有効期限は 24 時間です。つまりここから先の手順であるイグニッションファイルの作成から OCP インストール完了までを 24 時間以内に行う必要があります。よほど貧弱な仮想環境とかでない限りは 24 時間以内に終わるのが普通の処理内容ではあるのですが、24 時間を超えてしまうとイグニッションファイルが無効になってしまうので、実行タイミングは気を付けてください(日をまたぐ可能性があるタイミングでの実行はやめたほうがいいです)。
というわけで PXE インストール用のファイルを用意します。まずは先程作成した ~/install-config.yaml ファイルと OCP4 ヘルパーノードが用意してくれた openshift-install コマンドを使ってマニフェストファイルを作成します:
このコマンドの結果、~/config/ フォルダが作られ、その中に各種マニフェストファイルが作成されるのですが、一部は OCP4 ヘルパーノードが用意したものを使う必要があります:
ここまで用意したマニフェストファイルを使ってイグニッションファイルを作成します。繰り返しますが、ここから先 OCP のインストール完了まで 24 時間以内に実施する必要があることに注意してください:
成功すると config フォルダ直下に拡張子が .ign となっているイグニッションファイルが生成されています。これを PXE インストール時に HTTP 経由で取り出せるよう、ドキュメントルートにコピーします:
これで PXE インストール実行時に必要なイグニッションファイルも用意できました。最後に PXE シーケンスの最初にファイルをダウンロードさせるための TFTP サーバーを設定します:
これで PXE インストール前にバスチョンサーバー上で実行しておく必要のある準備は全て完了しました。
後は各ノードサーバーの電源を順次入れていきます。実際のところ、どのような順に電源を入れても構わないのですが、OCP としては以下の順に起動していくので、この順序で電源を入れていくのがいいと思われます:
・ブートストラップノード
・マスターノード
・ワーカーノード
各ノードとも PXE ブートが実行され、バスチョンサーバーに用意された環境から CoreOS をダウンロードしてインストールし、OCP を構成するサーバーとして自分自身を作り上げてゆきます。PXE ブート、慣れないとうまく行っているのかどうかもわかりにくいと思いますが、成功していると以下のような "PXE" とか "iPXE" といった文字列が表示され、RHCOS がネットワーク経由でダウンロード/インストールされていく様子が確認できます(画面は機種によって少し変わると思います。しばらく待ってもこうならない場合は何かミスってる可能性大です):

各ノードとも以下のような "Red Hat Enterprise Linux CoreOS" で始まる以下のような画面になっていれば、用意したイグニッションファイルが適用されて、少なくとも CoreOS のインストールまでは完了していると思ってください(OCP としてはまだインストール中の可能性があります):

なお、私の手元の環境だとブートストラップノードの画面に(以下図のように)赤字で Unable to pull OpenShift release image と表示されて、OCP インストールが先に進まなくなってしまうことが度々ありました:

この場合はバスチョンサーバー上で
を実行すると、数秒後にブートストラップノード上の赤い文字も消え、インストールが先に進むようになりました。もし同じ現象を確認された方がいたら試してみてください。
ここからは基本的には「OCP インストール完了を待つ」作業になります。ただ OCP インストール完了前からでも、下で紹介するような一部の OCP 関連コマンドが実行できるようになるので、インストール状況を確認する意味でも試してみてください。
まずマスターノードの OCP 導入状況を確認するには openshift-install コマンドに "wait-for bootstrap-complete" オプションを付けて実行します(ついでにログレベルも debug にして、より詳細な情報を表示するようにします)。約30分間にわたり、マスターノードのインストール状況が進んでいく様子を確認できます(マスターノードは数度リブートを繰り返しながら CoreOS と OCP のインストールが進んでいきます。環境次第ですが早ければ 30 分程度あればマスターノードのインストールは完了します。このコマンドは途中で Ctrl+C で終了して、再度同じコマンドを実行することで再度インストール状況の続きを見ることができます):

以下のように "Bootstrap status: complete" と表示されればマスターノードの導入は成功しています(続けてワーカーノードの導入が進んでいます):

また全てのマスターノードの導入が上記のように完了していると一部の oc コマンドが使えるようになります。oc コマンドを実行するには以下のようにバスチョンサーバー上で環境変数 KUBECONFIG を設定し、コマンド("oc get nodes")を実行してみます:
oc コマンドが使える状態になっていれば、現在までに OCP が認識しているマスターノードの一覧が表示されるはずです(この時点ではワーカーノードは表示されません)。まずは3つ全てのマスターノードが Ready のステータスで表示されるようになるのを待ちましょう:

3つのマスターノードが全て Ready になるとワーカーノードの導入が開始されます。ただワーカーノードは自動的に "oc get nodes" で表示されるようにはならず、手動で CSR を承認する必要があります。
まずは承認が必要な状態になっているものがあるかどうかを以下のコマンドで確認します(CSR の一覧を表示し、その中に承認待ち(Pending)ステータスになっているものがあれば表示する、というコマンドです):
このコマンドの結果、承認待ちステータスになっている CSRが存在していると以下のような画面になります(マスターノードが全て準備できてから、この状態になるまで数十分~数時間かかります):

その場合は以下のコマンドを実行して、承認待ちの CSR をまとめて承認します:

この「承認待ち CSR があるか?」と「あったらまとめて承認する」を何度か繰り返し、数分待っても承認待ち CSR が新たに追加されなくなる状態を待ちます。本当に全ての CSR が承認されていればワーカーノードも順次 OCP に組み込まれてゆき、"oc get nodes" コマンドの結果に表示されるようになります。全てのマスターノードと全てのワーカーノードが "oc get nodes" コマンドの結果として、ステータスが Ready の状態で表示されるようになることを確認します:

ここまで完了すれば「ゴールまであとちょっと」です。最後に OCP としての基本機能(認証とかウェブコンソールとか・・)を提供するクラスターオペレーターが全て Ready な状態になることを確認します。確認コマンドは以下で、その結果全ての行でエラーメッセージや警告メッセージが表示されず、AVAILABLE=True なステータスになる状態を待ちます(つまり待つだけです):

クラスターオペレーターが全て有効な状態になったことが確認できれば OCP のインストールは完了したことになります。確認のため、ウェブブラウザからウェブコンソール画面にアクセスしてみましょう。その前に管理者ユーザー(kubeadmin)のパスワードを確認するため、以下のコマンドを実行してログインパスワードを表示します:
ログインパスワードを確認したら改めてウェブブラウザを起動し、ウェブコンソール画面である以下の URL にアクセスします(SSL は自己署名証明書を使っているので警告画面になりますが、警告を無視して先に進めてください):
すると以下のようなログイン画面が表示されます。(これが表示できた時点で OCP インストールは成功しているといえそうですが、、)ユーザー名に "kubeadmin" 、パスワードには先ほど確認したログインパスワードを入力してログインします:

ログインが成功すると以下のようなウェブコンソールのトップ画面が表示されます:

ここまでできれば OCP のエアギャップ環境下でのインストールは成功したと言えます! そしてイグニッションファイル作成からここまでを 24 時間以内に実行する必要がある、という点に改めて注意してください(過ぎちゃった場合は ~/config フォルダごと消してマニフェストファイルの作成からやり直し)。
なお、バスチョンサーバーであれば上述のように環境変数 KUBECONFIG を設定することで oc CLI が使えるようになりますが、他のサーバーであったり、バスチョンサーバーでも実施コマンドによってはトークンでログインしておく必要が生じます。ここでの紹介の最後にトークンでのログイン方法を紹介しておきます。
・・と言っても、トークンでのログイン方法はエアギャップ環境ではない時と同様です。まず上述の方法でウェブコンソールにログインし、画面右上のメニューから "Copy login command" を選択します:

このような画面が表示されたら "Display Token" と書かれた箇所をクリックします:

すると以下のような画面になるので "Log in with this token" と書かれた "oc login" で始まる文字列をコピーします:

コピーした文字列を oc コマンドが導入された環境でペーストして実行すると CLI でのログインが完了し、"oc get nodes" や "oc get clusteroperators" などのコマンドが同様に実行できるようになります。
【(3)OCP インストール後の作業】
ここまでの手順でエアギャップ環境での OCP がインストールされて、稼働状態になりました。が、実はこの状態だとまだエアギャップ環境に対応していない箇所が残っています。最終的にそれらの部分をエアギャップ環境用の調整して作業完了とみなすことにします。
まずこの時点では OperatorHub が使えません。オフライン環境ではこの方法でインストールした OCP の OperatorHub は未対応なので、OperatorHub のオフライン対応を行います。そのため、一旦全ての Sources を disable に設定します:
そしてミラーレジストリを構築した際にできたフォルダ(~/oc-mirror-workspace/results-xxxxxxxxxx/)の情報を使ってオフライン対応を実施します:
上の2番目のコマンド("oc apply -f oc-mirror-workspace/results-xxxxxxxxxx")を実行した時に以下のようなエラーメッセージが表示されますが、エアギャップ環境では無視して構いません:

ここまで実行することで OperatorHub もエアギャップ環境に対応できました。今回の環境では imageset-config-4.13.0.yaml ファイルを作った時に入れておいた Local Storage Operator が表示されます:

またワーカーノードをインフラノードとして利用する場合、対象ノードに以下のラベリングを行います。例えば worker0 のみインフラノードにする場合は、以下のコマンドを実行します(worker1 や worker2 を対象にする場合も同様に追加実行します):
そして、インストールを終えてもう使うことのないブートストラップノードをシャットダウンします。OCP 環境ではバスチョンサーバーからは各ノードの CoreOS に "core" ユーザーで(パスワードなしで)ssh ログインが可能です。また CoreOS 上では core ユーザーは sudo 権限を持っているので、以下のようにシャットダウンコマンドを実行可能です:
なお、ブートストラップノード以外のノードについては OCP 新規インストールから 24 時間はシャットダウンしないように気を付けてください。この辺り、詳しくはこちらも参照してください:
https://www.reddit.com/r/openshift/comments/c7e5na/how_to_shutdown_all_openshift_hosts_safely_in/?rdt=44062
最後にバスチョンサーバーの haproxy(ロードバランサー)からブートストラップノードを分離します。バスチョンサーバー上で /etc/haproxy/haproxy.cfg ファイルを開き、bootstrap ノードに負荷分散する設定になっている2行を削除するかコメントアウトして保存します:

最後に haproxy を再起動します:
これでエアギャップ環境上での OCP のインストールができました。非常に長いインストール手順でしたが、これで「エアギャップ環境で OCP を使う」ための準備ができたことになります:

この後はエアギャップ環境の OCP 内にコンテナアプリケーションをデプロイする手順や、OCP をエアギャップ環境のままアップグレードする手順を紹介してゆく予定です。
・エアギャップ環境(インターネット接続のない環境)で OCP を導入/運用する上で必要な前提理解
・エアギャップ環境(インターネット接続のない環境)で OCP を導入する手順
・エアギャップ環境(インターネット接続のない環境)で OCP にアプリケーションを導入する手順
・エアギャップ環境(インターネット接続のない環境)に導入した OCP をエアギャップ環境内でアップグレードする手順
【大まかな流れ】
エアギャップ環境で OCP をインストールする場合、大きくは以下の流れを実施することになります:
(0)構成の検討・準備
(1)インターネット接続環境下で必要なインストールに必要なファイル群をダウンロード
(2)(1)でダウンロードしたファイルをエアギャップ環境に持ち込んで OCP を PXE インストール
(3)インストール後の作業
(0)は導入する OCP のバージョンの確定であったり、マスターノード/ワーカーノードの構成(台数)であったり、各ノードサーバーのスペック見積り、といった準備作業です。(1)以降の作業を行う上で RedHat アカウントが必要になるので、その取得なども含まれます。
(1)実際に「OCP をインストールする」と言える作業は(2)で行うことになるのですが、その準備としてインターネット接続環境下でインストールに必要なファイル群をまとめてダウンロードしておく、という作業です。具体的に必要なファイルは(0)で検討したバージョンなどにも依存しますが、単に OCP の導入に必要なファイルだけでなく、前回紹介した周辺環境をまとめてセットアップする OCP4 ヘルパーノードなどもこのタイミングでダウンロードしておきます。
(2)「OCP をインストールする」作業です。これも前回紹介しましたが、本ブログでは PXE インストールによる導入手順を紹介します。各種コマンドを実行することにはなるのですが、いわゆる "setup.exe" や "install.sh" のようなものとは異なり、「インストール自体は PXE で実行されるので、インストール状況を確認するコマンドを実行」することになります。
(3)OCP 導入後にエアギャップ環境特有の設定が必要になります。
ではこの流れで実際に OCP をエアギャップ環境でインストールしてみます。
【(0)構成の検討・準備】
今回構築する OCP は「エアギャップ環境で OCP を作る手順を確認する」ことを目的として(OCP 上で何か重いアプリケーションを動かすことを目的とはせず)、以下のスペックとしました:
・マスターノード3、ワーカーノード3
・ノードは全て仮想サーバー(x86_64)
・仮想サーバーのスペックは vCPU x 4、メモリ 16GB、ディスク 200GB
・各ノードサーバーの NIC は PXE ブートに対応したもの
・OCP バージョンは 4.13.0
ちなみに vCPU x 4 は最小スペックで、メモリはマスターノード 16GB、ワーカーノード 8GB が最小スペック。ディスクは 120 GB が最小で、これらを満たしていないとインストール時のチェックにひっかかります(引っかかった結果、どうなるかは知りません。とりあえず「満たしてない」というメッセージが出ることは確認)。ワーカーノードは(マスターノードにワーカーノードのロールを割り当てれば)0でもいいですが、マスターノードは最低3つ必要です。
これ以外にブートストラップノード(後述)やバスチョンサーバー(後述)も必要なので、1台のデスクトップ PC 内の仮想環境で作ろうとすると、vCPU やディスクはともかく、メモリがかなり厳しいはずで、最低 128GB はないと難しい(スワップしまくり)になると思います。64GB 搭載の PC だとマスターノード3、ワーカーノード0でも厳しいかも。。ちなみに私は(今更 VMWare を使うのもアレなので) VirtualBox を使って今回の作業を実施しています。
改めて、今回の OCP クラスタでは以下表の構成でサーバーを用意することにします:
サーバー | ホスト名 | vCPU | メモリ(GB) | ディスク(GB) | OS | IP アドレス |
---|---|---|---|---|---|---|
バスチョン | bastion | 4 | 4 | 500 | RHEL 9.2 | 10.10.0.10/24 |
ブートストラップ | bootstrap | 4 | 8 | 200 | RHCOS 4.13.0 | 10.10.0.32/24 |
マスター0 | master0 | 4 | 8 | 200 | RHCOS 4.13.0 | 10.10.0.33/24 |
マスター1 | master1 | 4 | 8 | 200 | RHCOS 4.13.0 | 10.10.0.34/24 |
マスター2 | master2 | 4 | 8 | 200 | RHCOS 4.13.0 | 10.10.0.35/24 |
ワーカー0 | worker0 | 4 | 8 | 200 | RHCOS 4.13.0 | 10.10.0.36/24 |
ワーカー1 | worker1 | 4 | 8 | 200 | RHCOS 4.13.0 | 10.10.0.37/24 |
ワーカー2 | worker2 | 4 | 8 | 200 | RHCOS 4.13.0 | 10.10.0.38/24 |
なお、ドメインは "ocp.xxx.localdomain" を使うことにします(バスチョンサーバーの FQDN は bastion.ocp.xxx.localdomain" となります)。ちょっと細かいことを言うと、この場合、OCP 導入時の「ドメイン」は "xxx.localdomain" で、"ocp" は「クラスターID」と呼ばれます。この辺り慣れていないとわかりにくいのですが、OCP 導入時は OCP 用のサブドメインを使うことが想定されているので、いわゆる一般的なドメインを使うのではなく、クラスター ID が追加されたサブドメインを使って構築する(OCP のドメインは「クラスターID + ドメイン」から成り立っている)、と理解しておくのが分かりやすいのではないかと思いました。
また今回は PXE インストールを行うため、各ノードサーバーの NIC は PXE 対応している必要があります。物理サーバーの場合は PXE に対応した物理 NIC を用意するか、ネットワークブート可能な KVM を用意してください。仮想サーバーの場合は PXE に対応した仮想 NIC を選択することになります。VirtualBox であればデフォルトの Intel PRO/1000 MT Desktop(82540EM) であれば PXE 対応しています:

また各ノードサーバーの起動優先順位を以下のように設定します(上にあるものほど優先順位を高く設定します):
・DVD, USB メモリ
・ディスクストレージ(HDD, SDDドライブ)
・ネットワーク
今回のインストールでは使いませんが、緊急時のメンテナンスなどの目的で DVD や USB メモリから起動したくなるケースが想定されます。そのような時のために DVD や USB メモリでの起動を最優先に設定しておきます。 次にディスクストレージを優先して起動します。今の段階ではディスクには何もインストールされていません(何らかの OS がインストール済みのディスクを使う場合は削除してください。詳しくはこちら)が、この後の作業で CoreOS をインストールします。CoreOS インストール後は CoreOS を起動する、という設定です。 そしてディスクに何もインストールされていない場合は PXE インストールを実施するためネットワークブートも可能になるよう(ディスクよりも低い優先順位で)設定しておく必要があります(下図はサンプル):

また OCP 4.13.0 は今となっては推奨バージョンとはいえないと思いますが、のちの作業で 4.14.0 へアップグレードしたいので、そのために敢えて低めのバージョンで初期インストールします。
【(1)インターネット接続環境下で必要なインストールに必要なファイル群をダウンロード】
では(0)で決めた OCP 4.13.0 をエアギャップ環境でインストールするために必要なファイルを用意します。まずはインターネットに接続できる RHEL(RedHat Enterprise Linux) 9.x を用意します。ディスクの空きは 4.13.0 の初期インストールだけなら 50GB くらい、初期インストール後に実施する 4.14.0 へのアップグレードに必要なファイルまでを同じ環境でダウンロードするつもりであれば 100GB は必要です。このダウンロードを実施するための PC のメモリは 4GB 程度ないと厳しいかも、、そのつもりで環境を準備してください。
では早速必要なファイルのダウンロード・・・なんですが、1つだけ入手方法が他と異なる特殊なファイルがあるので、まずはこれから紹介します。RedHat でアカウントを作成し(個人アカウントでも構いません)、そのアカウントでログインして pull-secret と呼ばれるファイルをダウンロードします。pull-secret は「ダウンロード」と表現していますが、正確には「ログイン済みのユーザー向けに作成されたものをダウンロード」します(つまりログインユーザー毎に内容は異なるファイルです)。ログイン時の RedHat アカウントに紐づいた内容で利用できるものですが、個人アカウントでも開発者サブスクリプションに登録することで無料で利用できるものなので、必要であれば開発者サブスクリプションに登録してください。この辺りの登録手順は前回の内容を参照してください。
pull-secret をダウンロードするには RedHat アカウント作成後にブラウザで https://cloud.redhat.com/openshift/install/pull-secret にアクセスします(ログイン前の場合はここでログインが必要です)。そして "Download pull secret" ボタンをクリックするとダウンロードが始まります:

ダウンロードした pull-secret は "pull-secret" または "pull-secret.txt" というファイル名でダウンロードされます。ファイル名は後者("pull-secret.txt")だった場合は前者("pull-secret")にリネームしておいてください。以降は "pull-secret" という拡張子のないファイル名でダウンロード済みであると仮定して説明を続けます。
このダウンロードした pull-secret ファイル自体もエアギャップ環境に持ち込む必要があるのですが、この後のインターネット接続環境での作業でも必要なファイルです。同 "pull-secret" ファイルを "/root/.docker/config.json" というファイル名で保存します(~/Downloads/pull-secret というファイルとしてダウンロード済みの場合の例です):
# mkdir -p /root/.docker/ # cp ~/Downloads/pull-secret /root/.docker/config.json
次にファイルをダウンロードする準備として、この後の作業の中で必要になるツール類をあらかじめまとめてインストールする、という手順を実施します。具体的には root ユーザーの CLI で以下のコマンドを実行します:
# yum install jq wget git yum-utils podman ansible-core python3-cryptography -y
またダウンロードするファイルを保管するためのフォルダ(/data)を作成しておきます:
# mkdir -p /data # cd /data
早速ダウンロードした pull-secret も /data にコピーしておきましょう:
# cp ~/Downloads/pull-secret /data
ここからが本格的な「ファイルダウンロード」作業となります。手順は決して短くはないのですが、最初は内容の理解が甘くても構いませんので、以下で紹介されている CLI コマンドを淡々と実行いただくことで済むものです。
ではエアギャップ環境に持ち込む必要があるファイルを順にダウンロードしていきます。まず最初は OCP4 ヘルパーノードを動かすために必要な ansible-galaxy のコレクションモジュールです。以下のコマンドを実行して、~/collections/ というフォルダに community.crypto と ansible-posix モジュールをダウンロードします(ここではインストールは不要で、ダウンロードのみ実行します):
# cd # ansible-galaxy collection download community.crypto # ansible-galaxy collection download ansible-posix # ls -la ~/collections/ # cp -r ~/collections /data
コマンドが正しく実行されると ~/collections/ というフォルダが作られていて、その中に community-crypto-x.x.x.tar.gz と ansible-posix-x.x.x.tar.gz というファイルが存在しているはずです(x.x.x 部分はバージョン番号で、実行したタイミングによって異なります)。上記最後のコマンドでダウンロードしたモジュールを collections/ フォルダごと /data にコピーしています。
続いてこの後バスチョンサーバーで使うことになる OCP4 ヘルパーノード本体と、NFS プロビジョナーを github からダウンロードします:
# cd /data # git clone https://github.com/RedHatOfficial/ocp4-helpernode # tar czvf ocp4-helpernode.tgz ocp4-helpernode; rm -rf ocp4-helpernode # git clone https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner.git nfs-subdir # tar czvf nfs-subdir.tgz nfs-subdir; rm -rf nfs-subdir
これらのコマンドが正しく実行されると /data 以下に ocp4-helpernode.tgz と nfs-subdir.tgz という2つのファイルが作られます。
次はいよいよ OCP 4.13.0 の OS 部分である RHCOS(RedHat CoreOS) 4.13.0 本体となるファイル群を RedHat サイトからダウンロードします:
# mkdir -p /data/ocp-files # cd /data/ocp-files # wget https://mirror.openshift.com/pub/openshift-v4/x86_64/dependencies/rhcos/4.13/4.13.0/rhcos-live-rootfs.x86_64.img # wget https://mirror.openshift.com/pub/openshift-v4/x86_64/dependencies/rhcos/4.13/4.13.0/rhcos-live-initramfs.x86_64.img # wget https://mirror.openshift.com/pub/openshift-v4/x86_64/dependencies/rhcos/4.13/4.13.0/rhcos-live-kernel-x86_64 # wget https://mirror.openshift.com/pub/openshift-v4/x86_64/clients/ocp/4.13.0/openshift-client-linux-4.13.0.tar.gz # wget https://mirror.openshift.com/pub/openshift-v4/x86_64/clients/ocp/4.13.0/openshift-install-linux-4.13.0.tar.gz # wget https://get.helm.sh/helm-v3.13.3-linux-amd64.tar.gz
/data/ocp-files/ というフォルダを作成し、その中に6つの RHCOS 4.13.0 インストール用ファイルをダウンロードしました。
OS のイメージをダウンロードした後はいよいよ OCP 本体部分のダウンロードに移ります。次はバスチョンサーバー内に構築する OCP 4.13.0 のミラーレジストリとなるコンテナイメージをダウンロードします。この実体は docker.io から提供されているコンテナイメージなので、上記手順で実行した docker 互換の podman を使い、インターネット接続環境でこのイメージを docker pull (正確には podman pull)して、その結果を tar ファイル(/data/registry.tar)にエクスポートする形でファイルの形でダウンロードします:
# cd /data # podman pull docker.io/library/registry # podman save docker.io/library/registry:latest -o /data/registry.tar
そしてこのミラーレジストリに展開する(ミラーリングする)中身となるミラーイメージの準備です。まずはミラーリング実行時のコマンドとなる oc と oc-mirror をダウンロードします。まずは oc-mirror から(この後実際にミラーリングするので /data だけでなく /usr/local/bin にもコピーしています):
# mkdir -p ~/oc-mirror # cd ~/oc-mirror # wget https://mirror.openshift.com/pub/openshift-v4/x86_64/clients/ocp/4.13.0/oc-mirror.tar.gz # tar -xf oc-mirror.tar.gz # chmod +x oc-mirror # cp oc-mirror /data # cp oc-mirror /usr/local/bin
同様に oc コマンドを用意します。ダウンロードする必要のあるファイルは上述でダウンロード済みの openshift-client-linux-4.13.0.tar.gz なので、ここから oc コマンドだけを取り出します:
# cd ~/oc-mirror # tar xzvf /data/ocp-files/openshift-client-linux-4.13.0.tar.gz oc # cp oc /data # cp oc /usr/local/bin
ここからが本作業の中で一番のメインイベントとなるミラーイメージのダウンロードとなります。インターネット接続環境にも依存しますが、最も時間のかかるダウンロード作業で、ダウンロード結果となるファイルのサイズも巨大なもの(1ファイルで 30GB 近く)となるものです。
ミラーイメージダウンロードの準備として、以下の内容で /data/imageset-config-4.13.0.yaml を作成します。このファイルに記載されている内容に従ってミラーレジストリ作成に必要なファイルがダウンロードされるもので、OCP 4.13.0 を初期インストールするための内容になっています。なお同時に local-storage-operator というオペレーターもダウンロードしています。これは今回特に使うわけではないのですが、エアギャップ環境のミラーレジストリでも OperatorHub を有効にできていることを確認する目的で指定しています(今回の OCP 4.13.0 のインストールが完了すると、Local Storage Operator だけが OperatorHub に表示されるようになります)。OCP インストール後に利用することが決まっているオペレーターがある場合はこの imageset-config-4.13.0.yaml ファイル内に記載して、一緒にダウンロードするようにしてください:
kind: ImageSetConfiguration apiVersion: mirror.openshift.io/v1alpha2 storageConfig: local: path: /data/mirror-ocp mirror: platform: # architectures: # - "x86_64" channels: - name: stable-4.13 type: ocp minVersion: '4.13.0' maxVersion: '4.13.0' graph: true operators: - catalog: registry.redhat.io/redhat/redhat-operator-index:v4.13 full: false packages: - name: local-storage-operator channels: - name: stable additionalImages: - name: registry.redhat.io/ubi8/ubi:latest - name: gcr.io/k8s-staging-sig-storage/nfs-subdir-external-provisioner:v4.0.2 - name: docker.io/rancher/busybox:1.31.1 helm: {}
上記ファイル内の赤字部分についてコメントしておきます。まず storageConfig.localpath = /data/mirror-ocp という部分でファイルのダウンロード先フォルダを指定しています。 次に mirror.platform.channels で "4.13 の安定板(stable-4.13)" を使うことを明記し、そのバージョンとして 4.13.0 から 4.13.0 まで(つまり 4.13.0)を対象にダウンロードすることを指定しています。 そして mirror.operators 内で local-storage-operator:stable オペレーターを一緒にダウンロードする旨を記載しています。必要に応じて適宜変更してください。
ではこのファイルを使ってミラーイメージを一括ダウンロードします。上述の pull-secret(~/.docker/config.json)がないとダウンロードは失敗するので注意してください:
# umask 0022 # mkdir -p /data/mirror-ocp # cd /data # oc mirror --config=imageset-config-4.13.0.yaml file:///data/mirror-ocp
最後のコマンドを実行すると(正しく実行されると)ファイルのダウンロードが開始されます。ここはかなり時間のかかる作業なので、ずっとこの環境のターミナルを開けない環境などの場合は tmux などでバックグラウンド実行することを推奨します。
コマンドが最後まで正しく実行されると /data/mirror-ocp/mirror_seq1_000000.tar という 30GB 前後の巨大なファイルが作られます。これがミラーイメージと呼ばれるもので、この後エアギャップ環境のミラーレジストリを作る際の中身に相当するものです。
インターネット接続環境を使って最低限ダウンロードしておくべきファイルは以上です。以下はエアギャップ環境によっては必要となるファイルであったり、事前にインターネット接続環境下で(というか、エアギャップ環境では使えるエディタも限られてしまうので、普段使っているテキストエディタが使える環境のうちに使って)用意しておくと便利なファイルです。
この後のエアギャップ環境下では主にバスチョンサーバーと呼ばれる作業マシン内に必要な環境を構築していくことになります。その際に RHEL の(yum/dnf コマンドを実行してパッケージをインストールする際の)パッケージリポジトリが必要になります。 RHEL の DVD(ISO) メディアを用意し、その DVD(ISO) を RHEL に挿入して作業することができる環境の場合はその方法でパッケージリポジトリを構築できるのでいいのですが、例えばバスチョンサーバーが物理サーバーで、かつ DVD ドライブを内蔵していないようなケースだったりすると DVD を挿入するだけでパッケージリポジトリを用意することができなくなります。そのような場合は RHEL ISO ファイルそのものをエアギャップ環境に持ち込む必要があります(サイズの小さい Boot DVD ではなく、フル DVD の ISO が必要です)。以下のサイトから RHEL DVD の ISO ファイル(例えば rhel-9.2-x86_64-dvd.iso)を事前にダウンロードして、/data フォルダに保存しておきます。なおここでもダウンロード時に RedHat アカウントでログインする必要があります:
https://developers.redhat.com/products/rhel/download
またこの ISO を使ってパッケージリポジトリを構築する場合は、以下の内容のリポジトリ構築用の設定ファイル(/data/isorepo.repo)が必要です。エアギャップ環境での作業になるとテキストエディタも自由には選べなくなるので、インターネット接続が使えるうちに設定ファイル類を作っておくことをお勧めします:
[iso-BaseOS] name=DVD for RHEL - BaseOS baseurl=file:///media/rheliso/BaseOS enabled=1 gpgcheck=0 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release [iso-AppStream] name=DVD for RHEL - AppStream baseurl=file:///media/rheliso/AppStream enabled=1 gpgcheck=0 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-release
このような設定ファイルがいくつか必要なので、インターネット接続環境で作れる範囲で作ってしまうことにします。というわけで次は OCP4 ヘルパーノードを使う際のパラメータファイルである /data/vars.yaml を以下の内容で作っておきます:
--- disk: sda helper: name: "bastion" ipaddr: "10.10.0.10" networkifacename: "enp0s3" dns: domain: "xxx.localdomain" clusterid: "ocp" # forwarder1: "8.8.8.8" # forwarder2: "8.8.4.4" dhcp: router: "10.10.0.10" bcast: "10.10.0.255" netmask: "255.255.255.0" poolstart: "10.10.0.30" poolend: "10.10.0.39" ipid: "10.10.0.0" netmaskid: "255.255.255.0" chronyconfig: enabled: true content: - server: 10.10.0.10 options: iburst bootstrap: name: "bootstrap" ipaddr: "10.10.0.32" macaddr: "" masters: - name: "master0" ipaddr: "10.10.0.33" macaddr: "" - name: "master1" ipaddr: "10.10.0.34" macaddr: "" - name: "master2" ipaddr: "10.10.0.35" macaddr: "" workers: - name: "worker0" ipaddr: "10.10.0.36" macaddr: "" - name: "worker1" ipaddr: "10.10.0.37" macaddr: "" - name: "worker2" ipaddr: "10.10.0.38" macaddr: "" setup_registry: deploy: true autosync_registry: false registry_image: "docker.io/registry:latest" local_repo: "ocp4/openshift4" product_repo: "openshift-release-dev" release_name: "ocp-release" release_tag: "4.13.0-x86_64" ppc64le: false ocp_bios: "file:///data/ocp-files/rhcos-live-rootfs.x86_64.img" ocp_initramfs: "file:///data/ocp-files/rhcos-live-initramfs.x86_64.img" ocp_install_kernel: "file:///data/ocp-files/rhcos-live-kernel-x86_64" ocp_client: "file:///data/ocp-files/openshift-client-linux-4.13.0.tar.gz" ocp_installer: "file:///data/ocp-files/openshift-install-linux-4.13.0.tar.gz" helm_source: "file:///data/ocp-files/helm-v3.13.3-linux-amd64.tar.gz"
ここでも赤字部分についてコメントしておきます。まず2行目に disk = "sda" という記載をしていますが、これは「OCP をインストールする環境ではディスクは /dev/sda として認識されている」ことを示しています。とりあえずこの値を設定していますが、実際の環境はエアギャップ環境内のバスチョンサーバーなどで確認いただきたいのですが、異なる場合はここを編集してください。また6行目で helper.networkifname = "enp0s3" と記載しています。これはバスチョンサーバーのネットワークインターフェース名("ip a" や "ifconfig" コマンドで確認できるインターフェース名)が "enp0s3" であることを意味しています。この値も実際のものと異なる場合は編集してください。 もう1つ、今回は OCP を構築するドメインを "ocp.xxx.localdomain" とする、と書きましたが、このファイルでは dns.domain と dns.clusterip に分けてドメインを設定している点に注意してください(2つを足して <dns.clusterid>.<dns.domain> で実際に利用するドメイン名になるよう指定してください)。
次に数か所で IP アドレスを指定していますが、各ノードサーバーの想定 IP アドレスに加えて、DHCP サーバーや chronyd サーバー(時刻同期サーバー)の IP アドレスも指定しています。今回は OCP4 ヘルパーノードを使って周辺環境を構築するので、DHCP, DNS などは全てバスチョンサーバーと同じ IP アドレスを指定する必要がある点に注意ください。また macaddr が空文字列になっている行が多いですが、これらには各ノードサーバーのネットワークインターフェースが持つ MAC アドレスを指定することになります。各サーバーの MAC アドレスの値を調べて、"xx:xx:xx:xx:xx:xx" 形式で入力する必要があるのですが、今の時点では(まだ使わないので)空文字列にしていても大丈夫です。
ただこの vars.yaml ファイルはとても大事なファイルです。この中で指定する IP アドレスや MAC アドレスが(ちょっとしたミスで間違えやすいものですが)1箇所でも間違えているとうまくインストールできなくなってしまうものなので、注意して入力するよう心掛けてください。
続いて、時刻同期サーバーである chronyd の設定ファイル(/data/chrony.conf)を以下の内容で用意します(10.10.0.0/24 のアドレスからのみリクエストを受け付ける設定をしています):
driftfile /var/lib/chrony/drift
makestep 1.0 3
rtcsync
allow 10.10.0.0/24
local stratum 8
keyfile /etc/chrony.keys
leapsectz right/UTC
logdir /var/log/chrony
もう1つ、OCP インストール時の設定ファイル(install-config.yaml)を生成するシェルスクリプト(/data/install-config.sh)を以下の内容で用意します:
# cat <install-config.yaml apiVersion: v1 baseDomain: xxx.localdomain compute: - hyperthreading: Enabled name: worker replicas: 3 controlPlane: hyperthreading: Enabled name: master replicas: 3 metadata: name: ocp networking: clusterNetwork: - cidr: 10.254.0.0/16 hostPrefix: 24 machineNetwork: - cidr: 10.10.0.0/24 networkType: OpenShiftSDN serviceNetwork: - 172.30.0.0/16 platform: none: {} pullSecret: '$(< ~/.openshift/pull-secret-updated)' sshKey: '$(< ~/.ssh/helper_rsa.pub)' additionalTrustBundle: | $(sed 's/^/ /' /opt/registry/certs/domain.crt) imageContentSources: - mirrors: - registry.ocp.xxx.localdomain:5000/openshift/release-images source: quay.io/openshift-release-dev/ocp-release - mirrors: - registry.ocp.xxx.localdomain:5000/openshift/release source: quay.io/openshift-release-dev/ocp-v4.0-art-dev EOF
上述の vars.yaml 同様、このファイルでも <metadata.name>.<baseDomain> で実際のドメイン名になるよう記載する点に注意が必要です。またこのファイルの中でマスターノードが3つ、ワーカーノードが3つそれぞれ必要になることが記載されている点にも注意してください(OCP が正しくインストールされているかどうかは、ここで指定した値の数だけノードが用意できているかどうかで判断されます)。
ここまでの作業を行うと、/data 以下に以下のファイル/フォルダができているはずです:
(以下は必須のファイル/フォルダ)
- /data/pull-secret
- /data/collections/
- /data/ocp4-helpernode.tgz
- /data/nfs-subdir.tgz
- /data/ocp-files/
- /data/registry.tar
- /data/oc-mirror
- /data/oc
- /data/mirror-ocp/mirror_seq1_000000.tar
(以下は必須ではないが、バスチョンサーバーに RHEL DVD をセットする術がない場合に必須)
- /data/rhel-9.2-x86_64-dvd.iso
- /data/isorepo.repo
(以下は必須ではないが、使い慣れたテキストエディタで作っておくべきもの)
- /data/vars.yaml
- /data/chrony.conf
- /data/install-config.sh
上記ファイルを全て(フォルダはフォルダまるごと) USB メモリなどに入れて、この後の作業となるバスチョンサーバーにコピーする必要があります。方法は USB メモリ以外に USB ディスクでも構いません。作業用の PC を持ち込むのであれば、その作業 PC の中に入れて持ち込むのも一つの方法です。1ファイルで 30GB 近くあるものも含まれているので1枚の DVD では無理ですが、ファイルを分割すれば複数枚の DVD で持ち運ぶことはできると思います。 方法はともかく、これらのファイルをなんらかの方法でインターネット接続のないバスチョンサーバーが利用できる状態にする必要があります。場合によってはここがエアギャップ OCP 環境構築の最初の関門になると思います。
ここまでの手順ができればインターネット接続のある環境で行う作業は以上です。ここまでで既にかなり長い説明になっていますが、本番はここから。次からはいよいよインターネット接続がない環境下で実施する作業に入ります。
【(2)OCP を PXE インストール】
ここから先は全てインターネット接続のない環境で実施することになります。これまでにインターネット接続環境で用意したファイルを使って OCP 4.13.0 をインストールします。
ここで構築する OCP は以下のようなサーバー群から構成されます:

このうち、バスチョンサーバー以外のノードは PXE インストールと呼ばれるネットワークインストールで導入します。つまり「ほぼ電源を入れるだけ」の作業です。 OCP をインストールするための作業という意味ではその大半が「バスチョンサーバーを構築する作業」となります。
ではエアギャップ環境でバスチョンサーバーを構築する手順を紹介します。まず前提としてエアギャップ環境内に RHEL がインストールされたサーバーを1台用意します(エアギャップ環境内で RedHat のサブスクリプションを有効にする手順等はこちらを参照してください)。またバスチョンサーバーは SELinux が無効になっていると OCP4 ヘルパーノード実行時にエラーとなってしまうので、SELinux はデフォルトの permissive や enforcing にするなどして無効以外の設定にしてください:

加えてバスチョンサーバーにインストールする RHEL は("Minimum Install" ではなく)"Server with GUI" オプションでインストールしておくことを推奨します。理由はインストールされた OCP のウェブコンソール画面にアクセスする際、このバスチョンサーバーのウェブブラウザからアクセスするしかない可能性があるためです。他の作業用 Windows PC などがある環境であれば、その Windows からウェブアクセスすることも可能ですが、そのような作業マシンがない場合は全てバスチョンサーバーを使って設定する必要があり、ウェブアクセスが必要な場合もバスチョンサーバーのウェブブラウザを使う必要に迫られる可能性があるからでした(以下はバスチョンサーバーが "Server with GUI" でインストールされている前提で説明します)。
そして上述の【1】でダウンロードしたファイル群はバスチョンサーバーの /data/ 以下にコピーされているものと仮定して以下の説明を続けます。つまりバスチョンサーバーにも以下のファイルが存在しているものと仮定して以下を続けます:
(以下は必須のファイル/フォルダ)
- /data/pull-secret
- /data/collections/
- /data/ocp4-helpernode.tgz
- /data/nfs-subdir.tgz
- /data/ocp-files/
- /data/registry.tar
- /data/oc-mirror
- /data/oc
- /data/mirror-ocp/mirror_seq1_000000.tar
(以下は必須ではないが、バスチョンサーバーに RHEL DVD をセットする術がない場合に必須)
- /data/rhel-9.2-x86_64-dvd.iso
- /data/isorepo.repo
(以下は必須ではないが、使い慣れたテキストエディタで作っておくべきもの)
- /data/vars.yaml
- /data/chrony.conf
- /data/install-config.sh
またブートストラップノードや各マスターノード/ワーカーノードのサーバーに付属している NIC の MAC アドレスも必要です。MAC アドレスの値は仮想サーバーなどであれば比較的簡単に調べることができますが、物理サーバーだと最悪の場合、実際に OS が動いている状態でないと調べる方法がない可能性もあります。このあたりの OS をインストールしなくても調べる具体的な手順はこちらでも紹介しているので参考にしてください。
改めてここからはエアギャップ環境(インターネット接続のない環境)下での、バスチョンサーバーと呼ばれる作業サーバーの準備手順を紹介します。以下のコマンドは全て root ユーザー権限で実行してください(sudo 権限のある一般ユーザーからは "sudo -i" を実行して root ユーザー権限でターミナルを準備してください)。
事前に確認する情報としてもう1点、これ以降の説明では /usr/local/bin フォルダに実行 PATH が設定されている必要があります。もし設定されていない場合は ~/.bashrc の最後に以下の1行を追加して再ログインしてください:
export PATH="$PATH:/usr/local/bin"
まずは対象サーバーにインストールした RHEL を起動します。この際に DVD ドライブに RHEL DVD を入れることができる場合は挿入しておきます(これで DVD のローカルリポジトリからパッケージがインストールできるようになります)。その様な環境ではない場合は、上述の手順で rhel-9.2-x86_64-dvd.iso と isorepo.repo ファイルをエアギャップ環境の /data フォルダ以下にコピーしているので、これらを使ってローカルリポジトリを作る作業が必要になります。 ISO ファイルを使ってローカルリポジトリを作成する場合は事前に用意した /data/isorepo.repo ファイルを併用して作成します。その場合、まずは /media/rheliso という空のフォルダを作成します:
# mkdir -p /media/rheliso
このフォルダに ISO ファイルをマウントします。一時的なマウントではなく恒久的にマウントしたいので、/etc/fstab ファイルに以下の1行を追加してバスチョンサーバーを再起動します(再起動後に /media/rheliso に DVD がマウントされているはずです):
/data/rhel-9.2-x86_64-dvd.iso /media/rheliso iso9660 loop,ro,auto,nofail 0 0
マウントされた DVD(ISO) を使ってローカルリポジトリを作成します。/data/isorepo.repo ファイルを /etc/yum.repos.d/ にコピーします。加えてサブスクリプションを無効にしてデフォルトのリポジトリが自動的に復元されないようにします。最後にデフォルトのリポジトリファイルを削除してからリポジトリを更新します(これでローカルリポジトリが作成され、使える状態になります):
# cp /data/isorepo.repo /etc/yum.repos.d/ # subscription-manager config --rhsm.manage_repos=0 # rm -f /etc/yum.repos.d/redhat*.repo # yum clean all # yum list
ローカルリポジトリが利用可能な状態になったので、ここからこの後の作業に必要なパッケージ類をインストールしていきます。以下のコマンドを実行して、ローカルリポジトリからまとめてインストールします:
# yum install -y tmux jq wget git tree yum-utils bind-utils nmstate podman python3-cryptography ansible-core
上のコマンドで ansible 系のコマンドもインストールしているので、インターネット接続環境でダウンロードした ansible collection コマンドが使えるようになります。以下のコマンドで2つのパッケージをインストールします(x.x 部分は実際にダウンロードしたファイルバージョンに合わせて指定して下さい):
# cd /data/collections/ # ansible-galaxy collection install community-crypto-2.x.x.tar.gz # ansible-galaxy collection install ansible-posix-1.x.x.tar.gz
次にネットワークインターフェースを設定します(ネットワーク設定が済んでいる場合、ここは飛ばしてください)。まずはネットワークインターフェース名を確認するため、以下のコマンドを実行します:
# ip a
コマンドの結果、"lo" のインターフェースに関する情報と、それとは別のインターフェースに関する情報が表示されます。"lo" はローカルホスト用の設定なのでこちらではなく、もう1つのインターフェースに関する情報は実際の通信に使うインターフェースです。この後、そのインターフェース名を使って設定を行うので、インターフェース名を見つけてください。以下の例では "enp0s3" が求めるインターフェース名で、以下この前提でコマンドを実行していきますが、実際に入力するコマンドは自分の環境でのインターフェース名に合わせて変更してください:

今回の前提ではバスチョンサーバーは IP アドレスは "10.10.0.10/24" 、FQDN は "bastion.ocp.xxx.localdomain" として構築するので、そのための設定変更を行います。なおデフォルトゲートウェイが存在する環境の場合はそのアドレスを指定する必要がありますが、特にない環境の場合は自分自身のアドレス(10.10.0.10)を指定します。また DNS はこの後 OCP4 ヘルパーノードが作る環境をそのまま使うので、ここは自分自身のアドレス(10.10.0.10)を指定します:
# nmcli con mod enp0s3 connection.autoconnect yes # nmcli con mod enp0s3 ipv4.addresses 10.10.0.10/24 # nmcli con mod enp0s3 ipv4.method manual # nmcli con mod enp0s3 ipv4.gateway 10.10.0.10 # nmcli con mod enp0s3 ipv4.dns 10.10.0.10 # hostnamectl set-hostname bastion.ocp.xxx.localdomain
また、このバスチョンサーバーは "registry.ocp.xxx.localdomain" という名前でもアクセスすることができるようにしておきます。そこで /etc/hosts ファイルを編集し、以下の1行を追加して保存します:
10.10.0.10 registry.ocp.xxx.localdomain
ネットワークの設定ができたら、次はミラーレジストリを作ります。ミラーレジストリとなるコンテナイメージを podman(docker)に展開して、空のミラーレジストリを作成しておきます:
# podman load -i /data/registry.tar
ミラーレジストリの中身をロードするにはいくつかのコマンドを用意する必要があるので、その辺りも含めて OCP4 ヘルパーノードの準備を先にしておきます。あらかじめダウンロードした tgz ファイルをホームディレクトリに展開し、更にあらかじめ用意しておいた設定ファイル(/data/vars.yaml)を上書きします:
# cd # tar xzvf /data/ocp4-helpernode.tgz # cd ocp4-helpernode/ # cp /data/vars.yaml .
OCP4 ヘルパーノードを実行する前に改めて ~/ocp4-helpernode/vars.yaml ファイルの中身を実際の環境に合わせた正しい情報に更新してください。赤字部分はコメントです。実際の環境に合わせて正しく変更してください(ここが間違っていると PXE インストールが正しく実行されなかったり、正しく導入完了を検知できなかったりします。特に MAC アドレスに注意):
--- disk: sda # ディスクデバイス名 helper: name: "bastion" # バスチョンサーバーのホスト名 ipaddr: "10.10.0.10" # バスチョンサーバーの IP アドレス networkifacename: "enp0s3" # ネットワークインターフェース名 dns: domain: "xxx.localdomain" # clusterid.domain でドメイン名となるようにする clusterid: "ocp" # forwarder1: "8.8.8.8" # 外部DNSを使う場合はここで指定(使わない場合はコメントアウト) # forwarder2: "8.8.4.4" dhcp: router: "10.10.0.10" # DHCP サーバーが設定するデフォルトゲートウェイ bcast: "10.10.0.255" # DHCP サーバーが設定するブロードキャストアドレス netmask: "255.255.255.0" # DHCP サーバーが設定するネットマスク poolstart: "10.10.0.30" # DHCP サーバーが予約する IP アドレスの開始アドレス poolend: "10.10.0.39" # DPCP サーバーが予約する IP アドレスの終了アドレス ipid: "10.10.0.0" netmaskid: "255.255.255.0" chronyconfig: enabled: true content: - server: 10.10.0.10 # バスチョンサーバーの IP アドレス options: iburst bootstrap: name: "bootstrap" # ブートストラップノードのホスト名 ipaddr: "10.10.0.32" # ブートストラップノードの IP アドレス macaddr: "xx:xx:xx:xx:xx:xx" # ブートストラップノードの MAC アドレス masters: - name: "master0" # master0 ノードのホスト名 ipaddr: "10.10.0.33" # master0 ノードの IP アドレス macaddr: "xx:xx:xx:xx:xx:xx" # master0 ノードの MAC アドレス(以下同様) - name: "master1" # master1 ノード ipaddr: "10.10.0.34" macaddr: "xx:xx:xx:xx:xx:xx" - name: "master2" # master2 ノード ipaddr: "10.10.0.35" macaddr: "xx:xx:xx:xx:xx:xx" workers: - name: "worker0" # worker0 ノード ipaddr: "10.10.0.36" macaddr: "xx:xx:xx:xx:xx:xx" - name: "worker1" # worker1 ノード ipaddr: "10.10.0.37" macaddr: "xx:xx:xx:xx:xx:xx" - name: "worker2" # worker2 ノード ipaddr: "10.10.0.38" macaddr: "xx:xx:xx:xx:xx:xx" setup_registry: # ローカルリポジトリに関する情報(このまま使ってください) deploy: true autosync_registry: false registry_image: "docker.io/registry:latest" local_repo: "ocp4/openshift4" product_repo: "openshift-release-dev" release_name: "ocp-release" release_tag: "4.13.0-x86_64" ppc64le: false # 以下 CoreOS や OC CLI に関する情報(このまま使ってください) ocp_bios: "file:///data/ocp-files/rhcos-live-rootfs.x86_64.img" ocp_initramfs: "file:///data/ocp-files/rhcos-live-initramfs.x86_64.img" ocp_install_kernel: "file:///data/ocp-files/rhcos-live-kernel-x86_64" ocp_client: "file:///data/ocp-files/openshift-client-linux-4.13.0.tar.gz" ocp_installer: "file:///data/ocp-files/openshift-install-linux-4.13.0.tar.gz" helm_source: "file:///data/ocp-files/helm-v3.13.3-linux-amd64.tar.gz"
OCP4 ヘルパーノードを実行するには(エアギャップ環境ではあるのですが) pull-secret に関する情報が必要です。以下の手順でダミーの pull-secret を作っておきます:
# cd # mkdir -p ./.openshift # echo "{}" > ./.openshift/pull-secret
このまま次の処理を続けてもいいはずなんですが、私が実際に試した環境だとここで一度サーバーを再起動しないといけないことがありました。自分でもどちらが正解か自信がないのですが、このまま続けて次の ansible-playbook コマンドが失敗する場合はバスチョンサーバーを再起動してください。
~/ocp4-helpernode/vars.yaml ファイルの準備ができたら OCP4 ヘルパーノードを実行します。コマンドは ansible playbook として用意されているので(その変数部分が vars.yaml に集約されているので)以下のコマンドを実行します。成功すると DNS や DHCP、TFTP、HAPROXY など、この後の PXE インストール時に必要な周辺環境に加え、oc コマンドの準備や ssh で利用する鍵の準備などもまとめて構築してくれます(完了まで数分から数十分かかります)。OCP4 ヘルパーノードを使わない場合、1つ1つこれらの環境を用意する必要があることを考えると、とても便利です:
# cd ~/ocp4-helpernode # ansible-playbook -e @vars.yaml tasks/main.yml
ここまでできていれば事前環境準備はほぼミラーレジストリの中身をインストールイメージ(今回の例だと OCP 4.13.0 インストール用のイメージ)にするだけなんですが、NTP(時刻同期サーバー)については少し手を加える必要があります。といっても事前に用意した /data/chrony.conf で /etc/chrony.conf を更新して起動するだけです:
# cp /data/chrony.conf /etc/chrony.conf # firewall-cmd --add-service=ntp --permanent # firewall-cmd --reload # systemctl enable chronyd # systemctl start chronyd
このタイミングで OCP インストール時用の設定ファイル(install-config.yaml)を作っておくことにします。これも事前に用意した /data/install-config.sh を実行することで install-config.yaml ファイルを作ります。 なお、/data/install-config.sh を実行する際には ~/.openshift/pull-secret, ~/.ssh/helper_rsa.pub, /opt/registry/certs/domain.crt の3つのファイルが存在している必要がありますが、ここまでのコマンドが成功していれば全て作成されているはずです。
では install-config.yaml ファイルを作成します:
# cd # cp /data/install-config.sh . # chmod +x ./install-config.sh # ./install-config.sh
正しく実行されるとカレントディレクトリに install-config.yaml というファイルが生成されています。このファイルは OCP インストール時に利用します(後で使います)。
いよいよ、このバスチョンサーバー構築時におけるメイン作業ともいえる(OCP 4.13.0 用の)ミラーレジストリの構築を行います。構築時の中身となるイメージは /data/mirror_seq1_000000.tar ファイルとして用意されているので、これをレジストリにインポートすればよいのですが、そのためにはもともと用意していた pull-secret と、今回のミラーレジストリにアクセスするための鍵情報をミックスした鍵ファイルを用意する必要があります。順に行っていきます。
まずはインターネット接続環境でダウンロードした pull-secret ファイル(/data/pull-secret)を JSON 変換したものを /data/config.json というファイルで書き出しておきます:
# cd # cat /data/pull-secret | jq > /data/config.json
次に(ansible-playbook 実行時に作成された)~/.openshift/pull-secret-update というファイルを "# cat ~/.openshift/pull-secret-update" などで表示します(赤枠部分をこの後使います):

そして /data/config.json をテキストエディタで開きます。以下のような内容が表示されます:

この2行目と3行目の間に先ほど確認した ~/.openshift/pull-secret-update ファイルの赤枠部分をコピー&ペーストなどで挿入し、最後に ","(カンマ)を入力して保存します:

こうして出来上がった /data/config.json を ~/.docker/config.json としてコピーします。これでミラーレジストリイメージをインポートする際に必要な鍵ファイルの準備ができました:
# cd # mkdir -p .docker # cp /data/config.json .docker/
そしてミラーレジストリのインポート実行時に必要な oc-mirror バイナリを /data/oc-mirror から /usr/local/bin にコピーします:
# cp /data/oc-mirror /usr/local/bin
ここまでに準備した環境を使って(OCP 4.13.0 用の)ミラーイメージをミラーレジストリにインポートします(上述の ansible-playbook を実行した時と比較しても、終了まで更に長い時間がかかるコマンドです):
# cd # oc mirror --from=/data/mirror_seq1_000000.tar docker://registry.ocp.xxx.localdomain:5000
正常に終了していると ~/oc-mirror-workspace/ というフォルダが作られ、その中に results-xxxxxxxxxx といった名称のフォルダが作られているはずです(このフォルダはインストール後の調整時に使います):

以下のコマンドを使ってミラーレジストリが正しくインポートされ、動作していることを確認します(例のように "4.13.0-" で始まるタグ行がたくさん表示されることが確認できれば成功です):
# podman image search --list-tags registry.ocp.xxx.localdomain:5000/openshift/release

ここまでできればバスチョンサーバーとしての準備は完了です(OCP インストールの大きな山を1つ越えた、くらいに考えてください)。後は実際に OCP をインストールする際の PXE インストール用のファイルを準備する必要がありますが、周辺環境の準備は完了した、くらいに理解していただいて大丈夫です。
PXE インストール用に用意するファイルの中にはイグニッションファイルと呼ばれるものが含まれます。これは CoreOS インストール時に必要な鍵ファイルですが、有効期限は 24 時間です。つまりここから先の手順であるイグニッションファイルの作成から OCP インストール完了までを 24 時間以内に行う必要があります。よほど貧弱な仮想環境とかでない限りは 24 時間以内に終わるのが普通の処理内容ではあるのですが、24 時間を超えてしまうとイグニッションファイルが無効になってしまうので、実行タイミングは気を付けてください(日をまたぐ可能性があるタイミングでの実行はやめたほうがいいです)。
というわけで PXE インストール用のファイルを用意します。まずは先程作成した ~/install-config.yaml ファイルと OCP4 ヘルパーノードが用意してくれた openshift-install コマンドを使ってマニフェストファイルを作成します:
# cd # mkdir config # cp install-config.yaml config/ # openshift-install --dir=config create manifests
このコマンドの結果、~/config/ フォルダが作られ、その中に各種マニフェストファイルが作成されるのですが、一部は OCP4 ヘルパーノードが用意したものを使う必要があります:
# cd # cp ocp4-helpernode/machineconfig/* ./config/openshift/
ここまで用意したマニフェストファイルを使ってイグニッションファイルを作成します。繰り返しますが、ここから先 OCP のインストール完了まで 24 時間以内に実施する必要があることに注意してください:
# cd # openshift-install --dir=config create ignition-configs
成功すると config フォルダ直下に拡張子が .ign となっているイグニッションファイルが生成されています。これを PXE インストール時に HTTP 経由で取り出せるよう、ドキュメントルートにコピーします:
# cd # cp config/*.ign /var/www/html/ignition/ # restorecon -vR /var/www/html/ # chmod o+r /var/www/html/ignition/*.ign
これで PXE インストール実行時に必要なイグニッションファイルも用意できました。最後に PXE シーケンスの最初にファイルをダウンロードさせるための TFTP サーバーを設定します:
# firewall-cmd --permanent --add-service=tftp # firewall-cmd --reload # systemctl daemon-reload # systemctl restart tftp.service # systemctl enable tftp.service # chown nobody:nobody /var/lib/tftpboot
これで PXE インストール前にバスチョンサーバー上で実行しておく必要のある準備は全て完了しました。
後は各ノードサーバーの電源を順次入れていきます。実際のところ、どのような順に電源を入れても構わないのですが、OCP としては以下の順に起動していくので、この順序で電源を入れていくのがいいと思われます:
・ブートストラップノード
・マスターノード
・ワーカーノード
各ノードとも PXE ブートが実行され、バスチョンサーバーに用意された環境から CoreOS をダウンロードしてインストールし、OCP を構成するサーバーとして自分自身を作り上げてゆきます。PXE ブート、慣れないとうまく行っているのかどうかもわかりにくいと思いますが、成功していると以下のような "PXE" とか "iPXE" といった文字列が表示され、RHCOS がネットワーク経由でダウンロード/インストールされていく様子が確認できます(画面は機種によって少し変わると思います。しばらく待ってもこうならない場合は何かミスってる可能性大です):

各ノードとも以下のような "Red Hat Enterprise Linux CoreOS" で始まる以下のような画面になっていれば、用意したイグニッションファイルが適用されて、少なくとも CoreOS のインストールまでは完了していると思ってください(OCP としてはまだインストール中の可能性があります):

なお、私の手元の環境だとブートストラップノードの画面に(以下図のように)赤字で Unable to pull OpenShift release image と表示されて、OCP インストールが先に進まなくなってしまうことが度々ありました:

この場合はバスチョンサーバー上で
# systemctl restart local-registry
を実行すると、数秒後にブートストラップノード上の赤い文字も消え、インストールが先に進むようになりました。もし同じ現象を確認された方がいたら試してみてください。
ここからは基本的には「OCP インストール完了を待つ」作業になります。ただ OCP インストール完了前からでも、下で紹介するような一部の OCP 関連コマンドが実行できるようになるので、インストール状況を確認する意味でも試してみてください。
まずマスターノードの OCP 導入状況を確認するには openshift-install コマンドに "wait-for bootstrap-complete" オプションを付けて実行します(ついでにログレベルも debug にして、より詳細な情報を表示するようにします)。約30分間にわたり、マスターノードのインストール状況が進んでいく様子を確認できます(マスターノードは数度リブートを繰り返しながら CoreOS と OCP のインストールが進んでいきます。環境次第ですが早ければ 30 分程度あればマスターノードのインストールは完了します。このコマンドは途中で Ctrl+C で終了して、再度同じコマンドを実行することで再度インストール状況の続きを見ることができます):
# openshift-install --dir=config --log-level=debug wait-for bootstrap-complete

以下のように "Bootstrap status: complete" と表示されればマスターノードの導入は成功しています(続けてワーカーノードの導入が進んでいます):

また全てのマスターノードの導入が上記のように完了していると一部の oc コマンドが使えるようになります。oc コマンドを実行するには以下のようにバスチョンサーバー上で環境変数 KUBECONFIG を設定し、コマンド("oc get nodes")を実行してみます:
# export KUBECONFIG=/root/config/auth/kubeconfig # oc get nodes
oc コマンドが使える状態になっていれば、現在までに OCP が認識しているマスターノードの一覧が表示されるはずです(この時点ではワーカーノードは表示されません)。まずは3つ全てのマスターノードが Ready のステータスで表示されるようになるのを待ちましょう:

3つのマスターノードが全て Ready になるとワーカーノードの導入が開始されます。ただワーカーノードは自動的に "oc get nodes" で表示されるようにはならず、手動で CSR を承認する必要があります。
まずは承認が必要な状態になっているものがあるかどうかを以下のコマンドで確認します(CSR の一覧を表示し、その中に承認待ち(Pending)ステータスになっているものがあれば表示する、というコマンドです):
# oc get csr | grep Pending
このコマンドの結果、承認待ちステータスになっている CSRが存在していると以下のような画面になります(マスターノードが全て準備できてから、この状態になるまで数十分~数時間かかります):

その場合は以下のコマンドを実行して、承認待ちの CSR をまとめて承認します:
# oc get csr -o go-template='{{range .items}}{{if not .status}}{{.metadata.name}}{{"\n"}}{{end}}{{end}}' | xargs oc adm certificate approve

この「承認待ち CSR があるか?」と「あったらまとめて承認する」を何度か繰り返し、数分待っても承認待ち CSR が新たに追加されなくなる状態を待ちます。本当に全ての CSR が承認されていればワーカーノードも順次 OCP に組み込まれてゆき、"oc get nodes" コマンドの結果に表示されるようになります。全てのマスターノードと全てのワーカーノードが "oc get nodes" コマンドの結果として、ステータスが Ready の状態で表示されるようになることを確認します:

ここまで完了すれば「ゴールまであとちょっと」です。最後に OCP としての基本機能(認証とかウェブコンソールとか・・)を提供するクラスターオペレーターが全て Ready な状態になることを確認します。確認コマンドは以下で、その結果全ての行でエラーメッセージや警告メッセージが表示されず、AVAILABLE=True なステータスになる状態を待ちます(つまり待つだけです):
# oc get clusteroperators

クラスターオペレーターが全て有効な状態になったことが確認できれば OCP のインストールは完了したことになります。確認のため、ウェブブラウザからウェブコンソール画面にアクセスしてみましょう。その前に管理者ユーザー(kubeadmin)のパスワードを確認するため、以下のコマンドを実行してログインパスワードを表示します:
# cat ~/config/auth/kubeadmin-password
ログインパスワードを確認したら改めてウェブブラウザを起動し、ウェブコンソール画面である以下の URL にアクセスします(SSL は自己署名証明書を使っているので警告画面になりますが、警告を無視して先に進めてください):
https://console-openshift-console.apps.ocp.xxx.localdomain/
すると以下のようなログイン画面が表示されます。(これが表示できた時点で OCP インストールは成功しているといえそうですが、、)ユーザー名に "kubeadmin" 、パスワードには先ほど確認したログインパスワードを入力してログインします:

ログインが成功すると以下のようなウェブコンソールのトップ画面が表示されます:

ここまでできれば OCP のエアギャップ環境下でのインストールは成功したと言えます! そしてイグニッションファイル作成からここまでを 24 時間以内に実行する必要がある、という点に改めて注意してください(過ぎちゃった場合は ~/config フォルダごと消してマニフェストファイルの作成からやり直し)。
なお、バスチョンサーバーであれば上述のように環境変数 KUBECONFIG を設定することで oc CLI が使えるようになりますが、他のサーバーであったり、バスチョンサーバーでも実施コマンドによってはトークンでログインしておく必要が生じます。ここでの紹介の最後にトークンでのログイン方法を紹介しておきます。
・・と言っても、トークンでのログイン方法はエアギャップ環境ではない時と同様です。まず上述の方法でウェブコンソールにログインし、画面右上のメニューから "Copy login command" を選択します:

このような画面が表示されたら "Display Token" と書かれた箇所をクリックします:

すると以下のような画面になるので "Log in with this token" と書かれた "oc login" で始まる文字列をコピーします:

コピーした文字列を oc コマンドが導入された環境でペーストして実行すると CLI でのログインが完了し、"oc get nodes" や "oc get clusteroperators" などのコマンドが同様に実行できるようになります。
【(3)OCP インストール後の作業】
ここまでの手順でエアギャップ環境での OCP がインストールされて、稼働状態になりました。が、実はこの状態だとまだエアギャップ環境に対応していない箇所が残っています。最終的にそれらの部分をエアギャップ環境用の調整して作業完了とみなすことにします。
まずこの時点では OperatorHub が使えません。オフライン環境ではこの方法でインストールした OCP の OperatorHub は未対応なので、OperatorHub のオフライン対応を行います。そのため、一旦全ての Sources を disable に設定します:
# oc patch OperatorHub cluster --type json -p '[{"op":"add","path":"/spec/disableAllDefaultSources","value":true}]'
そしてミラーレジストリを構築した際にできたフォルダ(~/oc-mirror-workspace/results-xxxxxxxxxx/)の情報を使ってオフライン対応を実施します:
# cd # oc apply -f oc-mirror-workspace/results-xxxxxxxxxx/ # oc apply -f oc-mirror-workspace/results-xxxxxxxxxx/release-signatures/
上の2番目のコマンド("oc apply -f oc-mirror-workspace/results-xxxxxxxxxx")を実行した時に以下のようなエラーメッセージが表示されますが、エアギャップ環境では無視して構いません:

ここまで実行することで OperatorHub もエアギャップ環境に対応できました。今回の環境では imageset-config-4.13.0.yaml ファイルを作った時に入れておいた Local Storage Operator が表示されます:

またワーカーノードをインフラノードとして利用する場合、対象ノードに以下のラベリングを行います。例えば worker0 のみインフラノードにする場合は、以下のコマンドを実行します(worker1 や worker2 を対象にする場合も同様に追加実行します):
# oc label node worker0.ocp.xxx.localdomain node-role.kubernetes.io/infra=""
そして、インストールを終えてもう使うことのないブートストラップノードをシャットダウンします。OCP 環境ではバスチョンサーバーからは各ノードの CoreOS に "core" ユーザーで(パスワードなしで)ssh ログインが可能です。また CoreOS 上では core ユーザーは sudo 権限を持っているので、以下のようにシャットダウンコマンドを実行可能です:
# ssh core@bootstrap $ sudo shutdown -h now
なお、ブートストラップノード以外のノードについては OCP 新規インストールから 24 時間はシャットダウンしないように気を付けてください。この辺り、詳しくはこちらも参照してください:
https://www.reddit.com/r/openshift/comments/c7e5na/how_to_shutdown_all_openshift_hosts_safely_in/?rdt=44062
最後にバスチョンサーバーの haproxy(ロードバランサー)からブートストラップノードを分離します。バスチョンサーバー上で /etc/haproxy/haproxy.cfg ファイルを開き、bootstrap ノードに負荷分散する設定になっている2行を削除するかコメントアウトして保存します:

最後に haproxy を再起動します:
# systemctl restart haproxy
これでエアギャップ環境上での OCP のインストールができました。非常に長いインストール手順でしたが、これで「エアギャップ環境で OCP を使う」ための準備ができたことになります:

この後はエアギャップ環境の OCP 内にコンテナアプリケーションをデプロイする手順や、OCP をエアギャップ環境のままアップグレードする手順を紹介してゆく予定です。
・エアギャップ環境(インターネット接続のない環境)で OCP を導入/運用する上で必要な前提理解
・エアギャップ環境(インターネット接続のない環境)で OCP を導入する手順
・エアギャップ環境(インターネット接続のない環境)で OCP にアプリケーションを導入する手順
・エアギャップ環境(インターネット接続のない環境)に導入した OCP をエアギャップ環境内でアップグレードする手順
コメント