# Getting Started with Kubernetes Functions can be deployed to any kubernetes cluster which has been configured to support function workloads. This guide details how to set up and configure a kubernetes cluster accordingly. This guide was developed using the dependency versions listed in their requisite sections. Instructions may deviate slightly as these projects are generally under active development. It is recommended to use the links to the official documentation provided in each section. ## Provision a Cluster Any Kubernetes-compatible API should be capable. Included herein are instructions for two popular variants: Kind and EKS. [Provision using Kind](provisioning/provision_kind.md) [Provision using Amazon EKS](provisioning/provision_eks.md) ## Configuring the Cluster Once access to a kubernetes-compatible cluster has been established, it will need to be configured to handle Function workloads. This includes Knative Serving and Eventing, the Kourier networking layer, and CertManager with the LetsEncrypt certificate provider. Create a namespace for your Functions: ``` kubectl create namespace func ``` Set the default namespace for subsequent commands: ``` kubectl config set-context --current --namespace=func ``` ### Serving Docs: https://knative.dev/docs/install/any-kubernetes-cluster/ ) Serving with Kourier networking ``` kubectl apply --filename https://github.com/knative/serving/releases/download/knative-v1.5.0/serving-crds.yaml kubectl apply --filename https://github.com/knative/serving/releases/download/knative-v1.5.0/serving-core.yaml kubectl apply --filename https://github.com/knative/net-kourier/releases/download/knative-v1.5.0/kourier.yaml ``` Update the networking layer to - Use Kourier - use TLS - Redirect HTTP requests to HTTPS - Add func subdomain annotations ``` kubectl apply -f knative/config-network.yaml ``` Note: for environments where Load Balancers are not supported (such as local Kind clusters), the Kourier service will be stuck in a pending state as it is awaiting the underlying infrastructure to provision a load-balancer. This can be solved by updating the Kourier configuration to type NodePort with its networking service attached to the host at ports HTTP 30080 and HTTPS 30443, you can use the following patch file: ``` kubectl patch -n kourier-system services/kourier -p "$(cat knative/config-kourier-nodeport.yaml)" ``` ### Domains Configure cluster-wide domain TLD+1 by editing k8s/config-domain.yaml to include supported domains. First edit `knative/config-domain.yaml` to contain your domain of choice and then apply: ``` kubectl apply -f knative/config-domain.yaml ``` Note that this step is [pending automation](https://github.com/knative-sandbox/kn-plugin-func/issues/47) ### DNS For external routing to the cluster, register domain(s) to be used with a registrar and configure a DNS CNAME to the DNS or IP returned from: (May also register a wildcard subdomain match). ``` kubectl --namespace kourier-system get service kourier ``` For local installations such as Kind, the Kourier networking layer is configured as a local port, so DNS can be resolved by modifying one's local DNS resolver, or /etc/hosts, to point to the local host. ### TLS In order to provision HTTPS routes, we optionally set up a Certificate Manager for the cluster. In this example we configure it to use LetsEncrypt certificates vi a certificate provider and CloudFlare as the DNS provider. #### Cert-Manager Docs: https://cert-manager.io/docs/installation/kubernetes/ ``` kubectl apply --validate=false -f https://github.com/cert-manager/cert-manager/releases/download/v1.9.0-beta.1/cert-manager.yaml ``` Create a Cluster Issuer by updating `tls/letsencrypt-issuer.yaml` with an email addresses for the LetsEncrypt registration and for the associated CloudFlare account: ``` kubectl apply -f tls/letsencrypt-issuer.yaml ``` Generate a token with CloudFlare with the following settings: * Permission: Zone - Zone - Read * Permission: Zone - DNS - Edit * Zone Resources: Include - All ZOnes Base64 encode the token: ``` echo -n "$CLOUDFLARE_TOKEN" | base64 ``` Update the `tls/cloudflare-secret.yaml` with the base64-encoded token value and create the secret: ``` kubectl apply -f tls/cloudflare-secret.yaml ``` #### KNative Serving Cert-Manager Integration Install the latest networking certmanager packaged with KNative Serving: Docs: https://knative.dev/docs/serving/using-auto-tls/ ``` kubectl apply --filename https://github.com/knative-sandbox/net-certmanager/releases/download/knative-v1.5.0/release.yaml ``` Edit config-certmanager to reference the letsencrypt issuer. There should be an issuerRef pointing to a ClusterIssuer of name `letsencrypt-issuer`: ``` kubectl edit configmap config-certmanager --namespace knative-serving ``` ### Eventing Eventing with In-memory channels, a Channel broker, and enable the default broker in the func namespace. ``` kubectl apply --filename https://github.com/knative/eventing/releases/download/knative-v1.5.1/eventing-crds.yaml kubectl apply --filename https://github.com/knative/eventing/releases/download/knative-v1.5.1/eventing-core.yaml kubectl apply --filename https://github.com/knative/eventing/releases/download/knative-v1.5.1/in-memory-channel.yaml kubectl apply --filename https://github.com/knative/eventing/releases/download/knative-v1.5.1/mt-channel-broker.yaml ``` GitHub events source: ``` kubectl apply --filename https://github.com/knative/eventing-contrib/releases/download/v0.16.0/github.yaml ``` Learn more about the GitHub source at https://knative.dev/docs/eventing/samples/github-source/index.html Enable Broker for func namespace: ``` kubectl label namespace func knative-eventing-injection=enabled ``` ### Monitoring Optionally the addition of the [metrics-server](https://github.com/kubernetes-sigs/metrics-server) API allows one to run `kubectl top nodes` and `kubectl top pods`. It can be installed with: ``` kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/download/v0.3.7/components.yaml ``` Note that on local clusters such as Kind, it is necessary to add the following arguments to the metrics-server deployment in kube-system: ``` args: - --kubelet-insecure-tls - --kubelet-preferred-address-types=InternalIP ``` ### Troubleshooting Get the installed KNative serving and Eventing versions ``` kubectl get namespace knative-serving -o 'go-template={{index .metadata.labels "serving.knative.dev/release"}}' kubectl get namespace knative-eventing -o 'go-template={{index .metadata.labels "eventing.knative.dev/release"}}' ```