设备端工作负载认证需要使用确定性 build 个性化 (ODP) 可信执行环境 (TEE),公开提供于 Google Cloud 作为机密空间 (CS)。
工作负载映像必须生成确定性映像哈希,供 工作负载证明的 CS(使用 NIST 的 RFC 9334 远程证明) 过程 (RATS) 架构)。
本文档将介绍确定性 构建在 odp-federatedcompute 存储库ODP Aggregator 和 Model Updater 服务将在 机密空间。该代码库支持确定性构建 是生产用例所必需的
确定性 build
确定性 build 包含两个主要部分:
- 编译所需二进制文件。这包括 jar、共享库 和元数据
- 基础映像和运行时依赖项。运行时环境的基础 用于执行已编译的二进制文件的映像。
截至目前,ODP 联合计算代码库支持以下类型的 工作负载:
- Java + Spring 工作负载
- TaskAssignment、TaskManagement、Collector
- Java + Spring 搭配 JNI TensorFlow 工作负载
- ModelUpdater、Aggregator
- Python 工作负载
- TaskBuilder
依赖项
以下列表是 ODP 维护确定性所依赖的依赖项 和可用性:
- Bazel
- GitHub
- Maven
- PyPi
- Debian 快照
- DockerHub 注册表
- Google Container Registry (GCR)
确定性工作负载
所有工作负载都使用 Bazel 和 使用 API 构建特定于语言的工具链和容器映像 rules_oci。工作区 文件 定义具有相应版本和哈希的所有依赖项。
Debian 快照
所有工作负载映像都应在提供的 dockerfile 基于 Debian 快照构建的应用。Debian 快照提供具有确定性的稳定代码库快照:
- 系统头文件和库
- 系统架构
- linux_x86_64
- Debian
- C++ 编译器
Java Spring 工作负载
Bazel 的
remotejdk_17
为
用于为编译提供封闭的 Java。其他 Java 依赖项包括
在WORKSPACE
文件。
Java Spring 工作负载编译为名为
<service>_application.jar
。jar 包含:
- Java 类文件
META-INF/
- Bazel 清单数据
build-data.properties
- Bazel 构建数据
BOOT-INF/
- 打包的 jar 依赖项, rules_spring。
图像层
Java Spring 工作负载映像由两层组成:
- 基础映像层
- Java 基础映像:
gcr.io/distroless/java17-debian11
- Java 基础映像:
- 工作负载层
binary_tar.tar
<service>_application.jar
映像配置
- 入口点
java -jar <service>_application.jar
JNI Tensorflow 工作负载
JNI Tensorflow 工作负载基于 Java Spring 工作负载构建而成。答 封闭的 Clang+LLVM Bazel 工具链是使用预构建的 Clang+LLVM 16,其中包含 sysroot 来编译机器代码。
JNI 工作负载编译到名为 libtensorflow.so
的共享库中
与 <service>_application.jar
相关联。
图像层
JNI TensorFlow 工作负载映像由多个层组成:
- 基础映像层
- Java 基础映像:
gcr.io/distroless/java17-debian11
- Java 基础映像:
- Debian 软件包依赖项层。这些层使用 deb 生成。
从 debian-snapshot 下载并重新打包为映像层的归档
libc++1-16_amd64.tar
libc++abi1-16_amd64.tar
libc6_amd64.tar
libunwind-16_amd64.tar
libgcc-s1_amd64.tar
gcc-13-base_amd64.tar
- 工作负载层
binary_tar.tar
<service>_application.jar
libtensorflow-jni.so
libaggregation-jni.so
映像配置
- 标签(仅适用于在 TEE 中运行的映像)
"tee.launch_policy.allow_env_override": "FCP_OPTS"
- 允许在以下位置设置
FCP_OPTS
环境变量: 机密 空格。 工作负载将在启动时使用FCP_OPTS
进行配置 必需参数。 FCP_OPTS
环境变量在映像运行时设置 (而不是 build)以保持 build 确定性。
- 允许在以下位置设置
"tee.launch_policy.log_redirect": "always"
"tee.launch_policy.monitoring_memory_allow": "always"
- 入口点
java -Djava.library.path=. -jar <service>_application.jar
Python 工作负载
Bazel 的 rules_python 用于 提供封闭的 Python 3.10 工具链。锁定 pip 要求 文件 用于确定性地提取 pip 依赖项。Debian 快照 可确保系统根据平台 兼容性 并提供用于编译源发行版的 C++ 工具链。
Python 工作负载会被打包成一组下载的 pip 软件包, Python 3.10 发行版、ODP Python 源代码和 Python 启动 脚本。
<service>.runfiles/
- Python 发行版存储在
python_x86_64-unknown-linux-gnu/
下 - 源代码存储在
com_google_ondevicepersonalization_federatedcompute/
- Pip 软件包存储在
pypi_<dependency_name>/
下
- Python 发行版存储在
<service>.runfiles_manifest
<service>.runfiles/
目录的清单文件
<service>
- 使用 runfile 运行 Python 工作负载的 Python 脚本
图像层
Python 工作负载映像包含以下四个层:
- 基础映像层
- Python 基础映像 python:slim
- 口译层
interpreter_layer.jar
<service>/<service>.runfiles/python_x86_64-unknown-linux-gnu/**
- 软件包层
packages_layer.jar
<service>/<service>.runfiles/**/site-packages/**
- 工作负载层
app_tar_manifest.tar
- 包含源代码、启动脚本和清单。
<service>/<service>.runfiles_manifest
<service>/<service>
<service>/<service>.runfiles/com_google_ondevicepersonalization_federatedcompute/**
- 包含源代码、启动脚本和清单。
映像配置
- 入口点
/<service>/<service>
构建映像
选择工作负载后,您就可以构建和发布 图片。
前提条件
过程
映像应在由提供的 Docker 容器构建的 Docker 容器中构建, dockerfile。 提供了两个脚本来帮助构建最终的确定性图像。
- docker_run.sh
docker_run.sh
将通过 dockerfile 构建 Docker 映像 安装工作目录,装载主机 Docker 守护程序,并使用 提供的 bash 命令在 bash 命令之前传递的所有变量 视为 Docker 运行标志
- build_images.sh
build_images.sh
将针对所有映像运行bazel build
,并输出 为每个已构建的映像生成的映像哈希
构建所有映像
./scripts/docker/docker_run.sh "./scripts/build_images.sh"
您可以在下面找到每个版本的预期映像哈希 odp-federatedcompute GitHub 版本。
发布图片
发布是使用 oci_push Bazel 规则。对于每项服务,都应为以下服务配置目标代码库: 全部:
- 聚合信息网站
- 收集器
- model_updater
- task_assignment
- task_management
- task_scheduler
- task_builder
发布单张图片
如需发布单张图片,请执行以下操作:
./scripts/docker/docker_run.sh "bazel run //shuffler/services/<servicename_no_underscore>:<servicename_with_underscore>_image_publish"
构建的映像
所有构建的映像都需要由创建者存储和托管,例如 GCP Artifact Registry。