Build deterministik komputasi gabungan yang dipersonalisasi di Perangkat

Build deterministik diperlukan untuk pengesahan workload di Trusted Execution Environment (TEE) Personalisasi Di Perangkat (ODP), yang tersedia secara publik di Google Cloud sebagai Confidential Space (CS).

Image workload harus menghasilkan hash image deterministik yang dapat digunakan oleh CS untuk pengesahan workload (yang menggunakan RFC 9334 Remote ATtestation procedureS (RATS) Architecture NIST).

Dokumen ini akan membahas penerapan dan dukungan untuk build deterministik di repositori odp-federatedcompute. Layanan ODP Aggregator dan Model Updater akan berjalan dalam Confidential Space. Repositori ini mendukung build deterministik untuk semua layanan kami, yang diperlukan untuk kasus penggunaan produksi.

Build deterministik

Build deterministik terdiri dari dua komponen utama:

  1. Kompilasi biner yang diperlukan. Hal ini mencakup JAR, library bersama, dan metadata.
  2. Image dasar dan dependensi runtime. Image dasar lingkungan runtime yang digunakan untuk mengeksekusi biner yang dikompilasi.

Mulai sekarang, repositori ODP Federated Compute mendukung jenis beban kerja berikut:

  • Java + beban kerja Spring
    • TaskAssignment, TaskManagement, Collector
  • Java + Spring dengan beban kerja tensorflow JNI
    • ModelUpdater, Aggregator
  • Beban kerja Python
    • TaskBuilder

Dependensi

Daftar berikut adalah dependensi yang digunakan ODP untuk mempertahankan determinisme dan ketersediaan:

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

Workload deterministik

Semua workload dikompilasi menggunakan Bazel dengan toolchain khusus bahasa dan image container yang dibuat menggunakan rules_oci. File WORKSPACE file menentukan semua dependensi dengan versi dan hash yang sesuai.

Snapshot Debian

Semua image workload harus dibangun dalam dockerfile yang disediakan, yang dibangun di atas snapshot Debian. Snapshot Debian menyediakan snapshot repositori yang stabil dengan deterministik:

Beban kerja Java Spring

remotejdk_17 Bazel digunakan untuk menyediakan Java hermetis untuk kompilasi. Dependensi Java lainnya dikelola dan ditentukan dalam file WORKSPACE.

Java Spring workloads dikompilasi ke file jar bernama <service>_application.jar. Botol berisi:

  • File class Java
  • META-INF/
    • Data manifes Bazel
  • build-data.properties
    • Data build Bazel
  • BOOT-INF/
    • Dependensi jar yang dikemas, dihasilkan oleh rules_spring.

Lapisan gambar

Image beban kerja Java Spring terdiri dari dua lapisan:

Konfigurasi gambar

  • Entrypoint
    • java -jar <service>_application.jar

Beban kerja JNI Tensorflow

Workload JNI Tensorflow dibangun di atas workload Java Spring. Toolchain Bazel Clang+LLVM hermetik disediakan menggunakan Clang+LLVM 16 pra-build dengan sysroot yang disediakan oleh image snapshot Debian untuk mengompilasi kode mesin.

Beban kerja JNI dikompilasi ke library bersama bernama libtensorflow.so bersama dengan <service>_application.jar.

Lapisan gambar

Image workload tensorflow JNI terdiri dari beberapa lapisan:

  • Lapisan gambar dasar
  • Lapisan dependensi paket Debian. Lapisan dibuat menggunakan arsip deb yang didownload dari debian-snapshot dan dikemas ulang sebagai lapisan image
    • 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
  • Lapisan workload
    • binary_tar.tar
      • <service>_application.jar
      • libtensorflow-jni.so
      • libaggregation-jni.so

