Skip to content

Enabling automatic TLS certificate provisioning

If you install and configure cert-manager, you can configure Knative to automatically obtain new TLS certificates and renew existing ones for Knative Services for external domains (like application.example.com). Please note that we are working on bringing automatic HTTPS connections for cluster-local domains (like application.namespace.svc.cluster.local) as well (for more details see the issue).

Before you begin

The following must be installed on your Knative cluster:

  • Knative Serving.

  • A Networking layer such as Kourier, Istio with SDS v1.3 or higher, or Contour v1.1 or higher. See Install a networking layer or Istio with SDS, version 1.3 or higher.

  • cert-manager version 1.0.0 or higher.

  • Your Knative cluster must be configured to use a custom domain.

  • Your DNS provider must be setup and configured to your domain.

  • If you want to use HTTP-01 challenge, you need to configure your custom domain to map to the IP of ingress. You can achieve this by adding a DNS A record to map the domain to the IP according to the instructions of your DNS provider.

Automatic TLS certificate provisioning configurations

Knative supports the following automatic TLS certificate provisioning configurations:

  1. Using DNS-01 challenge

    In this configuration, your cluster needs to be able to talk to your DNS server to verify the ownership of your domain. In this configuration, you are able to configure two modes:

    • Provisioning of a wildcard Certificate for each namespace

      • This is the recommended mode for faster certificate provision.
      • In this mode, a wildcard Certificate will be provisioned for each namespace and is reused across the Knative Services within the same namespace.
    • Provisioning of a Certificate for each Knative Service

      • This is the recommended mode for better Certificate isolation between Knative Services.
      • In this mode, a Certificate will be provisioned for each Knative Service.
      • The time to issue Certificates is longer as more Certificates are created in this mode.
  2. Using HTTP-01 challenge

    • In this configuration, your cluster does not need to be able to talk to your DNS server, but you must make sure that your DNS entry points to the IP of the cluster ingress.
    • When using HTTP-01 challenge, a certificate will be provisioned for each Knative Service.
    • HTTP-01 does not support provisioning wildcard Certificates per namespace.

Enabling automatic TLS provisioning

Creating a ClusterIssuer

  1. Create and add the ClusterIssuer configuration to your Knative cluster to define who issues the TLS certificates, how requests are validated, and which DNS provider validates those requests.

    • ClusterIssuer for DNS-01 challenge:

      Refer to the cert-manager documentation, like the Generic ClusterIssuer and the DNS01 example

      For example, the following ClusterIssuer file named letsencrypt-issuer is configured for the Let's Encrypt CA and Google Cloud DNS. The Let's Encrypt account info, required DNS-01 challenge type, and Cloud DNS provider info is defined under spec.

      apiVersion: cert-manager.io/v1
      kind: ClusterIssuer
      metadata:
        name: letsencrypt-dns-issuer
      spec:
        acme:
          server: https://acme-v02.api.letsencrypt.org/directory
          # This will register an issuer with LetsEncrypt.  Replace
          # with your admin email address.
          email: test-email@knative.dev
          privateKeySecretRef:
            # Set privateKeySecretRef to any unused secret name.
            name: letsencrypt-dns-issuer
          solvers:
          - dns01:
              cloudDNS:
                # Set this to your GCP project-id
                project: $PROJECT_ID
                # Set this to the secret that we publish our service account key
                # in the previous step.
                serviceAccountSecretRef:
                  name: cloud-dns-key
                  key: key.json
      
    • ClusterIssuer for HTTP-01 challenge

      Refer to the cert-manager documentation, like the HTTP01ClusterIssuer`.

      For example, the following ClusterIssuer uses Let's Encrypt using `HTTP01:

      apiVersion: cert-manager.io/v1
      kind: ClusterIssuer
      metadata:
        name: letsencrypt-http01-issuer
      spec:
        acme:
          privateKeySecretRef:
            name: letsencrypt
          server: https://acme-v02.api.letsencrypt.org/directory
          solvers:
          - http01:
             ingress:
               class: istio
      
    • Apply your ClusterIssuer YAML file by running the command:

      kubectl apply -f <filename>.yaml
      
  2. Ensure that the ClusterIssuer is created successfully:

    kubectl get clusterissuer <cluster-issuer-name> -o yaml
    

    Result: The Status.Conditions should include Ready=True.

DNS-01 challenge only: Configure your DNS provider

If you choose to use DNS-01 challenge, configure which DNS provider is used to validate the DNS-01 challenge requests.

Instructions about configuring cert-manager, for all the supported DNS providers, are provided in DNS01 challenge providers and configuration instructions.

Note that DNS-01 challenges can be used to either validate an individual domain name or to validate an entire namespace using a wildcard certificate like *.my-ns.example.com.

Install net-certmanager-controller deployment

  1. Determine if net-certmanager-controller is already installed by running the following command:

    kubectl get deployment net-certmanager-controller -n knative-serving
    
  2. If net-certmanager-controller is not found, run the following command:

    kubectl apply -f https://github.com/knative/net-certmanager/releases/download/knative-v1.13.0/release.yaml
    

Provisioning certificates per namespace (wildcard certificates)

Warning

