Create a network load balancer

This page describes how to set up an L4 load balancer with an AWS Elastic Load Balancer (ELB) or a Network Load Balancer (NLB) endpoint.

For more information on the other types of load balancers that you can use with GKE on AWS, see Load balancer overview.

This page is for Networking specialists who want to install, configure, and support network equipment. To learn more about common roles and example tasks that we reference in Google Cloud content, see Common GKE Enterprise user roles and tasks.

Before you begin

Choose a load balancer type

GKE on AWS creates a Service load balancer as either an AWS Classic Elastic Load Balancer (Classic ELB) or NLB. By default, GKE on AWS creates a Classic ELB. To create an NLB, set the service.beta.kubernetes.io/aws-load-balancer-type annotation to nlb. For more information on the differences between load balancer types, see Load balancer types in the AWS documentation.

Choose an internet-facing or internal load balancer

Service load balancers can be either internet-facing (with a publicly resolvable DNS name) or internal (only accessible within your VPC).

By default, new load balancers are internet-facing. To create an internal load balancer, set the service.beta.kubernetes.io/aws-load-balancer-internal annotation to "true" in your manifest.

You cannot apply the aws-load-balancer-internal annotation to an existing Service. To change between internet-facing and internal configurations, you must delete and recreate the existing LoadBalancer.

Choose your subnets

When creating load balancers, AWS needs to know what subnets to place them in. By default, these subnets are automatically discovered from among the subnets in the VPC. This requires that subnets have specific tags. For details of subnet auto-discovery and tagging, see Load Balancer Subnets.

Alternately, you can specify load balancer subnets with an annotation, by adding the service.beta.kubernetes.io/aws-load-balancer-subnets annotation to the Service. The value for this annotation is a comma-separated list of subnet IDs or subnet names— for example subnet-012345678abcdef,subnet-abcdef123456789,subnet-123456789abcdef.

Create an example load balancer

You create a Service of type LoadBalancer by creating a deployment and exposing that deployment with a Service. In the following example, you create a sample load balancer.

  1. Create your deployment. Containers in this Deployment listen on port 50001. Save the following YAML to a file named my-deployment-50001.yaml:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: my-deployment-50001
    spec:
      selector:
        matchLabels:
          app: products
          department: sales
      replicas: 3
      template:
        metadata:
          labels:
            app: products
            department: sales
        spec:
          containers:
          - name: hello
            image: "gcr.io/google-samples/hello-app:2.0"
            env:
            - name: "PORT"
              value: "50001"
    
  2. Create the Deployment with kubectl apply:

    kubectl apply -f my-deployment-50001.yaml
    
  3. Verify that three Pods are running:

    kubectl get pods --selector=app=products
    
  4. Create a Service of type LoadBalancer for your deployment.

  5. Decide what type of load balancer you need:

    • An internet-facing Classic ELB
    • An internet-facing NLB
    • An internal Classic ELB
    • An internal NLB

    Choose the tab that matches your requirements and copy the manifest within it to a file named my-lb-service.yaml.

    Internet-facing Classic

    apiVersion: v1
    kind: Service
    metadata:
      name: my-lb-service
    spec:
      type: LoadBalancer
      selector:
        app: products
        department: sales
      ports:
      - protocol: TCP
        port: 60000
        targetPort: 50001
    

    Internet-facing NLB

    You create an NLB by setting the annotation service.beta.kubernetes.io/aws-load-balancer-type to nlb. The following YAML includes this annotation.

    apiVersion: v1
    kind: Service
    metadata:
      name: my-lb-service
      annotations:
        service.beta.kubernetes.io/aws-load-balancer-type: nlb
    spec:
      type: LoadBalancer
      selector:
        app: products
        department: sales
      ports:
      - protocol: TCP
        port: 60000
        targetPort: 50001
    

    Internal Classic

    You create an internal LoadBalancer by setting the annotation service.beta.kubernetes.io/aws-load-balancer-internal to "true". The following YAML includes this annotation.

    apiVersion: v1
    kind: Service
    metadata:
      name: my-lb-service
      annotations:
        service.beta.kubernetes.io/aws-load-balancer-internal: "true"
    spec:
      type: LoadBalancer
      selector:
        app: products
        department: sales
      ports:
      - protocol: TCP
        port: 60000
        targetPort: 50001
    

    Internal NLB

    You create an internal NLB by setting the annotations:

    • service.beta.kubernetes.io/aws-load-balancer-internal to "true"
    • service.beta.kubernetes.io/aws-load-balancer-type to nlb

    The following YAML includes both annotations.

    apiVersion: v1
    kind: Service
    metadata:
      name: my-lb-service
      annotations:
        service.beta.kubernetes.io/aws-load-balancer-internal: "true"
        service.beta.kubernetes.io/aws-load-balancer-type: nlb
    spec:
      type: LoadBalancer
      selector:
        app: products
        department: sales
      ports:
      - protocol: TCP
        port: 60000
        targetPort: 50001
    
  6. Create the Service with kubectl apply:

    kubectl apply -f my-lb-service.yaml
    
  7. View the Service's address with kubectl get service.

    kubectl get service my-lb-service
    

    The output will include a column EXTERNAL-IP with an address of the load balancer (either public or private depending how the load balancer was created).

  8. If you have created an internet-facing load balancer you can connect to the load balancer with curl using the following command:

    curl http://EXTERNAL_IP:60000
    

    Replace EXTERNAL_IP with the address from the EXTERNAL-IP column in the previous step.

The output resembles the following:

```none
Hello, world!
Version: 2.0.0
Hostname: my-deployment-50001-84b6dc5555-zmk7q
```

Cleaning up

To remove the Service and Deployment, use the kubectl delete command:

kubectl delete -f my-lb-service.yaml
kubectl delete -f my-deployment-50001.yaml

Next steps