【OKD 5.0】 オフライン環境:ミラー レジストリを使って、インターネットに出られないノードにインストールする手順(Agent-based+baremetal)

インターネットに出られないネットワーク(オフライン環境)に OKD をインストールする手順です。インターネットに出られる踏み台サーバーを 1 台用意し、そこにミラー レジストリを立てて OKD のイメージを写しておきます。クラスタのノードは、イメージをミラー レジストリから、時刻を踏み台の NTP から取ります。

インストールの流れは オンライン環境・platform: baremetal の記事と同じです。この記事では、オフライン環境で追加・変更するところを書きます。

目次

この記事の前提

  • 踏み台サーバーの構築が終わっていること(ens19 10.30.0.1、DNS の okdoff と registry.hvdoc.lab のレコード)
  • 参照: OKD Documentation(Disconnected environments、Installing an on-premise cluster with the Agent-based Installer)

構成

項目値
クラスタ名okdoff(platform: baremetal、コントロール プレーン 3 台)
ノードのネットワーク10.30.0.0/24(Proxmox VE のブリッジ hvnet0、外部に出る経路なし)
ノードoff-master-1〜3(10.30.0.11〜13)。ゲートウェイ・DNS・NTP は踏み台の 10.30.0.1
VIPAPI 10.30.0.4、Ingress 10.30.0.5
ミラー レジストリ踏み台の registry.hvdoc.lab:5000(10.30.0.1)。registry:2 を podman で動かし、TLS と認証をかける
通信オンライン環境オフライン環境(この記事)
OKD のイメージquay.io から取る踏み台のミラー レジストリから取る
時刻インターネットの NTP踏み台の chrony
pull secretダミーでよい(quay.io の OKD は認証不要)ミラー レジストリの認証情報
install-config.yaml の追加なしadditionalTrustBundle(ミラーの CA)、imageDigestSources(取り先の置き換え)

踏み台は、インターネット側(192.168.1.0/24)とオフライン側(10.30.0.0/24)の両方に足を持ちます。踏み台はルーティング(IP フォワード)をしないので、ノードから外部には出られません。

NTP サーバー(chrony)

ノードの時刻がずれると、証明書の検証やインストールが失敗します。踏み台の chrony から、オフライン側へ時刻を配ります。

実行する場所:踏み台サーバー(root)

# dnf -y install chrony httpd-tools openssl
# cat >> /etc/chrony.conf <<'EOF'
# オフラインのクラスタへ時刻を配る
allow 10.30.0.0/24
local stratum 10
EOF
# systemctl enable --now chronyd
# systemctl restart chronyd
# firewall-cmd --permanent --add-service=ntp
# firewall-cmd --reload
設定意味
allow 10.30.0.0/24このネットワークからの NTP の問い合わせに答える
local stratum 10上位の NTP に届かないときも、自分の時計で時刻を配り続ける

ミラー レジストリの証明書

ノードは、ミラー レジストリに TLS で接続します。自己署名の CA を作り、その CA で registry.hvdoc.lab のサーバー証明書を発行します。CA の証明書は、あとで install-config.yaml の additionalTrustBundle に入れます。

実行する場所:踏み台サーバー(root)

# mkdir -p /srv/registry/{certs,auth,data}
# cd /srv/registry/certs
# openssl req -x509 -newkey rsa:4096 -sha256 -days 3650 -nodes -keyout ca.key -out ca.crt -subj "/CN=hvdoc-lab-ca"
# openssl req -newkey rsa:4096 -nodes -keyout registry.key -out registry.csr -subj "/CN=registry.hvdoc.lab"
# printf 'subjectAltName=DNS:registry.hvdoc.lab,IP:10.30.0.1\nextendedKeyUsage=serverAuth\n' > san.ext
# openssl x509 -req -in registry.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out registry.crt -days 3650 -sha256 -extfile san.ext
# openssl x509 -in registry.crt -noout -subject -ext subjectAltName
# cp ca.crt /etc/pki/ca-trust/source/anchors/hvdoc-lab-ca.crt
# update-ca-trust

