创建应用负载均衡器 (ALB)

本主题介绍如何使用 GKE on AWS 设置 AWS 应用负载均衡器 (ALB)。

准备工作

在开始使用 GKE on AWS 之前,请确保您已执行以下任务:

  • 有权为负载均衡器创建 AWS IAM 政策、角色和用户。
  • 安装管理服务
  • 创建用户集群。 如果您使用的是工作负载身份,请创建具有工作负载身份的用户集群
  • 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 on AWS 要求对包含 ALB 端点的子网进行标记。AWS on GKE 会自动标记在 AWSCluster 资源的 spec.Networking.ServiceLoadBalancerSubnetIDs 字段中指定的所有子网。

如果您将 GKE on AWS 安装到现有 VPC,或者想要使用其他子网,请将标记应用于两个或多个 AWS 可用区的子网。

在 GKE on AWS 上设置 ALB

在创建 ALB 之前,您可以通过设置 AWS IAM 权限并提供访问密钥来配置 GKE on AWS。

创建 AWS IAM 权限

如需为用户集群创建 ALB,您必须设置一个拥有创建和操作 ALB 权限的 AWS IAM 用户。

  1. 下载适用于 ALB Ingress 控制器的 IAM 政策。您可以在 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 命令行工具创建名为 ALBIngressControllerIAMPolicy 的 IAM 政策。

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

    响应中会显示 IAM 政策的 Amazon 资源名称 (ARN)。保存 ARN 供日后使用。

授予对负载均衡器的访问权限

在本部分中,您将用户政策与 AWS IAM 用户或具有已配置工作负载身份的 IAM 角色关联。

IAM 用户

  1. 使用 aws 工具为 ADB Ingress 控制器创建 IAM 用户。

    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 替换为您之前创建的 IAM 政策的 ARN。
  3. 为 ALB Ingress 控制器用户创建 AWS IAM 访问密钥。

    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. 使用访问密钥和 Secret 访问密钥在集群中创建 Secret。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
    

具有工作负载身份的角色

完成使用工作负载身份创建用户集群中的步骤。创建政策时,请使用 ALBIngressControllerIAMPolicy 的 ARN 作为 EXISTING_AWS_POLICY 的值。

配置集群

如需配置 ALB,您需要在用户集群中安装以下组件:

  1. 通过从 GitHub 安装清单来部署 Jetstack cert-manager。

    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. 从 GitHub 下载 AWS 负载均衡器控制器清单:

    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。将 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 IAM 用户时生成的 AWS 访问密钥
    • AWS_SECRET_ACCESS_KEY:创建 AWS IAM 用户时生成的 AWS Secret 访问密钥

    具有工作负载身份的角色

    修改文件 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:您的 AWS VPC 的 ID,例如 vpc-1234567890abc
    • LB_CONTROLLER_ROLE_ARN:AWSLBControllerRole 角色的 ARN
    • AWS_REGION:您的集群的 AWS 区域,例如 us-east-1
  4. 将控制器应用到您的集群。

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

    GKE on AWS 会安装 ALB Ingress 控制器。

创建 ALB

在本节中,您将创建一个提供游戏 2048 重制版的示例 ALB。

  1. 将以下 YAML 配置复制到名为 2048.yaml 的文件中。该配置会创建一个 Kubernetes Namespace、Service 和 Deployment。使用 Ingress 公开 Deployment。

    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 游戏。

后续步骤