Using Google-managed SSL certificates

This page shows how you can use Ingresses to create external load balancers with Google-managed SSL certificates. These certificates are Domain Validation (DV) certificates that Google provisions, renews, and manages for your domain names. These certificates do not demonstrate your individual or organizational identity. To learn how to create Google-managed certificates, see Google-managed certs.

Introducing v1beta2 API

Managed Certificates is a Beta feature available in all GKE versions. In clusters with masters running Kubernetes lower than 1.16.5-gke.1 Managed Certificates are available in version v1beta1, and they do not support multiple subject alternative names (SANs) per certificate.

In GKE 1.16.5-gke.1 and higher Managed Certificates are available in version v1beta2 and they support up to 100 SANs per certificate, version v1beta1 is also still available.

Migrating from v1beta1 to v1beta2 API

The difference between v1beta1 and v1beta2 is only in validation allowing more domain names per certificate. The version number is upgraded to clearly highlight the difference and to avoid silently changing the validation rules, and misunderstandings that it could lead to.

v1beta1 resources are automatically migrated to version v1beta2 when they are updated, the resources are updated automatically. Once version v1beta1 is removed, no new resources in this version can be created anymore.

Creating an Ingress with a managed certificate

To configure a managed SSL certificate and associate it with an Ingress, you need to:

  • Create a ManagedCertificate object.
  • Associate the ManagedCertificate object to an Ingress by adding an annotation networking.gke.io/managed-certificates to the Ingress. This annotation is a comma-separated list of ManagedCertificate resources, cert1,cert2,cert3 for example.

Limitations

Google-managed certificates are less flexible than certificates you obtain and manage yourself. Managed certificates support up to 100 non-wildcard domains, whereas self-managed certificates can support wildcards.

If you require self-managed certificates or if you already own SSL certificates that you would like to configure on your Ingress, refer to the Ingress documentation.

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

Updates on Google-managed certificates are not supported.

For manual changes with minimal downtime, follow the steps at Manually updating a Google-managed certificate.

Prerequisites

  • You must own the domain name. The domain name must be no longer than 63 characters. You can use Google Domains or another registrar.
  • Create a reserved (static) external IP address. Reserving a static IP address guarantees that it remains yours, even if you delete the Ingress. If you do not reserve an address, it may change requiring you to reconfigure your domain's DNS records. Use gcloud command-line tool or the 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
    

    where address-name is 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:

    address: 203.0.113.32
    ...
    

    Console

    1. Go to the Reserve a static address page in the Cloud Console.

      Go to the Reserve a static address page

    2. Specify a name for this IP address (for example, example-ip-address).
    3. Specify whether this is an IPv4 or IPv6 address. The following example uses an IPv4 address.
    4. Select the Global option for the address type.
    5. Click Reserve to reserve the IP.
    6. The IP address is listed in the External Address column.

    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 the managed certificate

  1. Create a ManagedCertificate resource. This resource specifies the domains that the SSL certificate will be created for. Wildcard domains are not supported.

    This is a sample ManagedCertificate manifest:

    apiVersion: networking.gke.io/v1beta2
    kind: ManagedCertificate
    metadata:
      name: certificate-name
    spec:
      domains:
        - domain-name1
        - domain-name2
    

    where:

    • certificate-name is the name of your ManagedCertificate resource.
    • domain-name1 and domain-name2 are your domain names.

    Save the manifest as a file named certificate-name.yaml, then create the resource with the following command:

    kubectl apply -f certificate-name.yaml
    
  2. Create a NodePort Service to expose your application to the Internet.

    The following is an example Service manifest file:

    apiVersion: v1
    kind: Service
    metadata:
      name: service-name
    spec:
      selector:
        key: value
      type: NodePort
      ports:
        - protocol: TCP
          port: 80
          targetPort: 8080
    

    This example specification selects Pods to include in the Service using the selector. Refer to the NodePort documentation for details on how to configure the Service.

    Save the manifest as a file named service-name.yaml, then create the Service with the following command:

    kubectl apply -f service-name.yaml
    
  3. Create an Ingress, linking it to the ManagedCertificate you created previously.

    The following is a sample Ingress manifest:

    apiVersion: networking.k8s.io/v1beta1
    kind: Ingress
    metadata:
      name: ingress-name
      annotations:
        kubernetes.io/ingress.global-static-ip-name: address-name
        networking.gke.io/managed-certificates: certificate-name
    spec:
      backend:
        serviceName: service-name
        servicePort: service-port
    

    where:

    • ingress-name is the name of your Ingress object.
    • address-name is the name of your reserved IP address.
    • certificate-name is the name of your certificate.
    • service-name is the name of the service you created in the previous step.
    • service-port is the port you specified in your Service manifest. Note that this should be the value of the port field, not targetPort.

    Save the manifest as a file named ingress-name.yaml, then create the Ingress with the following command:

    kubectl apply -f ingress-name.yaml
    
  4. Look up the IP address of the load balancer created in the previous step. Use the following command to get the IP address of the load balancer:

    kubectl get ingress
    

    The output is similar to:

    NAME              HOSTS     ADDRESS         PORTS     AGE
    example-ingress   *         203.0.113.32     80        54s
    

    The load balancer's IP address is listed in the ADDRESS column. If you are using a reserved static IP address that will be the load balancer's address.

    If the address is not listed, wait for the Ingress to finish setting up.

  5. Configure the DNS records for your domains to point to the IP address of the load balancer. If you use Cloud DNS, you can refer to the Managing Records guide for details.

  6. Wait for the managed certificate to be provisioned. This may take up to 15 minutes. You can check on the status of the certificate with the following command:

    kubectl describe managedcertificate certificate-name
    

    Once a certificate is successfully provisioned, the value of the Status.CertificateStatus field will be Active. The following example shows the output of kubectl describe after the certificate is successfully provisioned:

    Name:         certificate-name
    Namespace:    default
    Labels:       <none>
    Annotations:  <none>
    API Version:  networking.gke.io/v1beta1
    Kind:         ManagedCertificate
    (...)
    Spec:
      Domains:
        domain-name1
        domain-name2
    Status:
      CertificateStatus: Active
    (...)
    
  7. Verify that SSL is working by visiting your domains using the https:// prefix. Your browser will indicate 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, do not 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 managed certificate to the Ingress, as described in the Setting up the managed certificate 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 certificate-name
    
  3. When the status is Active, update the Ingress to remove the references to the self-managed certificate.

