온디바이스 맞춤설정 제휴 컴퓨팅 결정적 빌드

결정적 빌드는 온디바이스 개인화 (ODP) 신뢰할 수 있는 실행 환경 (TEE)의 워크로드 증명에 필요하며, Google Cloud에서 컨피덴셜 스페이스 (CS)로 공개적으로 제공됩니다.

워크로드 이미지는 CS가 워크로드 증명에 사용할 수 있는 결정적 이미지 해시를 생성해야 합니다 (NIST의 RFC 9334 원격 증명 절차 (RATS) 아키텍처 사용).

이 문서에서는 odp-federatedcompute 저장소에서 결정적 빌드의 구현 및 지원을 살펴봅니다. ODP Aggregator 및 Model Updater 서비스는 Confidential Space 내에서 실행됩니다. 이 저장소는 프로덕션 사용 사례에 필요한 모든 서비스의 결정적 빌드를 지원합니다.

결정론적 빌드

결정적 빌드는 두 가지 주요 구성요소로 구성됩니다.

  1. 필수 바이너리 컴파일 여기에는 JAR, 공유 라이브러리, 메타데이터가 포함됩니다.
  2. 기본 이미지 및 런타임 종속 항목 컴파일된 바이너리를 실행하는 데 사용되는 런타임 환경의 기본 이미지입니다.

현재 ODP 연합 컴퓨팅 저장소는 다음 유형의 워크로드를 지원합니다.

  • Java + Spring 워크로드
    • TaskAssignment, TaskManagement, Collector
  • JNI 텐서플로 워크로드가 있는 Java + Spring
    • ModelUpdater, Aggregator
  • Python 워크로드
    • TaskBuilder

종속 항목

다음 목록은 ODP가 결정성과 가용성을 유지하는 데 사용하는 종속 항목입니다.

  • Bazel
  • GitHub
  • Maven
  • PyPi
  • Debian 스냅샷
  • DockerHub 레지스트리
  • Google Container Registry(GCR)

확정적 워크로드

모든 워크로드는 rules_oci를 사용하여 빌드된 언어별 도구 모음 및 컨테이너 이미지와 함께 Bazel을 사용하여 컴파일됩니다. WORKSPACE 파일은 해당 버전과 해시를 사용하여 모든 종속 항목을 정의합니다.

Debian 스냅샷

모든 워크로드 이미지는 Debian 스냅샷을 기반으로 빌드된 제공된 dockerfile 내에서 빌드해야 합니다. Debian 스냅샷은 다음과 같은 결정적 속성을 갖춘 안정적인 저장소 스냅샷을 제공합니다.

Java Spring 워크로드

Bazel의 remotejdk_17은 컴파일을 위해 hermetic Java를 제공하는 데 사용됩니다. 기타 Java 종속 항목은 WORKSPACE 파일에서 관리되고 정의됩니다.

Java Spring 워크로드는 <service>_application.jar라는 jar 파일로 컴파일됩니다. JAR에는 다음이 포함됩니다.

  • Java 클래스 파일
  • META-INF/
    • Bazel 매니페스트 데이터
  • build-data.properties
    • Bazel build-data
  • BOOT-INF/
    • rules_spring으로 생성된 패키지 jar 종속 항목입니다.

이미지 레이어

Java Spring 워크로드 이미지는 다음 두 레이어로 구성됩니다.

이미지 구성

  • 진입점
    • java -jar <service>_application.jar

JNI TensorFlow 워크로드

JNI Tensorflow 워크로드는 Java Spring 워크로드 위에 빌드됩니다. 기계어 코드를 컴파일하기 위해 Debian 스냅샷 이미지에서 제공하는 sysroot를 사용하여 사전 빌드된 Clang+LLVM 16을 사용하는 hermetic Clang+LLVM Bazel 도구 체인이 제공됩니다.

JNI 워크로드는 <service>_application.jar와 함께 libtensorflow.so라는 공유 라이브러리로 컴파일됩니다.

이미지 레이어

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은 hermetic 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>
    • runfiles를 사용하여 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 데몬을 마운트하고, 제공된 bash 명령어로 Docker를 실행합니다. bash 명령어 전에 전달된 변수는 docker run 플래그로 처리됩니다.
  • 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 아티팩트 레지스트리).