全部产品
Search
文档中心

云服务器 ECS:在阿里云裸金属实例上部署 Confidential Containers (CoCo)

更新时间:Apr 01, 2026

简介

在当今云原生时代,企业日益依赖容器化应用来加速创新与交付,但随之而来的安全挑战也愈发严峻——尤其是在多租户、边缘计算或第三方托管等不可信环境中运行敏感工作负载时,传统容器隔离机制已难以抵御来自底层基础设施的威胁,包括恶意管理员、受损内核或固件级攻击。

CNCF云原生 Confidential Containers 项目应运而生,旨在弥合云原生敏捷性与数据安全之间的鸿沟。通过将 Kubernetes Pod 封装于基于硬件的机密虚拟机(Confidential VM)中,Confidential Containers 在几乎无需修改现有应用的前提下,将机密计算(Confidential Computing)的强大保护能力延伸至复杂的容器化工作负载。它不仅确保运行时内存内容对主机操作系统、云服务商乃至物理攻击者完全加密且不可窥探,还提供端到端的远程证明(Remote Attestation)与安全密钥分发机制,使用户能够确信其代码在可信环境中执行,并安全注入敏感凭证。

本文档将指导您基于8代裸金属实例ecs.ebmg8i.48xlarge部署Confidential Containers,利用Intel机密计算技术帮助您在不受信任的基础设施上构建真正可信、隔离且合规的云原生运行环境——让安全不再成为创新的代价,而是默认的基石。

架构

image

架构图展示了Confidential Containers单节点的架构,可以看到传统Kubernetes的Pod将被整体运行在一个TDX的机密虚拟机内,实现运行时数据的安全保护。所有数据的解密和明文的处理全都发生在TDX机密虚拟机内,保证整个数据生命周期的安全性。

目标

  • 实现单节点CoCo集群执行(版本v0.17.0)

  • 使用Kubeadm搭建单节点CoCo集群(v1.32.0)

实施步骤

步骤一:创建支持TDX的裸金属实例

创建一个支持Intel TDX技术的阿里云第8代裸金属实例。

  1. 前往实例购买页

  2. 按需选择付费类型并选择地域和可用区。本方案的特定社区镜像仅在部分可用区提供,示例地域和可用区为北京可用区 I 。

  3. 实例配置中单击弹性裸金属服务器,然后选择ecs.ebmg8i.48xlarge实例规格。

  4. 镜像配置中,选择社区镜像,并使用镜像ID m-2ze2ucup4c5bvgx751lx进行搜索和选择。在镜像选择下方,必须勾选机密虚拟机复选框,启用 TDX 功能。

    重要

    此镜像为基于Ubuntu的定制镜像,预装了支持TDX的相关驱动。默认SSH登录用户为ubuntu,而非root

  5. 完成网络、存储、带宽和安全组以及管理设置等配置项。各配置项详细说明,请参考配置项说明

  6. 在最终创建实例前,请在页面右侧检查实例的整体配置并配置使用时长等选项,确保各项配置符合要求。

  7. 单击确认下单,完成实例创建。

    创建实例一般需要3~5分钟,请耐心等待。可前往控制台的实例列表页面查看实例的状态,当实例状态变为运行中时,表示实例创建完成。

步骤二:准备 Kubernetes 节点环境

实例创建完成后,连接实例,为其安装配置作为单节点 Kubernetes 集群所需的基础软件。

  1. 安装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
  2. 配置 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
  3. 配置节点内核参数 为满足 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集群。

  1. 安装 Kubernetes 组件 安装kubeadmkubeletkubectl

    [需要确认:请使用与 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
  2. 初始化 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
  3. 安装网络插件 部署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
  4. 移除控制平面污点 由于是单节点集群,需要移除控制平面的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,该方式提供了更灵活的配置管理。

  1. 安装 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
  2. 配置 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
  3. 部署 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
  4. 创建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机密虚拟机中。

  1. 为节点添加标签 为工作节点添加标签,表明其支持Kata运行时。

    NODE_NAME=$(kubectl get nodes -o jsonpath='{.items[0].metadata.name}')
    kubectl label node $NODE_NAME katacontainers.io/kata-runtime=true
  2. 部署示例 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
  3. 验证部署状态 检查Pod是否成功运行,并确认其使用的运行时类是否正确。

    # 等待 Pod 状态变为 Running
    kubectl get pod coco-demo-pod
    
    # 描述 Pod 详情,确认 "Runtime Class" 字段为 "kata-qemu-tdx"
    kubectl describe pod coco-demo-pod | grep "Runtime Class"
  4. 验证TDX环境 登录到裸金属实例节点,通过内核日志确认 TDX 模块已成功初始化并被使用。

    # 在节点上执行
    dmesg | grep -i tdx

    如果看到包含TDX module initialized或类似与TDX相关的输出,表明TDX环境已成功激活,并且Kata运行时正在利用该硬件特性创建机密虚拟机。

成本与风险说明

  • 成本构成:本方案的主要成本来自 ecs.ebmg8i.48xlarge 裸金属实例。该实例规格配置较高,适用于对安全性和性能有严苛要求的生产级工作负载,初始评估和测试成本较高。

  • 方案限制与风险

    • 硬件与地域绑定:当前方案强依赖特定的裸金属实例规格和支持该规格的可用区。

    • 单点故障:本教程演示的是单节点集群,不具备高可用性,不适用于生产环境。生产部署需要规划多节点集群和高可用架构。

    • 版本兼容性:Confidential Containers、Kubernetes 及相关组件的版本紧密耦合,升级和维护需谨慎进行版本兼容性测试。