יצירת מאזן עומסים של אפליקציות (ALB)

במאמר הזה נסביר איך להגדיר מאזן עומסים של אפליקציות (ALB) ב-AWS עם GKE ב-AWS.

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

לפני שמתחילים להשתמש ב-GKE on AWS, חשוב לוודא שביצעתם את המשימות הבאות:

  • יש לכם הרשאות ליצור כללי מדיניות, תפקידים ומשתמשים ב-AWS IAM עבור איזון העומסים.
  • מתקינים שירות ניהול.
  • יוצרים אשכול משתמשים. אם אתם משתמשים ב-Workload Identity, צריך ליצור אשכול משתמשים עם Workload Identity.
  • בספריית anthos-aws, משתמשים ב-anthos-gke כדי להחליף הקשר לאשכול המשתמשים.
    cd anthos-aws
    env HTTPS_PROXY=http://localhost:8118 \
      anthos-gke aws clusters get-credentials CLUSTER_NAME
    מחליפים את CLUSTER_NAME בשם אשכול המשתמש.
  • מתקינים את כלי שורת הפקודה curl או כלי דומה.

תיוג של רשתות משנה

‫GKE ב-AWS דורש תגים ברשתות משנה שמכילות נקודות קצה של ALB. ‫GKE ב-AWS מתייג באופן אוטומטי את כל רשתות המשנה שצוינו בשדה spec.Networking.ServiceLoadBalancerSubnetIDs של משאב AWSCluster.

אם התקנתם GKE on AWS ב-VPC קיים, או אם אתם רוצים להשתמש בתתי-רשתות נוספות, צריך להחיל תגים על תתי-רשתות בשני אזורי זמינות של AWS או יותר.

הגדרה של ALB ב-GKE ב-AWS

כדי ליצור ALB, צריך להגדיר את GKE ב-AWS על ידי הגדרת הרשאות AWS IAM ומתן מפתחות גישה.

יצירת הרשאות AWS IAM

כדי ליצור ALB עבור אשכול המשתמשים, צריך להגדיר משתמש AWS IAM עם הרשאות ליצירה ולהפעלה של ה-ALB.

  1. הורדת מדיניות IAM עבור ALB Ingress Controller. אפשר לעיין במדיניות ב-GitHub.

    curl -o iam-policy.json https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.4.0/docs/install/iam_policy.json
    
  2. משתמשים בכלי aws של שורת הפקודה כדי ליצור מדיניות IAM בשם ALBIngressControllerIAMPolicy.

    aws iam create-policy \
      --policy-name ALBIngressControllerIAMPolicy \
      --policy-document file://iam-policy.json
    

    התשובה כוללת את שם המשאב של Amazon ‏ (ARN) של מדיניות IAM. שומרים את ה-ARN לשימוש מאוחר יותר.

הענקת גישה למאזן העומסים

בקטע הזה משייכים את מדיניות המשתמש למשתמש AWS IAM או לתפקיד IAM עם זהות עומס עבודה מוגדרת.

משתמש IAM

  1. משתמשים בכלי aws כדי ליצור משתמש IAM עבור בקר ה-ALB Ingress.

    aws iam create-user \
    --user-name ALB_CONTROLLER_USER_NAME
    

    מחליפים את ALB_CONTROLLER_USER_NAME בשם המשתמש שרוצים ליצור עבור בקר ALB Ingress.

  2. מצרפים את ALBIngressControllerIAMPolicy לשם המשתמש.

    aws iam attach-user-policy \
     --user-name ALB_CONTROLLER_USER_NAME \
     --policy-arn ALB_IAM_POLICY_ARN
    

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

    • ALB_CONTROLLER_USER_NAME בשם המשתמש שרוצים ליצור עבור בקר ALB Ingress.
    • ALB_IAM_POLICY_ARN עם ה-ARN של מדיניות IAM שיצרתם קודם.
  3. יוצרים מפתח גישה ל-AWS IAM עבור המשתמש של בקר הכניסה של ALB.

    aws iam create-access-key --user-name ALB_CONTROLLER_USER_NAME
    

    מחליפים את ALB_CONTROLLER_USER_NAME בשם המשתמש שרוצים ליצור עבור בקר ALB Ingress.

    כלי שורת הפקודה aws מדפיס את פרטי מפתח הגישה.

    {
      "AccessKey": {
        "UserName": ALB_CONTROLLER_USER_NAME
        "AccessKeyId": "AKIAIOSFODNN7EXAMPLE",
        "Status": "Active",
        "SecretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
        "CreateDate": "2020-07-23T17:53:58Z"
      }
    }
    
  4. שומרים את מפתח הגישה ואת מפתח הגישה הסודי במשתני סביבה. תשתמשו בהם כדי להגדיר את אשכול המשתמשים.

    ALB_ACCESS_KEY_ID=ACCESS_KEY_ID
    ALB_SECRET_ACCESS_KEY=SECRET_ACCESS_KEY
    
  5. יוצרים סוד באשכול עם מפתח הגישה ומפתח הגישה הסודי. בקר ה-ALB Ingress משתמש ב-Secret הזה כדי לבצע אימות ב-AWS ולנהל את ה-ALB.

    env HTTPS_PROXY=http://localhost:8118 \
      kubectl create secret generic alb-ingress-controller-creds \
      -n kube-system \
      --from-literal=access_key_id=$ALB_ACCESS_KEY_ID \
      --from-literal=secret_access_key=$ALB_SECRET_ACCESS_KEY
    

