Knative services are automatically assigned a default domain name based on your cluster configuration. For example, <service_name>.<namespace>.example.com.

You can customize the domain for your Knative service by using one of the following methods:

  • Configure the service as a private service and create the required Service Mesh resources.

    This method of configuring custom domains is only supported for clusters that have Kourier enabled. If you want to configure custom domains using only OpenShift Serverless with Service Mesh, without Kourier enabled, use the DomainMapping resources method instead.

  • Map a custom domain name that you own to a Knative service by creating a DomainMapping resource for the service. You can also create multiple DomainMapping resources to map multiple domains and subdomains to a single service.

    You can use DomainMapping resources to map custom domains either with or without Kourier enabled in your cluster, however TLS is not supported in clusters that have both Kourier and domain mapping enabled.

Creating a custom domain mapping

To map a custom domain name to a custom resource (CR), you must create a DomainMapping CR that maps to an Addressable target CR, such as a Knative service or a Knative route.

Prerequisites
  • The OpenShift Serverless Operator and Knative Serving are installed on your cluster.

  • You have created a Knative service and control a custom domain that you want to map to that service.

    Your custom domain must point to the IP address of the OpenShift Container Platform cluster.

Procedure
  1. Create a YAML file containing the DomainMapping CR in the same namespace as the target CR you want to map to:

    apiVersion: serving.knative.dev/v1alpha1
    kind: DomainMapping
    metadata:
     name: <domain_name> (1)
     namespace: <namespace> (2)
    spec:
     ref:
       name: <target_name> (3)
       kind: <target_type> (4)
       apiVersion: serving.knative.dev/v1
    1 The custom domain name that you want to map to the target CR.
    2 The namespace of both the DomainMapping CR and the target CR.
    3 The name of the target CR to map to the custom domain.
    4 The type of CR being mapped to the custom domain.
    Example service domain mapping
    apiVersion: serving.knative.dev/v1alpha1
    kind: DomainMapping
    metadata:
     name: example-domain
     namespace: default
    spec:
     ref:
       name: example-service
       kind: Service
       apiVersion: serving.knative.dev/v1
    Example route domain mapping
    apiVersion: serving.knative.dev/v1alpha1
    kind: DomainMapping
    metadata:
     name: example-domain
     namespace: default
    spec:
     ref:
       name: example-route
       kind: Route
       apiVersion: serving.knative.dev/v1
  2. Apply the DomainMapping CR as a YAML file:

    $ oc apply -f <filename>

Creating a custom domain mapping by using the Knative CLI

You can use the kn CLI to create a DomainMapping custom resource (CR) that maps to an Addressable target CR, such as a Knative service or a Knative route.

The --ref flag specifies an Addressable target CR for domain mapping.

If a prefix is not provided when using the --ref flag, it is assumed that the target is a Knative service in the current namespace. The examples in the following procedure show the prefixes for mapping to a Knative service or a Knative route.

Prerequisites
  • The OpenShift Serverless Operator and Knative Serving are installed on your cluster.

  • You have created a Knative service or route, and control a custom domain that you want to map to that CR.

    Your custom domain must point to the DNS of the OpenShift Container Platform cluster.

  • You have installed the kn CLI tool.

Procedure
  • Map a domain to a CR in the current namespace:

    $ kn domain create <domain_mapping_name> --ref <target_name>
    Example command
    $ kn domain create example-domain-map --ref example-service
  • Map a domain to a Knative service in a specified namespace:

    $ kn domain create <domain_mapping_name> --ref <ksvc:service_name:service_namespace>
    Example command
    $ kn domain create example-domain-map --ref ksvc:example-service:example-namespace
  • Map a domain to a Knative route:

    $ kn domain create <domain_mapping_name> --ref <kroute:route_name>
    Example command
    $ kn domain create example-domain-map --ref kroute:example-route

Configuring custom domains for private Knative services

You can configure a custom domain for an existing Knative service by completing the following procedures.

Prerequisites
  • The OpenShift Serverless Operator and Knative Serving are installed on your OpenShift Container Platform cluster.

  • Red Hat OpenShift Service Mesh version 1.x or 2.x is installed on your cluster, and the integration between Red Hat OpenShift Service Mesh and OpenShift Serverless has been correctly configured.