Konfigurasi gambar

  • Label (Hanya untuk gambar yang dibuat untuk dijalankan dalam TEE)
    • "tee.launch_policy.allow_env_override": "FCP_OPTS"
      • Mengizinkan variabel lingkungan FCP_OPTS ditetapkan di ruang rahasia. Workload akan menggunakan FCP_OPTS saat startup untuk mengonfigurasi parameter yang diperlukan.
      • Variabel lingkungan FCP_OPTS ditetapkan saat image dijalankan (bukan di-build) untuk mempertahankan determinisme build.
    • "tee.launch_policy.log_redirect": "always"
    • "tee.launch_policy.monitoring_memory_allow": "always"
  • Entrypoint
    • java -Djava.library.path=. -jar <service>_application.jar

Beban kerja Python

rules_python Bazel digunakan untuk menyediakan toolchain Python 3.10 yang hermetis. File requirements pip yang dikunci digunakan untuk pengambilan dependensi pip yang deterministik. Image snapshot Debian memastikan distribusi deterministik diambil berdasarkan kompatibilitas platform dan menyediakan toolchain C++ untuk mengompilasi distribusi sumber.

Beban kerja Python akan dikemas ke dalam serangkaian paket pip yang didownload, distribusi Python 3.10, kode sumber ODP Python, dan skrip startup Python.

  • <service>.runfiles/
    • Distribusi Python disimpan di python_x86_64-unknown-linux-gnu/
    • Kode sumber disimpan di com_google_ondevicepersonalization_federatedcompute/
    • Paket Pip disimpan di pypi_<dependency_name>/
  • <service>.runfiles_manifest
    • File manifes untuk direktori <service>.runfiles/
  • <service>
    • Skrip Python untuk menjalankan beban kerja Python menggunakan runfile

Lapisan gambar

Image beban kerja Python terdiri dari empat lapisan:

  • Lapisan gambar dasar
  • Lapisan interpreter
    • interpreter_layer.jar
      • <service>/<service>.runfiles/python_x86_64-unknown-linux-gnu/**
  • Lapisan paket
    • packages_layer.jar
      • <service>/<service>.runfiles/**/site-packages/**
  • Lapisan workload
    • app_tar_manifest.tar
      • Berisi kode sumber, skrip startup, dan manifes.
        • <service>/<service>.runfiles_manifest
        • <service>/<service>
        • <service>/<service>.runfiles/com_google_ondevicepersonalization_federatedcompute/**

Konfigurasi gambar

  • Entrypoint
    • /<service>/<service>

Membangun gambar

Setelah workload dipilih, Anda siap membuat dan memublikasikan gambar.

Prasyarat

  • Bazel 6.4.0
    • Memerlukan penginstalan Java dan C++
  • Docker

Prosedur

Image harus dibangun dalam container Docker yang dibangun oleh dockerfile yang disediakan. Dua skrip disediakan untuk membantu membuat gambar deterministik akhir.

  • docker_run.sh
    • docker_run.sh akan mem-build image Docker dari Dockerfile, memasang direktori kerja, memasang daemon Docker host, dan menjalankan Docker dengan perintah bash yang diberikan. Variabel apa pun yang diteruskan sebelum perintah bash akan diperlakukan sebagai tanda docker run.
  • build_images.sh
    • build_images.sh akan menjalankan bazel build untuk semua gambar dan menghasilkan hash gambar yang dibuat untuk setiap gambar yang dibangun.

Membangun semua gambar

./scripts/docker/docker_run.sh "./scripts/build_images.sh"

Hash gambar yang diharapkan untuk setiap rilis dapat ditemukan di bagian rilis GitHub odp-federatedcompute.

Memublikasikan gambar

Publikasi dikonfigurasi menggunakan aturan Bazel oci_push. Untuk setiap layanan, repositori target harus dikonfigurasi untuk semua:

  • agregator
  • kolektor
  • model_updater
  • task_assignment
  • task_management
  • task_scheduler
  • task_builder

Memublikasikan satu gambar

Untuk memublikasikan satu gambar:

./scripts/docker/docker_run.sh "bazel run //shuffler/services/<servicename_no_underscore>:<servicename_with_underscore>_image_publish"

Gambar yang dibuat

Semua image yang di-build harus disimpan dan dihosting oleh pembuatnya, seperti di GCP artifact registry.