תפקיד עם Workload Identity

פועלים לפי ההוראות שבמאמר יצירת אשכול משתמשים עם זהות של עומס עבודה. כשיוצרים מדיניות, משתמשים ב-ARN של ALBIngressControllerIAMPolicy כערך של EXISTING_AWS_POLICY.

הגדרת האשכול

כדי להגדיר ALB, צריך להתקין את הרכיבים הבאים באשכול המשתמש:

  • ‫Jetstack cert-manager כדי ליצור ולנהל אישורי TLS למשאבי ה-ALB של האשכול.
  • AWS Load Balancer Controller להקצאה ולניהול של מאזני עומסים של אפליקציות (ALB).
  1. פורסים את Jetstack cert-manager על ידי התקנת המניפסט מ-GitHub.

    env HTTPS_PROXY=http://localhost:8118 \
      kubectl apply \
      --validate=false \
      -f https://github.com/jetstack/cert-manager/releases/download/v1.5.4/cert-manager.yaml
    
  2. מורידים את המניפסט של AWS Load Balancer Controller מ-GitHub:

    curl -Lo v2_4_0_full.yaml https://github.com/kubernetes-sigs/aws-load-balancer-controller/releases/download/v2.4.0/v2_4_0_full.yaml
    
  3. בוחרים אם משתמשים בתפקיד או במשתמש IAM עם זהות עומס עבודה.

    משתמש IAM

    עורכים את הקובץ v2_4_0_full.yaml ומחפשים את kind: Deployment. מחליפים את אובייקט הפריסה בגרסה ששיניתם.

    kind: Deployment
    metadata:
      labels:
        app.kubernetes.io/component: controller
        app.kubernetes.io/name: aws-load-balancer-controller
      name: aws-load-balancer-controller
      namespace: kube-system
    spec:
      replicas: 1
      selector:
      matchLabels:
        app.kubernetes.io/component: controller
        app.kubernetes.io/name: aws-load-balancer-controller
      template:
        metadata:
          labels:
            app.kubernetes.io/component: controller
            app.kubernetes.io/name: aws-load-balancer-controller
        spec:
          containers:
            - args:
              - --cluster-name=CLUSTER_UID
              - --aws-region=AWS_REGION
              - --aws-vpc-id=AWS_VPC_ID
              - --ingress-class=alb
              - --disable-restricted-sg-rules=true
            image: amazon/aws-alb-ingress-controller:v2.4.0
            env:
            - name: AWS_ACCESS_KEY_ID
              valueFrom:
                secretKeyRef:
                  name: alb-ingress-controller-creds
                  key: access_key_id
            - name: AWS_SECRET_ACCESS_KEY
              valueFrom:
                secretKeyRef:
                  name: alb-ingress-controller-creds
                  key: secret_access_key
            livenessProbe:
              failureThreshold: 2
              httpGet:
                path: /healthz
                port: 61779
                scheme: HTTP
              initialDelaySeconds: 30
              timeoutSeconds: 10
            name: controller
            ports:
            - containerPort: 9443
              name: webhook-server
              protocol: TCP
            resources:
              limits:
                cpu: 200m
                memory: 500Mi
              requests:
                cpu: 100m
                memory: 200Mi
            securityContext:
              allowPrivilegeEscalation: false
              readOnlyRootFilesystem: true
              runAsNonRoot: true
            volumeMounts:
            - mountPath: /tmp/k8s-webhook-server/serving-certs
              name: cert
              readOnly: true
          priorityClassName: system-cluster-critical
          securityContext:
            fsGroup: 1337
          serviceAccountName: aws-load-balancer-controller
          terminationGracePeriodSeconds: 10
          volumes:
          - name: cert
            secret:
              defaultMode: 420
              secretName: aws-load-balancer-webhook-tls
        ---
    

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

    • AWS_ACCESS_KEY_ID: מפתח הגישה ל-AWS שנוצר כשיוצרים משתמש AWS IAM
    • AWS_SECRET_ACCESS_KEY: מפתח הגישה הסודי של AWS שנוצר כשיוצרים משתמש AWS IAM

    תפקיד עם Workload Identity

    עורכים את הקובץ v2_4_0_full.yaml ומחפשים את kind: Deployment. מחליפים את כל האובייקט Deployment בגרסה הזו ששונתה:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        app.kubernetes.io/component: controller
        app.kubernetes.io/name: aws-load-balancer-controller
      name: aws-load-balancer-controller
      namespace: kube-system
    spec:
      replicas: 1
      selector:
        matchLabels:
          app.kubernetes.io/component: controller
          app.kubernetes.io/name: aws-load-balancer-controller
      template:
        metadata:
          labels:
            app.kubernetes.io/component: controller
            app.kubernetes.io/name: aws-load-balancer-controller
        spec:
          containers:
          - args:
            - --cluster-name=CLUSTER_UID
            - --aws-region=AWS_REGION
            - --aws-vpc-id=AWS_VPC_ID
            - --ingress-class=alb
            - --disable-restricted-sg-rules=true
            image: amazon/aws-alb-ingress-controller:v2.4.0
            env:
            - name: AWS_ROLE_ARN
              value: LB_CONTROLLER_ROLE_ARN
            - name: AWS_WEB_IDENTITY_TOKEN_FILE
              value: /var/run/secrets/aws-load-balancer-controller/serviceaccount/token
            livenessProbe:
              failureThreshold: 2
              httpGet:
                path: /healthz
                port: 61779
                scheme: HTTP
              initialDelaySeconds: 30
              timeoutSeconds: 10
            name: controller
            ports:
            - containerPort: 9443
              name: webhook-server
              protocol: TCP
            resources:
              limits:
                cpu: 200m
                memory: 500Mi
              requests:
                cpu: 100m
                memory: 200Mi
            securityContext:
              allowPrivilegeEscalation: false
              readOnlyRootFilesystem: true
              runAsNonRoot: true
            volumeMounts:
            - mountPath: /tmp/k8s-webhook-server/serving-certs
              name: cert
              readOnly: true
            - mountPath: /var/run/secrets/aws-load-balancer-controller/serviceaccount
              name: aws-iam-token
              readOnly: true
          priorityClassName: system-cluster-critical
          securityContext:
            fsGroup: 1337
          serviceAccountName: aws-load-balancer-controller
          terminationGracePeriodSeconds: 10
          volumes:
          - name: cert
            secret:
              defaultMode: 420
              secretName: aws-load-balancer-webhook-tls
          - name: aws-iam-token
            projected:
              defaultMode: 420
              sources:
              - serviceAccountToken:
                  audience: sts.amazonaws.com
                  expirationSeconds: 86400
                  path: token
    ---
    

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

    • CLUSTER_UID: מזהה ה-UID של האשכול. לדוגמה: bbc7d232-21f6-4bb1-90dd-4b064cf8ccf8
    • AWS_VPC_ID: המזהה של ה-VPC ב-AWS – לדוגמה, vpc-1234567890abc
    • LB_CONTROLLER_ROLE_ARN: ה-ARN של התפקיד AWSLBControllerRole
    • AWS_REGION: האזור ב-AWS שבו נמצא האשכול – לדוגמה, us-east-1
  4. מחילים את הבקר על האשכול.

    env HTTPS_PROXY=http://localhost:8118 \
      kubectl apply -f v2_4_0_full.yaml
    

    ‫GKE ב-AWS מתקין את בקר הכניסה של ALB.

