שימוש ב-Workload Identity עם AWS

Workload Identity מאפשרת להקצות זהויות והרשאות שונות ומפורטות לכל אפליקציה באשכול. הדרך המומלצת לאפליקציות שפועלות ב-GKE ב-AWS לגשת לשירותי AWS ו- Google Cloud היא באמצעות Workload Identity. מידע נוסף זמין במאמר זהות עומס עבודה.

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

יצירת ספק OIDC של AWS IAM לאשכול

כדי להשתמש ב-Workload Identity עם האשכול, קודם צריך ליצור ספק OIDC של AWS IAM שמפנה לאשכול. אם כבר יש לכם ספק IAM OIDC לאשכול, אתם יכולים לדלג על הקטע הזה.

כדי ליצור את הספק, פועלים לפי השלבים הבאים:

  1. קובעים את ה-URI של מנפיק OIDC עבור האשכול:

    gcloud container aws clusters describe CLUSTER_NAME \
         --location=GOOGLE_CLOUD_LOCATION \
         --format='value(workloadIdentityConfig.issuerUri)'
    

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

    • CLUSTER_NAME: השם של האשכול
    • GOOGLE_CLOUD_LOCATION: השם של המיקום שממנו ינוהל מאגר הצמתים הזה, כפי שמוגדר בGoogle Cloud אזורי ניהול Google Cloud

    הפלט כולל את ה-URI של מנפיק OIDC של האשכול. שומרים את הערך הזה לשלב הבא.

  2. בשלב הבא, יוצרים ספק OIDC של AWS IAM שמפנה אל האשכול באמצעות הפקודה הבאה:

    aws iam create-open-id-connect-provider \
        --url ISSUER_URI \
        --client-id-list sts.amazonaws.com \
        --thumbprint-list 08745487e891c19e3078c1f2a07e452950ef36f6
    

    מחליפים את ISSUER_URI ב-URI של המוסד המנפיק מהשלב הקודם.

    טביעת האצבע של שירות Google Cloud שמציג את ה-URI של המוסד המנפיק היא תמיד 08745487e891c19e3078c1f2a07e452950ef36f6.

הגדרת תפקיד AWS IAM עם מדיניות IAM מצורפת

כדי להגדיר תפקיד AWS IAM ולצרף אליו מדיניות, פועלים לפי השלבים הבאים:

  1. כדי לקבוע את מארח המנפיק, מסירים את הקידומת https:// מ-URI המנפיק. לדוגמה, אם ה-URI הוא https://oidc-provider.com/v1/projects/pid/locations/us-west1/awsClusters/awscluster, המארח הוא oidc-provider.com/v1/projects/pid/locations/us-west1/awsClusters/awscluster. שומרים את הערך הזה. תצטרכו אותו בהמשך.

  2. מריצים את הפקודה הבאה כדי לקבוע את שם המשאב של Amazon‏ (ARN) של הספק:

    aws iam list-open-id-connect-providers --output=text \
        --query 'OpenIDConnectProviderList[?ends_with(Arn, `ISSUER_HOST`) == `true`].Arn'
    

    מחליפים את ISSUER_HOST בשם המארח מ-URI המנפיק של האשכול.

  3. לאחר מכן, יוצרים מדיניות אמון כדי לספק פרטי כניסה של OIDC לחשבון השירות של Kubernetes. יוצרים קובץ בשם trust-policy.json עם התוכן הבא:

    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Principal": {
            "Federated": "PROVIDER_ARN"
          },
          "Action": "sts:AssumeRoleWithWebIdentity",
          "Condition": {
            "StringEquals": {
              "ISSUER_HOST:sub": "system:serviceaccount:NAMESPACE:KSA_NAME"
            }
          }
        }
      ]
    }
    

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

    • PROVIDER_ARN: ה-ARN של ספק ה-IAM OIDC של האשכול
    • ISSUER_HOST: שם המארח מתוך ה-URI של המנפיק עבור האשכול.
    • NAMESPACE: מרחב השמות של Kubernetes שבו האפליקציה פועלת
    • KSA_NAME: חשבון השירות של Kubernetes‏ (KSA) שבו האפליקציה תשתמש
  4. יוצרים תפקיד AWS IAM:

    aws iam create-role --role-name=AWS_ROLE_NAME \
        --assume-role-policy-document file://trust-policy.json
    

    מחליפים את AWS_ROLE_NAME בשם תפקיד ה-IAM ב-AWS של האפליקציה.

  5. מצרפים מדיניות AWS IAM לתפקיד:

    aws iam attach-role-policy --role-name=AWS_ROLE_NAME \
        --policy-arn=AWS_POLICY_ARN
    

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

    • AWS_ROLE_NAME: שם תפקיד ה-IAM ב-AWS של האפליקציה

    לדוגמה, כדי ליצור תפקיד בשם ec2-readonly עם מדיניות arn:aws:iam::aws:policy/AmazonEC2ReadOnlyAccess, מריצים את הפקודה הבאה:

    aws iam attach-role-policy --role-name=ec2-readonly \
        --policy-arn=arn:aws:iam::aws:policy/AmazonEC2ReadOnlyAccess
    

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

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

  1. קובעים את ה-ARN של התפקיד:

    aws iam get-role --role-name=AWS_ROLE_NAME --query 'Role.Arn'
    

    החלפה של AWS_ROLE_NAME.

  2. יוצרים מניפסט עבור מרחב שמות, KSA ו-Pod של Kubernetes. מעתיקים את המניפסט הבא לקובץ בשם workload-identity-test.yaml:

    apiVersion: v1
    kind: Namespace
    metadata:
      name: NAMESPACE
    ---
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: KSA_NAME
      namespace: NAMESPACE
    automountServiceAccountToken: false
    ---
    apiVersion: v1
    kind: Pod
    metadata:
      name: aws-cli-example
      namespace: NAMESPACE
    spec:
      serviceAccount: KSA_NAME
      containers:
      - name: aws-cli
        image: amazon/aws-cli:latest
        command:
        - /bin/bash
        - -c
        - "set -eu -o pipefail; while true; do aws ec2 describe-availability-zones; sleep 5; done"
        env:
        - name: AWS_ROLE_ARN
          value: AWS_ROLE_ARN
        - name: AWS_WEB_IDENTITY_TOKEN_FILE
          value: /var/run/secrets/aws-iam-token/serviceaccount/token
        - name: AWS_REGION
          value: AWS_REGION
        volumeMounts:
        - mountPath: /var/run/secrets/aws-iam-token/serviceaccount
          name: aws-iam-token
          readOnly: true
      volumes:
      - name: aws-iam-token
        projected:
          defaultMode: 420
          sources:
          - serviceAccountToken:
              audience: sts.amazonaws.com
              expirationSeconds: 86400
              path: token
    

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

    • NAMESPACE
    • KSA_NAME
    • AWS_ROLE_ARN: ה-ARN של תפקיד AWS IAM עבור האפליקציה
    • AWS_REGION: אזור AWS של האשכול
  3. החלת המניפסט:

    kubectl apply -f workload-identity-test.yaml
    

    ממתינים כמה דקות עד שה-Pod יופעל, ועוברים לקטע הבא.

