Configuring a backend service through BackendConfig

This page shows you how to use a Kubernetes Ingress object to configure certain properties of a Google Cloud backend service (or BackendConfig). BackendConfig is a custom resource that holds configuration information for Google Cloud features.

Overview

In a GKE cluster, when you create a Kubernetes Ingress object, the GKE ingress controller "wakes up" and creates a Google Cloud HTTP(S) load balancer. The ingress controller configures the load balancer and also configures one or more backend services that are associated with the load balancer.

The configuration information for a backend service is held in a custom resource named BackendConfig.

To configure the properties of a backend service:

  1. Create a BackendConfig.
  2. Create a Service, and associate one of its ports with the BackendConfig.
  3. Create an Ingress, and associate the Ingress with the (Service, port) pair.

The exact properties you can configure depend on if you are using Ingress with Internal or External load balancing.

Configurable properties for the External HTTP(S) Load Balancer

Beginning with GKE version 1.11.3-gke.18, you can use an Ingress to configure these properties of a backend service:

Beginning with GKE version 1.15.3-gke.1, you can use an Ingress to configure these properties of a backend service:

Configurable properties for the Internal HTTP(S) Load Balancer

You can use a BackendConfig to configure an Internal HTTP(S) load balancer to use two additional features:

Before you begin

Before you start, make sure you have performed the following tasks:

Set up default gcloud settings using one of the following methods:

  • Using gcloud init, if you want to be walked through setting defaults.
  • Using gcloud config, to individually set your project ID, zone, and region.

Using gcloud init

  1. Run gcloud init and follow the directions:

    gcloud init

    If you are using SSH on a remote server, use the --console-only flag to prevent the command from launching a browser:

    gcloud init --console-only
  2. Follow the instructions to authorize gcloud to use your Google Cloud account.
  3. Create a new configuration or select an existing one.
  4. Choose a Google Cloud project.
  5. Choose a default Compute Engine zone.

Using gcloud config

  • Set your default project ID:
    gcloud config set project project-id
  • If you are working with zonal clusters, set your default compute zone:
    gcloud config set compute/zone compute-zone
  • If you are working with regional clusters, set your default compute region:
    gcloud config set compute/region compute-region
  • Update gcloud to the latest version:
    gcloud components update

Creating a Deployment

Before you create a BackendConfig and a Service, you need to create a Deployment. Here is a manifest for a Deployment:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-bsc-deployment
spec:
  selector:
    matchLabels:
      purpose: bsc-config-demo
  replicas: 2
  template:
    metadata:
      labels:
        purpose: bsc-config-demo
    spec:
      containers:
      - name: hello-app-container
        image: gcr.io/google-samples/hello-app:1.0

Copy the manifest to a file named my-bsc-deployment.yaml, and create the Deployment:

kubectl apply -f my-bsc-deployment.yaml

Creating a BackendConfig

Here's a manifest for a BackendConfig. The manifest specifies:

  • A timeout of 40 seconds.
  • A connection draining timeout of 60 seconds.
apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
  name: my-bsc-backendconfig
spec:
  timeoutSec: 40
  connectionDraining:
    drainingTimeoutSec: 60

Copy the manifest to a file named my-bsc-backendconfig.yaml, and create the BackendConfig:

kubectl apply -f my-bsc-backendconfig.yaml

Creating a Service

Here's a manifest for a Service:

apiVersion: v1
kind: Service
metadata:
  name: my-bsc-service
  labels:
    purpose: bsc-config-demo
  annotations:
    cloud.google.com/backend-config: '{"ports": {"80":"my-bsc-backendconfig"}}'
spec:
  type: NodePort
  selector:
    purpose: bsc-config-demo
  ports:
  - port: 80
    protocol: TCP
    targetPort: 8080

For the purpose of this exercise, these are the important things to note about your Service:

  • Any Pod that has the label purpose: bsc-config-demo is a member of the Service.

  • TCP port 80 of the Service is associated with a BackendConfig named my-bsc-backendconfig. The cloud.google.com/backend-config annotation specifies this.

  • A request sent to port 80 of the Service is forwarded to one of the member Pods on port 8080.

Save the manifest to a file named my-bsc-service.yaml, and create the Service:

kubectl apply -f my-bsc-service.yaml

Creating an Ingress

