diff --git a/config/nav.yml b/config/nav.yml index 77120ac46e5..9209bd8652e 100644 --- a/config/nav.yml +++ b/config/nav.yml @@ -159,8 +159,10 @@ nav: - Configure the Defaults ConfigMap: serving/configuration/config-defaults.md - Serving encryption configuration: - Overview: serving/encryption/encryption-overview.md - - Using custom TLS certificates in the networking layer: serving/encryption/using-certificates-in-networking-layer.md - - Enabling automatic TLS certificate provisioning: serving/encryption/enabling-automatic-tls-certificate-provisioning.md + - Install and configure net-certmanager: serving/encryption/install-and-configure-net-certmanager.md + - Configure external domain encryption: serving/encryption/external-domain-tls.md + - Configure cluster-local domain encryption: serving/encryption/cluster-local-domain-tls.md + - Configure Knative system-internal encryption: serving/encryption/system-internal-tls.md # Serving - Application Security - Application security: - About Security-Guard: serving/app-security/security-guard-about.md diff --git a/docs/serving/encryption/cluster-local-domain-tls.md b/docs/serving/encryption/cluster-local-domain-tls.md new file mode 100644 index 00000000000..eb33329cc7c --- /dev/null +++ b/docs/serving/encryption/cluster-local-domain-tls.md @@ -0,0 +1,75 @@ +# Configure cluster-local domain encryption + +## Before you begin + +You must meet the following requirements to enable secure HTTPS connections: + +- Knative Serving must be installed. For details about installing the Serving + component, see the [Knative installation guides](../../install/yaml-install/serving/install-serving-with-yaml.md). + +!!! warning + This feature is currently only supported with Kourier and Istio as a networking layer. + +## Enabling cluster-local-domain-tls + +First, you need to install and configure `cert-manager` and `net-certmanager`. Please refer to [Installing and configuring net-certmanager](./install-and-configure-net-certmanager.md) for details. + +Then, update the [`config-network` ConfigMap](https://github.com/knative/serving/blob/main/config/core/configmaps/network.yaml) in the `knative-serving` namespace to enable `cluster-local-domain-tls`: + +1. Run the following command to edit your `config-network` ConfigMap: + + ```bash + kubectl edit configmap config-network -n knative-serving + ``` + +1. Add the `cluster-local-domain-tls: Enabled` attribute under the `data` section: + + ```yaml + apiVersion: v1 + kind: ConfigMap + metadata: + name: config-network + namespace: knative-serving + data: + ... + cluster-local-domain-tls: Enabled + ... + ``` + +Congratulations! Knative is now configured to obtain and renew TLS certificates for cluster-local domains. + + +## Verification + +1. Deploy a Knative Service + +1. Check the URL with `kubectl get ksvc -n -o yaml` + +1. The service URL cluster-local domain (https://helloworld.test.svc.cluster.local) should now be **https**: + +```yaml +apiVersion: serving.knative.dev/v1 +kind: Service +metadata: + name: helloworld + namespace: test +spec: + # ... +status: + address: + # cluster-local-domain: + url: https://helloworld.test.svc.cluster.local + # ... + # external domain: + url: http://helloworld.first.example.com +``` + + +## Trust + +!!! note + A quick note on trust, all clients that call the cluster-local domain of a Knative Service need to trust the Certificate Authority + that signed the certificates. This is out of scope of Knative, but needs to be addressed to ensure a working system. Especially, + when a Certificate Authority performs a rotation of the CA or the intermediate certificates. Find more information on + [Install and configure net-certmanager](./install-and-configure-net-certmanager.md#managing-trust-and-rotation-without-downtime). + diff --git a/docs/serving/encryption/enabling-automatic-tls-certificate-provisioning.md b/docs/serving/encryption/enabling-automatic-tls-certificate-provisioning.md deleted file mode 100644 index f185997de2c..00000000000 --- a/docs/serving/encryption/enabling-automatic-tls-certificate-provisioning.md +++ /dev/null @@ -1,349 +0,0 @@ -# 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](https://github.com/knative/serving/issues/13472)). - - -## Before you begin - -The following must be installed on your Knative cluster: - -- [Knative Serving](../../install/yaml-install/serving/install-serving-with-yaml.md). - -- A Networking layer such as Kourier, Istio with SDS v1.3 or higher, or Contour v1.1 or higher. See [Install a networking layer](../../install/yaml-install/serving/install-serving-with-yaml.md#install-a-networking-layer) or [Istio with SDS, version 1.3 or higher](../../install/installing-istio.md#installing-istio-with-SDS-to-secure-the-ingress-gateway). - -- [`cert-manager`](../../install/installing-cert-manager.md) version `1.0.0` or higher. - -- Your Knative cluster must be configured to use a [custom domain](../using-a-custom-domain.md). - -- 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. - -1. 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`](https://cert-manager.io/docs/configuration/acme/#creating-a-basic-acme-issuer) and the [`DNS01` example](https://cert-manager.io/docs/configuration/acme/dns01/) - - 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`. - - ```yaml - 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 [`HTTP01 `ClusterIssuer`](https://cert-manager.io/docs/configuration/acme/http01/). - - For example, the following `ClusterIssuer` uses Let's Encrypt using `HTTP01: - - ```yaml - 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 - ``` - - 1. Apply your `ClusterIssuer` YAML file by running the command: - - ```bash - kubectl apply -f .yaml - ``` - -1. Ensure that the ClusterIssuer is created successfully: - - ```bash - kubectl get clusterissuer -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](https://cert-manager.io/docs/configuration/acme/dns01/#supported-dns01-providers). - -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: - - ```bash - kubectl get deployment net-certmanager-controller -n knative-serving - ``` - -1. If `net-certmanager-controller` is not found, run the following command: - - ```bash - kubectl apply -f {{ artifact( repo="net-certmanager", file="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: - -```yaml -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: - -```yaml -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): - -```bash -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](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors). - - -### Configure config-certmanager ConfigMap - -Update your [`config-certmanager` ConfigMap](https://github.com/knative-extensions/net-certmanager/blob/main/config/config.yaml) -in the `knative-serving` namespace to reference your new `ClusterIssuer`. - -1. Run the following command to edit your `config-certmanager` ConfigMap: - - ```bash - kubectl edit configmap config-certmanager -n knative-serving - ``` - -1. Add the `issuerRef` within the `data` section: - - ```yaml - 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. - -1. Ensure that the file was updated successfully: - - ```bash - kubectl get configmap config-certmanager -n knative-serving -o yaml - ``` - -### Turn on automatic TLS provisioning - -Update the [`config-network` ConfigMap](https://github.com/knative/serving/blob/main/config/core/configmaps/network.yaml) 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: - - ```bash - kubectl edit configmap config-network -n knative-serving - ``` - -1. Add the `external-domain-tls: Enabled` attribute under the `data` section: - - ```yaml - apiVersion: v1 - kind: ConfigMap - metadata: - name: config-network - namespace: knative-serving - data: - ... - external-domain-tls: Enabled - ... - ``` - -1. 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. - - ```yaml - data: - http-protocol: Redirected - ``` - - Example: - - ```yaml - apiVersion: v1 - kind: ConfigMap - metadata: - name: config-network - namespace: knative-serving - data: - ... - external-domain-tls: Enabled - http-protocol: Redirected - ... - ``` - -1. Ensure that the file was updated successfully: - - ```bash - 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: - - ```bash - kubectl apply -f https://raw.githubusercontent.com/knative/docs/main/docs/serving/autoscaling/autoscale-go/service.yaml - ``` - -1. When the certificate is provisioned (which could take up to several minutes depending on the challenge type), you should see something like: - - ```bash - 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: - - ```yaml - apiVersion: serving.knative.dev/v1 - kind: Service - metadata: - annotations: - ... - networking.knative.dev/disable-external-domain-tls: "true" - ... - ``` - -1. The service URL should now be **http**, indicating that automatic TLS Certificate provisioning is disabled: - - ```bash - NAME URL LATEST AGE CONDITIONS READY REASON - autoscale-go http://autoscale-go.default.1.arenault.dev autoscale-go-dd42t 8m17s 3 OK / 3 True - ``` diff --git a/docs/serving/encryption/encryption-overview.md b/docs/serving/encryption/encryption-overview.md index aff5cee4a83..f4e6ac618db 100644 --- a/docs/serving/encryption/encryption-overview.md +++ b/docs/serving/encryption/encryption-overview.md @@ -21,9 +21,9 @@ The different parts are independent of each other and (can) use different Certif * Certificate CN/SAN contains the external domain of a Knative Service, e.g. `myapp-.example.com`. * The certificates are hosted using SNI by the external endpoint of the ingress-controller. * The caller has to trust the (external) CA that signed the certificates (this is out of the scope of Knative). -* These certificates are either [provided manually](TODO) or by enabling [automatic certificate provisioning](TODO) +* These certificates are either provided manually or by enabling automatic certificate provisioning. -See [external-domain-tls](TODO) for more information on this feature. +See [Configure external domain encryption](./external-domain-tls.md) for more information on this feature. ### Cluster-local encryption @@ -34,7 +34,7 @@ See [external-domain-tls](TODO) for more information on this feature. * The caller has to trust the CA that signed the certificates (this is out of the scope of Knative). One option to do this is using [trust-manager](https://cert-manager.io/docs/trust/trust-manager/) from cert-manager. * To create the certificates, Knative relies on [cert-manager](https://cert-manager.io/) and our bridging component [net-certmanager](https://github.com/knative-extensions/net-certmanager/). They need to be installed and configured for the feature to work. -See [external-domain-tls](TODO) for more information on this feature. +See [Configure cluster-local domain encryption](./cluster-local-domain-tls.md) for more information on this feature. ### Knative system-internal encryption @@ -45,4 +45,4 @@ Knative system internal components (`ingress-controller`, `activator`, `queue-pr * To get the certificates, Knative relies on [cert-manager](https://cert-manager.io/) and our bridging component [net-certmanager](https://github.com/knative-extensions/net-certmanager/). They need to be installed and configured for the feature to work. * Specific SANs are used to verify each connection. Each component needs to trust the CA (possibly the full chain) that signed the certificates. For this, Knative system components will consume and trust a provided `CABundle`. The CA bundle needs to be provided by the cluster administrator, possibly using [trust-manager](https://cert-manager.io/docs/trust/trust-manager/) from cert-manager. -See [external-domain-tls](TODO) for more information on this feature. +See [Configure Knative system-internal encryption](./system-internal-tls.md) for more information on this feature. diff --git a/docs/serving/encryption/external-domain-tls.md b/docs/serving/encryption/external-domain-tls.md new file mode 100644 index 00000000000..0840c7b7388 --- /dev/null +++ b/docs/serving/encryption/external-domain-tls.md @@ -0,0 +1,353 @@ +# Configure external domain encryption + +Knative allows to use either use custom TLS certificates or to use automatically generated TLS certificates +to enable secure HTTPS connections for your Knative Services for the external domain (like `application.example.com`). + +## Before you begin + +You must meet the following requirements to enable secure HTTPS connections: + +- Knative Serving must be installed. For details about installing the Serving + component, see the [Knative installation guides](../../install/yaml-install/serving/install-serving-with-yaml.md). +- You must configure your Knative cluster to use a [custom external domain](../using-a-custom-domain.md). +- Your DNS provider must be setup and configured to your domain. +- A Networking layer such as Kourier, Istio with SDS v1.3 or higher, or Contour v1.1 or higher. See [Install a networking layer](../../install/yaml-install/serving/install-serving-with-yaml.md#install-a-networking-layer). + + +!!! warning + Istio only supports a single certificate per Kubernetes cluster. + To serve multiple domains using your Knative cluster, you must ensure that your new or existing certificate is signed for each of the domains that you want to serve. + + +## Automatically obtain and renew certificates + +### Installing and configuring net-certmanager + +!!! info + 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. + +First, you need to install and configure `cert-manager` and `net-certmanager`. Please refer to [Installing and configuring net-certmanager](./install-and-configure-net-certmanager.md) for details. + + +### Configuring Knative Serving + +Automatic certificate provisioning allows to request certificates in two ways: + +* One certificate for each individual Knative Service +* One wildcard certificate per namespace + +Only one of them can be active at the same time! + +#### Using a certificate for each Knative Service + +Update the [`config-network` ConfigMap](https://github.com/knative/serving/blob/main/config/core/configmaps/network.yaml) 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: + + ```bash + kubectl edit configmap config-network -n knative-serving + ``` + +1. Add the `external-domain-tls: Enabled` attribute under the `data` section: + + ```yaml + apiVersion: v1 + kind: ConfigMap + metadata: + name: config-network + namespace: knative-serving + data: + ... + external-domain-tls: Enabled + ... + ``` + +#### Using one wildcard certificate per namespace + +!!! 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: + +```yaml +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: + +```yaml +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): + +```bash +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](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors). + + +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. + + +## Manually obtain and renew certificates + +There are various ways on how to obtain certificates manually. You can either use tools like +[Certbot][cb] or [cert-manager][cm] or provide the certificates manually from another source. +In general, after you obtain a certificate, you must create a Kubernetes secret to use that +certificate in your cluster. See the procedures later in this topic for details +about manually obtaining and configuring certificates. + +### Obtaining a certificate using a tool + +Please refer to the according documentation of the tool: + +- [Certbot docs][cb-docs] +- [cert-manager docs][cm-docs] + +Knative expects a wildcard certificate signed for the DNS domain of your cluster external domain, like + +> `*.yourdomain.com` + +Once you have obtained the certificate and the private key, [create a Kubernetes Secret](#create-a-kubernetes-secret) +for the certificate and key to be used by Knative. + +!!! warning + Certificates issued by Let's Encrypt are valid for only [90days][le-faqs]. Therefore, if you choose to manually obtain and configure your certificates, you must ensure that you renew each certificate before it expires. + + +### Create a Kubernetes Secret + +Use the following steps in the relevant tab to add your certificate to your Knative cluster: + +=== "Contour" + + To add a TLS certificate to your Knative cluster, you must create a + Kubernetes secret and then configure the Knative Contour plugin. + + 1. Create a Kubernetes secret to hold your TLS certificate, `cert.pem`, and the + private key, `key.pem`, by running the command: + + ```bash + kubectl create -n contour-external secret tls default-cert \ + --key key.pem \ + --cert cert.pem + ``` + + !!! note + Take note of the namespace and secret name. You will need these in future steps. + + 1. To use this certificate and private key in different namespaces, you must + create a delegation. To do so, create a YAML file using the following template: + + ```yaml + apiVersion: projectcontour.io/v1 + kind: TLSCertificateDelegation + metadata: + name: default-delegation + namespace: contour-external + spec: + delegations: + - secretName: default-cert + targetNamespaces: + - "*" + ``` + 1. Apply the YAML file by running the command: + + ```bash + kubectl apply -f .yaml + ``` + Where `` is the name of the file you created in the previous step. + + 1. Update the Knative Contour plugin to use the certificate as a fallback + when `external-domain-tls` is disabled by running the command: + + ```bash + kubectl patch configmap config-contour -n knative-serving \ + -p '{"data":{"default-tls-secret":"contour-external/default-cert"}}' + ``` + + + +=== "Istio" + + To add a TLS certificate to your Knative cluster, you create a + Kubernetes secret and then configure the `knative-ingress-gateway`: + + 1. Create a Kubernetes secret to hold your TLS certificate, `cert.pem`, and the + private key, `key.pem`, by entering the following command: + + ```bash + kubectl create --namespace istio-system secret tls tls-cert \ + --key key.pem \ + --cert cert.pem + ``` + + + 1. Configure Knative to use the new secret that you created for HTTPS + connections: + + 1. Run the following command to open the Knative shared `gateway` in edit + mode: + + ```bash + kubectl edit gateway knative-ingress-gateway --namespace knative-serving + ``` + + 1. Update the `gateway` to include the following `tls:` section and + configuration: + + ```yaml + tls: + mode: SIMPLE + credentialName: tls-cert + ``` + + Example: + + ```yaml + # Edit the following object. Lines beginning with a '#' will be ignored. + # An empty file will abort the edit. If an error occurs while saving this + # file will be reopened with the relevant failures. + apiVersion: networking.istio.io/v1alpha3 + kind: Gateway + metadata: + # ... skipped ... + spec: + selector: + istio: ingressgateway + servers: + - hosts: + - "*" + port: + name: http + number: 80 + protocol: HTTP + - hosts: + - TLS_HOSTS + port: + name: https + number: 443 + protocol: HTTPS + tls: + mode: SIMPLE + credentialName: tls-cert + ``` + In this example, `TLS_HOSTS` represents the hosts of your TLS certificate. It can be a single host, multiple hosts, or a wildcard host. + For detailed instructions, please refer [Istio documentation](https://istio.io/latest/docs/tasks/traffic-management/ingress/secure-ingress/) + + +## Verification + +1. Deploy a Knative Service + +1. Check the URL with `kubectl get ksvc -n ` + +1. The service URL should now be **https**: + + ```bash + NAME URL LATEST AGE CONDITIONS READY REASON + autoscale-go https://autoscale-go.default.1.example.com autoscale-go-dd42t 8m17s 3 OK / 3 True + ``` + +## Trust + +!!! note + A quick note on trust, all clients that call the external domain of a Knative Service need to trust the Certificate Authority + that signed the certificates. This is out of scope of Knative, but needs to be addressed to ensure a working system. Especially, + when a Certificate Authority performs a rotation of the CA or the intermediate certificates. Find more information on + [Install and configure net-certmanager](./install-and-configure-net-certmanager.md#managing-trust-and-rotation-without-downtime). + + +## Additional configuration + +### Configuring HTTP redirects + +Knative Serving allows to automatically redirect HTTP traffic, when HTTPS is enabled on external domains. +To configure this + +1. 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. + + ```yaml + data: + http-protocol: Redirected + ``` + + Example: + + ```yaml + apiVersion: v1 + kind: ConfigMap + metadata: + name: config-network + namespace: knative-serving + data: + ... + external-domain-tls: Enabled + http-protocol: Redirected + ... + ``` + +### 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 `autoscale-go` example: + +1. Edit the service using `kubectl edit service.serving.knative.dev/autoscale-go -n default` and add the annotation: + + ```yaml + apiVersion: serving.knative.dev/v1 + kind: Service + metadata: + annotations: + ... + networking.knative.dev/disable-external-domain-tls: "true" + ... + ``` + +1. The service URL should now be **http**, indicating that automatic TLS Certificate provisioning is disabled: + + ```bash + NAME URL LATEST AGE CONDITIONS READY REASON + autoscale-go http://autoscale-go.default.1.example.com autoscale-go-dd42t 8m17s 3 OK / 3 True + ``` + + +[cm]: https://github.com/jetstack/cert-manager +[cm-docs]: https://cert-manager.io/docs/getting-started/ +[le-faqs]: https://letsencrypt.org/docs/faq/ +[cb]: https://certbot.eff.org +[cb-docs]: https://certbot.eff.org/docs/install.html#certbot-auto diff --git a/docs/serving/encryption/install-and-configure-net-certmanager.md b/docs/serving/encryption/install-and-configure-net-certmanager.md new file mode 100644 index 00000000000..fa90a13dcb9 --- /dev/null +++ b/docs/serving/encryption/install-and-configure-net-certmanager.md @@ -0,0 +1,228 @@ +# Installing and configuring net-certmanager + +Knative Serving relies on a bridging-component to use cert-manager for automated certificate provisioning. +If you intend to use that feature, you need to install net-certmanager. + +## Prerequisites + +The following must be installed on your Knative cluster: + +- [Knative Serving](../../install/yaml-install/serving/install-serving-with-yaml.md). +- [`cert-manager`](../../install/installing-cert-manager.md) version `1.0.0` or higher. + + +## Installing net-certmanager + +net-certmanager can be installed using the YAML installation method: + +```bash +kubectl apply -f {{ artifact( repo="net-certmanager", file="release.yaml") }} +``` + +!!! warning + Knative, per default, installs a self-signed cert-manager `ClusterIssuer` for an easy quick-start. + This issuer should **NOT BE USED IN PRODUCTION**! You can add a label filter to the command above, + to remove the issuer from the installation and configure your issuer manually: `--selector knative.dev/issuer-install!="true"` + +Installing net-certmanager using the Knative operator is not yet supported. +But the operator can be configured to install additional manifests from YAML, +see [issue-950](https://github.com/knative/operator/issues/950#issuecomment-1032769274) for more info. + + +## Issuer configuration + +net-certmanager defines three references to [cert-manager issuers](https://cert-manager.io/docs/configuration/issuers/) to configure different CAs +for the [three Knative Serving encryption features](./encryption-overview.md): + +* `issuerRef`: issuer for external-domain certificates used for ingress. +* `clusterLocalIssuerRef`: issuer for cluster-local-domain certificates used for ingress. +* `systemInternalIssuerRef`: issuer for certificates for system-internal-tls certificates used by Knative internal components. + +Per default, Knative uses a self-signed `ClusterIssuer` and net-certmanager references that `ClusterIssuer` for all three configurations. +As this **should not be used in production**, you should think about which CA should be used for each use-case and +how trust will be distributed to the clients calling the encrypted services. For the Knative system components, Knative provides +a way to specify a bundle of CAs that should be trusted (more on this below). + +There is no general answer on how to structure this, here an example on how it could look like: + +| Feature | Certificate Authority | Trusted via | +|--------------------------|--------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| external-domain-tls | Let's encrypt | Browser clients have the Let's encrypt chain already, all the root CAs will be added in company-wide Docker base image by DevOps team. | +| cluster-local-domain-tls | CA provided by cluster operator | The CA is managed by the DevOps team and will be added in company-wide Docker base image. | +| system-internal-tls | Self-signed Cert-Manager `ClusterIssuer` | The CA will be populated by cert-manager. DevOps team will use [trust-manager](https://cert-manager.io/docs/trust/trust-manager/) to distribute the CA to Knative system components. | + + +### Issuer selection + +In general, you can refer to the [cert-manager documentation](https://cert-manager.io/docs/configuration/acme/#creating-a-basic-acme-issuer). There are examples available for: + +* [CA based on a K8s secret](https://cert-manager.io/docs/configuration/ca/) +* [Let's encrypt](https://cert-manager.io/docs/configuration/acme/#creating-a-basic-acme-issuer) +* [DNS-01 challenges](https://cert-manager.io/docs/configuration/acme/dns01/) +* [Self-signed issuers](https://cert-manager.io/docs/configuration/selfsigned/) + +!!! important + Please note, that not all issuer types work for each Knative feature. + +`cluster-local-domain-tls` needs to be able to sign certificates for cluster-local domains like `myapp.`, `myapp..svc` and `myapp..svc.cluster.local`. +As the CA usually is not within the cluster, verification via ACME protocol (DNS01/HTTP01) is not possible. You can use an issuer that allows creating the these certificates (e.g. CA issuer). + +`system-internal-tls` needs to be able to sign specific SANs that Knative validates for. As these kn-routingcomponents are not strictly routable, the defined set of SANs is: + +* `kn-routing` +* `kn-user-` (where is each namespace where Knative Services are created) +* `data-plane.knative.dev` + +As this is also not possible via ACME protocol (DNS01/HTTP01), you need to configure an issuer that allows creating the these certificates (e.g. CA issuer). + + +### Configuring issuers + +1. Create your `Issuer` and/or `ClusterIssuer` + +1. Ensure that your namespace `Issuer` or `ClusterIssuer` exists: + + ```bash + kubectl get clusterissuer -o yaml + ``` + ```bash + kubectl get issuer -n -o yaml + ``` + + Result: The `Status.Conditions` should include `Ready=True`. + +1. Then reference it in the `config-certmanager` ConfigMap: + + ```bash + kubectl edit configmap config-certmanager -n knative-serving + ``` + + Add the fields within the `data` section: + + ```yaml + 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 + clusterLocalIssuerRef: | + kind: ClusterIssuer + name: cluster-local-ca-issuer + systemInternalIssuerRef: | + kind: ClusterIssuer + name: self-signed-issuer + ``` + + Ensure that the file was updated successfully: + + ```bash + kubectl get configmap config-certmanager -n knative-serving -o yaml + ``` + + +## Managing trust and rotation without downtime + +As pointed out above, each client that calls a Knative Service using HTTPS needs to trust the CA and/or intermediate chain. +If you take a look at the [encryption overview](./encryption-overview.md), you can see that there are multiple places where +trust needs to be distributed: + +* **Cluster external client (Browser and/or other application)**: this is considered out of scope of Knative. +* **Cluster internal client (e.g. Knative or Vanilla K8s workload)**: see below. +* **Knative system components (e.g. Activator, Queue-Proxy, Ingress-Controller)**: see below. + + +### Trusting for cluster internal clients (e.g. Knative or Vanilla K8s workload) + +As we do not control all your workload and the settings are highly dependent on your runtime and/or language, this is out of scope of Knative. +But here a few points to consider. There are several ways on how to provide CAs to your application: + +* Adding the CA bundle to a Container image on build-time (be aware that this causes more strain on CA rotation) +* Mounting a CA bundle to the filesystem (e.g. from a `Secret` or `ConfigMap`) +* Reading it from environment variable +* Accessing it from a `Secret`/`ConfigMap` via K8s API + +Important is to decide if a reload without downtime is necessary, if so the workload must either watch changes on the K8s resource or watch the filesystem. For the latter it is important, that `ionotify` on changing Secrets/ConfigMaps does not work super reliable on K8s. Tests showed that it is more reliable to regularly poll and check the certificate on the filesystem for changes. + +Here are a few examples for golang: + +* Saving the bundle as a file to a defined path: [https://go.dev/src/crypto/x509/root_linux.go](https://go.dev/src/crypto/x509/root_linux.go) (note does not reload without restart) +* Reloading dynamically via K8s API: [https://github.com/knative/serving/blob/main/pkg/activator/certificate/cache.go](https://github.com/knative/serving/blob/main/pkg/activator/certificate/cache.go#L95) +* Reloading from filesystem with a watcher process: [https://github.com/knative/serving/blob/main/pkg/queue/certificate/watcher.go](https://github.com/knative/serving/blob/main/pkg/queue/certificate/watcher.go#L32) + + +### Trusting for Knative system components + +Knative system components can be configured to trust one or many CA bundles from `ConfigMaps`. The cluster operator needs to make sure, +to configure them accordingly to avoid any downtimes [during a rotation](#trust-during-rotation). Knative components look for a `ConfigMap` +in the namespace where the component runs, e.g: + +* knative-serving +* istio-system (when using net-istio) +* kourier-system (when using net-kourier) +* Each namespace where a Knative Service runs + +Knative looks for a `ConfigMap` with the label `knative-ca-trust-bundle="true"` and will read all keys. One key can contain one or multiple CAs/Intermediates. +If they are valid, they will be added to the trust store of the Knative components. + +Here is an example of how `ConfigMap` could look like: + +```yaml +apiVersion: v1 +data: + cacerts.pem: | + -----BEGIN CERTIFICATE----- + MIIDDTCCAfWgAwIBAgIQMQuip05h7NLQq2TB+j9ZmTANBgkqhkiG9w0BAQsFADAW + MRQwEgYDVQQDEwtrbmF0aXZlLmRldjAeFw0yMzExMjIwOTAwNDhaFw0yNDAyMjAw + OTAwNDhaMBYxFDASBgNVBAMTC2tuYXRpdmUuZGV2MIIBIjANBgkqhkiG9w0BAQEF + AAOCAQ8AMIIBCgKCAQEA3clC3CV7sy0TpUKNuTku6QmP9z8JUCbLCPCLACCUc1zG + FEokqOva6TakgvAntXLkB3TEsbdCJlNm6qFbbko6DBfX6rEggqZs40x3/T+KH66u + 4PvMT3fzEtaMJDK/KQOBIvVHrKmPkvccUYK/qWY7rgBjVjjLVSJrCn4dKaEZ2JNr + Fd0KNnaaW/dP9/FvviLqVJvHnTMHH5qyRRr1kUGTrc8njRKwpHcnUdauiDoWRKxo + Zlyy+MhQfdbbyapX984WsDjCvrDXzkdGgbRNAf+erl6yUm6pHpQhyFFo/zndx6Uq + QXA7jYvM2M3qCnXmaFowidoLDsDyhwoxD7WT8zur/QIDAQABo1cwVTAOBgNVHQ8B + Af8EBAMCAgQwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDwYDVR0TAQH/BAUwAwEB/zAd + BgNVHQ4EFgQU7p4VuECNOcnrP9ulOjc4J37Q2VUwDQYJKoZIhvcNAQELBQADggEB + AAv26Vnk+ptQrppouF7yHV8fZbfnehpm07HIZkmnXO2vAP+MZJDNrHjy8JAVzXjt + +OlzqAL0cRQLsUptB0btoJuw23eq8RXgJo05OLOPQ2iGNbAATQh2kLwBWd/CMg+V + KJ4EIEpF4dmwOohsNR6xa/JoArIYH0D7gh2CwjrdGZr/tq1eMSL+uZcuX5OiE44A + 2oXF9/jsqerOcH7QUMejSnB8N7X0LmUvH4jAesQgr7jo1JTOBs7GF6wb+U76NzFa + 8ms2iAWhoplQ+EHR52wffWb0k6trXspq4O6v/J+nq9Ky3vC36so+G1ZFkMhCdTVJ + ZmrBsSMWeT2l07qeei2UFRU= + -----END CERTIFICATE----- +kind: ConfigMap +metadata: + labels: + knative-ca-trust-bundle: "true" + name: knative-bundle + namespace: knative-serving +``` + +### Using trust-manager to distribute the bundle + +As it can be a cumbersome task to distribute the CA bundle to all the namespaces, you can use [trust-manager](https://cert-manager.io/docs/trust/trust-manager/) +to automatically distribute the CA bundles. Please refer to their documentation for more information on how to do this. + + +### Trust during rotation + +During a rotation of a CA and/or Intermediate certificates your clients will need to trust the old and the new chain until the +rotation is done. Using the [trust approach](#managing-trust-and-rotation-without-downtime) from above, you can do a full +chain rotation without downtime: + +1. Make sure your existing setup is up and running. +2. Make sure all Knative Services have the relevant certificates and are not expired. +3. Make sure your CA (and full chain) is not expired. +4. Add the existing **and** the new CA (and the full chain) to the trust bundle (either manually or via trust-manager). +5. Reconfigure your cert-manager `ClusterIssuers` or `Issuers` to use the new CA. +6. Wait until all certificates are expired and are renewed by cert-manager. +7. All certificates are now signed by the new CA. +8. Add some grace period to make sure all components did pick up all the changes. +9. Remove the old CA from the trust bundle. + + diff --git a/docs/serving/encryption/system-internal-tls.md b/docs/serving/encryption/system-internal-tls.md new file mode 100644 index 00000000000..369b3aa1a35 --- /dev/null +++ b/docs/serving/encryption/system-internal-tls.md @@ -0,0 +1,71 @@ +# Configure Knative system-internal encryption + +## Before you begin + +You must meet the following requirements to enable secure HTTPS connections: + +- Knative Serving must be installed. For details about installing the Serving + component, see the [Knative installation guides](../../install/yaml-install/serving/install-serving-with-yaml.md). + +!!! warning + This feature is currently only supported with Kourier as a networking layer. + +## Enabling system-internal-tls + +First, you need to install and configure `cert-manager` and `net-certmanager`. Please refer to [Installing and configuring net-certmanager](./install-and-configure-net-certmanager.md) for details. + +Then, update the [`config-network` ConfigMap](https://github.com/knative/serving/blob/main/config/core/configmaps/network.yaml) in the `knative-serving` namespace to enable `system-internal-tls`: + +1. Run the following command to edit your `config-network` ConfigMap: + + ```bash + kubectl edit configmap config-network -n knative-serving + ``` + +1. Add the `system-internal-tls: Enabled` attribute under the `data` section: + + ```yaml + apiVersion: v1 + kind: ConfigMap + metadata: + name: config-network + namespace: knative-serving + data: + ... + system-internal-tls: Enabled + ... + ``` + +Congratulations! Knative will now use TLS between its internal system components (Ingress-Controller, Activator and Queue-Proxy). + + +## Verification + +1. Deploy a Knative Service + +1. Check if certificates are created and ready with `kubectl get kcert -n ` + +1. Check if the Queue-Proxy container reads the certificate on startup with + + ```bash + kubectl logs your-pod -n your-knative-service-namespace -c queue-proxy | grep -E 'certDir|Certificate|tls' + ``` + + It should look like this: + + ``` + {"severity":"INFO","timestamp":"2024-01-03T07:07:32.892810888Z","logger":"queueproxy","caller":"certificate/watcher.go:62","message":"Starting to watch the following directories for changes{certDir 15 0 /var/lib/knative/certs } {keyDir 15 0 /var/lib/knative/certs }","commit":"86420f2-dirty","knative.dev/key":"first/helloworld-00001","knative.dev/pod":"helloworld-00001-deployment-75fbb7d488-qgmxx"} + {"severity":"INFO","timestamp":"2024-01-03T07:07:32.89397512Z","logger":"queueproxy","caller":"certificate/watcher.go:131","message":"Certificate and/or key have changed on disk and were reloaded.","commit":"86420f2-dirty","knative.dev/key":"first/helloworld-00001","knative.dev/pod":"helloworld-00001-deployment-75fbb7d488-qgmxx"} + {"severity":"INFO","timestamp":"2024-01-03T07:07:32.894232939Z","logger":"queueproxy","caller":"sharedmain/main.go:282","message":"Starting tls server admin:8022","commit":"86420f2-dirty","knative.dev/key":"first/helloworld-00001","knative.dev/pod":"helloworld-00001-deployment-75fbb7d488-qgmxx"} + {"severity":"INFO","timestamp":"2024-01-03T07:07:32.894268548Z","logger":"queueproxy","caller":"sharedmain/main.go:282","message":"Starting tls server main:8112","commit":"86420f2-dirty","knative.dev/key":"first/helloworld-00001","knative.dev/pod":"helloworld-00001-deployment-75fbb7d488-qgmxx"} + ``` + +## Trust + +!!! warning + A quick note on trust, Knative will automatically trust the CA that signed the Certificates, if the cert-manager issuer allows + putting the CA directly in the field `ca.crt` of the certificates `Secret`. Regardless of that, Cluster admins **should always** + provide a trust-bundle, as described in [Install and configure net-certmanager](./install-and-configure-net-certmanager.md#managing-trust-and-rotation-without-downtime). + This is also strongly recommended in the [cert-manager documentation](https://cert-manager.io/docs/trust/trust-manager/#cert-manager-integration-intentionally-copying-ca-certificates) + to avoid issues with rotation. + diff --git a/docs/serving/encryption/using-certificates-in-networking-layer.md b/docs/serving/encryption/using-certificates-in-networking-layer.md deleted file mode 100644 index 835fbe90e06..00000000000 --- a/docs/serving/encryption/using-certificates-in-networking-layer.md +++ /dev/null @@ -1,256 +0,0 @@ -# Using custom certificates in the networking layers - -Knative allows to use custom TLS certificates to enable secure HTTPS connections for your Knative Services -for the external domain (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](https://github.com/knative/serving/issues/13472)). - -For external domains, you can configure Knative to handle certificates that you manually specify, or -you can enable Knative to automatically obtain and renew certificates. - -You can use either [Certbot][cb] or [cert-manager][cm] to obtain certificates. -Both tools support TLS certificates but if you want to enable Knative for -automatic TLS certificate provisioning, you must install and configure the -cert-manager tool: - -- **Manually obtain and renew certificates**: Both the Certbot and cert-manager - tools can be used to manually obtain TLS certificates. In general, after you - obtain a certificate, you must create a Kubernetes secret to use that - certificate in your cluster. See the procedures later in this topic for details - about manually obtaining and configuring certificates. - -- **Enable Knative to automatically obtain and renew TLS certificates**: You can - also use cert-manager to configure Knative to automatically obtain new TLS - certificates and renew existing ones. If you want to enable Knative to - automatically provision TLS certificates, instead see the - [Enabling automatic TLS certificate provisioning](enabling-automatic-tls-certificate-provisioning.md) topic. - -By default, the [Let's Encrypt Certificate Authority (CA)][le] is used to -demonstrate how to enable HTTPS connections, but you can configure Knative to -use any certificate from a CA that supports the ACME protocol. However, you must -use and configure your certificate issuer to use the -[`DNS-01` challenge type](https://letsencrypt.org/docs/challenge-types/#dns-01-challenge). - -!!! warning - Certificates issued by Let's Encrypt are valid for only [90days][le-faqs]. Therefore, if you choose to manually obtain and configure your certificates, you must ensure that you renew each certificate before it expires. - -[cm]: https://github.com/jetstack/cert-manager -[cm-docs]: https://cert-manager.readthedocs.io/en/latest/getting-started/ -[cm-providers]: https://cert-manager.io/docs/configuration/acme/dns01/ -[le]: https://letsencrypt.org -[le-faqs]: https://letsencrypt.org/docs/faq/ -[cb]: https://certbot.eff.org -[cb-docs]: https://certbot.eff.org/docs/install.html#certbot-auto -[cb-providers]: https://certbot.eff.org/docs/using.html#changing-the-acme-server -[cb-cli]: https://certbot.eff.org/docs/using.html#certbot-command-line-options - -## Before you begin - -You must meet the following requirements to enable secure HTTPS connections: - -- Knative Serving must be installed. For details about installing the Serving - component, see the [Knative installation guides](../../install/yaml-install/serving/install-serving-with-yaml.md). -- You must configure your Knative cluster to use a [custom domain](../using-a-custom-domain.md). - -!!! warning - Istio only supports a single certificate per Kubernetes cluster. - To serve multiple domains using your Knative cluster, you must ensure that your new or existing certificate is signed for each of the domains that you want to serve. - -## Obtaining a TLS certificate - -If you already have a signed certificate for your domain, see -[manually adding a TLS certificate](#manually-adding-a-tls-certificate) for -details about configuring your Knative cluster. - -If you need a new TLS certificate, you can choose to use one of the following -tools to obtain a certificate from Let's Encrypt: - -- Setup Certbot to manually obtain Let's Encrypt certificates -- Setup cert-manager to either manually obtain a certificate, or to - automatically provision certificates - -This page covers details for both options. - -For details about using other CA's, see the tool's reference documentation: - -- [Certbot supported providers][cb-providers] -- [cert-manager supported providers][cm-providers] - -### Using Certbot to manually obtain Let’s Encrypt certificates - -Use the following steps to install [Certbot][cb] and the use the tool to -manually obtain a TLS certificate from Let's Encrypt. - -1. Install Certbot by following the [`certbot-auto` wrapper script][cb-docs] - instructions. - -1. Run the following command to use Certbot to request a certificate using DNS - challenge during authorization: - - ```bash - ./certbot-auto certonly --manual --preferred-challenges dns -d '*.default.yourdomain.com' - ``` - - where `-d` specifies your domain. If you want to validate multiple domain's, - you can include multiple flags: - `-d MY.EXAMPLEDOMAIN.1 -d MY.EXAMPLEDOMAIN.2`. For more information, see the - [Cerbot command-line][cb-cli] reference. - - The Certbot tool walks you through the steps of validating that you own each - domain that you specify by creating TXT records in those domains. - - Result: CertBot creates two files: - - - Certificate:`fullchain.pem` - - Private key: `privkey.pem` - -What's next: - -Add the certificate and private key to your Knative cluster by -[creating a Kubernetes secret](#manually-adding-a-tls-certificate). - -### Using cert-manager to obtain Let's Encrypt certificates - -You can install and use [cert-manager][cm] to either manually obtain a -certificate or to configure your Knative cluster for automatic certificate -provisioning: - -**Manual certificates**: - - 1. [Install and configure cert-manager](../../install/installing-cert-manager.md). - - 1. Continue to the steps about - [manually adding a TLS certificate](#manually-adding-a-tls-certificate) by - creating and using a Kubernetes secret. - -**Automatic certificates**: - -See [enabling automatic TLS certificate provisioning](enabling-automatic-tls-certificate-provisioning.md). - - -## Manually adding a TLS certificate - -If you have an existing certificate or have used one of the Certbot or -cert-manager tool to manually obtain a new certificate, you can use the -following steps in the relevant tab to add that certificate to your Knative cluster. - - -=== "Contour" - - To manually add a TLS certificate to your Knative cluster, you must create a - Kubernetes secret and then configure the Knative Contour plugin. - - 1. Create a Kubernetes secret to hold your TLS certificate, `cert.pem`, and the - private key, `key.pem`, by running the command: - - ```bash - kubectl create -n contour-external secret tls default-cert \ - --key key.pem \ - --cert cert.pem - ``` - - !!! note - Take note of the namespace and secret name. You will need these in future steps. - - 1. To use this certificate and private key in different namespaces, you must - create a delegation. To do so, create a YAML file using the following template: - - ```yaml - apiVersion: projectcontour.io/v1 - kind: TLSCertificateDelegation - metadata: - name: default-delegation - namespace: contour-external - spec: - delegations: - - secretName: default-cert - targetNamespaces: - - "*" - ``` - 1. Apply the YAML file by running the command: - - ```bash - kubectl apply -f .yaml - ``` - Where `` is the name of the file you created in the previous step. - - 1. Update the Knative Contour plugin to use the certificate as a fallback - when `external-domain-tls` is disabled by running the command: - - ```bash - kubectl patch configmap config-contour -n knative-serving \ - -p '{"data":{"default-tls-secret":"contour-external/default-cert"}}' - ``` - - - -=== "Istio" - To manually add a TLS certificate to your Knative cluster, you create a - Kubernetes secret and then configure the `knative-ingress-gateway`: - - 1. Create a Kubernetes secret to hold your TLS certificate, `cert.pem`, and the - private key, `key.pem`, by entering the following command: - - ```bash - kubectl create --namespace istio-system secret tls tls-cert \ - --key key.pem \ - --cert cert.pem - ``` - - - 1. Configure Knative to use the new secret that you created for HTTPS - connections: - - 1. Run the following command to open the Knative shared `gateway` in edit - mode: - - ```bash - kubectl edit gateway knative-ingress-gateway --namespace knative-serving - ``` - - 1. Update the `gateway` to include the following `tls:` section and - configuration: - - ```yaml - tls: - mode: SIMPLE - credentialName: tls-cert - ``` - - Example: - - ```yaml - # Edit the following object. Lines beginning with a '#' will be ignored. - # An empty file will abort the edit. If an error occurs while saving this - # file will be reopened with the relevant failures. - apiVersion: networking.istio.io/v1alpha3 - kind: Gateway - metadata: - # ... skipped ... - spec: - selector: - istio: ingressgateway - servers: - - hosts: - - "*" - port: - name: http - number: 80 - protocol: HTTP - - hosts: - - TLS_HOSTS - port: - name: https - number: 443 - protocol: HTTPS - tls: - mode: SIMPLE - credentialName: tls-cert - ``` - In this example, `TLS_HOSTS` represents the hosts of your TLS certificate. It can be a single host, multiple hosts, or a wildcard host. - For detailed instructions, please refer [Istio documentation](https://istio.io/latest/docs/tasks/traffic-management/ingress/secure-ingress/) - -## What's next: - -After your changes are running on your Knative cluster, you can begin using the -HTTPS protocol for secure access your deployed Knative services on external domains.