אבטחת אספקת תוכנות

1. סקירה כללית

באמצעות Artifact Registry אפשר לאחסן סוגים שונים של ארטיפקטים, ליצור כמה מאגרים בפרויקט אחד ולשייך אזור ספציפי או מספר אזורים לכל מאגר. יש כמה מצבים של מאגרים. כל מצב משרת מטרה אחרת. בתרשים הבא מוצגת אחת מהדרכים השונות האפשריות לשימוש במאגרים במצבים שונים יחד. בדיאגרמה מוצג תהליך עבודה בשני פרויקטים ב-Google Cloud. בפרויקט פיתוח, מפתחים מפתחים אפליקציית Java. בפרויקט זמן ריצה נפרד, גרסת build אחרת יוצרת קובץ אימג' של קונטיינר עם האפליקציה לפריסה ב-Google Kubernetes Engine.

5af5e4da3ccfdff3.png

בשיעור ה-Lab הזה תלמדו איך לבצע את המשימות הבאות.

  • להשתמש ב-Standard Repositories לפריסת חבילות פרטיות
  • שימוש במאגרים מרוחקים כדי לשמור חבילות מרכזיות ב-maven
  • שימוש במאגרים וירטואליים כדי לשלב כמה מאגרים ב-upstream בהגדרה אחת

הגדרת סביבה בקצב אישי

  1. נכנסים למסוף Google Cloud ויוצרים פרויקט חדש או עושים שימוש חוזר בפרויקט קיים. אם אין לכם עדיין חשבון Gmail או חשבון Google Workspace, עליכם ליצור חשבון.

b35bf95b8bf3d5d8.png

a99b7ace416376c4.png

bd84a6d3004737c5.png

  • Project name הוא השם המוצג של המשתתפים בפרויקט. זו מחרוזת תווים שלא משמשת את Google APIs. אפשר לעדכן אותו בכל שלב.
  • Project ID הוא ייחודי בכל הפרויקטים ב-Google Cloud ואי אפשר לשנות אותו (אי אפשר לשנות אותו אחרי שמגדירים אותו). מסוף Cloud יוצר מחרוזת ייחודית באופן אוטומטי; בדרך כלל לא מעניין אותך מה זה. ברוב ה-Codelabs תצטרכו להפנות אל מזהה הפרויקט (בדרך כלל הוא מזוהה כ-PROJECT_ID). אם המזהה שנוצר לא מוצא חן בעיניך, יש לך אפשרות ליצור מזהה אקראי אחר. לחלופין, אפשר לנסות תבנית משלך ולבדוק אם היא זמינה. לא ניתן לשנות אותו אחרי השלב הזה, והוא יישאר למשך הפרויקט.
  • לידיעתך, יש ערך שלישי – Project Number (מספר פרויקט), שחלק מממשקי ה-API משתמשים בו. מידע נוסף על כל שלושת הערכים האלה זמין במסמכי התיעוד.
  1. בשלב הבא צריך להפעיל את החיוב במסוף Cloud כדי להשתמש במשאבים או בממשקי API של Cloud. מעבר ב-Codelab הזה לא אמור לעלות הרבה, אם בכלל. כדי להשבית את המשאבים ולא לצבור חיובים מעבר למדריך הזה, אתם יכולים למחוק את המשאבים שיצרתם או למחוק את הפרויקט כולו. משתמשים חדשים ב-Google Cloud זכאים להצטרף לתוכנית תקופת ניסיון בחינם בשווי 1,200 ש"ח.

הגדרת Workspace

הגדרת gcloud

ב-Cloud Shell, מגדירים את מזהה הפרויקט ואת מספר הפרויקט. שומרים אותם כמשתנים מסוג PROJECT_ID ו-PROJECT_NUMBER.

export PROJECT_ID=$(gcloud config get-value project)
export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format='value(projectNumber)')

הפעלת ממשקי API

gcloud services enable artifactregistry.googleapis.com

שכפול המאגר

git clone https://github.com/GoogleCloudPlatform/java-docs-samples
cd java-docs-samples/container-registry/container-analysis

2. מאגרים רגילים

Standard Repositories מספק דרך לאחסן את החבילות הפרטיות שלכם ולשתף אותן באפליקציות אחרות

יצירת מאגר Maven

כדי ליצור מאגר ארטיפקטים של Java, מריצים את הפקודה הבאה ב-Cloud Shell:

gcloud artifacts repositories create container-dev-java-repo \
    --repository-format=maven \
    --location=us-central1 \
    --description="Java package repository for Container Dev Workshop"

אם מופיעה בקשת ההרשאה של Cloud Shell, לוחצים על Authorize (אישור).

