本文已超過一年。較舊的文章可能包含過時的內容。請檢查頁面中的資訊自發布以來是否已變得不正確。
使用 Kubeadm 部署離線 (Air Gapped) 叢集
您是否想過軟體如何部署到故意與網際網路和其他網路斷開連接的系統上?這些系統通常由於其敏感性而斷開連接。敏感性如公用事業(電力/水)、銀行、醫療保健、武器系統、其他政府用例等。 有時,如果您在水下船隻上運行 Kubernetes,則在技術上是水隙。儘管如此,這些環境仍然需要軟體才能運行。這種在斷線狀態下部署的概念就是部署到氣隙的另一側的意義。
再次強調,儘管有這種姿態,軟體仍然需要在這些環境中運行。傳統上,軟體工件是以實體方式跨氣隙攜帶,使用硬碟、USB 隨身碟、CD 或軟碟(對於舊系統,這種情況仍然發生)。 Kubernetes 特別適合在氣隙後方運行軟體,原因有很多,主要是因為它的宣告式特性。
在這篇部落格文章中,我將逐步介紹在氣隙實驗室環境中使用 Fedora Linux 和 kubeadm 引導 Kubernetes 叢集的過程。
氣隙 VM 設定
建立真正的氣隙網路可能需要一些努力,因此在這篇文章中,我將在筆記型電腦上使用一個範例 VM,並進行一些網路修改。以下是拓撲
本地拓撲
此 VM 將停用其網路連線,但方式不會關閉 VM 的虛擬 NIC。相反,它的網路將透過將預設路由注入到虛擬介面來關閉,使任何網際網路託管的內容都無法訪問。但是,VM 仍然具有到主機上橋接介面的已連線路由,這表示到主機的網路連線仍然有效。這種姿態表示資料可以透過 scp
從主機/筆記型電腦傳輸到 VM,即使 VM 上的預設路由會封鎖所有非預定到本地橋接子網路的流量。這種傳輸類型類似於跨氣隙攜帶資料,並將在整篇文章中使用。
關於實驗室設定的其他詳細資訊
VM 作業系統: Fedora 37
Kubernetes 版本: v1.27.3
CNI 外掛程式版本: v1.3.0
CNI 提供者和版本: Flannel v0.22.0
雖然這個單一 VM 實驗室是一個簡化的範例,但以下圖表更接近地顯示了真正的氣隙環境可能的外觀
請注意,環境與網際網路之間仍然存在刻意的隔離。為了保持圖表簡潔,還有一些未顯示的內容,例如氣隙安全側的惡意軟體掃描。
回到單一 VM 實驗室環境。
識別所需的軟體工件
我已經費盡心思地識別了所有需要跨氣隙攜帶的必要軟體組件,以便啟動此叢集
- Docker(託管內部容器映像檔儲存庫)
- Containerd
- libcgroup
- socat
- conntrack-tools
- CNI 外掛程式
- crictl
- kubeadm
- kubelet
- kubectl 和 k9s(嚴格來說,這些不是啟動叢集所必需的,但它們對於與叢集互動很有用)
- kubelet.service systemd 檔案
- kubeadm 組態檔
- Docker 容器映像檔儲存庫容器映像檔
- Kubernetes 組件容器映像檔
- CNI 網路外掛程式容器映像檔(此實驗室將使用 Flannel)
- CNI 網路外掛程式 manifest 檔案
- CNI 工具容器映像檔
我識別這些組件的方式是嘗試進行安裝,並解決所有因需要額外依賴項而拋出的錯誤。在真正的氣隙情境中,每次跨氣隙傳輸工件可能代表安裝人員花費 20 分鐘到數週的時間。也就是說,目標系統可能位於與您的辦公桌位於同一樓層的資料中心、偏遠地區的衛星下行鏈路設施,或是在海上航行的潛艇上。了解系統在任何給定時間的狀態非常重要,這樣您才能知道必須攜帶什麼。
準備節點以用於 K8s
在下載工件並將其移動到 VM 之前,讓我們先準備該 VM 以運行 Kubernetes。
VM 準備
以一般使用者身分執行這些步驟
為軟體工件建立目標目錄
mkdir ~/tmp
以超級使用者 (root
) 身分執行以下步驟
寫入 /etc/sysctl.d/99-k8s-cri.conf
cat > /etc/sysctl.d/99-k8s-cri.conf << EOF
net.bridge.bridge-nf-call-iptables=1
net.ipv4.ip_forward=1
net.bridge.bridge-nf-call-ip6tables=1
EOF
寫入 /etc/modules-load.d/k8s.conf
(啟用 overlay
和 nbr_netfilter
)
echo -e overlay\\nbr_netfilter > /etc/modules-load.d/k8s.conf
安裝 iptables
dnf -y install iptables-legacy
設定 iptables 以使用傳統模式(而非模擬 iptables
的 nft
)
update-alternatives --set iptables /usr/sbin/iptables-legacy
關閉 swap
touch /etc/systemd/zram-generator.conf
systemctl mask systemd-zram-setup@.service
sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
停用 firewalld
(在示範環境中可以這樣做)
systemctl disable --now firewalld
停用 systemd-resolved
systemctl disable --now systemd-resolved
為 NetworkManager 設定 DNS 預設值
sed -i '/\[main\]/a dns=default' /etc/NetworkManager/NetworkManager.conf
清空系統級別 DNS 解析器組態
unlink /etc/resolv.conf || true
touch /etc/resolv.conf
停用 SELinux (僅適用於示範 - 在生產環境中執行此操作之前請檢查!)
setenforce 0
確保所有變更在重新啟動後仍然存在
reboot
下載所有工件
在筆記型電腦/主機上,下載上一節中列舉的所有工件。由於氣隙 VM 正在運行 Fedora 37,因此此部分中顯示的所有依賴項都適用於 Fedora 37。請注意,此程序僅適用於 AArch64 或 AMD64 CPU 架構,因為它們是最流行且廣泛可用的架構。您可以在任何具有寫入權限的地方執行此程序;您的主目錄是一個非常合適的選擇。
請注意,現在可以在 pkgs.k8s.io 上找到需要跨越的 Kubernetes 工件的作業系統套件。這篇部落格文章將結合 Fedora 儲存庫和 GitHub,以便下載所有必要的工件。當您在自己的叢集上執行此操作時,您應該決定是使用官方 Kubernetes 套件,還是使用來自您的作業系統發行版的官方套件 - 兩者都是有效的選擇。
# Set architecture variables
UARCH=$(uname -m)
if [["$UARCH" == "arm64" || "$UARCH" == "aarch64"]]; then
ARCH="aarch64"
K8s_ARCH="arm64"
else
ARCH="x86_64"
K8s_ARCH="amd64"
fi
設定要使用的軟體版本的環境變數
CNI_PLUGINS_VERSION="v1.3.0"
CRICTL_VERSION="v1.27.0"
KUBE_RELEASE="v1.27.3"
RELEASE_VERSION="v0.15.1"
K9S_VERSION="v0.27.4"
建立 download
目錄,變更到該目錄,然後下載所有 RPM 和組態檔
mkdir download && cd download
curl -O https://download.docker.com/linux/fedora/37/${ARCH}/stable/Packages/docker-ce-cli-23.0.2-1.fc37.${ARCH}.rpm
curl -O https://download.docker.com/linux/fedora/37/${ARCH}/stable/Packages/containerd.io-1.6.19-3.1.fc37.${ARCH}.rpm
curl -O https://download.docker.com/linux/fedora/37/${ARCH}/stable/Packages/docker-compose-plugin-2.17.2-1.fc37.${ARCH}.rpm
curl -O https://download.docker.com/linux/fedora/37/${ARCH}/stable/Packages/docker-ce-rootless-extras-23.0.2-1.fc37.${ARCH}.rpm
curl -O https://download.docker.com/linux/fedora/37/${ARCH}/stable/Packages/docker-ce-23.0.2-1.fc37.${ARCH}.rpm
curl -O https://download-ib01.fedoraproject.org/pub/fedora/linux/releases/37/Everything/${ARCH}/os/Packages/l/libcgroup-3.0-1.fc37.${ARCH}.rpm
echo -e "\nDownload Kubernetes Binaries"
curl -L -O "https://github.com/containernetworking/plugins/releases/download/${CNI_PLUGINS_VERSION}/cni-plugins-linux-${K8s_ARCH}-${CNI_PLUGINS_VERSION}.tgz"
curl -L -O "https://github.com/kubernetes-sigs/cri-tools/releases/download/${CRICTL_VERSION}/crictl-${CRICTL_VERSION}-linux-${K8s_ARCH}.tar.gz"
curl -L --remote-name-all https://dl.k8s.io/release/${KUBE_RELEASE}/bin/linux/${K8s_ARCH}/{kubeadm,kubelet}
curl -L -O "https://raw.githubusercontent.com/kubernetes/release/${RELEASE_VERSION}/cmd/kubepkg/templates/latest/deb/kubelet/lib/systemd/system/kubelet.service"
curl -L -O "https://raw.githubusercontent.com/kubernetes/release/${RELEASE_VERSION}/cmd/kubepkg/templates/latest/deb/kubeadm/10-kubeadm.conf"
curl -L -O "https://dl.k8s.io/release/${KUBE_RELEASE}/bin/linux/${K8s_ARCH}/kubectl"
echo -e "\nDownload dependencies"
curl -O "https://dl.fedoraproject.org/pub/fedora/linux/releases/37/Everything/${ARCH}/os/Packages/s/socat-1.7.4.2-3.fc37.${ARCH}.rpm"
curl -O "https://dl.fedoraproject.org/pub/fedora/linux/releases/37/Everything/${ARCH}/os/Packages/l/libcgroup-3.0-1.fc37.${ARCH}.rpm"
curl -O "https://dl.fedoraproject.org/pub/fedora/linux/releases/37/Everything/${ARCH}/os/Packages/c/conntrack-tools-1.4.6-4.fc37.${ARCH}.rpm"
curl -LO "https://github.com/derailed/k9s/releases/download/${K9S_VERSION}/k9s_Linux_${K8s_ARCH}.tar.gz"
curl -LO "https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml"
下載所有必要的容器映像檔
images=(
"registry.k8s.io/kube-apiserver:${KUBE_RELEASE}"
"registry.k8s.io/kube-controller-manager:${KUBE_RELEASE}"
"registry.k8s.io/kube-scheduler:${KUBE_RELEASE}"
"registry.k8s.io/kube-proxy:${KUBE_RELEASE}"
"registry.k8s.io/pause:3.9"
"registry.k8s.io/etcd:3.5.7-0"
"registry.k8s.io/coredns/coredns:v1.10.1"
"registry:2.8.2"
"flannel/flannel:v0.22.0"
"flannel/flannel-cni-plugin:v1.1.2"
)
for image in "${images[@]}"; do
# Pull the image from the registry
docker pull "$image"
# Save the image to a tar file on the local disk
image_name=$(echo "$image" | sed 's|/|_|g' | sed 's/:/_/g')
docker save -o "${image_name}.tar" "$image"
done
上述命令將查看目前主機/筆記型電腦的 CPU 架構,建立並變更到名為 download 的目錄,最後下載所有依賴項。然後必須透過 scp 將這些檔案中的每一個傳輸到氣隙。命令的確切語法將因 VM 上的使用者、您是否建立了 SSH 金鑰以及氣隙 VM 的 IP 而異。粗略的語法是
scp -i <<SSH_KEY>> <<FILE>> <<AIRGAP_VM_USER>>@<<AIRGAP_VM_IP>>:~/tmp/
一旦所有檔案都已傳輸到氣隙 VM,部落格文章的其餘部分將在 VM 上進行。開啟該系統的終端機工作階段。
將工件放置到位
啟動 Kubernetes 叢集所需的一切現在都存在於氣隙 VM 上。本節更加複雜,因為各種類型的工件現在都在氣隙 VM 的磁碟上。在氣隙 VM 上取得 root shell,因為本節的其餘部分將從那裡執行。讓我們先設定與主機/筆記型電腦上設定的相同的架構變數和環境變數,然後安裝所有 RPM 套件
UARCH=$(uname -m)
# Set architecture variables
if [["$UARCH" == "arm64" || "$UARCH" == "aarch64"]]; then
ARCH="aarch64"
K8s_ARCH="arm64"
else
ARCH="x86_64"
K8s_ARCH="amd64"
fi
# Set environment variables
CNI_PLUGINS_VERSION="v1.3.0"
CRICTL_VERSION="v1.27.0"
KUBE_RELEASE="v1.27.3"
RELEASE_VERSION="v0.15.1"
K9S_VERSION="v0.27.4"
cd ~/tmp/
dnf -y install ./*.rpm
接下來,安裝 CNI 外掛程式和 crictl
mkdir -p /opt/cni/bin
tar -C /opt/cni/bin -xz -f "cni-plugins-linux-${K8s_ARCH}-v1.3.0.tgz"
tar -C /usr/local/bin-xz -f "crictl-v1.27.0-linux-${K8s_ARCH}.tar.gz"
使 kubeadm、kubelet 和 kubectl 可執行,並將它們從 /tmp
目錄移動到 /usr/local/bin
chmod +x kubeadm kubelet kubectl
mv kubeadm kubelet kubectl /usr/local/bin
為 systemd kubelet 服務檔案定義覆寫,並將其移動到正確的位置
mkdir -p /etc/systemd/system/kubelet.service.d
sed "s:/usr/bin:/usr/local/bin:g" 10-kubeadm.conf > /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
containerd 的 CRI 外掛程式預設為停用;啟用它
sed -i 's/^disabled_plugins = \["cri"\]/#&/' /etc/containerd/config.toml
放置自訂的 /etc/docker/daemon.json
檔案
echo '{
"exec-opts": ["native.cgroupdriver=systemd"],
"insecure-registries" : ["localhost:5000"],
"allow-nondistributable-artifacts": ["localhost:5000"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"group": "rnd",
"storage-driver": "overlay2",
"storage-opts": [
"overlay2.override_kernel_check=true"
]
}' > /etc/docker/daemon.json
Docker daemon.json
組態檔中要強調的兩個重要項目。 insecure-registries 行表示括號中的容器映像檔儲存庫不支援 TLS。即使在氣隙環境內部,這也不是一個好的做法,但對於本實驗室的目的來說還可以。 allow-nondistributable-artifacts 行告訴 Docker 允許將不可散發的工件推送到此容器映像檔儲存庫。預設情況下,Docker 不會推送這些層,以避免圍繞許可或散發權的潛在問題。Windows 基礎容器映像檔就是一個很好的例子。此行將允許 Docker 標記為「外部」的層被推送到容器映像檔儲存庫。雖然對於本文來說這不是什麼大不了的事,但某些氣隙環境可能需要該行。所有層都必須在本機存在,因為氣隙環境內部的任何內容都無法連線到公共容器映像檔儲存庫以取得所需的內容。
(重新)啟動 Docker 並啟用它,以便在系統啟動時啟動
systemctl restart docker
systemctl enable docker
啟動並啟用 containerd 和 kubelet
systemctl enable --now containerd
systemctl enable --now kubelet
在 Docker 中運行的容器映像檔儲存庫僅用於任何 CNI 相關容器和後續工作負載容器。此容器映像檔儲存庫不用於容納 Kubernetes 組件容器。請注意,nerdctl 也可以在此處作為 Docker 的替代方案,並且允許與 containerd 直接互動。選擇 Docker 是因為它的熟悉度。
在 Docker 內部啟動容器映像檔儲存庫
docker load -i registry_2.8.2.tar
docker run -d -p 5000:5000 --restart=always --name registry registry:2.8.2
將 Flannel 容器載入到 Docker 容器映像檔儲存庫
注意: 由於 Flannel 較為常見,因此在本實驗室中選擇了 Flannel。請選擇最適合您環境的 CNI。
docker load -i flannel_flannel_v0.22.0.tar
docker load -i flannel_flannel-cni-plugin_v1.1.2.tar
docker tag flannel/flannel:v0.22.0 localhost:5000/flannel/flannel:v0.22.0
docker tag flannel/flannel-cni-plugin:v1.1.1 localhost:5000/flannel/flannel-cni-plugin:v1.1.1
docker push localhost:5000/flannel/flannel:v0.22.0
docker push localhost:5000/flannel/flannel-cni-plugin:v1.1.1
透過 ctr
載入 Kubernetes 組件的容器映像檔
images_files=(
"registry.k8s.io/kube-apiserver:${KUBE_RELEASE}"
"registry.k8s.io/kube-controller-manager:${KUBE_RELEASE}"
"registry.k8s.io/kube-scheduler:${KUBE_RELEASE}"
"registry.k8s.io/kube-proxy:${KUBE_RELEASE}"
"registry.k8s.io/pause:3.9"
"registry.k8s.io/etcd:3.5.7-0"
"registry.k8s.io/coredns/coredns:v1.10.1"
)
for index in "${!image_files[@]}"; do
if [[-f "${image_files[$index]}" ]]; then
# The below line loads the images where they need to be on the VM
ctr -n k8s.io images import ${image_files[$index]}
else
echo "File ${image_files[$index]} not found!" 1>&2
fi
done
在這裡,一個完全合理的問題可能是「為什麼不使用剛剛建立的 Docker 登錄檔來存放 K8s 組件映像檔?」即使對傳遞給 kubeadm 的設定檔進行了適當的修改,這仍然行不通。
啟動 Kubernetes 叢集
檢查叢集是否已在執行,如果是,則將其關閉
if systemctl is-active --quiet kubelet; then
# Reset the Kubernetes cluster
echo "A Kubernetes cluster is already running. Resetting the cluster..."
kubeadm reset -f
fi
從氣隙 VM 內部登入 Docker 登錄檔
# OK for a demo; use secure credentials in production!
DOCKER_USER=user
DOCKER_PASS=pass
echo ${DOCKER_PASS} | docker login --username=${DOCKER_USER} --password-stdin localhost:5000
建立叢集設定檔並初始化叢集
echo "---
apiVersion: kubeadm.k8s.io/v1beta3
kind: ClusterConfiguration
clusterName: kubernetes
kubernetesVersion: v1.27.3
networking:
dnsDomain: cluster.local
podSubnet: 10.244.0.0/16 # --pod-network-cidr
serviceSubnet: 10.96.0.0/12
---
apiVersion: kubeadm.k8s.io/v1beta3
kind: InitConfiguration
localAPIEndpoint:
advertiseAddress: 10.10.10.10 # Update to the IP address of the air gap VM
bindPort: 6443
nodeRegistration:
criSocket: unix:///run/containerd/containerd.sock # or rely on autodetection
name: airgap # this must match the hostname of the air gap VM
# Since this is a single node cluster, this taint has to be commented out,
# otherwise the coredns pods will not come up.
# taints:
# - effect: NoSchedule
# key: node-role.kubernetes.io/master" > kubeadm_cluster.yaml
kubeadm init --config kubeadm_config.yaml
設定 $KUBECONFIG
並使用 kubectl
等待直到 API 伺服器健康
export KUBECONFIG=/etc/kubernetes/admin.conf
until kubectl get nodes; do
echo -e "\nWaiting for API server to respond..." 1>&2
sleep 5
done
設定網路
更新 Flannel manifest 中的 Flannel 映像檔位置,並套用它
sed -i 's/image: docker\.io/image: localhost:5000/g' kube-flannel.yaml
kubectl apply -f kube-flannel.yaml
執行 kubectl get pods -A --watch
直到所有 Pod 都已啟動並執行。
執行一個範例 Pod
叢集運作後,下一步是工作負載。在這個簡單的示範中,將部署 Podinfo 應用程式。
安裝 Helm
此程序的第一部分必須從主機/筆記型電腦執行。如果尚未安裝,請按照安裝 Helm進行安裝。
接下來,下載 Linux 的 Helm 二進制檔案
UARCH=$(uname -m)
# Reset the architecture variables if needed
if [["$UARCH" == "arm64" || "$UARCH" == "aarch64"]]; then
ARCH="aarch64"
K8s_ARCH="arm64"
else
ARCH="x86_64"
K8s_ARCH="amd64"
fi
curl -LO https://get.helm.sh/helm-v3.12.2-linux-${K8s_ARCH}.tar.gz
新增 Podinfo Helm 儲存庫、下載 Podinfo Helm Chart、下載 Podinfo 容器映像檔,然後最後將其儲存到本機磁碟
helm repo add https://stefanprodan.github.io/podinfo
helm fetch podinfo/podinfo --version 6.4.0
docker pull ghcr.io/stefanprodan/podinfo:6.4.0
將 podinfo 映像檔儲存到本機磁碟上的 tar 檔案
docker save -o podinfo_podinfo-6.4.0.tar ghcr.io/stefanprodan/podinfo
### Transfer the image across the air gap
Reuse the `~/tmp` directory created on the air gapped VM to transport these artifacts across the air gap:
```bash
scp -i <<SSH_KEY>> <<FILE>> <<AIRGAP_VM_USER>>@<<AIRGAP_VM_IP>>:~/tmp/
在隔離端繼續
現在切換到氣隙 VM 以進行剩餘的安裝程序。
切換到 ~/tmp
cd ~/tmp
解壓縮並移動 helm
二進制檔案
tar -zxvf helm-v3.0.0-linux-amd64.tar.gz
mv linux-amd64/helm /usr/local/bin/helm
將 Podinfo 容器映像檔載入到本機 Docker 登錄檔
docker load -i podinfo_podinfo-6.4.0.tar
docker tag podinfo/podinfo:6.4.0 localhost:5000/podinfo/podinfo:6.4.0
docker push localhost:5000/podinfo/podinfo:6.4.0
確保 `$KUBECONFIG` 設定正確,然後安裝 Podinfo Helm Chart
# Outside of a demo or lab environment, use lower (or even least) privilege
# credentials to manage your workloads.
export KUBECONFIG=/etc/kubernetes/admin.conf
helm install podinfo ./podinfo-6.4.0.tgz --set image.repository=localhost:5000/podinfo/podinfo
驗證 Podinfo 應用程式已啟動
kubectl get pods -n default
或執行 k9s (Kubernetes 的終端使用者介面)
k9s
Zarf
Zarf 是一個開源工具,它採用宣告式方法來進行軟體封裝和交付,包括氣隙環境。在本節中,將使用 Zarf 將相同的 podinfo 應用程式安裝到氣隙 VM 上。第一步是在主機/筆記型電腦上安裝 Zarf。
或者,可以從 GitHub 下載適用於各種作業系統/CPU 架構的預先建置的二進制檔案到主機/筆記型電腦上。
在氣隙中的 VM 上也需要一個二進制檔案
UARCH=$(uname -m)
# Set the architecture variables if needed
if [["$UARCH" == "arm64" || "$UARCH" == "aarch64"]]; then
ARCH="aarch64"
K8s_ARCH="arm64"
else
ARCH="x86_64"
K8s_ARCH="amd64"
fi
export ZARF_VERSION=v0.28.3
curl -LO "https://github.com/defenseunicorns/zarf/releases/download/${ZARF_VERSION}/zarf_${ZARF_VERSION}_Linux_${K8s_ARCH}"
Zarf 需要透過使用初始化套件將自身引導到 Kubernetes 叢集中。該套件也需要跨氣隙傳輸,因此讓我們將其下載到主機/筆記型電腦上
curl -LO "https://github.com/defenseunicorns/zarf/releases/download/${ZARF_VERSION}/zarf-init-${K8s_ARCH}-${ZARF_VERSION}.tar.zst"
Zarf 宣告式特性的實現方式是透過使用 zarf.yaml 檔案。這是將用於此 Podinfo 安裝的 zarf.yaml 檔案。將其寫入您在主機/筆記型電腦上具有寫入權限的任何目錄;您的主目錄即可
echo 'kind: ZarfPackageConfig
metadata:
name: podinfo
description: "Deploy helm chart for the podinfo application in K8s via zarf"
components:
- name: podinfo
required: true
charts:
- name: podinfo
version: 6.4.0
namespace: podinfo-helm-namespace
releaseName: podinfo
url: https://stefanprodan.github.io/podinfo
images:
- ghcr.io/stefanprodan/podinfo:6.4.0' > zarf.yaml
下一步是建置 Podinfo 套件。這必須從 zarf.yaml 檔案所在的相同目錄位置完成。
zarf package create --confirm
此命令將下載定義的 Helm Chart 和映像檔,並將它們放入寫入磁碟的單一檔案中。這個單一檔案是所有需要跨氣隙傳輸的內容
ls zarf-package-*
範例輸出
zarf-package-podinfo-arm64.tar.zst
將 Linux Zarf 二進制檔案、Zarf 初始化套件和 Podinfo 套件傳輸到氣隙 VM
scp -i <<SSH_KEY>> <<FILE>> <<AIRGAP_VM_USER>>@<<AIRGAP_VM_IP>>:~/tmp/
從氣隙 VM 中,切換到放置所有 Artifact 的 ~/tmp 目錄
cd ~/tmp
將 $KUBECONFIG
設定為包含本機叢集憑證的檔案;並設定 Zarf 版本
export KUBECONFIG=/etc/kubernetes/admin.conf
export ZARF_VERSION=$(zarf version)
將 zarf
二進制檔案設為可執行,並 (以 root
身份) 將其移動到 /usr/bin
chmod +x zarf && sudo mv zarf /usr/bin
同樣地,將 Zarf 初始化套件移動到 /usr/bin
mv zarf-init-arm64-${ZARF_VERSION}.tar.zst /usr/bin
將 Zarf 初始化到叢集中
zarf init --confirm --components=git-server
當此命令完成後,Zarf 套件即可部署。
zarf package deploy
此命令將在目前目錄中搜尋 Zarf 套件。選擇 podinfo 套件 (zarf-package-podinfo-${K8s_ARCH}.tar.zst) 並繼續。套件部署完成後,執行 zarf tools monitor
以啟動 k9s 來檢視叢集。
結論
這是一種可以用於啟動氣隙叢集的方法,以及兩種部署任務應用程式的方法。在不同的作業系統上,關於需要跨氣隙傳輸的確切軟體 Artifact 可能會有所不同,但從概念上來說,此程序仍然有效。
此示範也建立了一個人工氣隙環境。在現實世界中,每個遺漏的依賴項都可能代表數小時,甚至數天或數週的損失時間,才能在氣隙環境中運行軟體。這種人工氣隙也掩蓋了一些常見的方法或氣隙軟體交付方式,例如使用資料二極體。根據環境的不同,資料二極體的使用成本可能非常高昂。此外,在跨氣隙傳輸之前,沒有對任何 Artifact 進行掃描。氣隙的存在通常意味著在那裡運行的工作負載更為敏感,除非已知是安全的,否則不應跨氣隙傳輸任何內容。