Share Notes

chundev

View the Project on GitHub latteouka/share-notes

ML 平台安裝包逆向分析 — 從 Ansible Playbook 理解企業級 K8s 架構

日期:2026-04-10 技術棧:Kubernetes 1.29 / kubeadm / Calico / Harbor / Ansible


TL;DR

拿到一套企業 ML 平台的離線安裝包(Ansible-based, ~17GB),目標是理解其架構後自行建置 single-node K8s 環境。透過解壓分析 playbook 和 role,完整還原了安裝流程、元件依賴、以及 K8s 1.29 下的架構差異(例如 seldon-core 在 1.29 不再安裝)。本文記錄分析方法和所有 K8s 元件的實務解釋。


背景

某 ML 協作管理平台提供離線安裝包,使用 Ansible 自動化部署到多台 Ubuntu/RHEL 主機。安裝包包含 K8s 叢集建置、容器映像倉庫、GPU 虛擬化、監控棧等完整基礎設施。原廠提供的安裝指南是 PDF,目標是理解底層架構後,自行建立 single-node All-In-One 環境。


分析方法

Step 1: 不解壓,先看結構

17GB 的 tgz 不適合直接解壓(磁碟空間有限),先用 tar -tzf 列出目錄:

# 列出所有條目
tar -tzf installer.tgz | wc -l
# → 398 個條目

# 只看目錄結構
tar -tzf installer.tgz | grep -E '/$' | sort

Step 2: 只解壓文字檔

tar -xzf installer.tgz \
  --include='*.yml' --include='*.yaml' \
  --include='*.sh' --include='*.cfg' \
  --include='*.org' --include='*.j2' \
  --include='*.conf'
# → 181 個文字檔,足以分析完整架構

Step 3: 從 Playbook 反推架構

Ansible Playbook 的命名和執行順序就是安裝流程的藍圖:

cluster-01  環境檢查
cluster-02  跳板機 kernel 升級
cluster-03  所有主機 kernel 升級
cluster-04  檔案派送(infra 安裝包)
cluster-05  profile 設定
cluster-10  Harbor 安裝
cluster-11  K8s Master 安裝
cluster-12  AI-Stack Web 安裝
cluster-13  GPU Driver 安裝
cluster-14  Worker 安裝
cluster-15  Worker 加入叢集
cluster-20  K8s 附加元件(ingress、監控、儲存)
cluster-21  GPU Label + Skyport Key
cluster-22  ixgpu 安裝
cluster-90  CVE Patch

安裝包結構

installer.tgz (17GB)
├── AI-Stack-Infra-*.tar.xz        ← K8s 基礎設施(kubeadm, kubelet, containerd, Calico 等)
├── aistack-web-*.tar.gz           ← ML 平台 Web 應用(專有)
├── ix-gpu-setup-*.tar.gz          ← GPU 虛擬化(專有)
└── aistack-installer/             ← Ansible 自動化
    ├── hosts                      ← 角色配置
    ├── ansible.cfg
    ├── files/
    │   ├── conf-jitignore.yml     ← 核心變數(版本、網路、路徑)
    │   └── config.yml             ← 使用者可調設定
    ├── playbooks/                 ← 22 個 Playbook
    └── roles/                     ← 48 個 Role

核心變數檔

# conf-jitignore.yml — 整個安裝系統的設定中樞
aistack_ver: "4.27.2"
k8s: "1.29"              # 支援 1.22 / 1.29 / 1.32
nv_driver: "570"          # NVIDIA driver 版本
AISP: "~/ai-stack-install"  # 安裝工作目錄

# 每台機器的網路資訊
netinfo:
  - { dist: Ubuntu, ver: "24.04", name: hostname, ip: x.x.x.x, gw: x.x.x.x }

關鍵發現

1. K8s 1.29 不裝 seldon-core

# seldon-core-install/tasks/main.yml
- ansible.builtin.import_role:
    name: infinser-inpans
  vars:
    package_name: "seldon-core-install"
  when: k8s == "1.22"   # ← 只有 1.22 才裝!

K8s 1.29 改為只 push 一個 courier-executor image 到 Harbor,不再部署完整的 seldon-core。

2. 核心安裝邏輯藏在 infra 包裡

幾乎所有安裝步驟都透過一個叫 infinser-inpans 的 role,它只是個 wrapper:

# infinser-inpans/tasks/main.yml
- become: true
  ansible.builtin.script:
    cmd: ../files/infinities-installer-exec-steps-v2.sh "input=" ""
  args:
    chdir: ""
    creates: /tmp/.done  # 冪等:做過就跳過

實際的安裝腳本 infinities-installer.sh 在 infra 安裝包內,而非 Ansible role 裡。

3. All-In-One 的 Taint 移除邏輯

# sc-master-node-as-also-worker/tasks/main.yml
- set_fact: mastertaint="asworker"
  when: groups['workers'] | length == 0   # workers 群組為空 → AIO 模式

- shell: |
    kubectl taint node "$(hostname)" \
      node-role.kubernetes.io/control-plane- --overwrite
  when: mastertaint == "asworker"

4. 儲存支援四種後端

類型 用途 複雜度
NFS 檔案共享、分佈式訓練
MinIO 物件儲存(S3 相容)
BigTera 企業儲存
NetApp Trident 企業儲存

K8s 元件完整解釋(k3s 使用者視角)

以下是這套 ML 平台用到的所有 K8s 元件,特別標注與 k3s 的差異。

叢集基礎

kubeadm — K8s 叢集初始化工具

kubeadm 是 Kubernetes 官方的叢集建置工具。與 k3s 的「一個 binary 搞定一切」不同,kubeadm 需要你分開安裝 kubelet、kubectl、containerd,然後用 kubeadm init 初始化 Control Plane。

# k3s 的做法(一行搞定)
curl -sfL https://get.k3s.io | sh -

# kubeadm 的做法(多步驟)
apt install kubelet kubeadm kubectl containerd
kubeadm init --pod-network-cidr=192.168.0.0/16

好處是完全可控、相容所有標準 K8s 工具鏈、企業支援。代價是複雜度高。

Calico CNI — 容器網路外掛

CNI(Container Network Interface)負責 Pod 之間的網路通訊。k3s 預設用 Flannel(簡單的 VXLAN overlay),這套平台用 Calico

  Flannel (k3s 預設) Calico
協定 VXLAN overlay BGP 路由
效能 一般 較佳(少一層封裝)
NetworkPolicy 不支援 完整支援
適用場景 開發、小規模 生產、多租戶

ML 平台需要 Calico 是因為多租戶隔離:不同專案的 Pod 不應該互相存取。

# kubeadm init 時指定 Calico 的 Pod CIDR
kubeadm init --pod-network-cidr=192.168.0.0/16
# 然後部署 Calico
kubectl apply -f calico.yaml

Node Taint / Toleration — 節點排程控制

Taint 是節點上的「禁止標籤」。Master 節點預設有 NoSchedule taint,意思是:「除非你的 Pod 明確聲明能容忍(Tolerate)我,否則不要排程到我這裡。」

# 查看 taint
kubectl describe node master | grep Taints
# → Taints: node-role.kubernetes.io/control-plane:NoSchedule

# All-In-One 模式:移除 taint,讓業務 Pod 也能跑在 master 上
kubectl taint node master node-role.kubernetes.io/control-plane:NoSchedule-
#                                                                         ^ 注意這個減號

k3s 預設就是沒有 taint 的(server 節點可以跑 workload),所以你可能沒注意過這件事。

containerd vs Docker — 容器執行時

K8s 1.24 起棄用 Docker 作為容器執行時(Container Runtime),改用 containerd。但「棄用 Docker」不代表 Docker image 不能用——只是 kubelet 不再透過 dockershim 跟 Docker daemon 溝通。

K8s 1.22 (舊):  kubelet → dockershim → Docker → containerd → runc
K8s 1.29 (新):  kubelet → containerd → runc   (少了兩層)

注意:這套平台仍然安裝 Docker CE,因為:

所以 K8s 用 containerd,但主機上同時有 Docker CLI 可用。

映像管理

Harbor Registry — 企業映像倉庫

Harbor 是 VMware(現 Broadcom)開源的容器映像倉庫。它不只是存映像的地方,還提供:

這套平台的 Harbor 跑在 port 18080,所有 container image 都先 push 到 harbor:18080/infinitiessoft-tools/,K8s 再從 Harbor 拉取。