OpenShift Serverless only supports the use of Red Hat OpenShift Service Mesh functionality that is explicitly documented in this guide, and does not support other undocumented features.

Making Knative services privately accessible

By default, Knative services are published to a public IP address. Being published to a public IP address means that Knative services are public applications, and have a publicly accessible URL.

Publicly accessible URLs are accessible from outside of the cluster. However, developers may need to build back-end services that are only be accessible from inside the cluster, known as private services. Developers can label individual services in the cluster with the networking.knative.dev/visibility=cluster-local label to make them private.

For OpenShift Serverless 1.15.0 and newer versions, the serving.knative.dev/visibility label is no longer available. You must update existing services to use the networking.knative.dev/visibility label instead.

Procedure
  • Set the visibility for your service by adding the networking.knative.dev/visibility=cluster-local label:

    $ oc label ksvc <service_name> networking.knative.dev/visibility=cluster-local
Verification
  • Check that the URL for your service is now in the format http://<service_name>.<namespace>.svc.cluster.local, by entering the following command and reviewing the output:

    $ oc get ksvc
    Example output
    NAME            URL                                                                         LATESTCREATED     LATESTREADY       READY   REASON
    hello           http://hello.default.svc.cluster.local                                      hello-tx2g7       hello-tx2g7       True

Creating necessary Service Mesh resources

You can use the following procedure to create necessary resources for using Service Mesh with OpenShift Serverless.

Procedure
  1. Create an Istio gateway to accept traffic:

    apiVersion: networking.istio.io/v1alpha3
    kind: Gateway
    metadata:
      name: <namespace> (1)
    spec:
      selector:
        istio: ingressgateway
      servers:
      - port:
          number: 80
          name: http
          protocol: HTTP
        hosts:
        - "*"
    1 The namespace where your Knative services have been created. This namespace must be a member of the Service Mesh member roll.
  2. Apply the Gateway resource:

    $ oc apply -f <filename>
  3. Create an Istio virtual service to rewrite the host header:

    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      name: hello
    spec:
      hosts:
      - custom-ksvc-domain.example.com
      gateways:
      - default-gateway
      http:
      - rewrite:
          authority: hello.default.svc (1)
        route:
        - destination:
            host: hello.default.svc (1)
            port:
              number: 80
    1 Your Knative service in the format <service_name>.<namespace>.svc.
  4. Apply the VirtualService resource:

    $ oc apply -f <filename>
  5. Create an Istio service entry. This is required for OpenShift Serverless because Kourier is outside of the Service Mesh:

    apiVersion: networking.istio.io/v1alpha3
    kind: ServiceEntry
    metadata:
      name: hello.default.svc
    spec:
      hosts:
      - hello.default.svc (1)
      location: MESH_EXTERNAL
      endpoints:
      - address: kourier-internal.knative-serving-ingress.svc
      ports:
      - number: 80
        name: http
        protocol: HTTP
      resolution: DNS
    1 Your Knative service in the format <service_name>.<namespace>.svc.
  6. Apply the ServiceEntry resource:

    $ oc apply -f <filename>
  7. Create an OpenShift Container Platform route that points to the VirtualService object:

    apiVersion: route.openshift.io/v1
    kind: Route
    metadata:
      name: hello
      namespace: istio-system (1)
    spec:
      host: custom-ksvc-domain.example.com
      port:
        targetPort: 8080
      to:
        kind: Service
        name: istio-ingressgateway
    1 The OpenShift Container Platform route must be created in the same namespace as the ServiceMeshControlPlane. In this example, the ServiceMeshControlPlane is deployed in the istio-system namespace.
  8. Apply the Route resource:

    $ oc apply -f <filename>

Accessing a service using your custom domain

You can use the following procedure to access a service that uses a custom domain.

Procedure
  1. Access the custom domain by using the Host header in a curl request. For example:

    $ curl -H "Host: custom-ksvc-domain.example.com" http://<ip_address>

    where <ip_address> is the IP address that the OpenShift Container Platform ingress router is exposed to.

    Example output
    Hello OpenShift!

Additional resources