One place for hosting & domains


      Getting Started with Load Balancing on a Linode Kubernetes Engine (LKE) Cluster

      Updated by Linode Contributed by Linode

      The Linode Kubernetes Engine (LKE) is Linode’s managed Kubernetes service. When you deploy an LKE cluster, you receive a Kubernetes Master which runs your cluster’s control plane components, at no additional cost. The control plane includes Linode’s Cloud Controller Manager (CCM), which provides a way for your cluster to access additional Linode services. Linode’s CCM provides access to Linode’s load balancing service, Linode NodeBalancers.

      NodeBalancers provide your Kubernetes cluster with a reliable way of exposing resources to the public internet. The LKE control plane handles the creation and deletion of the NodeBalancer, and correctly identifies the resources, and their networking, that the NodeBalancer will route traffic to. Whenever a Kubernetes Service of the LoadBalancer type is created, your Kubernetes cluster will create a Linode NodeBalancer service with the help of the Linode CCM.


      Adding external Linode NodeBalancers to your LKE cluster will incur additional costs. See Linode’s Pricing page for details.


      All existing LKE clusters receive CCM updates automatically every two weeks when a new LKE release is deployed. See the LKE Changelog for information on the latest LKE release.


      The Linode Terraform K8s module also deploys a Kubernetes cluster with the Linode CCM installed by default. Any Kubernetes cluster with a Linode CCM installation can make use of Linode NodeBalancers in the ways described in this guide.

      In this Guide

      This guide will show you:

      Before You Begin

      This guide assumes you have a working Kubernetes cluster that was deployed using the Linode Kubernetes Engine (LKE). You can deploy a Kubernetes cluster using LKE in the following ways:

      Adding Linode NodeBalancers to your Kubernetes Cluster

      To add an external load balancer to your Kubernetes cluster you can add the example lines to a new configuration file, or more commonly, to a Service file. When the configuration is applied to your cluster, Linode NodeBalancers will be created, and added to your Kubernetes cluster. Your cluster will be accessible via a public IP address and the NodeBalancers will route external traffic to a Service running on healthy nodes in your cluster.


      Billing for Linode NodeBalancers begin as soon as the example configuration is successfully applied to your Kubernetes cluster.

        type: LoadBalancer
        - name: http
          port: 80
          protocol: TCP
          targetPort: 80
      • The spec.type of LoadBalancer is responsible for telling Kubernetes to create a Linode NodeBalancer.
      • The remaining lines provide port definitions for your Service’s Pods and maps an incoming port to a container’s targetPort.

      Viewing Linode NodeBalancer Details

      To view details about running NodeBalancers on your cluster:

      1. Get the services running on your cluster:

        kubectl get services

        You will see a similar output:

        NAME            TYPE           CLUSTER-IP      EXTERNAL-IP    PORT(S)        AGE
        kubernetes      ClusterIP      none           443/TCP        3h5m
        example-service LoadBalancer   80:30028/TCP   36m
        • Viewing the entry for the example-service, you can find your NodeBalancer’s public IP under the EXTERNAL-IP column.
        • The PORT(S) column displays the example-service incoming port and NodePort.
      2. View details about the example-service to retrieve information about the deployed NodeBalancers:

        kubectl describe service example-service
        Name:                     nginx-service
        Namespace:                default
        Labels:                   app=nginx
        Annotations:     4
        Selector:                 app=nginx
        Type:                     LoadBalancer
        LoadBalancer Ingress:
        Port:                     http  80/TCP
        TargetPort:               80/TCP
        NodePort:                 http  30028/TCP
        Endpoints:      ,,
        Session Affinity:         None
        External Traffic Policy:  Cluster

      Configuring your Linode NodeBalancers with Annotations

      The Linode CCM accepts annotations that configure the behavior and settings of your cluster’s underlying NodeBalancers.

      • The table below provides a list of all available annotation suffixes.
      • Each annotation must be prefixed with For example, the complete value for the throttle annotation is
      • Annotation values such as http are case-sensitive.

      Annotations Reference

      Annotation (suffix) Values Default Value Description
      throttle • integer
      0 disables the throttle
      20 The client connection throttle limits the number of new connections-per-second from the same client IP.
      default-protocol • string
      tcp, http, https
      tcp Specifies the protocol for the NodeBalancer to use.
      port-* A JSON object of port configurations
      For example:
      { "tls-secret-name": "prod-app-tls", "protocol": "https"})
      None • Specifies a NodeBalancer port to configure, i.e. port-443.

      • Ports 1-65534 are available for balancing.

      • The available port configurations are:

      "tls-secret-name" use this key to provide a Kubernetes secret name when setting up TLS termination for a service to be accessed over HTTPS. The secret type should be

      "protocol" specifies the protocol to use for this port, i.e. tcp, http, https. The default protocol is tcp, unless you provided a different configuration for the default-protocol annotation.

      check-type • string
      none, connection, http, http_body
      None • The type of health check to perform on Nodes to ensure that they are serving requests. The behavior for each check is the following:

      none no check is performed

      connection checks for a valid TCP handshake

      http checks for a 2xx or 3xx response code

      http_body checks for a specific string within the response body of the healthcheck URL. Use the check-body annotation to provide the string to use for the check.

      check-path string None The URL path that the NodeBalancer will use to check on the health of the back-end Nodes.
      check-body string None The string that must be present in the response body of the URL path used for health checks. You must have a check-type annotation configured for a http_body check.
      check-interval integer None The duration, in seconds, between health checks.
      check-timeout • integer
      • value between 130
      None Duration, in seconds, to wait for a health check to succeed before it is considered a failure.
      check-attempts • integer
      • value between 130
      None Number of health checks to perform before removing a back-end Node from service.
      check-passive boolean false When true, 5xx status codes will cause the health check to fail.
      preserve boolean false When true, deleting a LoadBalancer service does not delete the underlying NodeBalancer


      Configuring Linode NodeBalancers for TLS Encryption

      This section describes how to set up TLS termination on your Linode NodeBalancers so a Kubernetes Service can be accessed over HTTPS.

      Generating a TLS type Secret

      Kubernetes allows you to store sensitive information in a Secret object for use within your cluster. This is useful for storing things like passwords and API tokens. In this section, you will create a Kubernetes secret to store Transport Layer Security (TLS) certificates and keys that you will then use to configure TLS termination on your Linode NodeBalancers.

      In the context of the Linode CCM, Secrets are useful for storing Transport Layer Security (TLS) certificates and keys. The linode-loadbalancer-tls annotation requires TLS certificates and keys to be stored as Kubernetes Secrets with the type tls. Follow the steps in this section to create a Kubernetes TLS Secret.


      1. Generate a TLS key and certificate using a TLS toolkit like OpenSSL. Be sure to change the CN and O values to those of your own website domain.

        openssl req -newkey rsa:4096 
            -days 3650 
            -out tls.crt 
            -keyout tls.key 
            -subj "/"
      2. Create the secret using the create secret tls command. Ensure you substitute $SECRET_NAME for the name you’d like to give to your secret. This will be how you reference the secret in your Service manifest.

        kubectl create secret tls $SECRET_NAME --cert tls.crt --key tls.key
      3. You can check to make sure your Secret has been successfully stored by using describe:

        kubectl describe secret $SECRET_NAME

        You should see output like the following:

        kubectl describe secret docteamdemosite
        Name:         my-secret
        Namespace:    default
        tls.crt:  1164 bytes
        tls.key:  1704 bytes

        If your key is not formatted correctly you’ll receive an error stating that there is no PEM formatted data within the key file.

      Configuring TLS within a Service

      In order to use https you’ll need to instruct the Service to use the correct port using the required annotations. You can add the following code snippet to a Service file to enable TLS termination on your NodeBalancers:

 '{ "tls-secret-name": "example-secret", "protocol": "https" }'
      • The annotation configures the NodeBalancer’s default protocol.

      • specifies port 443 as the port to be configured. The value of this annotation is a JSON object designating the TLS secret name to use (example-secret) and the protocol to use for the port being configured (https).

      If you have multiple Secrets and ports for different environments (testing, staging, etc.), you can define more than one secret and port pair:

 '{ "tls-secret-name": "example-secret", "protocol": "https" }'
 '{ "tls-secret-name": "example-secret-staging", "protocol": "https" }'

      Configuring Session Affinity for Cluster Pods

      kube-proxy will always attempt to proxy traffic to a random backend Pod. To direct traffic to the same Pod, you can use the sessionAffinity mechanism. When set to clientIP, sessionAffinity will ensure that all traffic from the same IP will be directed to the same Pod. You can add the example lines to a Service configuration file to

        type: LoadBalancer
          app: example-app
        sessionAffinity: ClientIP
            timeoutSeconds: 100

      Removing Linode NodeBalancers from your Kubernetes Cluster

      To delete a NodeBalancer and the Service that it represents, you can use the Service manifest file you used to create the NodeBalancer. Simply use the delete command and supply your file name with the f flag:

      kubectl delete -f example-service.yaml

      Similarly, you can delete the Service by name:

      kubectl delete service example-service

      After deleting your service, its corresponding NodeBalancer will be removed from your Linode account.


      If your Service file used the preserve annotation, the underlying NodeBalancer will not be removed from your Linode account. See the annotations reference for details.

      This guide is published under a CC BY-ND 4.0 license.

      Source link