期待する出力:

subject=CN=registry.hvdoc.lab
X509v3 Subject Alternative Name:
    DNS:registry.hvdoc.lab, IP Address:10.30.0.1

証明書には、CN だけでなく subjectAltName(SAN)が必要です。SAN がないと、ノードの CRI-O が証明書を受け付けません。

ミラー レジストリ(registry:2)

認証用のユーザーを作り、registry:2 のコンテナを podman で起動します。systemd に登録して、踏み台を再起動しても自動で起動するようにします。

実行する場所:踏み台サーバー(root)

# htpasswd -bBc /srv/registry/auth/htpasswd okd 'P@ssw0rd-reg'
# podman pull docker.io/library/registry:2
# podman run -d --name mirror-registry --restart=always -p 5000:5000 \
  -v /srv/registry/data:/var/lib/registry:z \
  -v /srv/registry/certs:/certs:z \
  -v /srv/registry/auth:/auth:z \
  -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/registry.crt \
  -e REGISTRY_HTTP_TLS_KEY=/certs/registry.key \
  -e REGISTRY_AUTH=htpasswd \
  -e REGISTRY_AUTH_HTPASSWD_REALM=okd \
  -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \
  -e REGISTRY_STORAGE_DELETE_ENABLED=true \
  docker.io/library/registry:2
# podman generate systemd --name mirror-registry --files --new
# mv container-mirror-registry.service /etc/systemd/system/
# systemctl daemon-reload
# systemctl enable container-mirror-registry
# firewall-cmd --permanent --add-port=5000/tcp
# firewall-cmd --reload
# curl -u okd:'P@ssw0rd-reg' https://registry.hvdoc.lab:5000/v2/_catalog

期待する出力:

{"repositories":[]}
設定意味
-p 5000:5000レジストリのポート。ノードからは registry.hvdoc.lab:5000 で接続する
/srv/registry/dataイメージの保存先。OKD 5.0 のリリース イメージ一式で約 18GB
REGISTRY_AUTH=htpasswdユーザー名とパスワードで認証する

本番では、Red Hat の mirror registry for Red Hat OpenShift(Quay)や、既存の Harbor・Nexus などを使うこともできます。ここでは手順を短くするため registry:2 を使います。

OKD のイメージをミラーする

踏み台(インターネットに出られる)で oc adm release mirror を実行し、OKD のリリース イメージをミラー レジストリへ写します。

実行する場所:踏み台サーバー(root)

# REL=$(openshift-install version | awk '/release image/{print $3}')
# echo $REL
# AUTH=$(echo -n 'okd:P@ssw0rd-reg' | base64 -w0)
# echo "{\"auths\":{\"registry.hvdoc.lab:5000\":{\"auth\":\"$AUTH\"}}}" > /root/okd/pull-secret-mirror.json
# oc adm release mirror -a /root/okd/pull-secret-mirror.json \
  --from=$REL \
  --to=registry.hvdoc.lab:5000/okd/scos-release \
  --to-release-image=registry.hvdoc.lab:5000/okd/scos-release:5.0.0-okd-scos.3 \
  --keep-manifest-list=true
オプション意味
-aミラー レジストリへ書き込むための認証情報
–from写すリリース イメージ(openshift-install に組み込まれているもの)
–to写し先のリポジトリ。リリースに含まれるイメージをすべてここに入れる
–to-release-imageリリース イメージ自体の写し先(タグ付き)
–keep-manifest-list=trueマニフェスト リストを、リストのまま写す(下の注意を参照)

–keep-manifest-list=true を必ず付けます。 OKD 5.0 のリリースでは、ノードの OS のイメージ(stream-coreos・stream-coreos-extensions)がマニフェスト リスト(amd64 の 1 つだけを含む)のダイジェストで参照されています。このオプションがないと、amd64 のマニフェストだけが写されてリスト自体はミラーに入りません。そのため、インストール中にランデブー ホストの node-image-pull.service が「manifest unknown」で止まります(この環境で実際に発生しました。ほかのノードは 10.30.0.4:22623 の ignition を待ったまま進みません)。

