はじめに
企業はアプリケーションの迅速な提供を実現するためにコンテナ化アプリケーションに依存していますが、これにより新たなセキュリティ課題が生じています。マルチテナントクラウドやエッジロケーションなど、共有環境で機密性の高いワークロードを実行すると、新たなリスクにさらされます。従来のコンテナ隔離では、悪意ある管理者、侵害されたカーネル、ファームウェアレベルの攻撃など、基盤となるインフラストラクチャからの脅威に対して十分な保護を提供できません。
CNCF の Confidential Containers (CoCo) プロジェクトは、クラウドネイティブな俊敏性とデータセキュリティのギャップを埋めます。Kubernetes Pod をハードウェアベースのコンフィデンシャル VM でカプセル化することで、既存のアプリケーションに対する変更を最小限に抑えつつ、複雑なコンテナ化ワークロードにもコンフィデンシャルコンピューティングの保護を拡張します。実行時のメモリを暗号化し、ホストからアクセス不能な状態にするとともに、シークレットを注入する前に環境の整合性を検証するリモートアテステーションを提供します。
本ドキュメントでは、8 世代目 `ecs.ebmg8i.48xlarge` ベアメタルインスタンスへの Confidential Containers のデプロイ方法を説明します。Intel のコンフィデンシャルコンピューティング技術を活用して、信頼性と隔離性の高い実行環境を構築し、セキュリティをクラウドネイティブインフラストラクチャのデフォルト機能として実現します。
アーキテクチャ
アーキテクチャ図は、Confidential Containers のシングルノードアーキテクチャを示しています。各 Kubernetes Pod は TDX コンフィデンシャル VM 内で実行され、実行時のデータを保護します。すべてのデータ処理はこの安全な境界内で行われるため、データライフサイクル全体を通じてセキュリティが保証されます。
目的
シングルノード CoCo クラスター(バージョン v0.17.0)をデプロイします。
Kubeadm を使用してシングルノード Kubernetes クラスター(v1.32.0)を構築します。
操作手順
ステップ 1:TDX 対応ベアメタルインスタンスの作成
Intel TDX 技術をサポートする 8 世代目 Alibaba Cloud ベアメタルインスタンスを作成します。
インスタンス購入ページに移動します。
支払い方法、リージョン、および可用性ゾーンを選択します。必要なコミュニティイメージは特定の可用性ゾーンでのみ利用可能です。本例では、北京ゾーン I を選択します。
インスタンス 構成セクションで、Elastic Bare Metal Server をクリックし、インスタンスタイプとして
ecs.ebmg8i.48xlargeを選択します。イメージ 構成セクションで、コミュニティイメージ を選択し、イメージ ID
m-2ze2ucup4c5bvgx751lxを使用してイメージを検索します。イメージ選択の下部で、TDX 機能を有効化するために コンフィデンシャル VM のチェックボックスを必ず選択します。重要これは、TDX をサポートするプリインストール済みドライバーを含むカスタム Ubuntu ベースのイメージです。デフォルトの SSH ログインユーザーは
ubuntuであり、rootではありません。ネットワーク、ストレージ、帯域幅、セキュリティグループ、および管理の設定を構成します。各設定項目の詳細については、「設定項目の説明」をご参照ください。
インスタンスの作成前に、ページ右側の全体構成を確認し、サブスクリプション期間などのオプションを設定します。すべての設定が要件を満たしていることを確認してください。
注文の確定 をクリックしてインスタンスを作成します。
インスタンスの作成には通常 3~5 分かかります。コンソールの「インスタンス」ページでステータスを確認できます。インスタンスステータスが 実行中 に変更された場合、インスタンスの準備が完了しています。
ステップ 2: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.iocontainerd の構成 デフォルトの構成ファイルを生成した後、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 # cgroup ドライバーを systemd に変更し、Kubernetes の要件を満たします。 sudo sed -i 's#SystemdCgroup = false#SystemdCgroup = true#g' /etc/containerd/config.toml # 変更を適用するために containerd サービスを再起動します。 sudo systemctl restart containerdノードのカーネルパラメーターの構成 Kubernetes のネットワーキングおよびランタイム要件を満たすために、スワップ領域を無効化し、必要なカーネルモジュールを読み込みます。
# スワップを一時的に無効化します。 sudo swapoff -a # fstab ファイル内のスワップエントリをコメントアウトして、永続的に無効化します。 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をインストールします。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 kubectlKubernetes コントロールプレーンの初期化
kubeadm initコマンドを使用してコントロールプレーンを初期化します。# API サーバーのアドバタイズアドレスとして使用するプライマリネットワークインターフェースの 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ネットワークプラグインのインストール 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 マニフェストを修正し、正しい 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コントロールプレーンの Taint の削除 このシングルノードクラスター上でワークロードをスケジュール可能にするため、コントロールプレーンノードから
NoScheduleTaint を削除します。NODE_NAME=$(kubectl get nodes -o jsonpath='{.items[0].metadata.name}') kubectl taint nodes $NODE_NAME node-role.kubernetes.io/control-plane-
ステップ 4:CoCo コンポーネントのデプロイ
Confidential Containers は複数のデプロイ方法を提供します。いずれか一方を選択してください:Helm チャート方式 または オペレーター方式。
Helm チャート
より柔軟な構成を実現するために、Helm チャートを使用して 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.shCoCo Helm チャートの構成 CoCo チャートリポジトリをクローンし、TDX 関連ランタイムを有効化するカスタム
values.yamlファイルを作成します。# チャートリポジトリをクローンし、指定されたバージョンをチェックアウトします。 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: setup: ["nydus"] # TDX 関連のシャイムを有効化します。 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 シャイムを明示的に無効化します。 qemu-snp: enabled: false qemu-se: enabled: false # RuntimeClass の作成を有効化します。 runtimeClasses: enabled: true createDefault: false defaultName: "kata" # アーキテクチャごとのデフォルトシャイム defaultShim: amd64: qemu-tdx EOFCoCo のデプロイ 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.0RuntimeClass の作成 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 のデプロイ 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 が正常に実行中であることを確認し、正しい RuntimeClass が使用されていることを確認します。
# Pod ステータスが「実行中」になるまで待機します。 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 ランタイムがこのハードウェア機能を使用してコンフィデンシャル VM を作成しています。
コストとリスク
コストの内訳:本ソリューションの主なコストは、
ecs.ebmg8i.48xlargeベアメタルインスタンスから発生します。このインスタンスタイプは高スペックであり、厳格なセキュリティおよびパフォーマンス要件を持つ本番ワークロードに適していますが、その結果、初期評価およびテストコストが増加します。制限事項およびリスク:
ハードウェアおよびリージョンへの依存:本ソリューションは特定のベアメタルインスタンスタイプおよびそれをサポートする可用性ゾーンに依存します。
単一障害点:本チュートリアルではシングルノードクラスターを紹介しており、高可用性を提供せず、本番環境には不適切です。本番環境へのデプロイには、マルチノードクラスターおよび高可用性アーキテクチャが必要です。
バージョン互換性:Confidential Containers、Kubernetes、および関連コンポーネントのバージョンは密接に結合しています。アップグレードおよびメンテナンスには、慎重な互換性テストが必要です。