אימות הפעולה של האפליקציה לדוגמה

כדי לוודא שלאפליקציית הדוגמה יש גישה ל-EC2 API, מעיינים ביומנים של ה-pod:

kubectl logs -f aws-cli-example -n NAMESPACE

אם ל-Pod יש גישה ל-EC2 API, הפלט כולל מידע על אזורי הזמינות של EC2 ונראה בערך כך:

-------------------------------------------------
|           DescribeAvailabilityZones           |
+-----------------------------------------------+
||              AvailabilityZones              ||
|+---------------------+-----------------------+|
||  GroupName          |  us-west-2            ||
||  NetworkBorderGroup |  us-west-2            ||
||  OptInStatus        |  opt-in-not-required  ||
||  RegionName         |  us-west-2            ||
||  State              |  available            ||
||  ZoneId             |  usw2-az1             ||
||  ZoneName           |  us-west-2a           ||
|+---------------------+-----------------------+|
||              AvailabilityZones              ||
|+---------------------+-----------------------+|
||  GroupName          |  us-west-2            ||
||  NetworkBorderGroup |  us-west-2            ||
||  OptInStatus        |  opt-in-not-required  ||
||  RegionName         |  us-west-2            ||
||  State              |  available            ||
||  ZoneId             |  usw2-az2             ||
||  ZoneName           |  us-west-2b           ||
|+---------------------+-----------------------+|
||              AvailabilityZones              ||
|+---------------------+-----------------------+|
||  GroupName          |  us-west-2            ||
||  NetworkBorderGroup |  us-west-2            ||
||  OptInStatus        |  opt-in-not-required  ||
||  RegionName         |  us-west-2            ||
||  State              |  available            ||
||  ZoneId             |  usw2-az3             ||
||  ZoneName           |  us-west-2c           ||
|+---------------------+-----------------------+|
||              AvailabilityZones              ||
|+---------------------+-----------------------+|
||  GroupName          |  us-west-2            ||
||  NetworkBorderGroup |  us-west-2            ||
||  OptInStatus        |  opt-in-not-required  ||
||  RegionName         |  us-west-2            ||
||  State              |  available            ||
||  ZoneId             |  usw2-az4             ||
||  ZoneName           |  us-west-2d           ||
|+---------------------+-----------------------+|

הסרת המשאבים

כדי להסיר את האפליקציה לדוגמה הזו:

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

    kubectl delete -f workload-identity-test.yaml
    
  2. מנתקים את מדיניות AWS IAM מהתפקיד:

    aws iam detach-role-policy --role-name AWS_ROLE_NAME \
        --policy-arn arn:aws:iam::aws:policy/AmazonEC2ReadOnlyAccess
    

    מחליפים את AWS_ROLE_NAME בשם תפקיד ה-IAM ב-AWS של האפליקציה.

  3. מוחקים את התפקיד ב-AWS IAM:

    aws iam delete-role --role-name AWS_ROLE_NAME
    

    מחליפים את AWS_ROLE_NAME בשם תפקיד ה-IAM ב-AWS של האפליקציה.

  4. מחיקת ספק OIDC של AWS IAM:

    aws iam delete-open-id-connect-provider --open-id-connect-provider-arn PROVIDER_ARN
    

    מחליפים את PROVIDER_ARN ב-ARN של ספק ה-OIDC של IAM עבור האשכול.

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