Using Google-managed SSL certificates

This page shows how you can use Ingress objects 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 with Google Cloud, see Google-managed certificates.

GKE Google-managed SSL certificates support public and private clusters.

API versions

You configure Google-managed SSL certificates using a ManagedCertificate custom resource, which is available in different API versions, depending on your Google Kubernetes Engine (GKE) cluster version:

  • The ManagedCertificate v1beta2 API is available in GKE versions 1.15 and later.
  • The ManagedCertificate v1 API is available in GKE versions 1.17.9-gke.6300 and later.

Although GKE clusters currently support the ManagedCertificate v1beta1 API, this API version is deprecated and will be removed in future GKE versions. It's recommended that you use a newer API version.

Migrating between API versions

ManagedCertificate objects are automatically promoted to a newer API version when they are updated in a cluster that supports the newer API version. The resources are periodically updated, so you do not need to take any action to migrate the resources.

Creating an Ingress with a Google-managed certificate

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

  • Create a ManagedCertificate object in the same namespace as the Ingress.
  • Associate the ManagedCertificate object 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

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 do not support wildcard domains.

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.

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 manual changes with minimal downtime, see 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.
  • The cluster must have the HttpLoadBalancing add-on enabled.
  • Your "kubernetes.io/ingress.class" must be "gce".
  • 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 guarantees that it remains yours, even if you delete the Ingress. If you do not reserve an IP address, it might 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
    

    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 addresses page in the 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 IPv4 or IPv6 address.

    4. Select the Global option for Type.

    5. Click Reserve. 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 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: managed-cert
    spec:
      domains:
        - DOMAIN_NAME1
        - DOMAIN_NAME2
    

    Replace the following:

    • DOMAIN_NAME1 and DOMAIN_NAME2: domain names that you own. For example, example.com and www.example.com.
  2. Apply the manifest to your cluster:

    kubectl apply -f managed-cert.yaml
    
  3. Create a Service of type NodePort to expose your application to the internet.

    The following manifest describes a Service of type NodePort. Save the manifest as mc-service.yaml.

    apiVersion: v1
    kind: Service
    metadata:
      name: mc-service
    spec:
      selector:
        app: mc-service
      type: NodePort
      ports:
        - protocol: TCP
          port: 80
          targetPort: 8080
    
  4. Apply the manifest to your cluster:

    kubectl apply -f mc-service.yaml
    
  5. Create an Ingress.

    The following manifest describes an Ingress that uses the ManagedCertificate you created. Save the manifest as managed-cert-ingress.yaml.

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: managed-cert-ingress
      annotations:
        kubernetes.io/ingress.global-static-ip-name: ADDRESS_NAME
        networking.gke.io/managed-certificates: managed-cert
        kubernetes.io/ingress.class: "gce"
    spec:
      defaultBackend:
        service:
          name: mc-service
          port:
            number: SERVICE_PORT
    

    Replace the following:

    • ADDRESS_NAME: the name of your reserved IP address.
    • SERVICE_PORT: the value of ports.port in your Service manifest.
  6. Apply the manifest to your cluster:

    kubectl apply -f managed-cert-ingress.yaml
    
  7. Get the IP address of the load balancer:

    kubectl get ingress
    

    The output is similar to the following:

    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.

  8. Configure the DNS records for your domains to point to the IP address of the load balancer. If you use Cloud DNS, see Managing records for details.

  9. Wait for the Google-managed certificate to finish provisioning. This might take up to 60 minutes. You can check the status of the certificate 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:
       DOMAIN_NAME1
       DOMAIN_NAME2
    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.

  10. 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, 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 Google-managed certificate to the Ingress, as described in the Setting up a Google-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 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 gcloud command-line tool, the 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 addresses page in the 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
    

Troubleshooting

This section provides information on how to resolve issues with Google-managed certificates.

Check events on ManagedCertificate and Ingress resources

If you exceed the number of allowed certificates, an event with a TooManyCertificates reason is added to the ManagedCertificate. You can check the events on a ManagedCertificate object using the following command:

kubectl describe managedcertificate CERTIFICATE_NAME

Replace CERTIFICATE_NAME with the name of your ManagedCertificate.

If you attach a non-existent ManagedCertificate v1 to an Ingress, an event with a MissingCertificate reason is added to the Ingress. You can check the events on an Ingress by using the following command:

kubectl describe ingress INGRESS_NAME

Replace INGRESS_NAME with the name of your Ingress.

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 Ingress objects), you should create a single ManagedCertificate object and attach it to all the Ingress objects. If you instead create many ManagedCertificate objects and attach each of them to a separate Ingress, the Certificate Authority might not be able to verify the ownership of your domain and some of your certificates might not be provisioned. For the verification to be successful, the certificate must 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 objects, you should create a single ManagedCertificate object and attach it to both Ingresses.

Disrupted communication between Google-managed certificates and Ingress

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

  • Run an automated process that clears the kubernetes.io/pre-shared-cert annotation.
  • Store a snapshot of Ingress then delete and restore the Ingress from the snapshot. In the meantime, an SslCertificate resource listed in the pre-shared-cert annotation might have been deleted. Ingress does not work if any certificates attached to it are missing.

If communication between Google-managed certificates and Ingress is disrupted, delete the contents of the kubernetes.io/pre-shared-cert annotation and wait for the system to reconcile. To prevent recurrence, ensure that the annotation is not inadvertently modified or deleted.

Validation errors when creating a Google-managed certificate

ManagedCertificate definitions are validated before the ManagedCertificate object is created. If validation fails, the ManagedCertificate object 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. Google-managed certificates support only up to 100 domains.

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 object 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. Google-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 ManagedCertificate for the new domain.
  2. Add the name of the ManagedCertificate to the networking.gke.io/managed-certificates annotation on the Ingress using a comma-separated list. Do not remove the old certificate name.
  3. Wait until the ManagedCertificate becomes Active.
  4. Detach the old certificate from the Ingress and delete it.

When you create a ManagedCertificate, Google Cloud creates a Google-managed SSL certificate. You cannot update this certificate. If you update the ManagedCertificate, Google Cloud deletes and recreates the Google-managed SSL certificate.

What's next