期待する出力(最後の部分):

Success
Update image:  registry.hvdoc.lab:5000/okd/scos-release:5.0.0-okd-scos.3
Mirror prefix: registry.hvdoc.lab:5000/okd/scos-release

To use the new mirrored repository to install, add the following section to the install-config.yaml:

imageContentSources:
- mirrors:
  - registry.hvdoc.lab:5000/okd/scos-release
  source: quay.io/okd/scos-content
- mirrors:
  - registry.hvdoc.lab:5000/okd/scos-release
  source: quay.io/okd/scos-release

この環境では、約 10 分・約 18GB でした。最後に表示される mirrors と source の組み合わせを、install-config.yaml に書きます(OKD 5.0 では imageContentSources ではなく imageDigestSources という名前で書きます)。

踏み台もインターネットに出られない完全なオフライン環境では、oc adm release mirror –to-dir でイメージをファイルに書き出し、媒体で運んでから –from-dir でミラー レジストリへ入れます。オペレーター(OKD Virtualization など)もミラーする場合は oc-mirror を使います。この記事では、リリース イメージ(クラスタ本体)だけをミラーします。

install-config.yaml

オンライン環境との違いは、pullSecret・additionalTrustBundle・imageDigestSources の 3 か所と、ネットワーク(machineNetwork・VIP)です。

実行する場所:踏み台サーバー(root)

# mkdir -p /root/okd/okdoff && cd /root/okd/okdoff
# CA=$(sed 's/^/  /' /srv/registry/certs/ca.crt)
# cat > install-config.yaml <<EOF
apiVersion: v1
baseDomain: hvdoc.lab
metadata:
  name: okdoff
compute:
- name: worker
  replicas: 0
controlPlane:
  name: master
  replicas: 3
networking:
  networkType: OVNKubernetes
  machineNetwork:
  - cidr: 10.30.0.0/24
  clusterNetwork:
  - cidr: 10.128.0.0/14
    hostPrefix: 23
  serviceNetwork:
  - 172.30.0.0/16
platform:
  baremetal:
    apiVIPs:
    - 10.30.0.4
    ingressVIPs:
    - 10.30.0.5
pullSecret: '$(cat /root/okd/pull-secret-mirror.json)'
sshKey: '$(cat /root/.ssh/id_ed25519.pub)'
additionalTrustBundle: |
$CA
imageDigestSources:
- mirrors:
  - registry.hvdoc.lab:5000/okd/scos-release
  source: quay.io/okd/scos-content
- mirrors:
  - registry.hvdoc.lab:5000/okd/scos-release
  source: quay.io/okd/scos-release
EOF
項目内容
pullSecretミラー レジストリの認証情報(ユーザー okd)
additionalTrustBundleミラー レジストリの証明書を発行した CA。ノードがこの CA を信頼する
imageDigestSourcesquay.io/okd/… のイメージを、ミラー レジストリから取るように置き換える
machineNetwork・VIPオフライン側のネットワーク 10.30.0.0/24 と、その中の未使用の IP アドレス

agent-config.yaml

baremetal の記事と同じ形です。IP アドレス、ゲートウェイ・DNS(踏み台 10.30.0.1)と、additionalNTPSources が違います。

実行する場所:踏み台サーバー(root)

# cat > agent-config.yaml <<'EOF'
apiVersion: v1beta1
kind: AgentConfig
metadata:
  name: okdoff
