Secure traffic for GKE Ingress

This page shows you how to secure and optimize traffic for Google Kubernetes Engine (GKE) Ingress. You can configure SSL certificates between the client and the load balancer, and secure traffic between the load balancer and your backend application. Before you continue, ensure that you're familiar with how GKE secures Ingress with HTTPS .

This page is for Networking specialists who design and architect the network for their organization and 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 user roles and tasks .

Secure and optimize traffic between client and load balancer

To accept HTTPS requests from your clients, the load balancer must have a certificate to prove its identity to your clients. The load balancer must also have a private key to complete the HTTPS handshake. To learn more about providing SSL certificates to an HTTP(S) load balancer, see Configuring TLS between the client and the load balancer .

Use Google-managed certificates

To configure one or more Google-managed SSL certificates and associate them with an Ingress, you need to:

  • Create one or more ManagedCertificate objects in the same namespace as the Ingress. You can specify up to 15 certificates for the load balancer
  • Associate the ManagedCertificate objects to an Ingress by adding the networking.gke.io/managed-certificates annotation to the Ingress. This annotation is a comma-separated list of ManagedCertificate objects.

Limitations

This section describes the limitations of Google-managed certificates. If you require self-managed certificates or if you already own SSL certificates that you would like to configure on your Ingress, see Setting up HTTPS (TLS) between client and load balancer .

  • Google-managed certificates are less flexible than certificates you obtain and manage yourself. Google-managed certificates support up to 100 non-wildcard domains. Unlike self-managed certificates, Google-managed certificates don't support wildcard domains.

  • The number and type of certificates supported by an Ingress are defined by the limits of Google-managed SSL certificates .

  • Updates on Google-managed certificates are not supported. For more information, see Manually updating a Google-managed certificate .

  • If the certificate is revoked directly with the Certificate Authority, Google does not automatically rotate the certificate. You must delete the ManagedCertificate and create a new one.

  • GKE Ingress does not support certificates managed by Certificate Manager. To use certificates managed by Certificate Manager, use the Gateway API .

Prerequisites

  • You must own the domain name. The domain name must be no longer than 63 characters. You can use any domain name registrar to obtain a domain name.

  • If you use a GKE Standard cluster, the HttpLoadBalancing add-on must be enabled.

  • Your Ingress manifest must include the kubernetes.io/ingress.class: "gce" annotation. The ingressClassName field is not supported.

  • You must apply Ingress and ManagedCertificate resources in the same project and namespace.

  • Create a reserved (static) external IP address . Reserving a static IP address ensures that it remains yours, even if you delete the Ingress. If you don't reserve an IP address, it might change, requiring you to reconfigure your domain's DNS records. Use Google Cloud CLI or the Google Cloud console to create a reserved IP address.

    gcloud

    To create a reserved IP address, run the following command:

     gcloud  
    compute  
    addresses  
    create  
     ADDRESS_NAME 
      
    --global 
    

    Replace ADDRESS_NAME with the name of the reserved IP address you are creating.

    To find the static IP address you created, run the following command:

     gcloud  
    compute  
    addresses  
    describe  
     ADDRESS_NAME 
      
    --global 
    

    The output is similar to the following:

     address: 203.0.113.32
    ... 
    

    Console

    To create a reserved IP address, perform the following steps:

    1. Go to the External IP addressespage in the Google Cloud console.

      Go to External IP addresses

    2. Specify a name for the IP address (for example, example-ip-address ).

    3. Specify if you want an IPv4or IPv6address.

    4. Select the Globaloption for Type.

    5. Click Reserve. The IP address is listed in the External Addresscolumn.

    Config Connector

    Note: This step requires Config Connector . Follow the installation instructions to install Config Connector on your cluster.

      apiVersion 
     : 
      
     compute.cnrm.cloud.google.com/v1beta1 
     kind 
     : 
      
     ComputeAddress 
     metadata 
     : 
      
     name 
     : 
      
     example-ip-address 
     spec 
     : 
      
     location 
     : 
      
     global 
     
    
    To deploy this manifest, download it to your machine as compute-address.yaml , and run:
     kubectl  
    apply  
    -f  
    compute-address.yaml 
    