נכנסים למסוף Google Cloud – Artifact Registry – Repositories, ושמים לב למאגר Maven החדש שיצרתם בשם container-dev-java-repo. אם תלחצו עליו הוא יהיה ריק כרגע.

gcloud artifacts repositories describe container-dev-java-repo \
    --location=us-central1

אמורה להחזיר תשובה שדומה לזו

Encryption: Google-managed key
Repository Size: 0.000MB
createTime: '2023-03-21T19:01:45.461589Z'
description: Java package repository for Container Dev Workshop
format: MAVEN
mavenConfig: {}
mode: STANDARD_REPOSITORY
name: projects/qwiklabs-gcp-03-4304110dc461/locations/us-central1/repositories/container-dev-java-repo
updateTime: '2023-03-21T19:01:45.461589Z'

הגדרת Maven ל-Artifact Registry

מריצים את הפקודה הבאה כדי להדפיס את תצורת המאגר כדי להוסיף אותה לפרויקט Java:

gcloud artifacts print-settings mvn \
    --repository=container-dev-java-repo \
    --location=us-central1

הפקודה הקודמת מחזירה קובץ xml שיתווסף לפרויקטים שלכם, pom.xml.

  • בקטע repositories מצוין איפה Maven יכול להוריד ארטיפקטים מרחוק לשימוש בפרויקט הנוכחי.
  • הקטע distributionManagement (ניהול הפצה) מציין לאיזה מאגר מרוחק הפרויקט יקדם את הפרויקט במהלך הפריסה.
  • בקטע extensions מתווסף ארטיפקטרג'יטרי-maven-wagon (ארטיפקטרגיה-MAven-wagon) שמאפשר את שכבת האימות וההעברה שנדרשת לחיבור ל-Artifact Registry
  • הערה: התוספים יכולים להיות קיימים בקובץ pom.xml או extensions.xml. במקרים שבהם הפרויקט תלוי בפרויקט הורה, מתבצעת גישה ליחסי התלות האלה לפני טעינת שאר הערכים בקובץ pom.xml. כדי לוודא שלהורה יש גישה לתוסף, אפשר למקם אותו בקובץ extensions.xml שנטען לפני pom.xml וכך הוא זמין ליחסי התלות של ההורה.

מעתיקים את שלושת הקטעים, פותחים את pom.xml ב-Cloud Shell Editor ומוסיפים את ההגדרות שהוחזרו לתחתית הקובץ, ממש בתוך התג project הסוגר.

טיפ: ב-cloudshell, מריצים את הפקודה הבאה בטרמינל כדי לפתוח את העורך בספרייה הנוכחית.

cloudshell workspace .

דוגמה: (שמות הפרויקטים יהיו שונים בכתובות ה-URL שלכם)

  ...

  <distributionManagement>
    <snapshotRepository>
      <id>artifact-registry</id>
      <url>artifactregistry://us-central1-maven.pkg.dev/qwiklabs-gcp-04-3c51830ea757/container-dev-java-repo</url>
    </snapshotRepository>
    <repository>
      <id>artifact-registry</id>
      <url>artifactregistry://us-central1-maven.pkg.dev/qwiklabs-gcp-04-3c51830ea757/container-dev-java-repo</url>
    </repository>
  </distributionManagement>

  <repositories>
    <repository>
      <id>artifact-registry</id>
      <url>artifactregistry://us-central1-maven.pkg.dev/qwiklabs-gcp-04-3c51830ea757/container-dev-java-repo</url>
      <releases>
        <enabled>true</enabled>
      </releases>
      <snapshots>
        <enabled>true</enabled>
      </snapshots>
    </repository>
  </repositories>

  <build>
    <extensions>
      <extension>
        <groupId>com.google.cloud.artifactregistry</groupId>
        <artifactId>artifactregistry-maven-wagon</artifactId>
        <version>2.2.0</version>
      </extension>
    </extensions>
  </build>

</project>

העלאת חבילת Java ל-Artifact Registry

כש-Artifact Registry מוגדר ב-Maven, אפשר עכשיו להשתמש ב-Artifact Registry כדי לאחסן צנצנות Java לשימוש בפרויקטים אחרים בארגון.

מריצים את הפקודה הבאה כדי להעלות את חבילת ה-Java ל-Artifact Registry:

mvn deploy -DskipTests

אם רוצים להריץ את הפקודה הזו שוב, צריך להגדיל את הגרסה בקובץ pom.xml.

בדיקה של חבילת Java ב-Artifact Registry

עוברים אל מסוף Cloud – Artifact Registry – מאגרים לוחצים על container-dev-java-repo ובודקים שהארטיפקט הבינארי hello-world נמצא שם:

147eac5168648db1.png

3. מאגרים מרוחקים