Removing a managed certificate

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

  1. Delete the ManagedCertificate resource with kubectl:

    kubectl delete -f certificate-name.yaml
    

    You will get the following output:

    managedcertificate.networking.gke.io "certificate-name" deleted
    
  2. Remove the annotation from the Ingress:

    kubectl annotate ingress ingress-name 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:

    gcloud

    Using the gcloud command-line tool:

    gcloud compute addresses delete address-name --global
    

    where address-name is the name of the IP address.

    Console

    1. Go to the External IP addresses page in the Cloud Console.

      Go to the External IP addresses page

    2. Check the box next to the IP address 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

Troubleshooting

This section provides information on how to resolve issues with Managed Certificates.

Managed Certificate not provisioned when domain resolves to IP addresses of multiple load balancers

When your domain resolves to IP addresses of multiple load balancers (multiple Ingresses), you should create a single ManagedCertificate resource and attach it to all the Ingresses. If you instead create many ManagedCertificate resources and attach each of them to a separate Ingress, the Certificate Authority may not be able to verify the ownership of your domain and some of your certificates may not be provisioned. For the verification to be successful, the certificate has to be visible under all the IP addresses to which your domain resolves to.

Specifically, when your domain resolves to an IPv4 and an IPv6 addresses which are configured with different Ingress resources, you should create a single ManagedCertificate resource and attach it to both Ingresses.

Disrupted communication between Managed Certificates and Ingress

Managed Certificates communicate with Ingress using the kubernetes.io/pre-shared-cert annotation. You can disrupt this communication, for example if you:

  • Run an automated process that keeps clearing the kubernetes.io/pre-shared-cert annotation.
  • Store a snapshot of Ingress, tear it down and restore Ingress from the snapshot. In the meantime, an SslCertificate resource listed in the Ingress's pre-shared-cert annotation might have been deleted. Ingress has all-or-nothing semantics and will not work if any of certificates attached to it are missing.

Validation errors when creating a Managed Certificate

ManagedCertificate definitions are validated before the ManagedCertificate resource is created. If validation fails the ManagedCertificate resource is not created and an error message is printed. The different error messages and reasons are explained below:

spec.domains in body should have at most 100 items

Your ManagedCertificate manifest lists more than 100 domains in the spec.domains field. Managed Certificates support only up to 100 domains. Managed Certificates in clusters older than 1.16.5-gke.1 support only one domain.

spec.domains in body should match '^(([a-zA-Z0-9]+|[a-zA-Z0-9][-a-zA-Z0-9]*[a-zA-Z0-9])\.)+[a-zA-Z][-a-zA-Z0-9]*[a-zA-Z0-9]\.?$'

You specified an invalid domain name or a wildcard domain name in the spec.domains field. The ManagedCertificate resource does not support wildcard domains (for example, *.example.com).

spec.domains in body should be at most 63 chars long

You specified a domain name that is too long. Managed Certificates support domain names with at most 63 characters.

Manually updating a Google-managed certificate

To manually update the certificate so that the certificate for the old domain continues to work until the certificate for the new domain is provisioned, follow these steps:

  1. Create a new managed certificate for the new domain.
  2. Attach it to the Ingress without removing the old certificate.
  3. Wait until it becomes ACTIVE.
  4. Detach the old certificate from the Ingress and delete it.

What's next