Setting up a Google-managed certificate

  1. Create a ManagedCertificate object. This resource specifies the domains for the SSL certificate. Wildcard domains are not supported.

    The following manifest describes a ManagedCertificate object. Save the manifest as managed-cert.yaml .

      apiVersion 
     : 
      
     networking.gke.io/v1 
     kind 
     : 
      
     ManagedCertificate 
     metadata 
     : 
      
     name 
     : 
      
      FIRST_CERT_NAME 
     
     spec 
     : 
      
     domains 
     : 
      
     - 
      
      FIRST_DOMAIN 
     
     --- 
     apiVersion 
     : 
      
     networking.gke.io/v1 
     kind 
     : 
      
     ManagedCertificate 
     metadata 
     : 
      
     name 
     : 
      
      SECOND_CERT_NAME 
     
     spec 
     : 
      
     domains 
     : 
      
     - 
      
      SECOND_DOMAIN 
     
     
    

    Replace the following:

    • FIRST_CERT_NAME : the name of your first ManagedCertificate object.
    • FIRST_DOMAIN : the first domain that you own.
    • SECOND_CERT_NAME : the name of the second ManagedCertificate object.
    • SECOND_DOMAIN : the second domain that you own.

    The names of the ManagedCertificate objects are different from the names of the actual certificates that they create. You only need to know the names of the ManagedCertificate objects to use them in your Ingress.

  2. Apply the manifest to your cluster:

     kubectl  
    apply  
    -f  
    managed-cert.yaml 
    
  3. Follow the instructions to create a Deployment and a Service to expose your application to the internet.

  4. For this ManagedCertificate object to become Active , attach it to your Ingress by using the networking.gke.io/managed-certificates annotation, as in the following example. The ManagedCertificate does not have to already be Active for you to attach it to an Ingress.

       
     apiVersion 
     : 
      
     networking.k8s.io/v1 
      
     kind 
     : 
      
     Ingress 
      
     metadata 
     : 
      
     name 
     : 
      
     my-gmc-ingress 
      
     annotations 
     : 
      
     networking.gke.io/managed-certificates 
     : 
      
     " FIRST_CERT_NAME 
    , SECOND_CERT_NAME 
    " 
      
     spec 
     : 
      
     rules 
     : 
      
     - 
      
     host 
     : 
      
      FIRST_DOMAIN 
     
      
     http 
     : 
      
     paths 
     : 
      
     - 
      
     pathType 
     : 
      
     ImplementationSpecific 
      
     backend 
     : 
      
     service 
     : 
      
     name 
     : 
      
     my-mc-service 
      
     port 
     : 
      
     number 
     : 
      
     60001 
      
     - 
      
     host 
     : 
      
      SECOND_DOMAIN 
     
      
     http 
     : 
      
     paths 
     : 
      
     - 
      
     pathType 
     : 
      
     ImplementationSpecific 
      
     backend 
     : 
      
     service 
     : 
      
     name 
     : 
      
     my-mc-service 
      
     port 
     : 
      
     number 
     : 
      
     60002 
      
     ``` 
     Replace <code><var>FIRST_DOMAIN</var></code> and 
    < code><var>SECOND_DOMAIN</var></code> with your domain names. 
     This manifest describes an Ingress that lists pre-shared certificate 
     resources in an annotation. 
     Note 
     : 
      
     It might take several hours for Google Cloud to provision the load 
     balancer and the managed certificates, and for the load balancer to begin 
     using the new certificates. For more information, see 
     [ 
     Deploy a Google-managed certificate with load balancer authorization 
     ] 
     (/certificate-manager/docs/deploy-google-managed-lb-auth#wait_until_the_certificate_has_been_activated). 
     
    
  5. Wait for the Google-managed certificates to finish provisioning. This might take up to 60 minutes. You can check the status of the certificates using the following command:

     kubectl  
    describe  
    managedcertificate  
    managed-cert 
    

    The output is similar to the following:

     Name:         managed-cert
    Namespace:    default
    Labels:       <none>
    Annotations:  <none>
    API Version:  networking.gke.io/v1
    Kind:         ManagedCertificate
    (...)
    Spec:
     Domains: FQDN_1 
     FQDN_2 
    Status:
     CertificateStatus: Active
    (...) 
    

    The value of the Status.CertificateStatus field indicates the certificate is provisioned. If Status.CertificateStatus is not Active , the certificate is not yet provisioned.

  6. Verify that SSL is working by visiting your domains using the https:// prefix. Your browser indicates that the connection is secure and you can view the certificate details.

Migrating to Google-managed certificates from self-managed certificates

When you migrate an Ingress from using self-managed SSL certificates to Google-managed SSL certificates, don't delete any self-managed SSL certificates before the Google-managed SSL certificates are active. After the Google-managed SSL certificates are successfully provisioned, they automatically become active. When the Google-managed SSL certificates are active, you can delete your self-managed SSL certificates.

Use these instructions for migrating from self-managed to Google-managed SSL certificates.

  1. Add a new Google-managed certificate to the Ingress, as described in the preceding section.
  2. Wait until the status of the Google-managed certificate resource is Active . Check the status of the certificate with the following command:

     kubectl  
    describe  
    managedcertificate  
    managed-cert 
    
  3. When the status is Active , update the Ingress to remove the references to the self-managed certificate.

Removing a Google-managed certificate

To remove a Google-managed certificate from your cluster you must delete the ManagedCertificate object and remove the Ingress annotation that references it.

  1. Delete the ManagedCertificate object:

     kubectl  
    delete  
    -f  
    managed-cert.yaml 
    

    The output is similar to the following:

     managedcertificate.networking.gke.io "managed-cert" deleted 
    
  2. Remove the annotation from the Ingress:

     kubectl  
    annotate  
    ingress  
    managed-cert-ingress  
    networking.gke.io/managed-certificates- 
    

    Notice the minus sign, - , at the end of the command.

  3. Release the static IP address that you reserved for your load balancer.

    You can use the Google Cloud CLI, the Google Cloud console, or Config Connector to release a reserved IP address.

    gcloud

    Use the following command to release the reserved IP address:

     gcloud  
    compute  
    addresses  
    delete  
     ADDRESS_NAME 
      
    --global 
    

    Replace ADDRESS_NAME with the name of the IP address.

    Console

    To release the reserved IP address, perform the following steps:

    1. Go to the External IP addressespage in the Google Cloud console.

      Go to External IP addresses

    2. Select the checkbox next to the IP address you want to release.

    3. Click Release IP address.

    Config Connector

    Note: This step requires Config Connector . Follow the installation instructions to install Config Connector on your cluster.

      apiVersion 
     : 
      
     compute.cnrm.cloud.google.com/v1beta1 
     kind 
     : 
      
     ComputeAddress 
     metadata 
     : 
      
     name 
     : 
      
     example-ip-address 
     spec 
     : 
      
     location 
     : 
      
     global 
     
    

    To deploy this manifest, download it to your machine as compute-address.yaml , and run:

     kubectl  
    delete  
    -f  
    compute-address.yaml 
    

Create certificates and keys

To use pre-shared certificates or Kubernetes Secrets, you first need one or more certificates, with corresponding private keys. Each certificate must have a Common Name (CN) that is equal to a domain name that you own. If you already have two certificate files with the appropriate values for Common Name, you can skip ahead to the next section.

  1. Create your first key:

     openssl  
    genrsa  
    -out  
    test-ingress-1.key  
     2048 
     
    
  2. Create your first certificate signing request:

     openssl  
    req  
    -new  
    -key  
    test-ingress-1.key  
    -out  
    test-ingress-1.csr  
     \ 
      
    -subj  
     "/CN= FIRST_DOMAIN 
    " 
     
    

    Replace FIRST_DOMAIN with a domain name that you own, such as example.com .

  3. Create your first certificate:

     openssl  
    x509  
    -req  
    -days  
     365 
      
    -in  
    test-ingress-1.csr  
    -signkey  
    test-ingress-1.key  
     \ 
      
    -out  
    test-ingress-1.crt 
    
  4. Create your second key:

     openssl  
    genrsa  
    -out  
    test-ingress-2.key  
     2048 
     
    
  5. Create your second certificate signing request:

     openssl  
    req  
    -new  
    -key  
    test-ingress-2.key  
    -out  
    test-ingress-2.csr  
     \ 
      
    -subj  
     "/CN= SECOND_DOMAIN 
    " 
     
    

    Replace SECOND_DOMAIN with another domain name that you own, such as examplepetstore.com .

  6. Create your second certificate:

     openssl  
    x509  
    -req  
    -days  
     365 
      
    -in  
    test-ingress-2.csr  
    -signkey  
    test-ingress-2.key  
     \ 
      
    -out  
    test-ingress-2.crt 
    

For more information about certificates and keys, see the SSL certificates overview .

You now have two certificate files and two key files.

The remaining tasks use the following placeholders to refer to your domains, certificates, and keys:

  • FIRST_CERT_FILE : the path to your first certificate file.
  • FIRST_KEY_FILE : the path to the key file that goes with your first certificate.
  • FIRST_DOMAIN : a domain name that you own.
  • FIRST_SECRET_NAME : the name of the Secret containing your first certificate and key.
  • SECOND_CERT_FILE : the path to your second certificate file.
  • SECOND_KEY_FILE : the path to the key file that goes with your second certificate.
  • SECOND_DOMAIN : a second domain name that you own.
  • SECOND_SECRET_NAME : the name of the Secret containing your second certificate and key.

Use pre-shared certificates

You can use self-managed SSL certificates that you upload to your Google Cloud project. These are called pre-shared certificates. You can specify one or more pre-shared certificates for an Ingress.

To use multiple pre-shared certificates, follow these steps:

  1. For each of your certificate and key pairs, create a publicly-visible SSL certificate resource in Google Cloud.

       
    gcloud  
    compute  
    ssl-certificates  
    create  
     FIRST_CERT_NAME 
      
     \ 
      
    --certificate = 
     FIRST_CERT_FILE 
      
     \ 
      
    --private-key = 
     FIRST_KEY_FILE 
      
     ``` 
     ``` 
    sh  
    gcloud  
    compute  
    ssl-certificates  
    create  
     SECOND_CERT_NAME 
      
     \ 
      
    --certificate = 
     SECOND_CERT_FILE 
      
     \ 
      
    --private-key = 
     SECOND_KEY_FILE 
      
     ``` 
    Replace  
    the  
    following: 
    
    • FIRST_CERT_NAME , SECOND_CERT_NAME : the names of your first and second certificates.
    • FIRST_CERT_FILE , SECOND_CERT_FILE : your first and second certificate files .
    • FIRST_KEY_FILE :, SECOND_KEY_FILE your first and second key files.
  2. In your Ingress manifest, add the ingress.gcp.kubernetes.io/pre-shared-cert annotation. The value of the annotation is a comma-separated list of your certificate names. Also, in the spec.rules section, include the host fields to specify the domains for your services.

       
     apiVersion 
     : 
      
     networking.k8s.io/v1 
      
     kind 
     : 
      
     Ingress 
      
     metadata 
     : 
      
     name 
     : 
      
     my-psc-ingress 
      
     annotations 
     : 
      
     ingress.gcp.kubernetes.io/pre-shared-cert 
     : 
      
     " FIRST_CERT_NAME 
    , SECOND_CERT_NAME 
    " 
      
     spec 
     : 
      
     rules 
     : 
      
     - 
      
     host 
     : 
      
      FIRST_DOMAIN 
     
      
     http 
     : 
      
     paths 
     : 
      
     - 
      
     pathType 
     : 
      
     ImplementationSpecific 
      
     backend 
     : 
      
     service 
     : 
      
     name 
     : 
      
     my-mc-service 
      
     port 
     : 
      
     number 
     : 
      
     60001 
      
     - 
      
     host 
     : 
      
      SECOND_DOMAIN 
     
      
     http 
     : 
      
     paths 
     : 
      
     - 
      
     pathType 
     : 
      
     ImplementationSpecific 
      
     backend 
     : 
      
     service 
     : 
      
     name 
     : 
      
     my-mc-service 
      
     port 
     : 
      
     number 
     : 
      
     60002 
      
     ``` 
     Replace <code><var>FIRST_DOMAIN</var></code> and 
    < code><var>SECOND_DOMAIN</var></code> with your domain names. 
     This manifest describes an Ingress that lists pre-shared certificate 
     resources in an annotation. 
     
    

Use Kubernetes Secrets

To provide an HTTP(S) load balancer with a certificates and keys that you created yourself, create one or more Kubernetes Secret objects. Each Secret holds a certificate and key. You add the Secrets to the tls field of your Ingress manifest. The load balancer uses Server Name Indication (SNI) to determine which certificate to present to the client, based on the domain name in the TLS handshake.

To use multiple certificates, follow these steps:

  1. Create a Secret for each of your certificate and key pairs:

       
    kubectl  
    create  
    secret  
    tls  
     FIRST_SECRET_NAME 
      
     \ 
      
    --cert = 
     FIRST_CERT_FILE 
      
     \ 
      
    --key = 
     FIRST_KEY_FILE 
      
     ``` 
     ``` 
    sh  
    kubectl  
    create  
    secret  
    tls  
     SECOND_SECRET_NAME 
      
     \ 
      
    --cert = 
     SECOND_CERT_FILE 
      
     \ 
      
    --key = 
     SECOND_KEY_FILE 
      
     ``` 
     
    
  2. In your Ingress manifest, in the spec.tls section, list the Secrets that you created. Also, in the spec.rules section, include the host fields to specify the domains for your services.

      apiVersion 
     : 
      
     networking.k8s.io/v1 
     kind 
     : 
      
     Ingress 
     metadata 
     : 
      
     name 
     : 
      
     my-mc-ingress 
     spec 
     : 
      
     tls 
     : 
      
     - 
      
     secretName 
     : 
      
      FIRST_SECRET_NAME 
     
      
     - 
      
     secretName 
     : 
      
      SECOND_SECRET_NAME 
     
      
     rules 
     : 
      
     - 
      
     host 
     : 
      
      FIRST_DOMAIN 
     
      
     http 
     : 
      
     paths 
     : 
      
     - 
      
     pathType 
     : 
      
     ImplementationSpecific 
      
     backend 
     : 
      
     service 
     : 
      
     name 
     : 
      
     my-mc-service 
      
     port 
     : 
      
     number 
     : 
      
     60001 
      
     - 
      
     host 
     : 
      
      SECOND_DOMAIN 
     
      
     http 
     : 
      
     paths 
     : 
      
     - 
      
     pathType 
     : 
      
     ImplementationSpecific 
      
     backend 
     : 
      
     service 
     : 
      
     name 
     : 
      
     my-mc-service 
      
     port 
     : 
      
     number 
     : 
      
     60002 
     
    

    Replace FIRST_DOMAIN and SECOND_DOMAIN with domain names that you own, for example example.com and examplepetstore.com .

