פריסת אפליקציה של שרת אינטרנט בקונטיינר

במדריך הזה מתואר איך להעלות אפליקציית קונטיינר בסביבת מכשיר עם פער אבטחה של Google Distributed Cloud ‏ (GDC), ולהריץ את האפליקציה בסביבת המכשיר. במדריך הזה נסביר איך ליצור פרויקטים ב-Harbor, להעלות תמונות ל-Harbor וליצור עומסי עבודה. עומס עבודה מבוסס-קונטיינר פועל במרחב שמות של פרויקט.

סביבת האפליקציות של GDC עם air gap כוללת מאגר Harbor שהוגדר מראש בשם tear-harbor בפרויקט GDC בשם tear. בדוגמה הזו נשתמש במאגר הזה.

במדריך הזה נעשה שימוש באפליקציית שרת אינטרנט לדוגמה שזמינה ב- Google CloudArtifact Registry.

מטרות

  • דחיפה של קובץ אימג' של קונטיינר למאגר Harbor המנוהל.
  • פורסים את אפליקציית הקונטיינר לדוגמה באשכול.

לפני שמתחילים

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

שליחת בקשה לתפקידי IAM

כדי לקבל את ההרשאות שדרושות לכם, אתם צריכים לבקש מאדמין ה-IAM של הפרויקט להקצות לכם את התפקידים הבאים במרחב השמות של הפרויקט, בהתאם למשימה שאתם רוצים לבצע:

  • Namespace Admin (namespace-admin): create, delete, edit, and view project resources. ההרשאה הזו נדרשת כדי לפרוס עומסי עבודה של קונטיינרים בפרויקט.

  • Harbor Instance Viewer (harbor-instance-viewer): צפייה במופע Harbor ובחירה שלו.

  • Harbor Project Creator (harbor-project-creator): יצירה של פרויקטים ב-Harbor וצפייה בהם.

הכנת הסביבה

  1. מוודאים שיש לכם פרויקט לניהול הפריסות של הקונטיינרים. אם אין לכם פרויקט, אתם יכולים ליצור פרויקט.

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

    export NAMESPACE=PROJECT_NAMESPACE
    
  3. מורידים ומתקינים את gdcloud CLI.

  4. נכנסים לאשכול Kubernetes ויוצרים את קובץ ה-kubeconfig שלו עם זהות משתמש. חשוב לוודא שהגדרתם את הנתיב של kubeconfig כמשתנה סביבה:

    export KUBECONFIG=CLUSTER_KUBECONFIG
    

יצירת פרויקט Harbor במאגר

‫GDC מספקת את Harbor כשירות (Harbor as a Service). זהו שירות מנוהל מלא שמאפשר לכם לאחסן ולנהל קובצי אימג' של קונטיינרים באמצעות Harbor.

כדי להשתמש ב-Harbor כשירות, צריך ליצור פרויקט Harbor בתוך מופע הרישום tear-harbor כדי לנהל את קובצי האימג' של הקונטיינרים:

  1. צריך את כתובת ה-URL של tear-harbor. מציינים את כתובת ה-URL של המכונה:

    gdcloud harbor instances describe tear-harbor --project=tear
    

    הפלט אמור להיראות כך: harbor-1.org-1.zone1.google.gdc.test.

  2. מגדירים את כתובת ה-URL של המופע כמשתנה לשימוש בהמשך המדריך:

    export INSTANCE_URL=INSTANCE_URL
    

    מזינים את כתובת ה-URL של המכונה בלי הקידומת https://.

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

  4. יוצרים את הפרויקט ב-Harbor:

    gdcloud harbor harbor-projects create HARBOR_PROJECT \
        --project=tear \
        --instance=tear-harbor
    

    מחליפים את HARBOR_PROJECT בשם של פרויקט Harbor שרוצים ליצור. אי אפשר ליצור את פרויקט Harbor במרחב שמות של פרויקט. חובה להשתמש בפרויקט tear.

  5. מגדירים את שם הפרויקט ב-Harbor כמשתנה כדי להשתמש בו בהמשך המדריך:

    export HARBOR_PROJECT=HARBOR_PROJECT
    

הגדרת Docker

כדי להשתמש ב-Docker במאגר Harbor, צריך לבצע את השלבים הבאים:

  1. הגדרת Docker כך שיסמוך על Harbor כשירות. מידע נוסף זמין במאמר הגדרת Docker כך שיסמוך על CA הבסיסי של Harbor.

  2. הגדרת אימות Docker ל-Harbor. מידע נוסף זמין במאמר בנושא הגדרת אימות Docker למופעי מאגר Harbor.

  3. מכיוון ש-tear-harbor הוא מאגר Harbor שהוגדר מראש, אתם צריכים לסמוך על האישור שנחתם על ידי רשות האישורים הפנימית של Google Distributed Cloud במודל Air-gapped:

    1. כדאי לבקש מה-IO את הפרטים הבאים:

      1. כתובת ה-URL החיצונית של אשכול Harbor.
      2. קובץ .crt של רשות האישורים (CA) הפנימית של Google Distributed Cloud במודל Air-gapped. הקובץ מאוחסן בדרך כלל במישור הבקרה כסוד בשם trust-store-internal-only במרחב השמות anthos-creds.
    2. בדומה לשלב הקודם, יוצרים תיקייה בשם של כתובת ה-URL החיצונית של אשכול Harbor ושומרים את הקובץ .crt בתוך התיקייה.

יצירת סוד למשיכת תמונות ב-Kubernetes

