概要
共有環境におけるコンテナ化されたワークロードは、悪意のある管理者、侵害されたカーネル、ファームウェアレベルの攻撃など、従来のコンテナ分離では対処できない脅威に直面します。
CNCF の Confidential Containers (CoCo) プロジェクトは、Kubernetes Pod をハードウェアベースのコンフィデンシャル VM にカプセル化します。実行時メモリを暗号化してホストからアクセスできないようにし、Secret を注入する前に環境の整合性を検証するためのリモートアテステーションを提供します。
このトピックでは、コンテナ化されたワークロード向けに信頼できる、分離されたランタイムを構築するために、Intel TDX を搭載した ecs.ebmg8i.48xlarge ベアメタルインスタンスに CoCo をデプロイする手順を説明します。
アーキテクチャ
各 Kubernetes Pod は、実行時のデータを保護する TDX コンフィデンシャル VM 内で実行されます。すべての処理は、このセキュアな境界内で行われます。
目的
-
単一ノードの CoCo クラスター (バージョン v0.17.0) のデプロイ。
-
kubeadm を使用した、単一ノード Kubernetes クラスター (v1.32.0) のセットアップ。
手順
手順1:TDX ベアメタルインスタンスの作成
Intel TDX をサポートする第8世代の Alibaba Cloud ベアメタルインスタンスを作成します。
-
インスタンス購入ページに移動します。
-
課金方法、リージョン、アベイラビリティーゾーンを選択します。必要なコミュニティイメージは特定のゾーンでのみ利用できます。この例では、[北京ゾーン I] を選択します。
-
[Instance] セクションで、[Elastic Bare Metal Server] をクリックし、
ecs.ebmg8i.48xlargeインスタンスタイプを選択します。 -
[Image] セクションで、[Community Image] を選択し、イメージ ID
m-2ze2ucup4c5bvgx751lxを検索します。[Confidential VM] チェックボックスにチェックを入れ、TDX を有効にします。重要これは TDX ドライバーがプリインストールされた Ubuntu ベースのカスタムイメージです。デフォルトの SSH ユーザーは
ubuntuであり、rootではありません。 -
ネットワーク、ストレージ、帯域幅、セキュリティグループ、管理設定を構成します。Configuration Item Descriptions をご参照ください。
-
ページの右側で全体構成を確認します。サブスクリプション期間などのオプションを設定し、すべての設定が要件を満たしていることを確認します。
-
[Confirm Order] をクリックしてインスタンスを作成します。
インスタンスの作成には 3~5 分かかります。コンソールのインスタンスページでステータスを確認します。ステータスが [Running] に変わると、インスタンスの準備が完了です。
手順2:Kubernetes ノードの準備
インスタンスに接続し、必要なソフトウェアをインストールして、単一ノード Kubernetes クラスターとしてセットアップします。
-
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 イメージレジストリを Alibaba Cloud のミラーに置き換え、イメージの取得を高速化します。 sudo sed -i -E 's#registry.k8s.io#registry.aliyuncs.com/google_containers#g' /etc/containerd/config.toml # Kubernetes の要件を満たすために cgroup ドライバーを systemd に変更します。 sudo sed -i 's#SystemdCgroup = false#SystemdCgroup = true#g' /etc/containerd/config.toml # 変更を適用するために containerd サービスを再起動します。 sudo systemctl restart containerd -
カーネルパラメーターの設定 swap パーティションを無効化し、Kubernetes ネットワークとランタイムに必要なカーネルモジュールをロードします。
# swap を一時的に無効化します。 sudo swapoff -a # fstab ファイル内の swap エントリをコメントアウトして 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
手順3:単一ノード Kubernetes クラスターのインストール
kubeadm を使用して単一ノード Kubernetes クラスターをセットアップします。
-
Kubernetes コンポーネントのインストール
kubeadm、kubelet、kubectlをインストールします。# 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 -
コントロールプレーンの初期化
kubeadm initを使用してコントロールプレーンを初期化します。# API サーバーの advertise address として使用する、プライマリネットワークインターフェイスの IP アドレスを取得します。 # 注:このコマンドは、プライマリインターフェイスが 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 -
ネットワークプラグインのインストール Pod 間通信のために Flannel CNI プラグインをデプロイします。
# 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 マニフェストを変更して、正しい Pod ネットワーク CIDR を設定し、リージョナルイメージミラーを使用します。 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テイントを削除し、この単一ノードクラスターでワークロードを実行できるようにします。NODE_NAME=$(kubectl get nodes -o jsonpath='{.items[0].metadata.name}') kubectl taint nodes $NODE_NAME node-role.kubernetes.io/control-plane-
手順4:CoCo コンポーネントのデプロイ
Helm チャート または オペレーター のいずれかの方法で CoCo をデプロイします。
Helm チャート
Helm チャートを使用して CoCo をデプロイします。
-
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 チャートの設定 CoCo charts リポジトリをクローンし、TDX ランタイムを有効にするカスタム
values.yamlを作成します。# 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 の設定 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" # アーキテクチャごとのデフォルト shim 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 を作成しません。Pod で必要な
RuntimeClassオブジェクトを手動で作成します。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
オペレーター
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
# 現在のノードがワーカーとして機能するようにします。
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
手順5:サンプル Pod のデプロイと検証
サンプル Pod を実行し、TDX コンフィデンシャル VM 内で実行されていることを確認します。
-
ノードへのラベル付与 Kata ランタイムをサポートしていることを示すために、ワーカーノードにラベルを付与します。
NODE_NAME=$(kubectl get nodes -o jsonpath='{.items[0].metadata.name}') kubectl label node $NODE_NAME katacontainers.io/kata-runtime=true -
サンプル Pod のデプロイ
runtimeClassNameのspecを使用して TDX ランタイムを指定する Pod を作成します。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 が正しい RuntimeClass で実行されていることを確認します。
# Pod のステータスが Running になるまで待機します。 kubectl get pod coco-demo-pod # Pod を describe し、"Runtime Class" フィールドが "kata-qemu-tdx" であることを確認します。 kubectl describe pod coco-demo-pod | grep "Runtime Class" -
TDX 有効化の確認 ベアメタルインスタンス上のカーネルログを確認し、TDX の初期化を検証します。
# このコマンドはノード上で実行します。 dmesg | grep -i tdx出力に
TDX module initializedなどのメッセージが含まれている場合、TDX 環境が有効であり、Kata ランタイムがコンフィデンシャル VM に対して TDX を使用していることを示しています。
コストとリスク
-
コストの内訳:主なコストは
ecs.ebmg8i.48xlargeベアメタルインスタンスです。その高い仕様は、厳格なセキュリティ要件とパフォーマンス要件を持つ本番ワークロードに適していますが、評価やテストのコストは増加します。 -
制限事項とリスク:
-
ハードウェアとリージョンへの依存:このソリューションには、特定のベアメタルインスタンスタイプと、それをサポートするアベイラビリティーゾーンが必須です。
-
単一障害点:このチュートリアルでは単一ノードクラスターを使用するため、高可用性はありません。本番環境では、高可用性アーキテクチャを備えたマルチノードクラスターが必要です。
-
バージョン互換性:CoCo、Kubernetes、および関連コンポーネントのバージョンは密接に関連しています。アップグレードには慎重な互換性テストが必要です。
-