Changes to Secrets are picked up periodically so if you modify the data inside of the Secret, it will take a max of 10 minutes for those changes to be applied to the load balancer.

To secure HTTPS encrypted Ingress for your GKE clusters, see example Secure Ingress .

Disabling HTTP

If you want all traffic between the client and the load balancer to use HTTPS, you can disable HTTP by including the kubernetes.io/ingress.allow-http annotation in your Ingress manifest. Set the value of the annotation to "false" .

  apiVersion 
 : 
  
 networking.k8s.io/v1 
 kind 
 : 
  
 Ingress 
 metadata 
 : 
  
 name 
 : 
  
 my-ingress-2 
  
 annotations 
 : 
  
  kubernetes.io/ingress.allow-http 
 : 
  
 "false" 
 spec 
 : 
  
 tls 
 : 
  
 - 
  
 secretName 
 : 
  
  SECRET_NAME 
 
  
 ... 
 

This manifests includes the SECRET_NAME that is the name of the Secret you created.

HTTP/2 between client and load balancer

Clients can use HTTP/2 to send requests to the load balancer. No configuration is required.

Secure and optimize traffic between load balancer and application

You can configure the protocol used for communication between the load balancer and your application Pods to ensure end-to-end security or to optimize internal traffic performance. While the load balancer defaults to unencrypted HTTP/1.1 for backend connections, you can enable HTTPS or HTTP/2 to meet your application's specific requirements.