מכיוון שאתם משתמשים בפרויקט פרטי של Harbor, אתם צריכים ליצור סוד למשיכת תמונות של Kubernetes.

  1. מוסיפים חשבון רובוט של פרויקט Harbor. פועלים לפי השלבים בממשק המשתמש של Harbor כדי ליצור את חשבון הרובוט ולהעתיק את אסימון הסוד של הרובוט: https://goharbor.io/docs/2.8.0/working-with-projects/project-configuration/create-robot-accounts/#add-a-robot-account.

  2. שימו לב לשם החדש של חשבון הפרויקט של הרובוט, שמופיע בתחביר הבא:

    <PREFIX><PROJECT_NAME>+<ACCOUNT_NAME>
    

    לדוגמה, פורמט שם החשבון של פרויקט הרובוט דומה ל-harbor@library+artifact-account.

    מידע נוסף על איתור שם החשבון של פרויקט הרובוט ב-Harbor זמין במסמכי התיעוד של Harbor:‏ https://goharbor.io/docs/2.8.0/working-with-projects/project-configuration/create-robot-accounts/#view-project-robot-accounts.

  3. נכנסים ל-Docker באמצעות חשבון הרובוט של פרויקט Harbor ואסימון הסודי:

    docker login ${INSTANCE_URL}
    

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

  4. מגדירים שם שרירותי לסוד של משיכת התמונה:

    export SECRET=SECRET
    
  5. יוצרים את הסוד שנדרש לשליפת התמונה:

    kubectl create secret docker-registry ${SECRET}  \
        --from-file=.dockerconfigjson=DOCKER_CONFIG \
        -n NAMESPACE
    

    מחליפים את מה שכתוב בשדות הבאים:

    • DOCKER_CONFIG: הנתיב לקובץ .docker/config.json.
    • NAMESPACE: מרחב השמות של הסוד שיוצרים.

העברת קובץ אימג' של קונטיינר למאגר Harbor מנוהל

במדריך הזה תורידו את תמונת שרת האינטרנט nginx ותדחפו אותה למאגר Harbor המנוהל, ותשתמשו בה כדי לפרוס אפליקציית שרת אינטרנט לדוגמה של nginx לאשכול Kubernetes. אפליקציית שרת האינטרנט nginx זמינה מ- Google Cloud Artifact Registry הציבורי.

  1. שולפים את התמונה nginx מ- Google Cloud Artifact Registry אל תחנת העבודה המקומית באמצעות רשת חיצונית:

    docker pull gcr.io/cloud-marketplace/google/nginx:1.25
    
  2. הגדרת שם התמונה. הפורמט של שם תמונה מלא הוא:

    ${INSTANCE_URL}/${HARBOR_PROJECT}/nginx
    
  3. מתייגים את התמונה המקומית עם שם המאגר:

    docker tag gcr.io/cloud-marketplace/google/nginx:1.25 ${INSTANCE_URL}/${HARBOR_PROJECT}/nginx:1.25
    
  4. מעלים את קובץ האימג' של הקונטיינר nginx למאגר Harbor המנוהל:

    docker push ${INSTANCE_URL}/${HARBOR_PROJECT}/nginx:1.25
    

פריסת אפליקציית הקונטיינר לדוגמה

עכשיו אפשר לפרוס את קובץ אימג' של קונטיינר nginx באשכול המכשיר.

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

בקטע הזה, יוצרים Deployment Kubernetes כדי להריץ את אפליקציית nginx הקונטיינר באשכול. לפריסה הזו יש רפליקות או pods. פוד Deployment אחד מכיל רק קונטיינר אחד: קובץ האימג' של קונטיינר nginx. אפשר גם ליצור משאב Service שמספק ללקוחות דרך יציבה לשליחת בקשות אל הפודים של Deployment.

פורסים את שרת האינטרנט nginx:

  1. יוצרים ופורסים את המשאבים המותאמים אישית של Kubernetes‏ Deployment ו-Service:

    kubectl --kubeconfig ${KUBECONFIG} -n ${NAMESPACE} \
    create -f - <<EOF
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-deployment
      labels:
        app: nginx
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: nginx
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx
            image: ${INSTANCE_URL}/${HARBOR_PROJECT}/nginx:1.25
            ports:
            - containerPort: 80
          imagePullSecrets:
          - name: ${SECRET}
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: nginx-service
    spec:
      selector:
        app: nginx
      ports:
        - port: 80
          protocol: TCP
      type: LoadBalancer
    EOF
    
  2. בודקים שה-pods נוצרו על ידי הפריסה:

    kubectl get pods -l app=nginx -n ${NAMESPACE}
    

    הפלט אמור להיראות כך:

    NAME                                READY     STATUS    RESTARTS   AGE
    nginx-deployment-1882529037-6p4mt   1/1       Running   0          1h
    nginx-deployment-1882529037-p29za   1/1       Running   0          1h
    nginx-deployment-1882529037-s0cmt   1/1       Running   0          1h
    
  3. יוצרים מדיניות רשת שמאפשרת את כל תעבורת הנתונים ברשת אל מרחב השמות:

    kubectl --kubeconfig ${KUBECONFIG} -n ${NAMESPACE} \
    create -f - <<EOF
    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      annotations:
      name: allow-all
    spec:
      ingress:
      - from:
        - ipBlock:
            cidr: 0.0.0.0/0
      podSelector: {}
      policyTypes:
      - Ingress
    EOF
    
  4. מייצאים את כתובת ה-IP של שירות nginx:

      export IP=`kubectl --kubeconfig=${KUBECONFIG} get service nginx-service \
          -n ${NAMESPACE} -o jsonpath='{.status.loadBalancer.ingress[*].ip}'`
    
  5. בודקים את כתובת ה-IP של השרת nginx באמצעות curl:

      curl http://$IP
    

המאמרים הבאים