簡介
在當今雲原生時代,企業日益依賴容器化應用來加速創新與交付,但隨之而來的安全挑戰也愈發嚴峻——尤其是在多租戶、邊緣計算或第三方託管等不可信環境中運行敏感工作負載時,傳統容器隔離機制已難以抵禦來自底層基礎設施的威脅,包括惡意管理員、受損核心或韌體級攻擊。
CNCF雲原生 Confidential Containers 專案應運而生,旨在彌合雲原生敏捷性與資料安全之間的鴻溝。通過將 Kubernetes Pod 封裝於基於硬體的機密虛擬機器(Confidential VM)中,Confidential Containers 在幾乎無需修改現有應用的前提下,將機密計算(Confidential Computing)的強大保護能力延伸至複雜的容器化工作負載。它不僅確保運行時記憶體內容對主機作業系統、雲端服務商乃至物理攻擊者完全加密且不可窺探,還提供端到端的遠程證明(Remote Attestation)與安全密鑰分發機制,使使用者能夠確信其代碼在可信環境中執行,並安全注入敏感憑證。
本文檔將指導您基於8代裸金屬執行個體ecs.ebmg8i.48xlarge部署Confidential Containers,利用Intel機密計算技術協助您在不受信任的基礎設施上構建真正可信、隔離且合規的雲原生運行環境——讓安全不再成為創新的代價,而是預設的基石。
架構
架構圖展示了Confidential Containers單節點的架構,可以看到傳統Kubernetes的Pod將被整體運行在一個TDX的機密虛擬機器內,實現運行時資料的安全保護。所有資料的解密和明文的處理全都發生在TDX機密虛擬機器內,保證整個資料生命週期的安全性。
目標
實現單節點CoCo叢集執行(版本v0.17.0)
使用Kubeadm搭建單節點CoCo叢集(v1.32.0)
實施步驟
步驟一:建立支援TDX的裸金屬執行個體
建立一個支援Intel TDX技術的阿里雲第8代裸金屬執行個體。
前往執行個體購買頁。
按需選擇付費類型並選擇地區和可用性區域。本方案的特定社區鏡像僅在部分可用性區域提供,樣本地區和可用性區域為北京可用性區域 I 。
在實例配置中單擊ECS Bare Metal Instance,然後選擇
ecs.ebmg8i.48xlarge執行個體規格。在鏡像配置中,選擇社區鏡像,並使用鏡像ID
m-2ze2ucup4c5bvgx751lx進行搜尋和選擇。在鏡像選擇下方,必須勾選機密虛擬機複選框,啟用 TDX 功能。重要此鏡像為基於Ubuntu的定製鏡像,預裝了支援TDX的相關驅動。預設SSH登入使用者為
ubuntu,而非root。完成網路、儲存、頻寬和安全性群組以及管理設定等配置項。各配置項詳細說明,請參考配置項說明。
在最終建立執行個體前,請在頁面右側檢查執行個體的整體配置並配置使用時間長度等選項,確保各項配置符合要求。
單擊確認下單,完成執行個體建立。
建立執行個體一般需要3~5分鐘,請耐心等待。可前往控制台的執行個體列表頁面查看執行個體的狀態,當執行個體狀態變為運行中時,表示執行個體建立完成。
步驟二:準備 Kubernetes 節點環境
執行個體建立完成後,串連執行個體,為其安裝配置作為單節點 Kubernetes 叢集所需的基礎軟體。
安裝Containerd 為了運行容器,需要安裝containerd作為容器運行時。
# 更新軟體源並安裝依賴 sudo apt-get update sudo apt-get install -y ca-certificates curl # 添加 Docker 的官方 GPG 密鑰 sudo install -m 0755 -d /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc sudo chmod a+r /etc/apt/keyrings/docker.asc # 添加 Docker 的 APT 軟體源 echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \ $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \ sudo tee /etc/apt/sources.list.d/docker.list > /dev/null # 安裝 containerd sudo apt-get update sudo apt-get install -y containerd.io配置 Containerd 產生預設設定檔,並修改其中的關鍵參數以適配 Kubernetes。
# 產生預設設定檔 sudo mkdir -p /etc/containerd containerd config default | sudo tee /etc/containerd/config.toml # 將 Kubernetes 鏡像倉庫地址替換為阿里雲鏡像,加速拉取 sudo sed -i -E 's#registry.k8s.io#registry.aliyuncs.com/google_containers#g' /etc/containerd/config.toml # 將 cgroup 驅動修改為 systemd,以滿足 Kubernetes 要求 sudo sed -i 's#SystemdCgroup = false#SystemdCgroup = true#g' /etc/containerd/config.toml # 重啟 containerd 服務使配置生效 sudo systemctl restart containerd配置節點核心參數 為滿足 Kubernetes 的網路和運行要求,需要禁用 Swap 分區並載入必要的核心模組。
# 臨時關閉 Swap sudo swapoff -a # 永久禁用 Swap,通過注釋掉 fstab 檔案中的 swap 配置 sudo sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab # 載入 overlay 和 br_netfilter 核心模組 sudo modprobe overlay sudo modprobe br_netfilter # 配置開機自動載入所需模組 sudo tee /etc/modules-load.d/k8s.conf <<EOF overlay br_netfilter EOF # 配置核心參數以允許 IP 轉寄和橋接器流量處理 sudo tee /etc/sysctl.d/kubernetes.conf <<EOT net.bridge.bridge-nf-call-ip6tables = 1 net.bridge.bridge-nf-call-iptables = 1 net.ipv4.ip_forward = 1 EOT # 應用所有 sysctl 配置 sudo sysctl --system
步驟三:安裝單節點Kubernetes叢集
使用kubeadm工具快速搭建一個單節點Kubernetes叢集。
安裝 Kubernetes 組件 安裝
kubeadm、kubelet和kubectl。[需要確認:請使用與 Confidential Containers 版本相容的Kubernetes 版本。本文檔使用 v1.32.0作為樣本。]
# 添加 Kubernetes 的 APT 軟體源 GPG 密鑰 curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.32/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg # 添加 Kubernetes 的 APT 軟體源 echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.32/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list # 安裝 Kubernetes 工具 sudo apt-get update sudo apt-get install -y kubectl kubeadm kubelet sudo apt-mark hold kubelet kubeadm kubectl初始化 Kubernetes 控制平面 使用
kubeadm init命令啟動叢集。# 擷取節點主網卡 IP 位址,作為 API Server 的廣播位址 # 注意:此命令假設主網卡為 eth0,如果環境不同,請手動替換為正確的 IP 位址 NODE_IP=$(ip -o -4 addr show dev eth0 | awk '{split($4,a,"/");print a[1]}') # 初始化叢集 sudo kubeadm init --pod-network-cidr=10.10.0.0/16 \ --apiserver-advertise-address ${NODE_IP} \ --kubernetes-version v1.32.0 \ --image-repository registry.aliyuncs.com/google_containers初始化完成後,根據輸出提示,配置
kubectl的訪問憑證。mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config安裝網路外掛程式 部署Flannel CNI外掛程式,為叢集提供Pod間通訊能力。
# 安裝flannel網路外掛程式 export KUBECONFIG=/etc/kubernetes/admin.conf FLANNEL_VERSION=v0.27.4 wget https://github.com/flannel-io/flannel/releases/download/${FLANNEL_VERSION}/kube-flannel.yml # 將 Flannel 鏡像倉庫地址替換為國內鏡像,加速拉取 sed -i -E 's#([0-9]{1,3}\.){3}[0-9]{1,3}/[0-9]+#10.10.0.0/16#g' kube-flannel.yml sed -i -E 's#ghcr.io/flannel-io#confidential-ai-registry.cn-shanghai.cr.aliyuncs.com/product#g' kube-flannel.yml # 部署 Flannel kubectl apply -f kube-flannel.yml移除控制平面汙點 由於是單節點叢集,需要移除控制平面的
NoSchedule汙點,以允許業務Pod調度到該節點。NODE_NAME=$(kubectl get nodes -o jsonpath='{.items[0].metadata.name}') kubectl taint nodes $NODE_NAME node-role.kubernetes.io/control-plane-
步驟四:部署 Confidential Containers (CoCo) 組件
Confidential Containers 提供多種部署方式,請在 Helm Chart 方式 和 Operator 方式 中任選其一進行部署。
Helm Chart方式
使用Helm Chart部署CoCo,該方式提供了更靈活的組態管理。
安裝 Helm 如果環境中沒有Helm,請先安裝。
curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 chmod 700 get_helm.sh ./get_helm.sh配置 CoCo Helm Chart 複製CoCo的charts倉庫,並建立一個自訂的
values.yaml檔案,用於啟用TDX相關的運行時。# 複製 charts 倉庫並切換到指定版本 git clone https://github.com/confidential-containers/charts.git cd charts git reset --hard v0.17.0 # 建立 TDX 專用設定檔 cat << EOF > values-tdx.yaml architecture: x86_64 # 將 CoCo 的鏡像倉庫指向國內鏡像地址 kata-as-coco-runtime: image: reference: registry-cn-hangzhou.ack.aliyuncs.com/dev/coco-kata-deploy imagePullPolicy: Always k8sDistribution: k8s debug: false # Snapshotter configuration snapshotter: setup: ["nydus"] # 啟用 TDX 相關的 shim shims: qemu-tdx: enabled: true supportedArches: - amd64 containerd: snapshotter: nydus forceGuestPull: false crio: guestPull: true agent: httpsProxy: "" noProxy: "" qemu-coco-dev: enabled: true supportedArches: - amd64 allowedHypervisorAnnotations: [] containerd: snapshotter: nydus forceGuestPull: false crio: guestPull: true agent: httpsProxy: "" noProxy: "" # 顯式禁用其他不需要的 TEE shim qemu-snp: enabled: false qemu-se: enabled: false # 啟用 RuntimeClass 建立 runtimeClasses: enabled: true createDefault: false defaultName: "kata" # Default shim per architecture defaultShim: amd64: qemu-tdx EOF部署 CoCo 使用Helm安裝CoCo,並應用上一步的自訂配置。
helm install coco oci://ghcr.io/confidential-containers/charts/confidential-containers \ -f values-tdx.yaml \ --namespace coco-system \ --create-namespace \ --version 0.17.0建立RuntimeClass 由於Helm配置中禁用了預設RuntimeClass的建立,需要手動建立所需的
RuntimeClass對象,以便在Pod中引用。cat <<EOF | kubectl apply -f - apiVersion: node.k8s.io/v1 kind: RuntimeClass metadata: name: kata-qemu-tdx handler: kata-qemu-tdx --- apiVersion: node.k8s.io/v1 kind: RuntimeClass metadata: name: kata-qemu-coco-dev handler: kata-qemu-coco-dev EOF
Operator方式
mkdir -p kustomize && cd kustomize
mkdir release && mkdir -p ccruntime/default
cat <<EOF > release/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- "github.com/confidential-containers/operator/config/release?ref=v0.17.0"
images:
- name: quay.io/confidential-containers/operator
newName: registry-cn-hangzhou.ack.aliyuncs.com/dev/coco-operator
EOF
cat <<EOF > ccruntime/default/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- "github.com/confidential-containers/operator/config/samples/ccruntime/default?ref=v0.17.0"
images:
- name: quay.io/confidential-containers/reqs-payload
newName: registry-cn-hangzhou.ack.aliyuncs.com/dev/coco-reqs-payload
- name: quay.io/kata-containers/kata-deploy-ci
newName: registry-cn-hangzhou.ack.aliyuncs.com/dev/coco-kata-deploy-ci
- name: quay.io/kata-containers/kata-deploy
newName: registry-cn-hangzhou.ack.aliyuncs.com/dev/coco-kata-deploy
EOF
# 允許當前節點作為worker
for NODE_NAME in $(kubectl get nodes -o jsonpath='{.items[*].metadata.name}'); do
kubectl label node $NODE_NAME node.kubernetes.io/worker=
done
kubectl apply -k release
kubectl apply -k ccruntime/default步驟五:部署並驗證機密容器Pod
完成所有組件部署後,運行一個樣本Pod,並驗證其是否成功運行在TDX機密虛擬機器中。
為節點添加標籤 為工作節點添加標籤,表明其支援Kata運行時。
NODE_NAME=$(kubectl get nodes -o jsonpath='{.items[0].metadata.name}') kubectl label node $NODE_NAME katacontainers.io/kata-runtime=true部署樣本 Pod 建立一個Pod,並在其
spec中通過runtimeClassName指定使用TDX運行時。cat <<EOF | kubectl apply -f - apiVersion: v1 kind: Pod metadata: name: coco-demo-pod spec: runtimeClassName: kata-qemu-tdx containers: - image: alibaba-cloud-linux-3-registry.cn-hangzhou.cr.aliyuncs.com/alinux3/alinux3:latest name: hello-alinux command: - "sleep" - "infinity" EOF驗證部署狀態 檢查Pod是否成功運行,並確認其使用的運行時類是否正確。
# 等待 Pod 狀態變為 Running kubectl get pod coco-demo-pod # 描述 Pod 詳情,確認 "Runtime Class" 欄位為 "kata-qemu-tdx" kubectl describe pod coco-demo-pod | grep "Runtime Class"驗證TDX環境 登入到裸金屬執行個體節點,通過核心日誌確認 TDX 模組已成功初始化並被使用。
# 在節點上執行 dmesg | grep -i tdx如果看到包含
TDX module initialized或類似與TDX相關的輸出,表明TDX環境已成功啟用,並且Kata運行時正在利用該硬體特性建立機密虛擬機器。
成本與風險說明
成本構成:本方案的主要成本來自
ecs.ebmg8i.48xlarge裸金屬執行個體。該執行個體規格配置較高,適用於對安全性和效能有嚴苛要求的生產級工作負載,初始評估和測試成本較高。方案限制與風險:
硬體與地區綁定:當前方案強依賴特定的裸金屬執行個體規格和支援該規格的可用性區域。
單點故障:本教程示範的是單節點叢集,不具備高可用性,不適用於生產環境。生產部署需要規劃多節點叢集和高可用架構。
版本相容性:Confidential Containers、Kubernetes 及相關組件的版本緊密耦合,升級和維護需謹慎進行版本相容性測試。