This page shows how to use Kubernetes Ingress and Service objects to configure an external Application Load Balancer to use HTTP/2 for communication with backend services.
Overview
An Application Load Balancer acts as a proxy between your clients and your application. Clients can use HTTP/1.1 or HTTP/2 to communicate with the load balancer proxy. However, the connection from the load balancer proxy to your application uses HTTP/1.1 by default. If your application, running in a Google Kubernetes Engine (GKE) Pod, is capable of receiving HTTP/2 requests, you configure the external load balancer to use HTTP/2 when it forwards requests to your application.
In this exercise, you create a Deployment, a Service, and an Ingress. You put a
cloud.google.com/app-protocols
annotation in your Service manifest to specify
that the load balancer should use HTTP/2 to communicate with your application.
Then you call your service and verify that your application received an HTTP/2
request.
Before you begin
Before you start, make sure you have performed the following tasks:
- Enable the Google Kubernetes Engine API. Enable Google Kubernetes Engine API
- If you want to use the Google Cloud CLI for this task,
install and then
initialize the
gcloud CLI. If you previously installed the gcloud CLI, get the latest
version by running
gcloud components update
.
- Read about the Kubernetes Ingress and Service resources.
- Read about the HTTP/2 limitations for an external Application Load Balancer.
Create the Deployment
Copy the following manifest to a file named
my-deployment.yaml
:apiVersion: apps/v1 kind: Deployment metadata: name: echoheaders spec: replicas: 2 selector: matchLabels: app: echoheaders template: metadata: labels: app: echoheaders spec: containers: - name: echoheaders image: registry.k8s.io/echoserver:1.10 ports: - containerPort: 8443
This manifest describes a Deployment with two replicas of the
echoheaders
web application.Apply the manifest to your cluster:
kubectl apply -f my-deployment.yaml
Create the Service
Copy the following manifest to a file named
my-service.yaml
:apiVersion: v1 kind: Service metadata: annotations: cloud.google.com/app-protocols: '{"my-port":"HTTP2"}' name: echoheaders labels: app: echoheaders spec: type: NodePort ports: - port: 443 targetPort: 8443 protocol: TCP name: my-port selector: app: echoheaders
This manifest describes a Service with the following properties:
type: NodePort
: Specifies that this is a Service of type NodePort.app: echoheaders
: Specifies that any Pod that has this label is a member of the Service.cloud.google.com/app-protocols
: Specifies thatmy-port
should use the HTTP/2 protocol.port: 443
,protocol: TCP
, andtargetPort: 8433
: Specify that traffic directed to the Service on TCP port 443 should be routed to TCP port 8422 on one of the member Pods.
Apply the manifest to your cluster:
kubectl apply -f my-service.yaml
View the Service:
kubectl get service echoheaders --output yaml
The output is similar to the following:
apiVersion: v1 kind: Service metadata: annotations: cloud.google.com/app-protocols: '{"my-port":"HTTP2"}' ... labels: app: echoheaders name: echoheaders ... spec: clusterIP: 10.39.251.148 ... ports: - name: my-port nodePort: 30647 port: 443 protocol: TCP targetPort: 8443 selector: app: echoheaders ... type: NodePort ...
Create the Ingress
Copy the following manifest to a file named
my-ingress.yaml
:apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: echomap spec: defaultBackend: service: name: echoheaders port: number: 443
This manifest describes an Ingress that specifies that incoming requests are sent to a Pod that is a member of the
echoheaders
Service. Requests are routed to the Pod on thetargetPort
that is specified in theechoheaders
Service manifest. In this exercise, the PodtargetPort
is8443
.Apply the manifest to your cluster:
kubectl apply -f my-ingress.yaml
This command can take several minutes to complete while the Kubernetes Ingress controller configures the Application Load Balancer.
View the Ingress:
kubectl get ingress echomap --output yaml
The output is similar to the following:
kind: Ingress metadata: ... name: echomap ... spec: backend: serviceName: echoheaders servicePort: 443 status: loadBalancer: ingress: - ip: 203.0.113.2
In this output, the IP address of the Ingress is
203.0.113.2
.
Test the load balancer
gcloud
List your backend services:
gcloud compute backend-services list
Describe your backend service:
gcloud beta compute backend-services describe BACKEND_SERVICE_NAME --global
Replace
BACKEND_SERVICE_NAME
with the name of your backend service.The output specifies the
protocol
isHTTP2
:backends: ... description: '{...,"kubernetes.io/service-port":"443","x-features":["HTTP2"]}' ... kind: compute#backendService loadBalancingScheme: EXTERNAL protocol: HTTP2 ...
Console
Go to the Load balancing page in the Google Cloud console.
Under Name, locate your load balancer.
Click the name of your load balancer to view your backend service.
Verify that the Endpoint protocol for your backend service is HTTP/2.
Call your Service
Wait a few minutes for GKE to configure the load balancer and backend service, then enter the external IP address of your load balancer in your browser's address bar.
The output is similar to the following:
Hostname: echoheaders-7886d5bc68-xnrwj
...
Request Information:
...
method=GET
real path=/
query=
request_version=2
request_scheme=https
...
Request Headers:
...
x-forwarded-for=[YOUR_IP_ADDRESS], 203.0.113.2
x-forwarded-proto=http
...
This output information about the request from the load balancer to the Pod:
request_version=2
: Indicates that the request between the load balancer and the Pod used HTTP/2.x-forwarded-proto=http
: Indicates that the request between the browser and the load balancer used HTTP 1.1, not HTTP/2.
What's next
Configure a static IP address and domain name for your application using Ingress.
Configure SSL certificates for your Ingress load balancer.