2021 Call for Code Awards: Live from New York, with SNL’s Colin Jost! Learn more

Update a Knative resource without publishing your custom manifests

Introduction

The artifacts released by Knative Serving and Eventing consist of many Kubernetes resources, meaning that there are many combinations of resources to configure Knative. The custom resources are the source of truth for configuration enabled with different fields, but it is almost impossible to enable all of the possible options. If you want to configure something that the custom resources of Knative Operator do not support, there is a flexible way for you to configure the resources by using customized manifests. You can either overwrite all of the resources, partially update them, or add some resources. This tutorial shows how you can partially update a Knative resource by giving Knative Operator access to your customized manifests within the local volume.

Prerequisites

To replicate the steps of this tutorial, you must install the following tools:

  • Kubectl, which is a Kubernetes command-line tool to run commands against the Kubernetes cluster
  • Knative Operator (0.24 or newer), which is a Kubernetes Operator to install, upgrade, and manage Knative components

In addition, you must set up a Kubernetes cluster (v1.16 or newer) as your environment to install Knative Operator. You may choose to use a Kubernetes service from any major cloud provider, such as IBM Cloud Kubernetes Service. If you choose to use a local Kubernetes cluster on your own machine, you can select minikube or Docker desktop depending on your operating system.

Estimated time

Based on your familiarity with the Knative Operator, it will take 5-10 minutes for you to go through the steps in this tutorial, which include creating the ConfigMap and linking to the YAML file, patching the deployment resource in Knative Operator, and applying the Knative Operator custom resource.

Steps

You can save the resources in a YAML file and make it accessible online for the Knative Operator to retrieve. To learn how to how to extend the configurations with the custom manifests available online, refer to the Extend Knative configurations with customized manifests tutorial. There is an alternative way of mounting a local volume to the deployment resource of Knative Operator, so you don’t need to publish your custom manifests.

It is up to you to change or add any Knative resource with the Knative Operator by applying the custom manifest. In this tutorial, I use the Gateway resource named knative-ingress-gateway, which is available in the network Istio plugin, to walk you through how the resource can be changed if it is unable to configure with the custom resources.

For example, if you want to add a new label called test-label: "test-label" into this resource, you can change any field or section available in it. This tutorial only demonstrates how to add an additional label.

  1. Create a file named custom-yaml.yaml locally with the following content:

    apiVersion: networking.istio.io/v1alpha3
    kind: Gateway
    metadata:
     name: knative-ingress-gateway
     namespace: knative-serving
     labels:
       test-label: "test-label"  # This is the new label you add.
       serving.knative.dev/release: "v0.24.0"
       networking.knative.dev/ingress-provider: istio
    spec:
     selector:
       istio: ingressgateway
     servers:
       - port:
           number: 80
           name: http
           protocol: HTTP
         hosts:
           - "*"
    

    As you can see, the content is exactly the same as the original definition, except that you added test-label: "test-label". If the custom manifest contains the resources that already existed in the default manifest that is bundled in the Knative Operator, the ones in the custom manifest will overwrite the default ones.

  2. Create a ConfigMap named config-manifest from this file with the following command:

    kubectl create configmap config-manifest --from-file=custom-yaml.yaml
    
  3. If the ConfigMap exists, you can update your ConfigMap with the following command:

    kubectl create configmap config-manifest --from-file=custom-yaml.yaml -o yaml --dry-run=client | kubectl replace -f -
    
  4. If you install Knative components with the Knative Operator, you should have a deployment resource named knative-operator in your cluster. Create a file named custom-deploy.json with the following content:

    {
       "spec": {
           "template": {
               "spec": {
                   "containers": [{
                       "name": "knative-operator",
                       "volumeMounts": [{
                           "mountPath": "/knative-custom-manifest",
                           "name": "config-manifest-volume"
                       }]
                   }],
                   "volumes": [{
                       "name": "config-manifest-volume",
                       "configMap": {
                           "name": "config-manifest"
                       }
                   }]
               }
           }
       }
    }
    

    As you see, the mount path is /knative-custom-manifest, which is where you can access the YAML file.

Patch the deployment resource in Knative Operator

  1. Run the following command to patch your deployment of knative-operator:

    kubectl patch deployment knative-operator --patch "$(cat custom-deploy.json)"
    

    Now, the deployment knative-operator should be able to access the local volume at the mount path.

Apply the Knative Operator custom resource

  1. You can install Knative Serving with your customized manifests by applying the following Serving custom resource:

    cat <<-EOF | kubectl apply -f -
    apiVersion: v1
    kind: Namespace
    metadata:
    name: knative-serving
    ---
    apiVersion: operator.knative.dev/v1alpha1
    kind: KnativeServing
    metadata:
     name: knative-serving
     namespace: knative-serving
    spec:
     version: "0.24"
     ingress:
       istio:
         enabled: true
     additionalManifests:
       - URL: /knative-custom-manifest
    EOF
    

    The field spec.additionalManifests provides you with the option to configure the path of the customized manifests. You will see the Gateway resource knative-ingress-gateway is overwritten by the one defined in your YAML file.

  2. Later, if you change your YAML file, you only need to run the following command to update your ConfigMap so that the change will be reflected in the Knative Operator:

    kubectl create configmap config-manifest --from-file=custom-yaml.yaml -o yaml --dry-run=client | kubectl replace -f -
    

Summary

This tutorial demonstrated how you can leverage customized manifests to partially update a Knative resource. This feature is key for Knative Operator because it enables you to configure anything within Knative. It is preferable to use Knative Operator custom resources to configure Knative. However, if the custom resources do not provide the options for you to configure the resources, you can always resort to the custom manifest to change any resource.