rendezvousIP: 10.30.0.11
additionalNTPSources:
- 10.30.0.1
hosts:
  - hostname: off-master-1
    role: master
    rootDeviceHints:
      deviceName: /dev/disk/by-path/pci-0000:09:01.0-scsi-0:0:0:0
    interfaces:
    - name: ens18
      macAddress: BC:24:11:0D:01:11
    networkConfig:
      interfaces:
      - name: ens18
        type: ethernet
        state: up
        identifier: mac-address
        mac-address: BC:24:11:0D:01:11
        ipv4:
          enabled: true
          dhcp: false
          address:
          - ip: 10.30.0.11
            prefix-length: 24
        ipv6:
          enabled: false
      dns-resolver:
        config:
          server:
          - 10.30.0.1
      routes:
        config:
        - destination: 0.0.0.0/0
          next-hop-address: 10.30.0.1
          next-hop-interface: ens18
  (off-master-2 は 10.30.0.12・MAC BC:24:11:0D:01:12、off-master-3 は 10.30.0.13・MAC BC:24:11:0D:01:13 で同じように書く)
EOF
項目内容
additionalNTPSourcesノードが時刻を取る NTP サーバー(踏み台の chrony)
routes の next-hop-address既定のゲートウェイ。外部へは出られないが、インストーラーの確認のために設定する

エージェント ISO の作成

実行する場所:踏み台サーバー(root)

# openshift-install agent create image --dir /root/okd/okdoff

期待する出力(抜粋):

INFO Extracting base ISO from release payload
WARNING Failed to extract base ISO from release payload - check registry configuration
INFO Downloading base ISO
INFO Generated ISO at /root/okd/okdoff/agent.x86_64.iso.

ベース ISO(CentOS Stream CoreOS)は、まずミラーからの取り出しを試し、失敗するとインターネットからダウンロードします。この環境では取り出しに失敗し、踏み台がインターネットに出られるためダウンロードで ISO を作れました。ISO を作るだけなので、ノード側のオフライン動作には影響しません。踏み台もインターネットに出られない場合は、ベース ISO をあらかじめ用意しておく必要があります。

ノードの起動とインストール

ISO を Proxmox VE にアップロードし、3 台の仮想マシンを作って起動します。手順は baremetal の記事と同じで、NIC をオフライン側のブリッジ(hvnet0)につなぐところだけが違います。

項目値
net0ブリッジ hvnet0、MAC BC:24:11:0D:01:11〜13(agent-config.yaml と同じ)
ディスク・CPU・メモリbaremetal の記事と同じ(scsi0 120GB、8 vCPU、24GB)

(1) ランデブー ホスト(off-master-1)の画面に「This host (10.30.0.11) is the rendezvous host.」と表示され、3 台がそろうと「Cluster installation in progress」に変わります。

ランデブー ホストの画面

(2) ほかのノードの画面には、ランデブー ホストの IP アドレスが表示されます。

ほかのノードの画面

(3) インストールの完了を待ちます。

実行する場所:踏み台サーバー(root)

# openshift-install agent wait-for bootstrap-complete --dir /root/okd/okdoff
# openshift-install agent wait-for install-complete --dir /root/okd/okdoff

期待する出力(抜粋):

INFO Bootstrap Kube API Initialized
INFO Bootstrap configMap status is complete
INFO cluster bootstrap is complete
INFO Install complete!
INFO Access the OpenShift web-console here: https://console-openshift-console.apps.okdoff.hvdoc.lab

この環境では、ノードの起動から完了まで約 55 分でした(うち約 20 分は、下の「インストールが進まないとき」の対処に使った時間です)。

インストールが進まないとき

ほかのノードの画面が「rendezvous host is at …」のまま 20 分以上進まないときは、ランデブー ホストにログインし、イメージの取得に失敗していないかを確認します。

実行する場所:踏み台サーバー(root)

# ssh [email protected] sudo journalctl -u node-image-pull -u release-image --no-pager -n 20

失敗しているときの出力(抜粋):