מאגרים מרוחקים מאפשרים לשמור חבילות של צד שלישי במטמון כדי לשפר את האמינות והאבטחה.

יצירת מאגר מרוחק

הערה: לקבלת פרטים על אימות והגדרה, אפשר לעיין במסמכי התיעוד של המוצר.

מ-Cloud Shell, מריצים את הפקודה הבאה כדי ליצור מאגר מרוחק עבור ארטיפקטים של Maven Central:

gcloud artifacts repositories create maven-central-cache \
    --project=$PROJECT_ID \
    --repository-format=maven \
    --location=us-central1 \
    --description="Remote repository for Maven Central caching" \
    --mode=remote-repository \
    --remote-repo-config-desc="Maven Central" \
    --remote-mvn-repo=MAVEN-CENTRAL

בדיקת המאגר במסוף

עוברים אל Cloud Console – Artifact Registry – Repositories לוחצים על maven-central-cache ומגלים שהוא נוצר וריק כרגע.

בדיקת המאגר בטרמינל

gcloud artifacts repositories describe maven-central-cache \
    --location=us-central1

שילוב המאגר בפרויקט

מריצים את הפקודה הבאה כדי להדפיס את תצורת המאגר כדי להוסיף אותה לפרויקט Java:

gcloud artifacts print-settings mvn \
    --repository=maven-central-cache \
    --location=us-central1

מוסיפים את הקטע של המאגר לקובץ pom.xml. אין להעתיק את <repositories> החיצוניים מהפלט.

משנים את המזהה של המאגר החדש שנוסף ל-'central'. כדי להבטיח שלכל רשומה במאגר יש מזהה ייחודי.

דוגמה: (שמות הפרויקטים יהיו שונים בכתובות ה-URL שלכם)

  ...

  <distributionManagement>
    <snapshotRepository>
      <id>artifact-registry</id>
      <url>artifactregistry://us-central1-maven.pkg.dev/qwiklabs-gcp-04-3c51830ea757/container-dev-java-repo</url>
    </snapshotRepository>
    <repository>
      <id>artifact-registry</id>
      <url>artifactregistry://us-central1-maven.pkg.dev/qwiklabs-gcp-04-3c51830ea757/container-dev-java-repo</url>
    </repository>
  </distributionManagement>

  <repositories>
    <repository>
      <id>artifact-registry</id>
      <url>artifactregistry://us-central1-maven.pkg.dev/qwiklabs-gcp-04-3c51830ea757/container-dev-java-repo</url>
      <releases>
        <enabled>true</enabled>
      </releases>
      <snapshots>
        <enabled>true</enabled>
      </snapshots>
    </repository>

    <repository>
      <id>central</id>
      <url>artifactregistry://us-central1-maven.pkg.dev/qwiklabs-gcp-04-3c51830ea757/maven-central-cache</url>
      <releases>
        <enabled>true</enabled>
      </releases>
      <snapshots>
        <enabled>true</enabled>
      </snapshots>
    </repository>


  </repositories>

  <build>
    <extensions>
      <extension>
        <groupId>com.google.cloud.artifactregistry</groupId>
        <artifactId>artifactregistry-maven-wagon</artifactId>
        <version>2.2.0</version>
      </extension>
    </extensions>
  </build>

</project>

מריצים את הפקודות הבאות בטרמינל כדי ליצור extensions.xml לפרויקט. כדי להשתמש במנגנון תוספי הליבה, מוודאים ש-Maven יכול לפתור יחסי תלות של הורה או פלאגין מ-Artifact Registry.

mkdir .mvn 
cat > .mvn/extensions.xml << EOF
<extensions xmlns="http://maven.apache.org/EXTENSIONS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/EXTENSIONS/1.0.0 http://maven.apache.org/xsd/core-extensions-1.0.0.xsd">
  <extension>
    <groupId>com.google.cloud.artifactregistry</groupId>
    <artifactId>artifactregistry-maven-wagon</artifactId>
    <version>2.2.0</version>
  </extension>
</extensions>
EOF

שליפת יחסי תלות מהמאגר המרוחק

מריצים את הפקודה הבאה כדי להדר את האפליקציה באמצעות המאגר המרוחק:

rm -rf ~/.m2/repository 
mvn compile

בדיקת החבילות במסוף

נכנסים אל מסוף Cloud – Artifact Registry – מאגרים לוחצים על maven-central-cache ובודקים שהארטיפקטים הבינאריים נשמרים במטמון:

9deea93caa5fefd7.png

4. מאגרים וירטואליים

מאגרים וירטואליים משמשים כממשק לכמה מאגרים שאפשר לגשת אליהם דרך הגדרה אחת. זה מפשט את הגדרת הלקוח לצרכני פריטי המידע שנוצרו בתהליך הפיתוח (Artifact) ומצמצם מתקפות של בלבול בגלל תלות.

