נדרשים build דטרמיניסטיים לאימות עומסי עבודה בסביבת מחשוב אמינה (TEE) של התאמה אישית במכשיר (ODP), שזמינה לציבור ב-Google Cloud כ-Confidential Space (CS).
התמונות של עומסי העבודה צריכות ליצור גיבוב תמונה דטרמיניסטי שאפשר להשתמש בו ב-CS לאימות עומסי עבודה (שמשתמש בארכיטקטורת הליכי אימות מרחוק (RATS) של NIST RFC 9334).
במסמך הזה נסביר על ההטמעה והתמיכה בבנייה דטרמיניסטית במאגר odp-federatedcompute. שירותי ODP Aggregator ו-Model Updater יפעלו בתוך Confidential Space. המאגר תומך בבנייה דטרמיניסטית של כל השירותים שלנו, שנדרשת לתרחישי שימוש בסביבת ייצור.
גרסאות build דטרמיניסטיות
הבנייה הדטרמיניסטית מורכבת משני רכיבים עיקריים:
- הידור של קובצי הבינארי הנדרשים. הנתונים האלה כוללים קובצי JAR, ספריות משותפות ומטא-נתונים.
- תמונת הבסיס ויחסי התלות בזמן הריצה. קובץ הבסיס של סביבת זמן הריצה שמשמש להרצת הקבצים הבינאריים שעברו קומפילציה.
נכון לעכשיו, מאגר המידע של ODP Federated Compute תומך בסוגי עומסי העבודה הבאים:
- עומסי עבודה של 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 עם שרשראות כלים ספציפיות לשפה וקובצי אימג' של קונטיינרים שנבנו באמצעות rules_oci. קובץ ה-WORKSPACE מגדיר את כל יחסי התלות עם הגרסאות והגיבובים התואמים.
תמונות מצב של Debian
כל תמונות עומסי העבודה צריכות להיבנות בתוך קובץ ה-Docker שסופק, על בסיס קובץ snapshot של Debian. תמונות מצב של Debian מספקות תמונת מצב יציבה של מאגר עם:
- כותרות וספריות של המערכת
- ארכיטקטורת המערכת
- linux_x86_64
- Debian
- קומפיילר C++
עומסי עבודה של Java Spring
remotejdk_17 של Bazel משמש כדי לספק Java הרמטית לקומפילציה. יחסי תלות אחרים של Java מנוהלים ומוגדרים בקובץ WORKSPACE.
עומסי העבודה של Java Spring עוברים קומפילציה לקובץ jar בשם <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 שסופק על ידי תמונת מצב של Debian כדי לקמפל קוד מכונה.
עומסי העבודה של JNI עוברים קומפילציה לספרייה משותפת בשם libtensorflow.so יחד עם <service>_application.jar.
שכבות תמונה
תמונת עומס העבודה של JNI tensorflow מורכבת מכמה שכבות:
- שכבת תמונת הבסיס
- תמונת בסיס של Java:
gcr.io/distroless/java17-debian11
- תמונת בסיס של Java:
- שכבות של יחסי תלות בחבילת Debian. השכבות נוצרות באמצעות ארכיונים של deb שהורדו מ-debian-snapshot ונארזו מחדש כשכבות של קובץ אימג'
libc++1-16_amd64.tarlibc++abi1-16_amd64.tarlibc6_amd64.tarlibunwind-16_amd64.tarlibgcc-s1_amd64.targcc-13-base_amd64.tar
- שכבת עומס העבודה
binary_tar.tar<service>_application.jarlibtensorflow-jni.solibaggregation-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
הכלל rules_python של Bazel משמש כדי לספק שרשרת כלים הרמטית של 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>- סקריפט 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 שנבנה על ידי dockerfile שסופק. כדי לעזור ליצור את קובצי האימג' הסופיים והדטרמיניסטיים, אנחנו מספקים שני סקריפטים.
- docker_run.sh
-
docker_run.shייצור את קובץ האימג' של Docker מ-Dockerfile, יטען את ספריית העבודה, יטען את דמון Docker של המארח ויריץ את Docker באמצעות פקודת ה-Bash שסופקה. כל המשתנים שמועברים לפני פקודת ה-bash ייחשבו כדגלים של docker run.
-
- build_images.sh
-
build_images.shיפעיל אתbazel buildלכל התמונות ויציג את הגיבובים של התמונות שנוצרו לכל תמונה שנבנתה.
-
יצירת כל התמונות
./scripts/docker/docker_run.sh "./scripts/build_images.sh"
אפשר למצוא את הגיבובים הצפויים של התמונות לכל מהדורה ב-GitHub של ODP-federatedcompute.
פרסום תמונות
הפרסום מוגדר באמצעות כללי oci_push של Bazel. לכל שירות, צריך להגדיר את מאגר היעד לכל האפשרויות הבאות:
- אתר אגרגטור
- תוכנת Collector
- 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.