# 典型流程
docker load -i kepler-release-0.7.2.tar.gz
docker tag quay.io/sustainable_computing_io/kepler:release-0.7.2 \
  harbor:18080/infinitiessoft-tools/kepler:release-0.7.2
docker push harbor:18080/infinitiessoft-tools/kepler:release-0.7.2

Helm — K8s 套件管理器

Helm 之於 Kubernetes,就像 apt 之於 Ubuntu。它用 Chart(模板包)定義一組 K8s 資源,支援參數化和版本控制。

# 安裝 kepler(Helm chart)
helm install kepler -n kepler --create-namespace kepler-0.5.5.tar.gz -f kepler-values.yaml

k3s 有內建的 Helm Controller(放 manifest 到特定目錄就自動部署),kubeadm 環境要手動裝 Helm CLI。

網路 & 入口

ingress-nginx — HTTP 流量路由

Ingress Controller 負責將外部 HTTP(S) 流量路由到叢集內的 Service。k3s 預設用 Traefik,這套平台用 ingress-nginx(NGINX 官方版本)。

  Traefik (k3s) ingress-nginx
設定方式 Annotation + CRD Annotation
自動 HTTPS 內建 Let’s Encrypt 需搭配 cert-manager
效能 極好(NGINX 底層)
社群生態 較小 最大

監控棧

Prometheus — 時序監控系統

Prometheus 用 pull 模式定期抓取各元件的 metrics endpoint,儲存為時序資料。這套平台的 Prometheus 整合了:

Kepler — 能耗監控

Kepler(Kubernetes-based Efficient Power Level Exporter)透過 eBPF 監控每個容器的電力消耗。對 GPU 密集的 ML 工作負載,這代表你能知道「跑一次訓練花了多少電」。

cadvisor — 容器資源監控

cadvisor(Container Advisor)是 Google 開發的,蒐集每個容器的 CPU、記憶體、網路、磁碟 I/O。它是 Prometheus 的資料來源之一。

metrics-server — K8s 內建 metrics

metrics-server 提供 kubectl top 和 HPA(Horizontal Pod Autoscaler)所需的即時 CPU/Memory 數據。k3s 預裝,kubeadm 要自己裝。

儲存

CSI (Container Storage Interface) — S3 儲存掛載

CSI 是 K8s 的標準儲存外掛介面。CSI-S3 讓 Pod 可以把 S3/MinIO 物件儲存當成本機目錄掛載(底層用 GeeseFS/s3fs)。

# 安裝後,Pod 可以這樣掛載 S3
volumes:
  - name: training-data
    persistentVolumeClaim:
      claimName: s3-pvc

NFS — 網路檔案系統

最簡單的共享儲存方案。ML 平台用 NFS 做分佈式訓練的共享工作目錄。注意需要 no_root_squash 參數(允許容器內的 root 操作 NFS 檔案)。

ML 專用

ixgpu — GPU 虛擬化

Kubernetes 原生的 GPU 分配是整卡分配(一個 Pod 拿一整張 GPU)。ixgpu 是這套平台的專有 GPU 虛擬化層,可以把一張 GPU 拆成多個 vGPU,讓多個容器共享。

原生 K8s:     1 Pod = 1 GPU(浪費)
ixgpu:        1 GPU = N 個 vGPU(共享,提高利用率)

安裝方式是 Helm chart(ixgpu-2.0.0),搭配 Prometheus config 變更。

seldon-core — ML 模型服務

seldon-core 將訓練好的模型包裝成 REST/gRPC API。但在 K8s 1.29 環境下,這套平台不再安裝完整的 seldon-core,改用自家的 courier-executor 取代。


k3s vs kubeadm 快速對照表

面向 k3s kubeadm (本案)
安裝 一行指令 多步驟手動配置
Binary 單一執行檔 (~60MB) kubelet + kubeadm + kubectl + containerd
CNI Flannel (內建) Calico (需另裝)
Ingress Traefik (內建) ingress-nginx (需另裝)
metrics-server 內建 需另裝
儲存 local-path (內建) NFS / CSI (需另裝)
etcd 預設 SQLite 預設 etcd
Master Taint 無 (預設可排程) 有 NoSchedule (需手動移除)
適用場景 邊緣、IoT、開發 生產、企業、多租戶

學到的事


參考資料