בדף הזה מוסבר איך ליצור ולפרסם את התמונה במאגר ב-Artifact Registry באמצעות crane ו-oras.
אפשר להגדיר את Config Sync כך שיסנכרן תמונות מ-OCI באמצעות Artifact Registry. כדי להשתמש בתכונה הזו, צריך להפעיל את ממשקי ה-API של RootSync ו-RepoSync.
מידע על Artifact Registry
Artifact Registry הוא שירות שמנוהל במלואו, עם תמיכה בקובצי אימג' לקונטיינרים ובארטיפקטים שאינם קונטיינרים. אנחנו ממליצים להשתמש ב-Artifact Registry לאחסון ולניהול של קובצי אימג' של קונטיינר ב- Cloud de Confiance by S3NS. יש הרבה כלים שאפשר להשתמש בהם כדי להעלות פריטי מידע שנוצרו בתהליך פיתוח (Artifact) אל Artifact Registry. לדוגמה, אתם יכולים להעביר בדחיפה קובץ אימג' של Docker או להשתמש בספריית go-containerregistry כדי לעבוד עם מאגרי קונטיינרים. בוחרים את הכלי שהכי מתאים לכם.
לפני שמתחילים
-
התקינו את ה-CLI של Google Cloud.
-
הגדירו שה-CLI של gcloud ישתמש בזהות המאוחדת שלכם.
-
כדי לאתחל את ה-CLI של gcloud, הריצו את הפקודה הבאה:
gcloud init -
יוצרים או בוחרים Cloud de Confiance פרויקט.
תפקידים שנדרשים כדי לבחור או ליצור פרויקט
- Select a project: כדי לבחור פרויקט לא צריך תפקיד IAM ספציפי – אפשר לבחור כל פרויקט שקיבלתם בו תפקיד.
-
יצירת פרויקט: כדי ליצור פרויקט, צריך את התפקיד Project Creator (
roles/resourcemanager.projectCreator), שכולל את ההרשאהresourcemanager.projects.create. איך מקצים תפקידים
-
יוצרים Cloud de Confiance פרויקט:
gcloud projects create PROJECT_ID
מחליפים את
PROJECT_IDבשם של פרויקט Cloud de Confiance שיוצרים. -
בוחרים את הפרויקט שיצרתם: Cloud de Confiance
gcloud config set project PROJECT_ID
מחליפים את
PROJECT_IDבשם הפרויקט ב- Cloud de Confiance .
מפעילים את ממשקי ה-API של GKE, סנכרון תצורות ו-Artifact Registry, אם אחד מהם עדיין לא מופעל:
תפקידים שנדרשים להפעלת ממשקי API
כדי להפעיל ממשקי API, צריך את ההרשאה
serviceusage.services.enable. אם יצרתם את הפרויקט, סביר להניח שכבר יש לכם את ההרשאה הזו דרך התפקיד 'בעלים' (roles/owner). אחרת, תוכלו לקבל את ההרשאה הזו דרך התפקיד 'אדמין בממשק Service Usage' (roles/serviceusage.serviceUsageAdmin). איך מקצים תפקידיםgcloud services enable container.googleapis.com
anthosconfigmanagement.googleapis.com artifactregistry.googleapis.com - ליצור אשכול שעומד בדרישות של סנכרון תצורות ופועלת בו הגרסה העדכנית של סנכרון תצורות, או לקבל גישה לאשכול כזה.
- מתקינים את
nomosCLI או משדרגים אותו לגרסה העדכנית. - (אופציונלי) אם רוצים להשתמש ב-Cosign כדי לאמת חתימות של תמונות OCI, צריך להתקין את הרכיבים הבאים:
עלויות
במסמך הזה משתמשים ברכיבים הבאים של Cloud de Confiance by S3NS, והשימוש בהם כרוך בתשלום:
יצירת מאגר Artifact Registry
בקטע הזה, יוצרים מאגר ב-Artifact Registry. מידע נוסף על יצירת מאגרי Artifact Registry זמין במאמר יצירת מאגרים.
יוצרים מאגר Artifact Registry:
gcloud artifacts repositories create AR_REPO_NAME \
--repository-format=docker \
--location=AR_REGION \
--description="Config Sync repo" \
--project=PROJECT_ID
מחליפים את מה שכתוב בשדות הבאים:
-
PROJECT_ID: מזהה הפרויקט של הארגון. -
AR_REPO_NAME: מזהה המאגר. -
AR_REGION: המיקום האזורי או הרב-אזורי של המאגר.
משתנים שנעשה בהם שימוש בקטעים הבאים:
-
FLEET_HOST_PROJECT_NUMBER: אם אתם משתמשים באיחוד זהויות של עומסי עבודה ב-GKE, זהה למספר הפרויקט שלPROJECT_ID. אם אתם משתמשים באיחוד שירותי אימות הזהות של עומסי עבודה ב-GKE, זהו מספר הפרויקט של ה-Fleet שהאשכול רשום בו. -
FLEET_HOST_PROJECT_ID: אם אתם משתמשים באיחוד זהויות של עומסי עבודה ל-GKE, הערך הזה זהה לערך שלPROJECT_ID. אם אתם משתמשים ב-Workload Identity Federation for GKE ב-Fleet, זהו מזהה הפרויקט של ה-Fleet שהאשכול רשום בו. -
KUBERNETES_SERVICEACCOUNT: חשבון השירות של Kubernetes בשביל ה-reconciler:- אם שם המאגר
RootSyncהואroot-sync, מוסיפיםroot-reconcilerלמאגרי הבסיס. אחרת, מוסיפים אתroot-reconciler-ROOT_SYNC_NAME. - עבור מאגרי מידע של מרחבי שמות, אם השם
RepoSyncהואrepo-sync, מוסיפיםns-reconciler-NAMESPACE. אחרת, מוסיפיםns-reconciler-NAMESPACE-REPO_SYNC_NAME-REPO_SYNC_NAME_LENGTHכאשרREPO_SYNC_NAME_LENGTHהוא מספר התווים ב-REPO_SYNC_NAME.
- אם שם המאגר
מתן הרשאת קריאה
מקצים את התפקיד 'קורא Artifact Registry' (roles/artifactregistry.reader) במאגר לחשבון השירות של Kubernetes:
gcloud artifacts repositories add-iam-policy-binding AR_REPO_NAME \
--location=AR_REGION \
--member="principal://iam.googleapis.com/projects/FLEET_HOST_PROJECT_NUMBER/locations/global/workloadIdentityPools/FLEET_HOST_PROJECT_ID.s3ns.svc.id.goog/subject/ns/config-management-system/sa/KUBERNETES_SERVICEACCOUNT" \
--role=roles/artifactregistry.reader \
--project=PROJECT_ID \
--condition=None
העברה בדחיפה של קובץ אימג' למאגר Artifact Registry
בקטע הזה, יוצרים תמונת OCI ומעבירים אותה בדחיפה ל-Artifact Registry.
יוצרים קובץ מניפסט
Namespace:cat <<EOF> test-namespace.yaml apiVersion: v1 kind: Namespace metadata: name: test EOFנכנסים ל-Artifact Registry:
gcloud auth configure-docker AR_REGION-docker.pkg.devאורזים את התמונה ומעבירים אותה בדחיפה ל-Artifact Registry:
craneהפקודות בקטע הזה משתמשות ב-
craneכדי ליצור אינטראקציה עם תמונות ומאגרי תמונות מרוחקים.יוצרים חבילה מהקובץ:
tar -cf test-namespace.tar test-namespace.yamlמתקינים את הכלי
crane.מעבירים את האימג' ל-Artifact Registry:
crane append -f test-namespace.tar -t AR_REGION-docker.pkg.dev/PROJECT_ID/AR_REPO_NAME/test-namespace:v1
orasהפקודות בקטע הזה משתמשות ב-
orasכדי ליצור אינטראקציה עם תמונות ומאגרי תמונות מרוחקים.יוצרים חבילה מהקובץ:
tar -czf test-namespace.tar.gz test-namespace.yamlמתקינים את הכלי
oras.מעבירים את האימג' ל-Artifact Registry:
oras push AR_REGION-docker.pkg.dev/PROJECT_ID/AR_REPO_NAME/test-namespace:v1 test-namespace.tar.gz
הגדרת סנכרון תצורות לסנכרון מהתמונה
בקטע הזה, יוצרים אובייקט RootSync ומגדירים את סנכרון תצורות לסנכרון מהתמונה של OCI.
יוצרים אובייקט
RootSyncעם שם ייחודי:cat <<EOF>> ROOT_SYNC_NAME.yaml apiVersion: configsync.gke.io/v1beta1 kind: RootSync metadata: name: ROOT_SYNC_NAME namespace: config-management-system spec: sourceFormat: unstructured sourceType: oci oci: image: AR_REGION-docker.pkg.dev/PROJECT_ID/AR_REPO_NAME/test-namespace:v1 dir: . auth: k8sserviceaccount EOFמחליפים את
ROOT_SYNC_NAMEבשם של אובייקטRootSync. השם צריך להיות ייחודי בקלאסטר, והאורך שלו לא יכול להיות יותר מ-26 תווים. רשימת האפשרויות המלאה להגדרת אובייקטים שלRootSyncמופיעה במאמר שדות שלRootSyncושלRepoSync.החלת אובייקט
RootSync:kubectl apply -f ROOT_SYNC_NAME.yamlמוודאים ש-Config Sync מסנכרן מהתמונה:
nomos status --contexts=$(kubectl config current-context)הפלט אמור להיראות כך:
Connecting to clusters... *publish-config-registry -------------------- <root>:root-sync-test AR_REGION-docker.pkg.dev/PROJECT_ID/AR_REPO_NAME/test-namespace:v1 SYNCED 05e6a6b77de7a62286387cfea833d45290105fe84383224938d7b3ab151a55a1 Managed resources: NAMESPACE NAME STATUS SOURCEHASH namespace/test Current 05e6a6bסיימתם לסנכרן תמונה עם האשכול.
(אופציונלי) אימות חתימות של מקור OCI
אפשר לאמת את האותנטיות של תמונות מקוריות של OCI לפני שההגדרות מוחלות על האשכולות. השיטה הזו משתמשת באובייקט ValidatingWebhookConfiguration ובשרת webhook לאימות כדי ליירט בקשות עדכון לאובייקטים RootSync ו-RepoSync. סנכרון תצורות מעדכן את האנוטציה configsync.gke.io/image-to-sync של אובייקטים מסוג RootSync ו-RepoSync אחרי שהוא מאחזר בהצלחה תקציר של תמונה חדשה. שרת ה-validating webhook משווה בין הערכים של האנוטציה הישנה לבין האנוטציה החדשה, ומריץ את האימות באמצעות כלי אימות כמו Cosign כשמזוהה שינוי.
הגדרת שרת לאימות חתימות
כדי לוודא שהמקורות של OCI אותנטיים, צריך שרת HTTP לאימות החתימות. אתם יכולים להשתמש בדוגמאות במאגר הדוגמאות של Config Sync או להשתמש בקובץ אימג' משלכם של Docker.
כדי להשתמש בדוגמה שסיפקנו, צריך לבצע את השלבים הבאים:
משכפלים את המאגר לדוגמה:
git clone https://github.com/GoogleCloudPlatform/anthos-config-management-samples/עוברים לספרייה שמכילה את הדוגמאות של שרת אימות החתימות:
cd anthos-config-management-samples/tree/main/pre-sync/oci-image-verification
כדי ליצור קובץ אימג' של Docker לשרת אימות החתימות ולהעביר אותו בדחיפה למרשם אימג'ים, מריצים את הפקודה הבאה:
docker build -t SIGNATURE_VERIFICATION_SERVER_IMAGE_URL:latest . && docker push SIGNATURE_VERIFICATION_SERVER_IMAGE_URL:latestמחליפים את
SIGNATURE_VERIFICATION_SERVER_IMAGE_URLבכתובת ה-URL של תמונת שרת אימות החתימה.
אימות לשירותים
כדי להגדיר את שרת אימות החתימה, צריך לבצע אימות ב-Artifact Registry, בלקוח Cosign ובשרת ה-webhook.
יוצרים מרחב שמות:
kubectl create ns signature-verificationכדי לבצע אימות ל-Artifact Registry באמצעות חשבון שירות של Kubernetes, מבצעים את השלבים הבאים:
יוצרים Kubernetes ServiceAccount במרחב השמות שיצרתם:
kubectl create sa signature-verification-sa -n signature-verificationמקצים את התפקיד 'קורא Artifact Registry' (
roles/artifactregistry.reader) במאגר לחשבון השירות של Kubernetes:gcloud artifacts repositories add-iam-policy-binding REPOSITORY_NAME \ --location=REPOSITORY_LOCATION \ --member="principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/PROJECT_ID.s3ns.svc.id.goog/subject/ns/signature-verification/sa/signature-verification-sa" \ --role=roles/artifactregistry.reader \ --project=PROJECT_ID \ --condition=Noneמחליפים את מה שכתוב בשדות הבאים:
-
REPOSITORY_NAME: השם של מאגר Artifact Registry שבו מאוחסנים תמונות OCI. -
REPOSITORY_LOCATION: המיקום של מאגר Artifact Registry. -
PROJECT_NUMBER: מספר הפרויקט. PROJECT_ID: מזהה הפרויקט.
-
כדי לבצע אימות ללקוח Cosign, פועלים לפי השלבים הבאים:
יוצרים זוג מפתחות Cosign. הפקודה הזו יוצרת מפתח ציבורי ומפתח פרטי:
cosign generate-key-pairמאחסנים את המפתח הציבורי ב-Kubernetes Secret במרחב השמות שיצרתם:
kubectl create secret generic cosign-key --from-file=cosign.pub -n signature-verification
כדי לאמת את שרת אימות החתימה:
כדי להצפין את התקשורת בתוך שרת אימות החתימה, צריך ליצור אישור TLS ומפתח פרטי באמצעות OpenSSL:
openssl req -nodes -x509 -sha256 -newkey rsa:4096 \ -keyout tls.key \ -out tls.crt \ -days 356 \ -subj "/CN=signature-verification-service.signature-verification.svc" \ -addext "subjectAltName = DNS:signature-verification-service,DNS:signature-verification-service.signature-verification.svc,DNS:signature-verification-service.signature-verification"שומרים את פרטי הכניסה שיצרתם ב-Kubernetes Secret:
kubectl create secret tls webhook-tls --cert=tls.crt --key=tls.key -n signature-verificationמקבלים את התוכן בקידוד base64 של
tls.cert. ההגדרה הזו נדרשת עבור אימות ההגדרות של ה-validating webhook שתיצרו בקטע הבא:cat tls.crt | base64 -w 0.
פריסת ה-webhook של אישור הבקשות
אפשר להשתמש בדוגמאות הבאות כדי ליצור פריסה לשרת אימות החתימה ולהגדיר webhook לאימות.
יוצרים פריסה לשרת אימות החתימה על ידי שמירת הקובץ הבא:
מחליפים את
SIGNATURE_VERIFICATION_SERVER_IMAGE_URLבכתובת ה-URL המלאה של תמונת השרת לאימות החתימה.החלת הפריסה על האשכול:
kubectl apply -f signature-verification-deployment.yaml -n signature-verificationיוצרים הגדרת webhook לאימות על ידי שמירת הקובץ הבא:
מחליפים את
CA_BUNDLEבתוכן בקידוד base64 מתוךtls.cert.החלת ההגדרות של ה-webhook לאימות על האשכול:
kubectl apply -f signature-verification-validatingwebhookconfiguration.yaml
בדיקת יומנים לאיתור שגיאות באימות תמונות
אחרי שמגדירים את שרת אימות התמונות, כל ניסיון לסנכרן תמונות OCI לא חתומות ייכשל.
כדי לבדוק אם יש שגיאות באימות החתימה, מציגים את היומנים משרת אימות החתימה על ידי הפעלת הפקודות הבאות:
בדיקת היומנים של
kubectl:kubectl logs deployment signature-verification-server -n signature-verificationשגיאות מ-
kubectlשקשורות לאימות חתימה נראות כך:main.go:69: error during command execution: no signatures foundבודקים את היומנים של סנכרון תצורות:
nomos statusשגיאות מ-Config Sync שקשורות לאימות חתימה נראות כך:
Error: KNV2002: admission webhook "imageverification.webhook.com" denied the request: Image validation failed: cosign verification failed: exit status 10, output: Error: no signatures found
אם לא מופיעות שגיאות, אפשר לוודא שהתמונה החתומה היא האובייקט שמסונכרן על ידי בדיקת ההגדרה של RootSync או RepoSync:
RootSync
kubectl get rootsync ROOTSYNC_NAME -n config-management-system -oyaml
מחליפים את ROOTSYNC_NAME בשם של RootSync.
RepoSync
kubectl get reposync REPOSYNC_NAME -n REPOSYNC_NAMESPACE -oyaml
מחליפים את מה שכתוב בשדות הבאים:
-
REPOSYNC_NAME: השם שלRepoSync. -
REPOSYNC_NAMESPACE: השם של מרחב השמות שמשויך ל-RepoSync.
ההערה configsync.gke.io/image-to-sync אמורה להופיע באובייקט RootSync או RepoSync. האנוטציה מכילה את כתובת ה-URL של תמונת ה-OCI המקורית ואת התקציר העדכני ביותר שאוחזר על ידי סנכרון תצורות.