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

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

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

5af5e4da3ccfdff3.png

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

  • שימוש במאגרים רגילים לפריסת חבילות פרטיות
  • שימוש במאגרים מרוחקים כדי לשמור במטמון חבילות מרכזיות של Maven
  • שימוש במאגרי מידע וירטואליים כדי לשלב כמה מאגרי מידע של upstream בתצורה אחת

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

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

b35bf95b8bf3d5d8.pnga99b7ace416376c4.pngbd84a6d3004737c5.png

  • שם הפרויקט הוא השם המוצג למשתתפים בפרויקט. זו מחרוזת תווים שלא נמצאת בשימוש ב-Google APIs. אפשר לעדכן את המיקום הזה בכל שלב.
  • מזהה הפרויקט הוא ייחודי לכל הפרויקטים ב-Google Cloud ואי אפשר לשנות אותו אחרי שהוא מוגדר. מסוף Cloud יוצר באופן אוטומטי מחרוזת ייחודית, ובדרך כלל לא צריך לדעת מה היא. ברוב ה-Codelabs, תצטרכו להפנות למזהה הפרויקט (בדרך כלל הוא מזוהה כ-PROJECT_ID). אם אתם לא אוהבים את המזהה שנוצר, אתם יכולים ליצור מזהה אקראי אחר. אפשר גם לנסות שם משתמש משלכם ולבדוק אם הוא זמין. אי אפשר לשנות את ההגדרה הזו אחרי השלב הזה, והיא תישאר כזו למשך הפרויקט.
  • לידיעתכם, יש ערך שלישי, מספר פרויקט, שחלק מממשקי ה-API משתמשים בו. מידע נוסף על שלושת הערכים האלה מופיע במאמרי העזרה.
  1. בשלב הבא, תצטרכו להפעיל את החיוב במסוף Cloud כדי להשתמש במשאבי Cloud או בממשקי API של Cloud. העלות של התרגול הזה לא אמורה להיות גבוהה, ואולי לא תהיה עלות בכלל. כדי להשבית את המשאבים ולא לחייב אתכם אחרי שתסיימו את המדריך הזה, תוכלו למחוק את המשאבים שיצרתם או למחוק את כל הפרויקט. משתמשים חדשים ב-Google Cloud זכאים לתוכנית תקופת ניסיון בחינם בשווי 300$.

הגדרת 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 מאפשרים לאחסן חבילות פרטיות ולשתף אותן עם אפליקציות אחרות

יצירת מאגר Maven רגיל

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

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 יכול להוריד פריטי מידע שנוצרו בתהליך פיתוח (Artifact) מרחוק לשימוש בפרויקט הנוכחי.
  • בקטע distributionManagement מציינים לאיזה מאגר מרחוק הפרויקט יידחף כשהוא ייפרס.
  • בקטע extensions מתווסף artifactregistry-maven-wagon שמאפשר את שכבת האימות והתעבורה שנדרשת לחיבור אל Artifact Registry
  • הערה: תוספים יכולים להיות בקובץ pom.xml או בקובץ extensions.xml. במקרים שבהם הפרויקט תלוי בפרויקט אב, הגישה לתלות הזו מתבצעת לפני טעינת שאר הרשומות בקובץ pom.xml. כדי לוודא שהרכיב העליון יוכל לגשת לתוסף, אפשר להוסיף אותו לקובץ extensions.xml שנטען לפני קובץ pom.xml, וכך הוא יהיה זמין לתלות של הרכיב העליון.

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

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

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 כדי לאחסן קובצי JAR של Java לשימוש בפרויקטים אחרים בארגון.

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

mvn deploy -DskipTests

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

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

עוברים אל Cloud Console - Artifact Registry - Repositories. לוחצים על 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

מוסיפים את הקטע repository לקובץ 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 Console - Artifact Registry - Repositories לוחצים על maven-central-cache ומוודאים שפריטי המידע הבינאריים שנוצרו בתהליך הפיתוח (Artifact) מאוחסנים שם במטמון:

9deea93caa5fefd7.png

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

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

יצירת קובץ מדיניות

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

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

דוגמה: (שמות הפרויקטים שלכם יהיו שונים בכתובות ה-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 Console – Artifact Registry – Repositories

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

rm -rf ~/.m2/repository 
mvn compile

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

עוברים אל Cloud Console - Artifact Registry - Repositories. לוחצים על maven-central-cache ומוודאים שפריטי המידע הבינאריים נוצרו בתהליך הפיתוח (Artifact) הוגדרו למשיכה ממאגר וירטואלי, אבל בסופו של דבר נמשכו מ-maven-central-cache:

9deea93caa5fefd7.png

5. מעולה!

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

מה נכלל

  • השתמשתם במאגרי מידע רגילים לפריסת החבילות הפרטיות
  • השתמשתם במאגרים מרוחקים כדי לשמור במטמון חבילות מרכזיות של Maven
  • השתמשתם במאגרי מידע וירטואליים כדי לשלב כמה מאגרי מידע במעלה הזרם בהגדרה אחת

הסרת המשאבים

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

gcloud projects delete ${PROJECT_ID}

—

העדכון האחרון: 22 במרץ 2023