יצירה של קובץ מדיניות

cat > ./policy.json << EOF
[
  {
    "id": "private",
    "repository": "projects/${PROJECT_ID}/locations/us-central1/repositories/container-dev-java-repo",
    "priority": 100
  },
  {
    "id": "central",
    "repository": "projects/${PROJECT_ID}/locations/us-central1/repositories/maven-central-cache",
    "priority": 80
  }
]

EOF

יוצרים את המאגר הווירטואלי

gcloud artifacts repositories create virtual-maven-repo \
    --project=${PROJECT_ID} \
    --repository-format=maven \
    --mode=virtual-repository \
    --location=us-central1 \
    --description="Virtual Maven Repo" \
    --upstream-policy-file=./policy.json

שילוב המאגר בפרויקט

מריצים את הפקודה הבאה כדי להדפיס את תצורת המאגר כדי להוסיף אותה לפרויקט Java:

gcloud artifacts print-settings mvn \
    --repository=virtual-maven-repo \
    --location=us-central1

מחליפים את כל הקטע של המאגרים בפום בקטע של המאגרים הווירטואליים היחידים מהפלט.

דוגמה: (שמות הפרויקטים יהיו שונים בכתובות ה-URL שלכם)

  ...


  <distributionManagement>
    <snapshotRepository>
      <id>artifact-registry</id>
      <url>artifactregistry://us-central1-maven.pkg.dev/qwiklabs-gcp-04-3c51830ea757/container-dev-java-repo</url>
    </snapshotRepository>
    <repository>
      <id>artifact-registry</id>
      <url>artifactregistry://us-central1-maven.pkg.dev/qwiklabs-gcp-04-3c51830ea757/container-dev-java-repo</url>
    </repository>
  </distributionManagement>

  <repositories>
    <repository>
      <id>artifact-registry</id>
      <url>artifactregistry://us-central1-maven.pkg.dev/qwiklabs-gcp-04-3c51830ea757/virtual-maven-repo</url>
      <releases>
        <enabled>true</enabled>
      </releases>
      <snapshots>
        <enabled>true</enabled>
      </snapshots>
    </repository>
  </repositories>

  <build>
    <extensions>
      <extension>
        <groupId>com.google.cloud.artifactregistry</groupId>
        <artifactId>artifactregistry-maven-wagon</artifactId>
        <version>2.2.0</version>
      </extension>
    </extensions>
  </build>

</project>


שליפת יחסי תלות מהמאגר הווירטואלי

מכיוון שמאגר וירטואלי הוא מעבר ולא יאחסן חבילות בפועל, כדי להדגים בבירור את התהליך, מוחקים את המאגר Maven-central-cache שיצרתם קודם ויצרתם אותו מחדש, כדי להתחיל שוב עם מאגר ריק.

מריצים את הפקודות הבאות כדי ליצור מחדש את מאגר המטמון

gcloud artifacts repositories delete maven-central-cache \
    --project=$PROJECT_ID \
    --location=us-central1 \
    --quiet

gcloud artifacts repositories create maven-central-cache \
    --project=$PROJECT_ID \
    --repository-format=maven \
    --location=us-central1 \
    --description="Remote repository for Maven Central caching" \
    --mode=remote-repository \
    --remote-repo-config-desc="Maven Central" \
    --remote-mvn-repo=MAVEN-CENTRAL

אפשר לבדוק את המאגר הריק במסוף. נכנסים אל מסוף Cloud – Artifact Registry – מאגרים

עכשיו נתרגל את המאגר הווירטואלי על ידי בניית הפרויקט באמצעות הפקודה הבאה

rm -rf ~/.m2/repository 
mvn compile

בדיקת החבילות במסוף

עוברים אל Cloud Console – Artifact Registry – מאגרים לוחצים על maven-central-cache ובודקים שהארטיפקטים הבינאריים הוגדרו לשליפה מהמאגר הווירטואלי, אבל בסופו של דבר נשלפו מהמאגר maven-central-cache:

9deea93caa5fefd7.png

5. מעולה!

כל הכבוד, סיימת את ה-Codelab!

מה נכלל

  • השתמשתם ב-Standard Repositories לפריסת החבילות הפרטיות שלכם.
  • שימוש במאגרים מרוחקים כדי לשמור חבילות מרכזיות ב-maven
  • השתמשו במאגרים וירטואליים כדי לשלב כמה מאגרים ב-upstream בהגדרה אחת

הסרת המשאבים

מריצים את הפקודה הבאה כדי למחוק את הפרויקט.

gcloud projects delete ${PROJECT_ID}

עדכון אחרון: 22.03.23