Provisioning a wildcard Certificate per namespace only works with DNS-01 challenge. This component cannot be used with HTTP-01 challenge.

The per-namespace configuration uses namespace labels to select which namespaces should have a certificate applied. The selection is configured using the key namespace-wildcard-cert-selector in the config-network ConfigMap. For example, you can use the following configurations:

  • namespace-wildcard-cert-selector: "" = Use an empty value to disable the feature (this is the default).
  • namespace-wildcard-cert-selector: {} = Use an empty object to enable for all namespaces.

You can also configure the selector to opt-out when a specific label is on the namespace:

namespace-wildcard-cert-selector:
  matchExpressions:
  - key: "networking.knative.dev/disableWildcardCert"
    operator: "NotIn"
    values: ["true"] 
This selects all namespaces where the label value is not in the set "true".

Or use existing kubernetes labels to select namespaces based on their name:

namespace-wildcard-cert-selector:
  matchExpressions:
    - key: "kubernetes.io/metadata.name"
      operator: "In"
      values: ["my-namespace", "my-other-namespace"] 

To apply the configuration you can use the following command (optionally adapting the label-selector):

kubectl patch --namespace knative-serving configmap config-network -p '{"data": {"namespace-wildcard-cert-selector": "{\"matchExpressions\": [{\"key\":\"networking.knative.dev/disableWildcardCert\", \"operator\": \"NotIn\", \"values\":[\"true\"]}]}"}}'

For more details on namespace selectors, see the Kubernetes documentation.

Configure config-certmanager ConfigMap

Update your config-certmanager ConfigMap in the knative-serving namespace to reference your new ClusterIssuer.

  1. Run the following command to edit your config-certmanager ConfigMap:

    kubectl edit configmap config-certmanager -n knative-serving
    
  2. Add the issuerRef within the data section:

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: config-certmanager
      namespace: knative-serving
      labels:
        networking.knative.dev/certificate-provider: cert-manager
    data:
      issuerRef: |
        kind: ClusterIssuer
        name: letsencrypt-http01-issuer
    

    issueRef defines which ClusterIssuer is used by Knative to issue certificates.

  3. Ensure that the file was updated successfully:

    kubectl get configmap config-certmanager -n knative-serving -o yaml
    

Turn on automatic TLS provisioning

Update the config-network ConfigMap in the knative-serving namespace to enable external-domain-tls and specify how HTTP requests are handled:

  1. Run the following command to edit your config-network ConfigMap:

    kubectl edit configmap config-network -n knative-serving
    
  2. Add the external-domain-tls: Enabled attribute under the data section:

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: config-network
      namespace: knative-serving
    data:
       ...
       external-domain-tls: Enabled
       ...
    
  3. Configure how HTTP and HTTPS requests are handled with the http-protocol attribute.

    By default, Knative ingress is configured to serve HTTP traffic (http-protocol: Enabled). Now that your cluster is configured to use TLS certificates and handle HTTPS traffic on external domains, you can specify whether any HTTP traffic is allowed or not.

    Supported http-protocol values:

    • Enabled: Serve HTTP traffic.
    • Redirected: Responds to HTTP request with a 302 redirect to ask the clients to use HTTPS.
    data:
      http-protocol: Redirected
    

    Example:

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: config-network
      namespace: knative-serving
    data:
      ...
      external-domain-tls: Enabled
      http-protocol: Redirected
      ...
    
  4. Ensure that the file was updated successfully:

    kubectl get configmap config-network -n knative-serving -o yaml
    

Congratulations! Knative is now configured to obtain and renew TLS certificates. When your TLS Certificate is issued and available on your cluster, your Knative services will be able to handle HTTPS traffic on the external domain.

Verification

  1. Run the following command to create a Knative Service:

    kubectl apply -f https://raw.githubusercontent.com/knative/docs/main/docs/serving/autoscaling/autoscale-go/service.yaml
    
  2. When the certificate is provisioned (which could take up to several minutes depending on the challenge type), you should see something like:

    NAME               URL                                           LATESTCREATED            LATESTREADY              READY   REASON
    autoscale-go       https://autoscale-go.default.{custom-domain}  autoscale-go-6jf85       autoscale-go-6jf85       True  
    

    Note that the URL will be https in this case.

Disable automatic TLS certificate provisioning per Service or Route

If you have automatic TLS certificate provisioning enabled in your cluster, you can choose to disable the feature for individual Knative Services or Routes by adding the annotation networking.knative.dev/disable-external-domain-tls: true.

Using the previous autoscale-go example:

  1. Edit the service using kubectl edit service.serving.knative.dev/autoscale-go -n default and add the annotation:

     apiVersion: serving.knative.dev/v1
     kind: Service
     metadata:
       annotations:
        ...
         networking.knative.dev/disable-external-domain-tls: "true"
        ...
    
  2. The service URL should now be http, indicating that automatic TLS Certificate provisioning is disabled:

    NAME           URL                                          LATEST               AGE     CONDITIONS   READY   REASON
    autoscale-go   http://autoscale-go.default.1.arenault.dev   autoscale-go-dd42t   8m17s   3 OK / 3     True
    

We use analytics and cookies to understand site traffic. Information about your use of our site is shared with Google for that purpose. Learn more.

× OK