鲲鹏机密容器
特性介绍
鲲鹏机密容器基于鲲鹏TEE技术,通过k8s+containerd+Kata+QEMU+KVM+CoCo的整套软件栈进行构建,实现机密容器部署。鲲鹏机密容器在开源Kata/CoCo社区的基础上进行了定制和适配,具备远程证明、镜像签名和加密、机密容器设备直通等安全特性。
应用场景
当业务机密性强需要部署在安全容器中时,本特性提供了类似传统虚拟机的强隔离,防止不同容器之间的安全问题。
能力范围
- 提供鲲鹏机密容器相关组件的快速编译构建能力。
- 提供针对鲲鹏机密容器定制和优化的Operator,在openFuyao管理的Kubernetes集群中实现鲲鹏机密容器环境的快速安装部署。
- 制定鲲鹏机密容器特性测试方法。
亮点特征
Kata/CoCo官方社区只支持Intel、AMD、IBM等硬件平台的机密容器,不支持鲲鹏机密容器。在openFuyao平台增加对鲲鹏机密容器环境的快速部署解决方案。
安装
前提条件
鲲鹏机密容器组件构建
build.sh脚本以鲲鹏virtCCA提供的TEE技术为基础,编译构建鲲鹏机密容器相关组件。
- 从源码编译构建机密容器运行时kata-deploy镜像,其中包括shim-v2,qemu,kernel等组件。
- 源码编译trustee组件,构建AS、KBS、RVPS镜像。
环境准备
构建环境使用ARM操作系统,内核版本为v5.0以上。
前提条件
构建环境需安装git、make、openssl、docker。
其中docker可以拉取镜像,可通过拉取下面镜像测试。
shelldocker pull ubuntu:22.04
开始构建
使用root用户进行构建编译。
git clone https://gitcode.com/openFuyao/confidential-containers-deployment.git
cd confidential-containers-deployment/build/kunpeng
chmod 755 ./build.sh执行如下命令,进行源码准备。
shell./build.sh prepare_src执行如下命令,编译kata-deploy所有组件并构建kata-deploy镜像。
shell./build.sh compile_kdeploy_all
最终构建产物为kata-deploy镜像kata-deploy_3.15.0.tar,所在目录:./kata-containers/tools/packaging/kata-deploy
执行如下命令,输入组件名,进行kata-deploy组件单点编译。
shell./build.sh compile_kdeploy_components [组件名] # 可用组件名如下 kernel - make kernel-tarball kernel-virtcca-confidential - make kernel-virtcca-confidential-tarball nydus - make nydus-tarball shim-v2 - make shim-v2-tarball virtiofsd - make virtiofsd-tarball qemu - make qemu-tarball qemu-virtcca-experimental - make qemu-virtcca-experimental-tarball agent - make agent-tarball pause-image - make pause-image-tarball coco-guest-components - make coco-guest-components-tarball rootfs-image - make rootfs-image-tarball rootfs-image-experimental - make rootfs-image-experimental-tarball merge-builds - make merge-builds to combine all tarballs
当输入组件名时,构建产物为组件包kata-static-组件名.tar.xz,所在目录:./kata-containers/tools/packaging/kata-deploy/local-build/build
当输入merge-builds时,检查所有所需组件并构建kata-deploy镜像kata-deploy_3.15.0.tar,所在目录:./kata-containers/tools/packaging/kata-deploy
执行如下命令, 编译远程证明组件镜像。
shell./build.sh compile_coco
构建产物为rvps-grpc_v0.12.0.tar、kbs-grpc-as_v0.12.0.tar、as-grpc_v0.12.0.tar,所在目录:./kata-containers/build/trustee/output
部署前准备
安装K8s集群,因为依赖containerd的Remote Snapshotter功能,要求容器运行时为containerd,且版本不低于v1.7。
部署需要用到以下容器镜像,确保集群节点可正常拉取。
- Operator Controller 镜像:quay.io/confidential-containers/operator:v0.13.0
- Pre-install Payload 镜像:quay.io/confidential-containers/reqs-payload:latest
kata-deploy镜像需导入到部署环境,构建参考鲲鹏机密容器组件构建章节。
shell# 以导入到containerd镜像仓为例 ctr -n k8s.io i import kata-deploy_3.15.0.tar
开始安装
部署cc-Operator
执行如下命令,部署cc-operator-controller-manager。
kubectl apply -k github.com/confidential-containers/operator/config/release?ref=v0.13.0执行如下命令,部署CcRuntime。
# 获取virtCCA的CcRuntime部署yaml
wget https://raw.gitcode.com/openeuler/virtCCA_sdk/raw/master/kata-v3.15.0/conf/virtcca-kata-deploy.yaml
# 其中payloadImage字段指定了kata-deploy镜像路径,例如:docker.io/library/kata-deploy:3.15.0,需根据导入的镜像仓库修改
kubectl apply -f virtcca-kata-deploy.yaml创建成功后confidential-containers-system 命名空间下有一个cc-operator-controller和两个daemonset管理的Pod。
# kubectl get pod -n confidential-containers-system -owide
NAMESPACE NAME
confidential-containers-system cc-operator-controller-manager-685bdf4fbb-mllt5
confidential-containers-system cc-operator-daemon-install-h4v42
confidential-containers-system cc-operator-pre-install-daemon-rcfdtK8s集群中已注册virtCCA对应的RuntimeClass。
# kubectl get runtimeclass
NAME HANDLER
kata kata-qemu
kata-qemu kata-qemu
kata-qemu-coco-dev kata-qemu-coco-dev
kata-qemu-virtcca kata-qemu-virtcca创建机密容器
通过部署一个测试Pod,验证鲲鹏机密容器运行时已正确配置并生效。
部署测试Pod
基于kata-qemu-virtcca容器运行时运行机密容器Pod:
kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
name: test-kata-qemu-virtcca
annotations:
io.containerd.cri.runtime-handler: "kata-qemu-virtcca"
io.katacontainers.config.hypervisor.kernel_params: "agent.debug_console agent.log=debug"
spec:
runtimeClassName: kata-qemu-virtcca
terminationGracePeriodSeconds: 5
containers:
- name: box-1
image: registry.hw.com:5000/busybox:latest
imagePullPolicy: Always
command:
- sh
tty: true
EOF部署trustee-Operator
安装kustomize 工具
为便于对Operator部署清单进行定制(如替换镜像地址),需要安装 kustomize 工具。
# 下载 kustomize 压缩包
wget -O "kustomize_v5.4.3_linux_arm64.tar.gz" "https://github.com/kubernetes-sigs/kustomize/releases/download/kustomize%2Fv5.4.3/kustomize_v5.4.3_linux_arm64.tar.gz"
# 解压到系统可执行目录
tar -zxf "kustomize_v5.4.3_linux_arm64.tar.gz" -C /usr/local/bin生成部署yaml
生成trustee-operator部署需要
deploy.yaml和kbsconfig.yaml。shell# 拉取trustee-operator代码 git clone https://github.com/confidential-containers/trustee-operator.git -b v0.3.0 cd /workdir/trustee-operator/config/manager kustomize edit set image controller=quay.io/confidential-containers/trustee-operator:v0.3.0 cd /workdir/trustee-operator && kustomize build "config/default" >/workdir/deploy.yaml cd /workdir/trustee-operator/config/samples/microservices openssl genpkey -algorithm ed25519 >privateKey openssl pkey -in privateKey -pubout -out kbs.pem kustomize build . >/workdir/kbsconfig.yaml修改
deploy.yaml中三个远程证明组件的镜像名。远程证明组件镜像的构建参考鲲鹏机密容器组件构建章节。
yaml... env: - name: KBS_IMAGE_NAME value: docker.io/library/kbs-grpc-as:v0.12.0 - name: AS_IMAGE_NAME value: docker.io/library/as-grpc:v0.12.0 - name: RVPS_IMAGE_NAME value: docker.io/library/rvps:v0.12.0 ...修改
kbsconfig.yaml中的配置。shell# 修改configmap: as-config-grpc,修改attestation_token_broker配置如下 "attestation_token_broker": { "type": "Simple", "duration_min": 5 } # 修改configmap: rvps-config-grpc,修改storage配置如下 "storage": { "type": "LocalFs", "file_path": "/opt/confidential-containers/attestation-service/rvps" } # 修改configmap: kbs-config-grpc,删除如下配置 [policy_engine] policy_path = "/opt/confidential-containers/opa/policy.rego"
部署operator
部署trustee-operator。
kubectl apply -f /workdir/deploy.yaml
# 创建成功后集群中有下面pod,kubectl get pod -n trustee-operator-system
NAMESPACE NAME
trustee-operator-system trustee-operator-controller-manager-6fcbf48f96-pgwg5部署远程证明组件。
kubectl apply -f /workdir/kbsconfig.yaml
# 创建成功后集群中有下面pod,kubectl get pod -n trustee-operator-system
NAMESPACE NAME
trustee-operator-system trustee-deployment-694bf879d5-7wzwp修改trustee-deployment部署文件。
# kubectl edit deployment -n trustee-operator-system trustee-deployment
# spec.template.spec.comtainers里的3个container都添加如下环境变量
...
env:
- name: RUST_LOG
value: DEBUG
# kbs容器volumeMounts里添加挂卷
- mountPath: /etc/attestation/attestation-service/verifier/virtcca/
name: verifier
# as容器volumeMounts里添加挂卷
- mountPath: /etc/attestation/attestation-service/verifier/virtcca/
name: verifier
- mountPath: /opt/confidential-containers/attestation-service
name: attestation-service
# rvps容器volumeMounts里添加挂卷
- mountPath: /etc/attestation/attestation-service/verifier/virtcca/
name: verifier
- mountPath: /opt/confidential-containers/attestation-service
name: attestation-service
# pod添加volumes
- hostPath:
path: /opt/confidential-containers/kbs/repository/default
type: Directory
name: default
- hostPath:
path: /etc/attestation/attestation-service/verifier/virtcca
type: Directory
name: verifier
- hostPath:
path: /opt/confidential-containers/attestation-service
type: Directory
name: attestation-service使用镜像加密和镜像签名功能
机密容器使用镜像加密和镜像签名功能,需要基于远程证明服务,以及安装镜像签名工具。
配置远程证明服务
操作步骤
配置验证VirtCCA度量报告的policy。
shellmkdir -p /opt/confidential-containers/attestation-service/token/simple/policies/opa vim /opt/confidential-containers/attestation-service/token/simple/policies/opa/default.rego # default.rego内容如下 package policy import future.keywords.every import future.keywords.if default allow := false allow if { print("Full Input:", input) print("Rim:", input["virtcca.realm.rim"]) print("Ref:", data.reference) input["virtcca.realm.rim"] in data.reference["virtcca.realm.rim"] }远程证明服务节点预置远程证明根证书、二级CA证书文件。
shellmkdir -p /etc/attestation/attestation-service/verifier/virtcca/ && cd /etc/attestation/attestation-service/verifier/virtcca/访问网站下载证书,并将下面证书放到当前目录,保持下载的证书名称不变。
shellHuawei Equipment Root CA.pem Huawei IT Product CA.pem
- RSA根证书下载链接:https://download.huawei.com/dl/download.do?actionFlag=download&nid=PKI1000000002&partNo=3001&mid=SUP_PKI
- RSA二级CA证书下载链接:https://download.huawei.com/dl/download.do?actionFlag=download&nid=PKI1000000040&partNo=3001&mid=SUP_PKI
- ECC根证书下载链接:https://download.huawei.com/dl/download.do?actionFlag=download&nid=PKI1100000224&partNo=3001&mid=SUP_PKI
- ECC二级CA证书下载链接:https://download.huawei.com/dl/download.do?actionFlag=download&nid=PKI1100000225&partNo=3001&mid=SUP_PKI
通过rvps工具添加RIM基线值。
shellcd /opt/confidential-containers/attestation-service cat << EOF > sample { "virtcca.realm.rim": [ "0f7733fcbaa9059d4d579fab25743868a2b4027290b09dfbc59964fc4b642kkk" ] } EOF provenance=$(cat sample | base64 --wrap=0) cat << EOF > message { "version" : "0.1.0", "type": "sample", "payload": "$provenance" } EOF # 将基线值注册到rvps服务 kubectl exec -it -n trustee-operator-system trustee-deployment-694bf879d5-7wzwp -c rvps -- bash ./rvps-tool register --path /opt/confidential-containers/attestation-service/message --addr http://127.0.0.1:50003说明:
virtcca.realm.rim 添加的RIM基线值(列表)可通过基线值生成工具生成。
安装基础工具
操作步骤
安装golang。
shellwget https://golang.google.cn/dl/go1.22.4.linux-arm64.tar.gz tar -zxvf go1.22.4.linux-arm64.tar.gz -C /usr/local echo "export GO_HOME=/usr/local/go" >> /etc/profile echo "export GOPATH=/home/work/go" >> /etc/profile source /etc/profile echo "export PATH=${GO_HOME}/bin:${PATH}" >> /etc/profile source /etc/profile安装cosign镜像签名工具。
shellwget https://github.com/sigstore/cosign/releases/download/v2.5.0/cosign-linux-arm64 chmod +x cosign-linux-arm64 mv cosign-linux-arm64 /usr/local/bin/cosignskopeo编译安装。
shellgit clone -b v1.15.1 https://github.com/containers/skopeo.git $GOPATH/src/github.com/containers/skopeo yum install -y gpgme-devel device-mapper-devel cd $GOPATH/src/github.com/containers/skopeo && make bin/skopeo cp bin/skopeo /usr/local/bin # 测试拉取镜像到本地,可以看到镜像被成功拉取 mkdir -p /home/work/images && cd /home/work/images skopeo copy --insecure-policy docker://docker.io/library/busybox:latest dir:busybox:latest
容器镜像加解密
官方参考文档: https://github.com/confidential-containers/guest-components/tree/main/attestation-agent/coco_keyprovider https://confidentialcontainers.org/docs/features/encrypted-images/
前提条件
操作步骤
生成加密秘钥并加密容器镜像
# 生成加密秘钥
KEY_FILE="image_key"
head -c 32 /dev/urandom | openssl enc > "$KEY_FILE"
# 创建加密镜像生成目录
mkdir output
# 创建容器并在容器中使用生成的秘钥加密明文镜像(-s指定被加密的原始镜像)
docker run -v "$PWD/output:/output" \\
-e http_proxy="http://IP:PORT" \\
-e https_proxy="http://IP:PORT" \\
ghcr.io/confidential-containers/staged-images/coco-keyprovider:latest /encrypt.sh \\
-k "$(base64 < image_key)" \\
-i kbs:///default/image_key/busybox_enc \\
-s docker://busybox:latest \\
-d dir:/output
# 推送加密镜像到本地镜像仓
skopeo copy dir:output docker://registry.hw.com:5000/busybox_enc:latest
# 通过下述命令检查镜像是否加密成功
skopeo inspect docker://registry.hw.com:5000/busybox_enc:latest
# 复制加密秘钥到指定路径
cp ./image_key /opt/confidential-containers/kbs/repository/default/image_key/busybox_enc启动加密镜像容器
kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
name: enc-test
annotations:
io.containerd.cri.runtime-handler: "kata-qemu-virtcca"
io.katacontainers.config.hypervisor.kernel_params: "agent.debug_console agent.log=debug agent.image_policy_file=kbs:///default/security-policy/test agent.enable_signature_verification=true agent.guest_components_rest_api=all agent.aa_kbc_params=cc_kbc::http:[证明服务pod IP]:8080"
spec:
runtimeClassName: kata-qemu-virtcca
terminationGracePeriodSeconds: 5
containers:
- name: box
image: registry.hw.com:5000/busybox_enc:latest
imagePullPolicy: Always
command:
- sh
tty: true
EOF补充pod.metadata.annotations中的agent.aa_kbc_params参数,需填入远程证明服务的Pod IP地址,示例如下。
# 查看远程证明服务pod,kubectl get pod -n trustee-operator-system -owide
NAMESPACE NAME READY STATUS IP
trustee-operator-system trustee-deployment-694bf879d5-7wzwp 3/3 Running 10.244.0.231
# pod annotations里agent.aa_kbc_params=cc_kbc::http:10.244.0.231:8080"容器镜像签名
CoCo社区参考文档:https://confidentialcontainers.org/docs/features/signed-images/
前提条件
操作步骤
签名镜像
# 生成密钥对(两次回车可无需设置密码,用户视自身诉求而定)
cosign generate-key-pair
# --tlog-upload=false表示不上传到cosign官方(即离线签名,用户视自身诉求而定)
cosign sign --key cosign.key --tlog-upload=false registry.hw.com:5000/busybox:latest
# 部署签名公钥
mkdir -p /opt/confidential-containers/kbs/repository/default/cosign-key
cp ./cosign.pub /opt/confidential-containers/kbs/repository/default/cosign-key/1指定镜像仓验证策略
vim /opt/confidential-containers/kbs/repository/default/security-policy/test
{
"default": [
{
"type": "reject"
}
],
"transports": {
"docker": {
"registry.hw.com:5000": [
{
"type": "sigstoreSigned",
"keyPath": "kbs:///default/cosign-key/1"
}
]
}
}
}说明:
设置type字段指定具体验证要求,"reject"为拒绝任何镜像,"sigstoreSigned"为要求验证签名,"insecureAcceptAnything"为不进行任何验证。
验签启动容器
签名验签demo:
apiVersion: v1
kind: Pod
metadata:
name: sign-test
annotations:
io.containerd.cri.runtime-handler: "kata-qemu-virtcca"
io.katacontainers.config.hypervisor.kernel_params: "agent.debug_console agent.log=debug agent.image_policy_file=kbs:///default/security-policy/test agent.enable_signature_verification=true agent.guest_components_rest_api=all agent.aa_kbc_params=cc_kbc::http:[证明服务pod IP]:8080"
spec:
runtimeClassName: kata-qemu-virtcca
terminationGracePeriodSeconds: 5
containers:
- name: box
image: registry.hw.com:5000/busybox:latest
imagePullPolicy: Always
command:
- sh
tty: true补充pod.metadata.annotations中的agent.aa_kbc_params参数,需填入远程证明服务的Pod IP地址,示例如下。
# 查看远程证明服务pod,kubectl get pod -n trustee-operator-system -owide
NAMESPACE NAME READY STATUS IP
trustee-operator-system trustee-deployment-694bf879d5-7wzwp 3/3 Running 10.244.0.231
# pod annotations里agent.aa_kbc_params=cc_kbc::http:10.244.0.231:8080"