HTTPS between load balancer and application

If your application, running in a GKE Pod, is capable of receiving HTTPS requests, you can configure the load balancer to use HTTPS when it forwards requests to your application. For more information, see HTTPS (TLS) between load balancer and your application .

To configure the protocol used between the load balancer and your application, use the cloud.google.com/app-protocols annotation in your Service manifest. This Service manifest must include type: NodePort unless you're using container-native load balancing . If you use container-native load balancing, use the type: ClusterIP .

The following Service manifest specifies two ports. The annotation says that when an HTTP(S) load balancer targets port 80 of the Service, it should use HTTP. And when the load balancer targets port 443 of the Service, it should use HTTPS.

The Service manifest must include a name value in the port annotation. You can only edit the Service port by referring to its assigned name , not by its targetPort value.

  apiVersion 
 : 
  
 v1 
 kind 
 : 
  
 Service 
 metadata 
 : 
  
 name 
 : 
  
 my-service-3 
  
 annotations 
 : 
  
 cloud.google.com/app-protocols 
 : 
  
 '{"my-https-port":"HTTPS","my-http-port":"HTTP"}' 
 spec 
 : 
  
 type 
 : 
  
 NodePort 
  
 selector 
 : 
  
 app 
 : 
  
 metrics 
  
 department 
 : 
  
 sales 
  
 ports 
 : 
  
 - 
  
 name 
 : 
  
 my-https-port 
  
 port 
 : 
  
 443 
  
 targetPort 
 : 
  
 8443 
  
 - 
  
 name 
 : 
  
 my-http-port 
  
 port 
 : 
  
 80 
  
 targetPort 
 : 
  
 50001 
 

