A new version of GKE on AWS was released on November 2. See the release notes for more information.

Creating an application load balancer (ALB)

This topic shows you how to set up an AWS Application Load Balancer (ALB) with GKE on AWS.

Before you begin

Before you start using GKE on AWS, make sure you have performed the following tasks:

  • Have permissions to create an AWS IAM user for the load balancer.
  • Install a management service.
  • Create a user cluster.
  • From your anthos-aws directory, use anthos-gke to switch context to your user cluster.
    cd anthos-aws
    env HTTP_PROXY=http://localhost:8118 \
    anthos-gke aws clusters get-credentials CLUSTER_NAME
  • Install the curl command-line tool or a similar tool.
  • Create or select subnets across two or more availability zones for your ALB.

Setting up ALB on GKE on AWS

Before you can create ALB, you configure ALB on GKE on AWS by setting up AWS IAM permissions and providing access keys to GKE on AWS.

Creating AWS IAM permissions

To create an ALB with GKE on AWS, you must set up an AWS IAM user with permissions to create and operate the ALB.

  1. Download an IAM policy for the ALB Ingress Controller. You can review the policy on GitHub.

    curl -o iam-policy.json https://raw.githubusercontent.com/kubernetes-sigs/aws-alb-ingress-controller/v1.1.8/docs/examples/iam-policy.json
    
  2. Use the aws tool to create an IAM policy named ALBIngressControllerIAMPolicy from the policy you downloaded.

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

    The response includes the Amazon Resource Name (ARN) of the IAM policy. Save the ARN for later use.

  3. Use the aws tool to create an IAM user for the ALB Ingress controller.

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

    Replace ALB_CONTROLLER_USER_NAME with the username you want to create for your ALB Ingress controller.

  4. Attach ALBIngressControllerIAMPolicy.

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

    Replace:

    • ALB_CONTROLLER_USER_NAME with the username you want to create for your ALB Ingress controller.
    • ALB_IAM_POLICY_ARN with the ARN of the IAM policy you created earlier.
  5. Create an AWS IAM access key for the ALB Ingress controller user.

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

    Replace ALB_CONTROLLER_USER_NAME with the username you want to create for your ALB Ingress controller.

    {
      "AccessKey": {
        "UserName": ALB_CONTROLLER_USER_NAME
        "AccessKeyId": "AKIAIOSFODNN7EXAMPLE",
        "Status": "Active",
        "SecretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
        "CreateDate": "2020-07-23T17:53:58Z"
      }
    }
    
  6. Save the access key and secret access key into environment variables. You will use these to configure GKE on AWS.

    ALB_ACCESS_KEY_ID=ACCESS_KEY_ID
    ALB_SECRET_ACCESS_KEY=SECRET_ACCESS_KEY
    

Configure GKE on AWS

To configure ALB on GKE on AWS, you save your AWS IAM credentials as a Kubernetes Secret.

  1. Create a Secret with the access key and secret access key pair. The ALB Ingress controller uses this Secret to authenticate to AWS and manage ALBs.

    env HTTP_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
    

Deploy ALB Ingress Controller

  1. Copy the following YAML into a file named aws-alb-ingress-controller.yaml.

    # Original from GitHub: https://github.com/kubernetes-sigs/aws-alb-ingress-controller
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        app.kubernetes.io/name: alb-ingress-controller
      name: alb-ingress-controller
      namespace: kube-system
    spec:
      selector:
        matchLabels:
          app.kubernetes.io/name: alb-ingress-controller
      template:
        metadata:
          labels:
            app.kubernetes.io/name: alb-ingress-controller
        spec:
          containers:
            - name: alb-ingress-controller
              args:
                - --ingress-class=alb
    
                # ID of your cluster. Used when naming resources created
                # by the ALB Ingress Controller, providing distinction between
                # clusters.
                - --cluster-name=CLUSTER_ID
    
                # AWS VPC ID this Ingress controller uses to create AWS resources.
                - --aws-vpc-id=AWS_VPC_ID
    
                # AWS region this Ingress controller operates in. Should match the region of your GKE on AWS cluster.
                - --aws-region=AWS_REGION
    
              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
    
              # Repository location of the ALB Ingress Controller.
              image: docker.io/amazon/aws-alb-ingress-controller:v1.1.8
          serviceAccountName: alb-ingress-controller
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
      labels:
        app.kubernetes.io/name: alb-ingress-controller
      name: alb-ingress-controller
    rules:
      - apiGroups:
          - ""
          - extensions
        resources:
          - configmaps
          - endpoints
          - events
          - ingresses
          - ingresses/status
          - services
          - pods/status
        verbs:
          - create
          - get
          - list
          - update
          - watch
          - patch
      - apiGroups:
          - ""
          - extensions
        resources:
          - nodes
          - pods
          - secrets
          - services
          - namespaces
        verbs:
          - get
          - list
          - watch
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      labels:
        app.kubernetes.io/name: alb-ingress-controller
      name: alb-ingress-controller
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: alb-ingress-controller
    subjects:
      - kind: ServiceAccount
        name: alb-ingress-controller
        namespace: kube-system
    ---
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      labels:
        app.kubernetes.io/name: alb-ingress-controller
      name: alb-ingress-controller
      namespace: kube-system
    

    Replace the following:

    • CLUSTER_ID with your GKE on AWS user cluster's name. For example, gke-abcdef12.

    • AWS_VPC_ID with the ID of your AWS VPC. For example, vpc-1234567890abc.

    • AWS_REGION with your user cluster's AWS region. For example, us-east-1.

    For more information on this configuration, see alb-ingress-controller in the aws-alb-ingress-controller GitHub repository.

  2. Apply the manifest to your cluster.

    env HTTP_PROXY=http://localhost:8118 \
      kubectl apply -f aws-alb-ingress-controller.yaml
    

Creating an ALB

In this section, you create an ALB that serves a remake of the game 2048.

  1. Copy the following YAML configuration into a file named 2048.yaml. The configuration creates a Kubernetes Namespace, Service, and Deployment. The Deployment is exposed using an 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. Use kubectl to apply the configuration to your cluster.

    env HTTP_PROXY=http://localhost:8118 \
    kubectl apply -f 2048.yaml
    
  3. Use kubectl to check the status of the Ingress resource.

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

    The status of your Ingress appears. The ADDRESS column contains the endpoint of your Ingress.

    NAME           HOSTS   ADDRESS                                                             PORTS   AGE
    2048-ingress   *       123456-2048game-2048ingr-6fa0-abcdefg.us-east-1.elb.amazonaws.com   80      2m19s
    
  4. Navigate to the ALB endpoint in a browser. For example: http://123456-2048game-2048ingr-6fa0-abcdefg.us-east-1.elb.amazonaws.com The 2048 game appears.