アプリケーション ロードバランサ(ALB)の作成

このトピックでは、GKE on AWS で AWS アプリケーション ロードバランサ(ALB)を設定する方法について説明します。

始める前に

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 on AWS では、ALB エンドポイントを含むサブネット上にタグが必要です。GKE on AWS は、AWSCluster リソースの spec.Networking.ServiceLoadBalancerSubnetIDs フィールドで指定されたすべてのサブネットに自動的にタグを付けます。

GKE on AWS を既存の VPC にインストールした場合、または追加のサブネットを使用する場合は、2 つ以上の 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 ユーザー、または構成された Workload Identity がある IAM ロールのいずれかに関連付けます。

IAM ユーザー

  1. aws ツールを使用して、ALB 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 をクラスタに作成します。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 を使用したロール

Workload Identity を使用してユーザー クラスタを作成の手順を完了します。ポリシーを作成する場合は、EXISTING_AWS_POLICY の値に ALBIngressControllerIAMPolicy の ARN を使用します。

クラスタを構成する

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 ユーザーまたは Workload Identity を使用したロールを使用しているかどうかを選択します。

    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 シークレット アクセスキー

    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: 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 が作成されます。Deployment は 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 が表示されます。

次のステップ