---
title: Implement load balancer for gateway cluster
source: https://docs.newrelic.com/docs/new-relic-control/pipeline-control/gateway/aws-alb
---

This section provides instructions for implementing a load balancer for your gateway cluster using AWS services. Starting from setting up an AWS Elastic Kubernetes Service (EKS) cluster, the guide covers IAM configuration, deployment of the AWS Load Balancer Controller, installation of Pipeline Control, and validation steps.

To implement AWS ALB for your gateway cluster:

1.  [Set up EKS cluster](https://docs.newrelic.com/docs/new-relic-control/pipeline-control/aws-alb-for-gateway#eks-cluster)
2.  [Configure IAM roles and policies](https://docs.newrelic.com/docs/new-relic-control/pipeline-control/aws-alb-for-gateway#iam-access)
3.  [Connect EKS](https://docs.newrelic.com/docs/new-relic-control/pipeline-control/aws-alb-for-gateway#connect-eks)
4.  [Create IAM role for AWS ALB](https://docs.newrelic.com/docs/new-relic-control/pipeline-control/aws-alb-for-gateway#iam-role)
5.  [Create AWS ALB controller](https://docs.newrelic.com/docs/new-relic-control/pipeline-control/aws-alb-for-gateway#aws-alb)
6.  [Install Pipeline Control](https://docs.newrelic.com/docs/new-relic-control/pipeline-control/aws-alb-for-gateway#pipeline-control)
7.  [Validate AWS ALB](https://docs.newrelic.com/docs/new-relic-control/pipeline-control/aws-alb-for-gateway#validate)
8.  [Test and optimize load](https://docs.newrelic.com/docs/new-relic-control/pipeline-control/aws-alb-for-gateway#optimize)

## Set Up EKS cluster [#eks-cluster]

1.  **Log in to AWS**:

    -   Select the desired region for EKS deployment from the top-right corner dropdown.

2.  **Access Elastic Kubernetes Service (EKS)**:

    -   Search for **EKS** in the AWS search box and open the Elastic Kubernetes Service. This is where you will manage your Kubernetes clusters.

3.  **Create cluster**:

    -   Click **Create Cluster** and select the configuration options:
        -   Choose **Quick configuration (with EKS Auto Mode)** for streamlined setup.
        -   Provide necessary details: Name, Kubernetes version, Cluster IAM role, Node IAM role, VPC & Subnets. If roles are not ready, use "Create Recommended Role" suggested by AWS.
    -   Click **Create** to initiate cluster creation. This sets up the foundational infrastructure for your Kubernetes environment.
    -   After the cluster is created, set up access entries for the current user to manage permissions.

## Identity and access management (IAM) entries [#iam-access]

1.  **Create access entry**:

    -   Select your IAM principal Amazon Resource Name (ARN) to define who can access the cluster.
    -   Choose **Standard IAM Access** type for typical user permissions.
    -   Create the access entry to establish user access.

2.  **Add access policies**:

    -   Attach the following policies to the IAM Access Entry to grant necessary permissions:

        -   `AmazonEKSAdminPolicy`
        -   `AmazonEKSAutoNodePolicy`
        -   `AmazonEKSClusterAdminPolicy`
        -   `AmazonEKSEditPolicy`
        -   `AmazonEKSNetworkingClusterPolicy`
        -   `AmazonEKSNetworkingPolicy`
        -   `AmazonEKSViewPolicy`

## Connect EKS from terminal [#connect-eks]

1.  **Update kubeconfig**:

    -   Run the following command:

        ```bash
        aws eks update-kubeconfig --region ap-south-1 --name pcg-cluster
        ```

    -   This command configures your local Kubernetes client to interact with the EKS cluster.

2.  **Check namespaces**:

    -   Run the following command:

        ```bash
        kubectl get namespaces
        ```

    -   Verify that the namespaces are correctly set up, which is crucial for organizing resources within the cluster.

3.  **Associate IAM OIDC provider**:

    -   Run the following command:

        ```bash
        eksctl utils associate-iam-oidc-provider --region=ap-south-1 --cluster=pcg-cluster --approve
        ```

    -   This step is necessary for enabling IAM roles for service accounts, enhancing security and access control.

## Create IAM role for AWS ALB [#iam-role]

1.  **Download IAM policy for AWS ALB controller**:

    -   Run the following command to download the policy:

        ```bash
        curl -O https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/v2.11.0/docs/install/iam_policy.json
        ```

    -   This policy defines permissions for the AWS Load Balancer Controller.

2.  **Create IAM policy**:

    -   Run the following command to create the policy:

        ```bash
        aws iam create-policy \
        --policy-name AWSLoadBalancerControllerIAMPolicy \
        --policy-document file://iam_policy.json
        ```

    -   This creates a policy that can be attached to roles, allowing the controller to manage load balancers.

3.  **Create IAM service account**:

    -   Replace `my-cluster` with your cluster name and `111122223333` with your account ID, then run the following command:

        ```bash
        eksctl create iamserviceaccount \
        --cluster=my-cluster \
        --namespace=kube-system \
        --name=aws-load-balancer-controller \
        --role-name AmazonEKSLoadBalancerControllerRole \
        --attach-policy-arn=arn:aws:iam::111122223333:policy/AWSLoadBalancerControllerIAMPolicy \
        --approve
        ```

    -   This step links the IAM policy to a service account, enabling the controller to operate within the cluster.

## Create AWS ALB controller [#aws-alb]

1.  **Add Helm chart repository**:

    -   Run the following command to add the Helm chart repository:

        ```bash
        helm repo add eks https://aws.github.io/eks-charts
        ```

    -   This adds the repository containing the AWS Load Balancer Controller Helm chart.

2.  **Update local repo**:

    -   Run the following command to update your local Helm repository:

        ```bash
        helm repo update eks
        ```

    -   This ensures you have the latest version of the charts for deployment.

3.  **Install AWS ALB controller**:

    -   Run the following command to install the AWS Load Balancer Controller:

        ```bash
        helm install aws-load-balancer-controller eks/aws-load-balancer-controller \
        -n kube-system \
        --set clusterName=pcg-cluster \
        --set serviceAccount.create=false \
        --set serviceAccount.name=aws-load-balancer-controller \
        --set vpcId=<your-vpc-id> \
        --set region=<your-region>
        ```

    -   Replace `<your-vpc-id>` and `<your-region>` with your specific VPC ID and AWS region.

4.  **Verify installation**:

    -   Check the deployment status to ensure the controller is running correctly:

        ```bash
        kubectl get deployment -n kube-system aws-load-balancer-controller
        ```

    -   The output should show the controller as deployed and running.

5.  **Check chart version**:

    -   Verify the version of the installed Helm chart:

        ```bash
        helm list -n kube-system
        ```

    -   This ensures you are using the correct version of the AWS Load Balancer Controller.

## Install Pipeline Control [#pipeline-control]

1.  **Install Pipeline Control**:

    -   Use New Relic Integrations & Agents to deploy Pipeline Control within your Kubernetes cluster.
    -   Follow the specific instructions provided by New Relic for installation, ensuring it integrates with your existing setup.

2.  **Create AWS ALB ingress resources**:

    Create two separate ingress resources due to protocol limitations.
    **APM data ingress (HTTP1):**

    -   Handles New Relic APM agent traffic
    -   Configured for HTTP1 protocol

        ```bash
        kubectl -n newrelic apply -f apm-ingress.yaml
        ```

        ### Sample `apm-ingress.yaml`

        ```yaml
            apiVersion: networking.k8s.io/v1
            kind: Ingress
            metadata:
            name: gateway-alb
            namespace: newrelic
            labels:
                test: test
            annotations:
                #kubernetes.io/ingress.class: alb
                alb.ingress.kubernetes.io/tags: owning_team=pipeline-control,service=gateway-alb,environment=test

                # health check stuff
                alb.ingress.kubernetes.io/healthcheck-protocol: HTTP
                alb.ingress.kubernetes.io/healthcheck-port: '13133'
                alb.ingress.kubernetes.io/healthcheck-path: /health/status
                # pull target out of ALB after 10 seconds of throwing 503s
                alb.ingress.kubernetes.io/healthcheck-interval-seconds: '5'
                alb.ingress.kubernetes.io/unhealthy-threshold-count: '2'
                alb.ingress.kubernetes.io/healthcheck-timeout-seconds: '3'
                alb.ingress.kubernetes.io/healthy-threshold-count: '2'

                alb.ingress.kubernetes.io/subnets: subnet-09499a12728c84cc0,subnet-0985931c0c134e164,subnet-00adc734c06241fc0
                
                alb.ingress.kubernetes.io/scheme: internal
                # enables HTTP/2
                alb.ingress.kubernetes.io/load-balancer-attributes: "routing.http2.enabled=true,idle_timeout.timeout_seconds=60"
                # sets deregistration_delay.timeout_seconds=10 since we wait 10 seconds to pull V out of LB based on failing health checks
                alb.ingress.kubernetes.io/target-group-attributes: "deregistration_delay.timeout_seconds=10,slow_start.duration_seconds=30"
                alb.ingress.kubernetes.io/target-type: "ip"
                alb.ingress.kubernetes.io/backend-protocol: "HTTP"
                alb.ingress.kubernetes.io/backend-protocol-version: "HTTP1"
            spec:
            ingressClassName: alb
            rules:
            - http:
                paths:
                - path: /v1/logs
                    pathType: Prefix
                    backend:
                    service:
                        name: pipeline-control-gateway
                        port:
                        number: 4318
                - path: /v1/metrics
                    pathType: Prefix
                    backend:
                    service:
                        name: pipeline-control-gateway
                        port:
                        number: 4318
                - path: /v1/traces
                    pathType: Prefix
                    backend:
                    service:
                        name: pipeline-control-gateway
                        port:
                        number: 4318
                - backend:
                    service:
                        name: pipeline-control-gateway
                        port:
                        number: 8080
                    path: /
                    pathType: Prefix
        ```

        **OpenTelemetry data ingress (HTTP2/gRPC):**

        -   Handles OpenTelemetry agent traffic
        -   Configured for HTTP2/gRPC protocol

            ```bash
            kubectl -n newrelic apply -f otlp-ingress.yaml
            ```

        ### Sample `otlp-ingress.yaml`

        ````yaml
            apiVersion: networking.k8s.io/v1
            kind: Ingress
            metadata:
            name: gateway-alb-otlp
            namespace: newrelic
            labels:
                test: test
            annotations:
                #kubernetes.io/ingress.class: alb
                alb.ingress.kubernetes.io/tags: owning_team=pipeline-control,service=gateway-alb,environment=test

                # health check stuff
                alb.ingress.kubernetes.io/healthcheck-protocol: HTTP
                alb.ingress.kubernetes.io/healthcheck-port: '13133'
                alb.ingress.kubernetes.io/healthcheck-path: /health/status
                # pull target out of ALB after 10 seconds of throwing 503s
                alb.ingress.kubernetes.io/healthcheck-interval-seconds: '5'
                alb.ingress.kubernetes.io/unhealthy-threshold-count: '2'
                alb.ingress.kubernetes.io/healthcheck-timeout-seconds: '3'
                alb.ingress.kubernetes.io/healthy-threshold-count: '2'

                alb.ingress.kubernetes.io/subnets: subnet-09499a12728c84cc0,subnet-0985931c0c134e164,subnet-00adc734c06241fc0
                
                alb.ingress.kubernetes.io/scheme: internal
                # enables HTTP/2
                alb.ingress.kubernetes.io/load-balancer-attributes: "routing.http2.enabled=true,idle_timeout.timeout_seconds=60"
                alb.ingress.kubernetes.io/conditions: >
                [{"field": "http-header","httpHeaderConfig":{"httpHeaderName": "Content-Type", "values":["application/grpc*"]}}]
                # sets deregistration_delay.timeout_seconds=10 since we wait 10 seconds to pull V out of LB based on failing health checks
                alb.ingress.kubernetes.io/target-group-attributes: "deregistration_delay.timeout_seconds=10,slow_start.duration_seconds=30"
                alb.ingress.kubernetes.io/target-type: "ip"
                alb.ingress.kubernetes.io/backend-protocol: "HTTP"
                alb.ingress.kubernetes.io/backend-protocol-version: "HTTP2"
            spec:
            ingressClassName: alb
            rules:
            - http:
                paths:
                - path: /opentelemetry.proto.collector.logs.v1.LogsService/Export
                    pathType: Prefix
                    backend:
                    service:
                        name: pipeline-control-gateway
                        port:
                        number: 4317
                - path: /opentelemetry.proto.collector.metrics.v1.MetricsService/Export
                    pathType: Prefix
                    backend:
                    service:
                        name: pipeline-control-gateway
                        port:
                        number: 4317
                - path: /opentelemetry.proto.collector.trace.v1.TraceService/Export
                    pathType: Prefix
                    backend:
                    service:
                        name: pipeline-control-gateway
                        port:
                        number: 4317
                - backend:
                    service:
                        name: pipeline-control-gateway
                        port:
                        number: 8080
                    path: /
                    pathType: Prefix
        ```
        <Callout variant="tip">

        This approach is specific to AWS ALB. Other cloud providers may support a single ingress resource for multiple protocols.

        </Callout>
        ````

3.  **Check ingress resource**:

    -   Describe the ingress resource to verify its configuration:

        ```bash
        kubectl -n newrelic describe ingress gateway-alb
        ```

## Validate AWS ALB [#validate]

1.  **Navigate to EC2 > Load Balancers**:

    -   In the AWS Management Console, go to the EC2 service and select **Load Balancers**.
    -   Verify that the load balancer has been created and is correctly configured.

2.  **Check Listener Rules**:

    -   Review the listener rules to ensure they are set up to route traffic appropriately to your gateway instances.

## Test and optimize load [#optimize]

1.  **Test Traffic Distribution**:

    -   Conduct load testing to ensure the load balancer effectively distributes traffic across gateway instances.
    -   Monitor performance metrics to identify any bottlenecks or areas for optimization.

2.  **Optimize Configuration**:

    -   Adjust settings based on testing results to improve efficiency and reliability.

## Next step

Next, you'll learn about [setting up DNS and security certificates](https://docs.newrelic.com/docs/new-relic-control/pipeline-control/gateway/dns-certificate) for the AWS ALB.