Use HTTP/2 between load balancer and application

If your application, running in a GKE Pod, is capable of receiving HTTP/2 requests, you can configure the load balancer to use HTTP/2 when it forwards requests to your application.

To enable HTTP/2, you must use the cloud.google.com/app-protocols annotation on the Kubernetes Service manifest. This annotation specifies the protocol the load balancer uses to communicate with your application. To ensure that the load balancer makes a correct HTTP/2 request to your backend, your backend must be configured with SSL.

The following is an example of a Service manifest configured for HTTP/2:

  apiVersion 
 : 
  
 v1 
 kind 
 : 
  
 Service 
 metadata 
 : 
  
 name 
 : 
  
 my-http2-service 
  
 annotations 
 : 
  
 cloud.google.com/app-protocols 
 : 
  
 '{"my-port":"HTTP2"}' 
 spec 
 : 
  
 type 
 : 
  
 NodePort 
  
 selector 
 : 
  
 app 
 : 
  
 my-app 
  
 ports 
 : 
  
 - 
  
 name 
 : 
  
 my-port 
  
 protocol 
 : 
  
 TCP 
  
 port 
 : 
  
 443 
  
 targetPort 
 : 
  
 8443 
 

Note the following:

  • The cloud.google.com/app-protocols annotation is set to '{"my-port":"HTTP2"}' , which instructs the load balancer to use HTTP/2 for traffic sent to the port named my-port .
  • The port is set to 443 and directs traffic to Pods on targetPort 8443 .
Create a Mobile Website
View Site in Mobile | Classic
Share by: