Menu Close

Chapter 12. Networking

12.1. Using Service Mesh with OpenShift Serverless

Using Service Mesh with OpenShift Serverless enables developers to configure additional networking and routing options that are not supported when using OpenShift Serverless with the default Kourier implementation. These options include setting custom domains, using TLS certificates, and using JSON Web Token authentication.

Procedure

  1. Add the default namespace to the ServiceMeshMemberRoll as a member:

    apiVersion: maistra.io/v1
    kind: ServiceMeshMemberRoll
    metadata:
      name: default
      namespace: istio-system
    spec:
      members:
        - default
    Important

    Adding sidecar injection to Pods in system namespaces such as knative-serving and knative-serving-ingress is not supported.

  2. Create a network policy that permits traffic flow from Knative system pods to Knative services:

    1. Add the serving.knative.openshift.io/system-namespace=true label to the knative-serving namespace:

      $ oc label namespace knative-serving serving.knative.openshift.io/system-namespace=true
    2. Add the serving.knative.openshift.io/system-namespace=true label to the knative-serving-ingress namespace:

      $ oc label namespace knative-serving-ingress serving.knative.openshift.io/system-namespace=true
    3. Copy the following NetworkPolicy resource into a YAML file:

      apiVersion: networking.k8s.io/v1
      kind: NetworkPolicy
      metadata:
        name: allow-from-serving-system-namespace
        namespace: default
      spec:
        ingress:
        - from:
          - namespaceSelector:
              matchLabels:
                serving.knative.openshift.io/system-namespace: "true"
        podSelector: {}
        policyTypes:
        - Ingress
    4. Apply the NetworkPolicy resource:

      $ oc apply -f <filename>

12.1.1. Enabling sidecar injection for a Knative service

You can add an annotation to the Service resource YAML file to enable sidecar injection for a Knative service.

Procedure

  1. Add the sidecar.istio.io/inject="true" annotation to the Service resource:

    apiVersion: serving.knative.dev/v1
    kind: Service
    metadata:
      name: hello-example-1
    spec:
      template:
        metadata:
          annotations:
            sidecar.istio.io/inject: "true" 1
        spec:
          containers:
          - image: docker.io/openshift/hello-openshift
            name: container
    1
    Add the sidecar.istio.io/inject="true" annotation.
  2. Apply the Service resource YAML file:

    $ oc apply -f <filename>

12.1.2. Additional resources

12.2. Using JSON Web Token authentication with Service Mesh and OpenShift Serverless

You can enable JSON Web Token (JWT) authentication for Knative services by creating a policy in your serverless application namespace that only allows requests with valid JWTs.

Prerequisites

Important

Adding sidecar injection to pods in system namespaces such as knative-serving and knative-serving-ingress is not supported.

Procedure

  1. Copy the following Policy resource into a YAML file:

    Important

    The paths /metrics and /healthz must be included in excludedPaths because they are accessed from system pods in the knative-serving namespace.

    apiVersion: authentication.istio.io/v1alpha1
    kind: Policy
    metadata:
      name: default
    spec:
      origins:
      - jwt:
          issuer: testing@secure.istio.io
          jwksUri: "https://raw.githubusercontent.com/istio/istio/release-1.6/security/tools/jwt/samples/jwks.json"
          triggerRules:
          - excludedPaths:
            - prefix: /metrics
            - prefix: /healthz
      principalBinding: USE_ORIGIN
  2. Apply the Policy resource YAML file:

    $ oc apply -f <filename>

Verification

  1. If you try to use a curl request to get the Knative service URL, it is denied.

    $ curl http://hello-example-default.apps.mycluster.example.com/

    Example output

    Origin authentication failed.

  2. Verify the request with a valid JWT.

    1. Get the valid JWT token by entering the following command:

      $ TOKEN=$(curl https://raw.githubusercontent.com/istio/istio/release-1.6/security/tools/jwt/samples/demo.jwt -s) && echo "$TOKEN" | cut -d '.' -f2 - | base64 --decode -
    2. Access the service by using the valid token in the curl request header:

      $ curl http://hello-example-default.apps.mycluster.example.com/ -H "Authorization: Bearer $TOKEN"

      The request is now allowed.

      Example output

      Hello OpenShift!

12.2.1. Additional resources

12.3. Using custom domains for Knative services with Service Mesh

By default, Knative services have a fixed domain format:

 <application_name>-<namespace>.<openshift_cluster_domain>

You can customize the domain for your Knative service by configuring the service as a private service and creating the required Service Mesh resources.

Prerequisites

12.3.1. Setting cluster availability to cluster-local

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 serving.knative.dev/visibility=cluster-local label to make them private.

Procedure

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

    $ oc label ksvc <service_name> serving.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

12.3.2. Creating necessary Service Mesh resources

Procedure

  1. Create an Istio gateway to accept traffic.

    1. Create a YAML file, and copy the following YAML into it:

      apiVersion: networking.istio.io/v1alpha3
      kind: Gateway
      metadata:
        name: default-gateway
      spec:
        selector:
          istio: ingressgateway
        servers:
        - port:
            number: 80
            name: http
            protocol: HTTP
          hosts:
          - "*"
    2. Apply the YAML file:

      $ oc apply -f <filename>
  2. Create an Istio VirtualService object to rewrite the host header.

    1. Create a YAML file, and copy the following YAML into it:

      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 2
              port:
                number: 80
      1 2
      Your Knative service in the format <service_name>.<namespace>.svc.
    2. Apply the YAML file:

      $ oc apply -f <filename>
  3. Create an Istio ServiceEntry object. This is required for OpenShift Serverless because Kourier is outside of the service mesh.

    1. Create a YAML file, and copy the following YAML into it:

      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.
    2. Apply the YAML file:

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

    1. Create a YAML file, and copy the following YAML into it:

      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.
  1. Apply the YAML file:

    $ oc apply -f <filename>

12.3.3. Accessing a service using your 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!

12.3.4. Additional resources