裝置端個人化功能聯合運算決定版本

在裝置端個人化 (ODP) 受信任的執行環境 (TEE) 中,工作負載認證需要確定性建構作業,這項作業在 Google Cloud 上以 Confidential Space (CS) 的形式公開提供。

工作負載映像檔必須產生可供 CS 用於工作負載認證的確定性映像檔雜湊 (這項認證使用 NIST 的 RFC 9334 遠端認證程序 (RATS) 架構)。

本文將說明如何在 odp-federatedcompute 存放區中,實作及支援確定性建構作業。ODP 匯總工具和模型更新工具服務會在 Confidential Space 中執行。這個存放區支援所有服務的確定性建構作業,這是生產用途的必要條件。

確定性建構作業

決定性建構作業包含兩個主要元件:

  1. 編譯必要二進位檔。包括 JAR、共用程式庫和中繼資料。
  2. 基本映像檔和執行階段依附元件。用於執行編譯後二進位檔的執行階段環境基礎映像檔。

目前,ODP 聯邦運算存放區支援下列類型的工作負載:

  • Java + Spring 工作負載
    • TaskAssignment、TaskManagement、Collector
  • Java + Spring,搭配 JNI tensorflow 工作負載
    • ModelUpdater、Aggregator
  • Python 工作負載
    • TaskBuilder

依附元件

以下列出 ODP 維持確定性和可用性時所依賴的依附元件:

  • Bazel
  • GitHub
  • Maven
  • PyPi
  • Debian 快照
  • DockerHub Registry
  • Google Container Registry (GCR)

確定性工作負載

所有工作負載都會使用 Bazel 編譯,並搭配語言專屬工具鍊,以及使用 rules_oci 建構的容器映像檔。WORKSPACE 檔案會定義所有依附元件,以及對應的版本和雜湊值。

Debian 快照

所有工作負載映像檔都應在提供的 dockerfile 中建構,並以 Debian 快照為基礎。Debian 快照提供穩定的存放區快照,並具有下列確定性:

Java Spring 工作負載

Bazel 的 remotejdk_17 用於提供編譯用的密封 Java。其他 Java 依附元件則是在 WORKSPACE 檔案中管理及定義。

Java Spring 工作負載會編譯為名為 <service>_application.jar 的 jar 檔案。這個 JAR 包含:

  • Java 類別檔案
  • META-INF/
    • Bazel 資訊清單資料
  • build-data.properties
    • Bazel 建構資料
  • BOOT-INF/

圖片圖層

Java Spring 工作負載映像檔包含兩層:

圖片設定

  • 進入點
    • java -jar <service>_application.jar

JNI TensorFlow 工作負載

JNI Tensorflow 工作負載是以 Java Spring 工作負載為基礎建構而成。我們使用預先建構的 Clang+LLVM 16,搭配 Debian 快照映像檔提供的 sysroot,編譯機器碼,藉此提供密封的 Clang+LLVM Bazel 工具鍊。

JNI 工作負載會編譯為名為 libtensorflow.so 的共用程式庫,以及 <service>_application.jar

圖片圖層

JNI TensorFlow 工作負載映像檔包含多個層:

  • 基礎映像檔層
  • Debian 套件依附元件層。這些層是使用從 debian-snapshot 下載的 deb 封存檔產生,並重新封裝為映像檔層
    • 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 環境變數,以維持建構確定性。
    • "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 requirements 檔案用於確定性擷取 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>/
  • <service>.runfiles_manifest
    • <service>.runfiles/ 目錄的資訊清單檔案
  • <service>
    • 使用 runfile 執行 Python 工作負載的 Python 指令碼

圖片圖層

Python 工作負載映像檔包含四層:

  • 基礎映像檔層
  • 解譯器層
    • 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>

建構映像檔

選擇工作負載後,即可建構及發布映像檔。

必要條件

程序

映像檔應在提供的 dockerfile 所建構的 Docker 容器中建構。我們提供兩個指令碼,協助您建構最終的確定性映像檔。

  • docker_run.sh
    • docker_run.sh 會從 Dockerfile 建構 Docker 映像檔、掛接工作目錄、掛接主機 Docker Daemon,並使用提供的 Bash 指令執行 Docker。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