Inclavare Containers是工业界首个面向机密计算场景的开源容器运行时,它在基于硬件的可信执行环境中启动受保护的容器,以防止不受信任的实体(例如:云服务商)访问您的敏感数据。在ACK-TEE集群中,您可以基于Inclavare
Containers灵活、便捷地部署机密容器。本文主要为您介绍如何在ACK-TEE集群中基于Inclavare Containers部署和使用机密容器(简称Inclavare
Containers机密容器)。
背景信息
在ACK-TEE集群中虽然也可以使用常规技术部署和使用机密容器,但您需要掌握机密计算领域的专业知识,并按照SGX SDK应用开发规范开发和构建镜像。而Inclavare
Containers能帮您省去这些复杂过程,降低机密计算的使用门槛,灵活对接不同类型的Enclave运行时形态,同时保持和普通容器一样的使用体验。更多信息,请参见inclavare-containers。
步骤一:搭建Inclavare Containers机密容器运行环境
说明 由于Pod的调度具有随机性,如果在部署Inclavare Containers机密容器时,您不通过打标签的方式定义被调度Pod所属的节点,则需要在每一个节点搭建Inclavare
Containers机密容器的运行环境。
- 执行以下命令,安装
rune
和shim-rune
。更多信息,请参见rune和shim-rune。
说明
rune
是符合OCI Runtime规范的命令行工具,用于在容器里创建和运行Enclave的命令行工具。更多信息,请参见runtime-container。
shim-rune
是为容器运行时rune
提供的shim
,在普通shim
功能的基础上额外提供了Enclave签名和管理功能。
yum-config-manager --add-repo https://mirrors.openanolis.org/inclavare-containers/alinux2-repo && \
rpm --import https://mirrors.openanolis.org/inclavare-containers/alinux2-repo/RPM-GPG-KEY-rpm-sign && \
yum install -y rune shim-rune
- 配置容器引擎Containerd。
说明 ACK-TEE机密计算容器引擎Containerd默认的OCI Runtime是runC,而运行机密容器需要用新的容器运行时runE。
- 执行以下命令,配置OCI Runtime runE运行时。
cd /etc/containerd/ && \
sed -i 's/\(default_runtime_name = \)"runc"/\1"rune"/' config.toml && \
sed -i '/\[plugins."io.containerd.grpc.v1.cri".containerd.runtimes\]/a\\t[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.rune]' config.toml && \
sed -i '/\[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.rune\]/a\\t runtime_type = "io.containerd.rune.v2"' config.toml
- 执行以下命令,重启Containerd。
systemctl restart containerd.service
- 执行以下命令,查看Containerd是否启动成功。
systemctl status containerd.service
预期输出:
containerd.service - containerd container runtime
Loaded: loaded (/usr/lib/systemd/system/containerd.service; enabled; vendor preset: disabled)
Active: active (running) since 二 2021-06-15 19:16:19 CST; 5s ago
Docs: https://containerd.io
Process: 212462 ExecStartPre=/sbin/modprobe overlay (code=exited, status=0/SUCCESS)
Main PID: 212464 (containerd)
Tasks: 288
Memory: 6.3G
...
- 执行以下命令,安装Occlum软件栈。
说明 Occlum是Inclavare Containers当前支持的Enclave运行时,而Inclavare Containers需要Enclave运行时的配合才能运行机密容器。
yum install -y occlum-pal occlum-rdfsbase-dkms
- 执行以下命令,查看
occlum-pal
是否安装成功。ls /opt/occlum/build/lib/
预期输出:
libocclum-pal.so.0.21.0
- 执行以下命令,查看
rdfsbase
驱动是否安装成功。lsmod | grep enable_rdfsbase
预期输出:
enable_rdfsbase 16384 0
步骤二:构建Inclavare Containers机密容器镜像
说明
- 步骤1~5:基于Occlum的开发镜像构建并打包Hello World可信应用。
- 步骤6:构建包含Hello World可信应用的机密容器镜像。
- 执行以下命令,运行Occlum开发环境
occlum-app-builder
。
说明 docker.io/occlum/occlum
镜像版本需要与安装的Occlum版本一致。
cat << EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
labels:
run: occlum-app-builder
name: occlum-app-builder
namespace: default
spec:
hostNetwork: true
containers:
- command:
- sleep
- infinity
image: docker.io/occlum/occlum:0.21.0-centos8.2
imagePullPolicy: IfNotPresent
securityContext:
privileged: true
name: occlum-app-builder
EOF
- 执行以下命令,登录到Occlum开发环境
occlum-app-builder
容器。kubectl exec -it occlum-app-builder -c occlum-app-builder -- /bin/bash
- 在Occlum开发环境
occlum-app-builder
内安装Docker。
- 安装Docker。具体安装操作,请参见Install Docker。
- Docker安装完成后,执行以下命令启动Docker服务。
nohup dockerd -b docker0 --storage-driver=vfs &
说明 在默认情况下Systemd未安装在容器中,因此您无法通过Systemd管理Docker服务,需要用nohup dockerd -b docker0 --storage-driver=vfs &
来启动Docker服务。
- 执行以下命令,确认Docker服务成功启动。
docker ps
预期输出:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
- 使用以下C代码样例,编写Hello World代码。
cat << EOF > hello_world.c
#include <stdio.h>
#include <unistd.h>
void main(void)
{
while (1) {
printf("Hello World!\n");
fflush(stdout);
sleep(5);
}
}
EOF
- 构建并打包Hello World可信应用。
- 执行下面命令,使用Occlum工具链编译程序。
occlum-gcc -o hello_world hello_world.c
- 执行下面命令,初始化
occlum_instance
。occlum new occlum_instance
- 执行下面命令,生成Occlum文件系统镜像和Occlum SGX Enclave。
cd occlum_instance && \
cp ../hello_world image/bin/ && \
openssl genrsa -aes128 -out occlum_key.pem -3 3072 && \
occlum build --sign-key occlum_key.pem
- 执行下面命令,打包Hello World可信应用。
occlum package occlum_instance.tar.gz
- 构建机密容器镜像。
- 使用以下Dockerfile模板样例,创建名为Dockerfile的文件。
cat << EOF >Dockerfile
FROM scratch
ADD occlum_instance.tar.gz /
ENTRYPOINT ["/bin/hello_world"]
EOF
- 执行以下命令,构建并上传镜像。
docker build -f Dockerfile -t "<$TARGET_IMAGE>" .
docker login -p <$password> -u <$username>
docker push "<$TARGET_IMAGE>"
说明
- 变量<$password>、<$username>分别表示登录
docker hub
的用户名和密码。
- 变量<$TARGET_IMAGE>表示镜像地址。
步骤三:使用Inclavare Containers机密容器
- 从Occlum开发环境
occlum-app-builder
中退出,在集群中执行以下命令,创建RuntimeClass对象runC和runE,从而您就可以在ACK-TEE集群中部署机密容器。cat << EOF | kubectl apply -f -
apiVersion: node.k8s.io/v1beta1
handler: runc
kind: RuntimeClass
metadata:
name: runc
---
apiVersion: node.k8s.io/v1beta1
handler: rune
kind: RuntimeClass
metadata:
name: rune
EOF
- 执行以下命令,部署机密容器。
cat << EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
labels:
run: occlum-helloworld
name: occlum-helloworld
namespace: default
spec:
restartPolicy: Always
runtimeClassName: rune
containers:
- command:
- /bin/hello_world
env:
- name: ENCLAVE_TYPE
value: intelSgx
- name: RUNE_CARRIER
value: occlum
- name: ENCLAVE_RUNTIME_LOGLEVEL
value: info
- name: ENCLAVE_RUNTIME_PATH
value: /opt/occlum/build/lib/libocclum-pal.so.0.21.0
- name: ENCLAVE_RUNTIME_ARGS
value: occlum_instance
image: <$TARGET_IMAGE>
imagePullPolicy: IfNotPresent
name: hello-world-client
dnsPolicy: ClusterFirst
EOF
上述YAML中涉及的参数含义如下:
参数 |
描述 |
ENCLAVE_TYPE |
指定要使用的机密计算硬件的类型。 |
RUNE_CARRIER |
shim-rune 创建和运行Occlum应用。
|
ENCLAVE_RUNTIME_LOGLEVEL |
指定运行时的日志级别;允许设置的值有:trace、debug、info、warning、error、fatal、panic和off。 |
ENCLAVE_RUNTIME_PATH |
指定启动Enclave运行时的路径。 |
ENCLAVE_RUNTIME_ARGS |
指定启动Enclave运行时的参数。 |
TARGET_IMAGE |
在步骤二第6步中自定义的容器镜像名称。 |
验证在ACK-TEE集群中使用Inclavare Containers机密容器是否成功运行
执行以下命令,查看容器运行日志。
kubectl logs -f occlum-helloworld
预期输出:
Hello World!
Hello World!
Hello World!
如果容器日志每隔5s打印一行Hello World!
,则表示Inclavare Containers环境安装成功且机密容器也被正确运行了。
说明 如果您有关于任何Inclavare Containers机密容器的问题,请在
issues中留言 。