יצירת ALB

בקטע הזה יוצרים דוגמה ל-ALB שמציג גרסה מחודשת של המשחק 2048.

  1. מעתיקים את הגדרות ה-YAML הבאות לקובץ בשם 2048.yaml. ההגדרה יוצרת מרחב שמות, שירות ופריסה של Kubernetes. הפריסה נחשפת באמצעות Ingress.

    apiVersion: v1
    kind: Namespace
    metadata:
      name: "2048-game"
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: "service-2048"
      namespace: "2048-game"
    spec:
      ports:
        - port: 80
          targetPort: 80
          protocol: TCP
      type: NodePort
      selector:
        app: "2048"
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: "2048-deployment"
      namespace: "2048-game"
    spec:
      selector:
        matchLabels:
          app: "2048"
      replicas: 5
      template:
        metadata:
          labels:
            app: "2048"
        spec:
          containers:
          - image: alexwhen/docker-2048
            imagePullPolicy: Always
            name: "2048"
            ports:
            - containerPort: 80
    ---
    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      name: "2048-ingress"
      namespace: "2048-game"
      annotations:
        kubernetes.io/ingress.class: alb
        alb.ingress.kubernetes.io/scheme: internet-facing
      labels:
        app: 2048-ingress
    spec:
      rules:
        - http:
            paths:
              - path: /*
                backend:
                  serviceName: "service-2048"
                  servicePort: 80
    
  2. משתמשים בפקודה kubectl כדי להחיל את ההגדרה על האשכול.

    env HTTPS_PROXY=http://localhost:8118 \
      kubectl apply -f 2048.yaml
    
  3. משתמשים ב-kubectl כדי לבדוק את הסטטוס של משאב ה-Ingress.

    env HTTPS_PROXY=http://localhost:8118 \
      kubectl get ingress -n 2048-game 2048-ingress
    

    יוצג הסטטוס של ה-Ingress. בעמודה ADDRESS מופיע נקודת הקצה של ה-Ingress.

    NAME           HOSTS   ADDRESS                                                             PORTS   AGE
    2048-ingress   *       123456-2048game-2048ingr-6fa0-abcdefg.us-east-1.elb.amazonaws.com   80      2m19s
    
  4. עוברים לנקודת הקצה של ה-ALB בדפדפן. לדוגמה: http://123456-2048game-2048ingr-6fa0-abcdefg.us-east-1.elb.amazonaws.com המשחק 2048 מופיע.

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