Here's a manifest for an Ingress:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: my-bsc-ingress
spec:
  rules:
  - http:
      paths:
      - path: /*
        backend:
          serviceName: my-bsc-service
          servicePort: 80

In the manifest, you can see that incoming requests are routed to port 80 of the Service named my-bsc-service.

Copy the manifest to a file named my-bsc-ingress.yaml, and create the Ingress:

kubectl apply -f my-bsc-ingress.yaml

Wait a few minutes for the ingress controller to configure an HTTP(S) load balancer and an associated backend service.

Viewing the backend service

You can view your backend service by using the get service command or by viewing the Ingress YAML file.

To view your backend service using the get service command:

  1. Run the following command:

    kubectl get service my-bsc-service
    
  2. Make a note of the node port value that shows in the output. For example, in the following output, the node port value is 30936.

    NAME             TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
    my-bsc-service   NodePort   10.83.15.111   none          80:30936/TCP   2m
    
  3. List the backend services in your Cloud project:

    gcloud compute backend-services list
    
  4. In the output, find the name of your backend service. It's the name that contains the node port of your Service. For example, if your node port is 30936, the name of your backend service would be similar to this:

    NAME
    ...
    k8s-be-30936--078bc860bb6f7a2f
    ...
    
  5. Describe your backend service:

    gcloud compute backend-services describe backend-service-name --global
    

    where backend-service-name is the name of your backend service.

    The output shows values for the properties that you configured:

    connectionDraining: drainingTimeoutSec: 60 ... timeoutSec: 40
    

You can also find the backend services from the Ingress YAML file. After you have set up the load balancer, the Ingress controller adds annotations with the namespace, service name, and service port.

To view your backend service using the Ingress YAML file:

  1. Open your Ingress YAML file.
  2. View the ingress.kubernetes.io/backends section. For example:

     ingress.kubernetes.io/backends: '{"k8s1-27fde173-default-my-bsc-service-80-8d4ca500":"HEALTHY","k8s1-27fde173-kube-system-default-http-backend-80-18dfe76c":"HEALTHY"}
    

    Where:

    • "k8s1-27fde173-default-my-bsc-service-80-8d4ca500":"HEALTHY" provides information about the backend service associated with the my-bsc-service Kubernetes Service.
      • k8s1-27fde173 is a hash used to describe the cluster.
      • default is the Kubernetes namespace.
      • HEALTHY indicates that the backend is healthy.
    • "k8s1-27fde173-kube-system-default-http-backend-80-18dfe76c":"HEALTHY" provides information about the backend service associated with the default backend (404-server).
      • k8s1-27fde173 is a hash used to describe the cluster.
      • kube-system is the namespace.
      • default-http-backend is the Kubernetes Service name.
      • 80 is the host port.
      • HEALTHY indicates that the backend is healthy.

Setting client IP affinity

You can use a BackendConfig to configure client IP affinity.

To do this exercise, you need a VPC-native cluster. Client IP affinity is useful only for Services that are backed by network endpoint groups, and network endpoint groups require a VPC-native cluster.

To set client IP affinity, set affinityType to "CLIENT_IP" in your BackendConfig manifest.

apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
  name: my-bsc-backendconfig
spec:
  timeoutSec: 40
  connectionDraining:
    drainingTimeoutSec: 60
  sessionAffinity:
    affinityType: "CLIENT_IP"

In your Service manifest, include the cloud.google.com/neg: '{"ingress": true}' annotation:

kind: Service
metadata:
  name: my-bsc-service
  labels:
    purpose: bsc-config-demo
  annotations:
    cloud.google.com/neg: '{"ingress": true}'
    cloud.google.com/backend-config: '{"ports": {"80":"my-bsc-backendconfig"}}'
...

Configure HTTP access logging

Ingress can log all HTTP requests from clients to Cloud Logging. Access logging can be enabled and disabled by using BackendConfig along with setting the access logging sampling rate.

To configure access logging, use the logging field in BackendConfig. Note that if your GKE version defaults to access logging "on", the logging field is not required to enable logging. Access logging defaults to "on" in all versions prior to GKE 1.18 but is exposed as a configurable field starting in 1.16.8-gke.10. For version support specifications, see the logging reference.

The following BackendConfig enables access logging and sets the sample rate to 50% of the HTTP requests for a given Ingress resource. sampleRate is an optional field, but if it is configured then enable: true must be set or else it will be interpreted as enable: false.

apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
  name: my-backendconfig
spec:
  logging:
    enable: true
    sampleRate: 0.5

You can use a BackendConfig to configure generated cookie affinity.

To do this exercise, you need a VPC-native cluster. Generated cookie affinity is useful only for Services that are backed by network endpoint groups, and network endpoint groups require a VPC-native cluster.

To set generated cookie affinity, set affinityType to "GENERATED_COOKIE" in your BackendConfig manifest. You can also use affinityCookieTtlSec to set the time period for the cookie.

sessionAffinity:
  affinityType: "GENERATED_COOKIE"
  affinityCookieTtlSec: 50

In your Service manifest, include the cloud.google.com/neg: '{"ingress": true}' annotation:

kind: Service
metadata:
  name: my-bsc-service
  labels:
    purpose: bsc-config-demo
  annotations:
    cloud.google.com/neg: '{"ingress": true}'
    cloud.google.com/backend-config: '{"ports": {"80":"my-bsc-backendconfig"}}'
...

Setting User-defined request headers

If you are using Ingress for external load balancing, you can use a BackendConfig to configure User-defined request headers.

To enable user-defined request headers, you specify a list of headers in the customRequestHeadersproperty of the BackendConfig resource. The load balancer adds the headers to the requests it forwards to the backends.

customRequestHeaders:
  headers:
  - "X-Client-Region:{client_region}"
  - "X-Client-City:{client_city}"
  - "X-Client-CityLatLong:{client_city_lat_long}"

In your Service manifest, include the cloud.google.com/neg: '{"ingress": true}' annotation:

kind: Service
metadata:
  name: my-bsc-service
  labels:
    purpose: bsc-config-demo
  annotations:
    cloud.google.com/neg: '{"ingress": true}'
    cloud.google.com/backend-config: '{"ports": {"80":"my-bsc-backendconfig"}}'
...

Cleaning up

After completing the exercises on this page, follow these steps to remove the resources to prevent unwanted charges incurring on your account:

Delete the Kubernetes objects that you created for this exercise:

kubectl delete ingress my-bsc-ingress
kubectl delete service my-bsc-service
kubectl delete backendconfig my-bsc-backendconfig
kubectl delete deployment my-bsc-deployment

What's next