TT Lab
はじめる
学ぶ 学習パス コース

Kubespray と Terraform でクラスターを構築する

閉域網に持ち込むものの一覧 — ファイル・イメージ・Python

TT Labで続きを見る

目標

kubesprayがインストール中にダウンロードするファイルとイメージの一覧を作り、インベントリのオフライン変数で、その一覧が社内ミラー(registry.lab.internal:5000、http://files.lab.internal)を指すように変更します。ミラーを用意する人に渡す対応表と、コントロールノードのAnsibleまで入れた持ち込みバンドルを作ります。実際のエアギャップ環境とミラーは作りません。

なぜ重要なのか

エアギャップ環境でのインストールの失敗は、ほとんどが「抜け」です。持ち込み審査を経て持って入った後で、ファイルが1つないことに気づくと、もう一度出て戻る必要があり、その往復が数日かかります。 そのため、インストールツールが何をダウンロードするかをツール自身に言わせ(generate_list.sh)、その一覧が本当に今回インストールするバージョンのものか、すべてのアドレスが社内を指しているかを、外にいるときに確認する必要があります。このモジュールで出会う、一覧のバージョンの落とし穴は、実際にこのコースを作りながら経験したものです。インベントリにバージョンを書いておいたのに、一覧は別のバージョンで出ました。

ステップ

  1. /opt/ks/kubespray/contrib/offlineで./generate_list.shを引数なしで実行し、作成されたtemp/files.listとtemp/images.listをコピーしてください(コピー先: /root/ks/offline/default/)。次のフィールドを書いてください(書き込み先: /root/ks/offline/default/count.json)。files、images(2つの一覧の行数)とregistries(images.listの最初のパスの部分ごとの個数。例: {"quay.io": 3})です。
  2. インベントリのkube_versionは1.35.8です。./generate_list.sh -i /root/ks/inventory/lab/inventory.iniで1回、これに-e kube_version=1.35.8を加えて1回実行し、それぞれのimages.listのkube-apiserverのタグを確認してください。次のフィールドを書いてください(書き込み先: /root/ks/offline/trap.json)。with_inventory(最初の実行のkube-apiserverのタグ)、with_extra_var(2回目の実行のタグ)、ignored_group(インベントリのkube_versionが書かれたgroup_varsのグループのうち、一覧のプレイブックに適用されなかったグループ名)です。
  3. registry_host: "registry.lab.internal:5000"とfiles_repo: "http://files.lab.internal"を置き(対象: /root/ks/inventory/lab/group_vars/all/offline.yml)、kubesprayのドキュメントのエアギャップ環境の節のとおり、kube_image_repo・gcr_image_repo・docker_image_repo・quay_image_repo・github_image_repoを{{ registry_host }}に、github_url・dl_k8s_io_url・storage_googleapis_url・get_helm_urlを{{ files_repo }}/<원래 도메인>にしてください(プレースホルダーは元のドメインです)。ファイルはgroup_vars/allにある必要があります。
  4. ./generate_list.sh -i /root/ks/inventory/lab/inventory.ini -e kube_version=1.35.8で一覧を作り直し、2つのファイルをコピーしてください(コピー先: /root/ks/offline/mirror/)。files.listのすべての行がhttp://files.lab.internal/で、images.listのすべての行がregistry.lab.internal:5000/で始まり、行数がステップ1と同じである必要があります。
  5. ミラーを用意する人に渡す対応表を作ってください。オフライン変数を適用していない1.35.8の元の一覧と、ステップ4のミラーの一覧を行単位で対応させて、원본<TAB>미러を1行に1つずつ(images.listのすべてのイメージ)書いてください(プレースホルダーは元の値とミラーです。書き込み先: /root/ks/offline/image-map.tsv)。
  6. containerd_registries_mirrorsを加え、prefixregistry.lab.internal:5000が、hosthttp://registry.lab.internal:5000をpullとresolveに使い、TLS検証をスキップする(skip_verify: true)ようにしてください(対象: /root/ks/inventory/lab/group_vars/all/offline.yml)。ansible-inventory --host node1が、この一覧をそのまま展開する必要があります。
  7. kubesprayのrequirements.txtでPythonパッケージをダウンロードし(pip download、ダウンロード先: /root/ks/offline/pypi/)、インターネットを使わないインストールが、そのディレクトリだけで解決できるかを、pip install --dry-run --no-index --find-links /root/ks/offline/pypi -r requirements.txtで確認してください。次のフィールドを書きます(書き込み先: /root/ks/offline/pypi.json)。wheels(ダウンロードしたファイルの数)、resolved(dry-runが成功したか、ブール値)です。

参考

何をダウンロードするか、まず一覧から

/opt/ks/kubespray/contrib/offlineで./generate_list.shを引数なしで実行し、作成されたtemp/files.listとtemp/images.listをコピーしてください(コピー先: /root/ks/offline/default/)。次のフィールドを書いてください(書き込み先: /root/ks/offline/default/count.json)。files、images(2つの一覧の行数)とregistries(images.listの最初のパスの部分ごとの個数。例: {"quay.io": 3})です。

generate_list.shは、roles/kubespray_defaults/defaults/main/download.ymlからdownload_urlとイメージのrepoとtagを取り出してテンプレートを作り、小さなプレイブックで変数を埋めます。有効にしていないCNIやアドオンのものまですべて入っているので、実際のインストールより余裕があります。イメージの一覧の最初の部分が、そのままミラーすべき元のレジストリです。

一覧が静かに別のバージョンで出る

インベントリのkube_versionは1.35.8です。./generate_list.sh -i /root/ks/inventory/lab/inventory.iniで1回、これに-e kube_version=1.35.8を加えて1回実行し、それぞれのimages.listのkube-apiserverのタグを確認してください。次のフィールドを書いてください(書き込み先: /root/ks/offline/trap.json)。with_inventory(最初の実行のkube-apiserverのタグ)、with_extra_var(2回目の実行のタグ)、ignored_group(インベントリのkube_versionが書かれたgroup_varsのグループのうち、一覧のプレイブックに適用されなかったグループ名)です。

generate_list.ymlは、hosts: localhostで動きます。localhostはインベントリのどのグループにもないので、allのgroup_varsしか受け取りません。一覧が間違ったバージョンで出ると、持ち込んだファイルでは、インストールが始まった途端に「ファイルがない」で止まります。それも、エアギャップ環境の現場でです。

インベントリが社内ミラーを指すようにする

registry_host: "registry.lab.internal:5000"とfiles_repo: "http://files.lab.internal"を置き(対象: /root/ks/inventory/lab/group_vars/all/offline.yml)、kubesprayのドキュメントのエアギャップ環境の節のとおり、kube_image_repo・gcr_image_repo・docker_image_repo・quay_image_repo・github_image_repoを{{ registry_host }}に、github_url・dl_k8s_io_url・storage_googleapis_url・get_helm_urlを{{ files_repo }}/<원래 도메인>にしてください(プレースホルダーは元のドメインです)。ファイルはgroup_vars/allにある必要があります。

ドキュメントのヒントのとおり、files_repoの下に元のドメインを最初のディレクトリとして置くと(files_repo/github.com/...)、ミラーを用意するときに、URLを機械的に移せます。変数をallに置く理由は2つです。etcdだけがあるノードもダウンロードする必要があり、一覧のプレイブック(localhost)もこの値を読み取る必要があります。

一覧がすべて社内のアドレスになったか

./generate_list.sh -i /root/ks/inventory/lab/inventory.ini -e kube_version=1.35.8で一覧を作り直し、2つのファイルをコピーしてください(コピー先: /root/ks/offline/mirror/)。files.listのすべての行がhttp://files.lab.internal/で、images.listのすべての行がregistry.lab.internal:5000/で始まり、行数がステップ1と同じである必要があります。

1行でも元のドメインが残っていれば、そのファイルやイメージは、エアギャップ環境ではダウンロードできません。残っている行があれば、どの変数が抜けているかを、その行のドメインが教えてくれます。

元とミラーの組み合わせ

ミラーを用意する人に渡す対応表を作ってください。オフライン変数を適用していない1.35.8の元の一覧と、ステップ4のミラーの一覧を行単位で対応させて、원본<TAB>미러を1行に1つずつ(images.listのすべてのイメージ)書いてください(プレースホルダーは元の値とミラーです。書き込み先: /root/ks/offline/image-map.tsv)。

オフライン変数はgroup_vars/allにあるので、元の一覧は、インベントリなしで-e kube_version=...だけを指定して作ります。2つの一覧は同じテンプレートから出るので、順序が同じです。レジストリのアドレスだけが変わってパスはそのままだという点が、ミラー設計の核心です。ミラー側のパスを変えると、この対応が壊れます。

ノードが社内レジストリを信頼するようにする

containerd_registries_mirrorsを加え、prefixregistry.lab.internal:5000が、hosthttp://registry.lab.internal:5000をpullとresolveに使い、TLS検証をスキップする(skip_verify: true)ようにしてください(対象: /root/ks/inventory/lab/group_vars/all/offline.yml)。ansible-inventory --host node1が、この一覧をそのまま展開する必要があります。

kubesprayのドキュメントは、containerd 2と1.7で設定方法が異なると書いています。2では、containerd_registries_mirrorsが/etc/containerd/certs.d//hosts.tomlに変わります。ラボ用なのでTLSを無効にしますが、本番では、社内のCAで署名した証明書を使い、skip_verifyを有効にしないのが原則です。

Ansibleも持ち込む必要がある

kubesprayのrequirements.txtでPythonパッケージをダウンロードし(pip download、ダウンロード先: /root/ks/offline/pypi/)、インターネットを使わないインストールが、そのディレクトリだけで解決できるかを、pip install --dry-run --no-index --find-links /root/ks/offline/pypi -r requirements.txtで確認してください。次のフィールドを書きます(書き込み先: /root/ks/offline/pypi.json)。wheels(ダウンロードしたファイルの数)、resolved(dry-runが成功したか、ブール値)です。

エアギャップ環境では、コントロールノードのAnsibleも持っていく必要があります。kubesprayのドキュメントがPythonパッケージを「オプション」と書いているのは、OSが同じバージョンを提供する場合を指していますが、このバージョンはansible==12.3.0のように正確なバージョンを要求するので、たいていは自分で持っていく必要があります。ダウンロードするときとインストールするときの、Pythonのバージョンと、CPUアーキテクチャが同じである必要があります。ホイールのファイル名に、それが書かれています。