node-image-pull.sh[8195]: level=warning msg="Failed, retrying in 1s ... (1/50). Error: (Mirrors also failed: [registry.hvdoc.lab:5000/okd/scos-release@sha256:4a1c64c2...: reading manifest sha256:4a1c64c2... in registry.hvdoc.lab:5000/okd/scos-release: manifest unknown]): quay.io/okd/scos-content@sha256:4a1c64c2...: pinging container registry quay.io: Get "https://quay.io/v2/": dial tcp 52.206.240.228:443: i/o timeout"
表示原因と対処
manifest unknownミラーにそのイメージがない。–keep-manifest-list=true を付けてミラーし直す(ミラー済みのデータは再転送されないので、この環境では 1 分半で終わった)。ノードは自動で再試行するため、ノードを作り直す必要はない
x509: certificate signed by unknown authorityadditionalTrustBundle の CA が違う。ISO を作り直す
unauthorizedpullSecret の認証情報が違う。ISO を作り直す
i/o timeout(quay.io)オフラインなので正常。ミラーの取得に失敗したときに、元の quay.io も試した記録

確認

(1) ノードとクラスタのバージョンを確認します。

実行する場所:踏み台サーバー(root)

# export KUBECONFIG=/root/okd/okdoff/auth/kubeconfig
# oc get nodes -o wide
# oc get clusterversion
# oc get co

期待する出力(抜粋):

NAME           STATUS   ROLES                         AGE   VERSION   INTERNAL-IP
off-master-1   Ready    control-plane,master,worker   6m    v1.36.3   10.30.0.11
off-master-2   Ready    control-plane,master,worker   27m   v1.36.3   10.30.0.12
off-master-3   Ready    control-plane,master,worker   27m   v1.36.3   10.30.0.13
NAME      VERSION            AVAILABLE   PROGRESSING   SINCE   STATUS
version   5.0.0-okd-scos.3   True        False         7m28s   Cluster version is 5.0.0-okd-scos.3

oc get co で、すべてのクラスタ オペレーターの AVAILABLE が True になっていることを確認します。

(2) イメージの取り先の置き換え(ImageDigestMirrorSet)がクラスタに入っていることを確認します。install-config.yaml の imageDigestSources から自動で作られます。

# oc get imagedigestmirrorset image-digest-mirror -o yaml

期待する出力(抜粋):

spec:
  imageDigestMirrors:
  - mirrors:
    - registry.hvdoc.lab:5000/okd/scos-release
    source: quay.io/okd/scos-content
  - mirrors:
    - registry.hvdoc.lab:5000/okd/scos-release
    source: quay.io/okd/scos-release

(3) ノードからインターネットに出られないこと、時刻を踏み台から取っていることを確認します。

# ssh [email protected] 'curl -s -m 5 https://quay.io/v2/ || echo NG; chronyc sources'

期待する出力(抜粋):

NG
^* registry.hvdoc.lab            3   6   377    90    -11us[ -155us] +/- 5206us
確認項目結果
quay.io への接続できない(NG)。イメージはすべてミラーから取っている
時刻の同期先registry.hvdoc.lab(踏み台 10.30.0.1 の chrony)に「*」(同期中)

ノードの crictl images では、イメージ名が quay.io/okd/scos-content と表示されます。これは「元の名前」で、実際の取得先は ImageDigestMirrorSet で置き換えたミラーです。

Web コンソール(https://console-openshift-console.apps.okdoff.hvdoc.lab)は Ingress の VIP(10.30.0.5)にあるため、10.30.0.0/24 に届く端末から開きます。画面は オンライン環境の記事と同じです。

オフライン環境で後から必要になること

作業方法
OperatorHub のオペレーター(OKD Virtualization など)oc-mirror でカタログとオペレーターのイメージをミラーし、作られた CatalogSource を適用する。既定のカタログ(インターネット)は無効にする
クラスタの更新新しいリリースを同じ手順(oc adm release mirror –keep-manifest-list=true)でミラーし、oc adm upgrade –to-image で更新する
ミラー レジストリの証明書の更新有効期限(この手順では 10 年)の前に作り直し、クラスタの additionalTrustBundle(user-ca-bundle)も更新する

次の手順

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

目次