Contour is a Kubernetes ingress controller that uses the Envoy reverse proxy. Deploy the TKG Extension for Contour Ingress to expose ingress routes to services running on Tanzu Kubernetes clusters.

Extension Prerequisites

This topic describes how to deploy the TKG Extension v1.3.1 for Contour Ingress. Adhere to the following requirements for deploying the extension.

Deploy the Contour Extension

The TKG Extension for Contour Ingress installs two containers on the cluster: Envoy and Contour. For more information, see https://projectcontour.io/.
Container Resource Type Replicas Description
Envoy DaemonSet 3 High performance reverse proxy
Contour Deployment 2 Management and configuration server for Envoy
The extension is configured to pull the containers from the VMware public registry at https://projects.registry.vmware.com/. If you are using a private registry, change the endpoint URL in the data values and extension configurations to match. See Configure the Contour Extension.
  1. Verify that you have completed each of the extension prerequisites. See Extension Prerequisites.
  2. Change directory to where you have downloaded the Contour extension files.
    cd /tkg-extensions-v1.3.1+vmware.1/extensions/ingress/contour
  3. Run the following command to create the tanzu-system-ingress namespace and the Contour service account and role objects.
    kubectl apply -f namespace-role.yaml
  4. Create a Contour data values file for vSphere.
    cp vsphere/contour-data-values-lb.yaml.example vsphere/contour-data-values.yaml
  5. Configure Contour by updating the file vsphere/contour-data-values.yaml.

    The example data values file provides the minimum required configuration. See Configure the Contour Extension for a description of all configuration fields and options.

    For example, the following Contour configuration for vSphere uses a service of type LoadBalancer.
    infrastructure_provider: "vsphere"
    contour:
      image:
        repository: projects.registry.vmware.com/tkg
    envoy:
      image:
        repository: projects.registry.vmware.com/tkg
        tag: v1.17.3_vmware.1
      service:
        type: "LoadBalancer"
    Note: It is recommended that you specify the Envoy image version v1.17.3_vmware.1 so that you do not use Envoy image version v1.16.2_vmware.1 which has a CVE. For more information, see the Release Notes.
  6. Create a secret with the data values.
    kubectl create secret generic contour-data-values --from-file=values.yaml=vsphere/contour-data-values.yaml -n tanzu-system-ingress
    The secret/contour-data-values is created in the tanzu-system-ingress namespace. Verify using the following command:
    kubectl get secrets -n tanzu-system-ingress
  7. Deploy the Contour Ingress controller app.
    kubectl apply -f contour-extension.yaml

    On success you should see app.kappctrl.k14s.io/contour created.

  8. Check the status of the Contour Ingress controller app.
    kubectl get app contour -n tanzu-system-ingress
    On success the status changes from Reconciling to Reconcile succeeded. If the status is Reconcile failed, see Troubleshoot Contour Ingress Deployment.
  9. View detailed information on the Contour Ingress controller app.
    kubectl get app contour -n tanzu-system-ingress -o yaml
  10. View the Envoy service of type LoadBalancer.
    kubectl get service envoy -n tanzu-system-ingress -o wide
    On success you should see the Envoy LoadBalancer details.
    NAME    TYPE           CLUSTER-IP     EXTERNAL-IP     PORT(S)                      AGE     SELECTOR
    envoy   LoadBalancer   10.79.65.110   10.178.147.73   80:30437/TCP,443:30589/TCP   2m42s   app=envoy,kapp.k14s.io/app=1629916985840017976
  11. Verify the Envoy DaemonSet.
    kubectl get daemonsets -n tanzu-system-ingress
    On success you should see the 3-pod Envoy DaemonSet.
    NAME    DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
    envoy   3         3         3       3            3           <none>          6m10s
  12. Verify the Contour Deployment.
    kubectl get deployments -n tanzu-system-ingress
    On success you should see the 2-pod Contour Deployment.
    NAME      READY   UP-TO-DATE   AVAILABLE   AGE
    contour   2/2     2            2           8m7s
  13. Verify that the Contour Ingress controller is installed correctly and ready for use.
    kubectl get pod,svc -n tanzu-system-ingress
    The status of the Contour and Envoy pods should be Running, and the LoadBalancer for the Envoy Service is assigned with an EXTERNAL-IP.
    NAME                           READY   STATUS    RESTARTS   AGE
    pod/contour-84bb5475cf-7h4cx   1/1     Running   0          9m52s
    pod/contour-84bb5475cf-v8k9r   1/1     Running   0          9m52s
    pod/envoy-4828j                2/2     Running   0          9m52s
    pod/envoy-c54dw                2/2     Running   0          9m52s
    pod/envoy-qpjqp                2/2     Running   0          9m52s
    
    NAME              TYPE           CLUSTER-IP     EXTERNAL-IP     PORT(S)                      AGE
    service/contour   ClusterIP      10.105.6.207   <none>          8001/TCP                     9m52s
    service/envoy     LoadBalancer   10.79.65.110   10.178.147.73   80:30437/TCP,443:30589/TCP   9m52s

Troubleshoot Contour Ingress Deployment

If the deployment or reconciliation fails, run kubectl get pods -n tanzu-system-ingress to view pod status. The contour and envoy pods should be Running. If a pod status is ImagePullBackOff or ImageCrashLoopBackOff, the container image could not be pulled. Check the registry URL in the data values and the extension YAML files and make sure they are accurate.

Check the container logs, where name-XXXX is the unique pod name when you run kubectl get pods -A:
kubectl logs pod/envoy-XXXXX -c envoy -n tanzu-system-ingress
 kubectl logs pod/contour-XXXXX -c contour -n tanzu-system-ingress

If you see that a Contour pod is stuck in a ContainerCreating state without failing with one of the above image errors, and without progressing ("contour-xxxxx has timed out progressing"), and it likely means you have an IP address conflict. Make sure that the Nodes CIDR range you specified when you configured the Workload Network does not conflict with the pods CIDR range in the cluster spec, which by default is 192.168.0.0/16. If there is a conflict, update the cluster with a different pods subnet, or change the nodes network.

Update the Contour Extension

Update the Contour extension that is deployed to a Tanzu Kubernetes cluster.

  1. Get Contour data values from the secret.
    kubectl get secret contour-data-values -n tanzu-system-ingress -o 'go-template={{ index .data "values.yaml" }}' | base64 -d > contour-data-values.yaml
    
  2. Update the Contour Ingress data values in ingress/contour/values.yaml. See Configure the Contour Extension.
    For example, the following Contour configuration for vSphere uses a service of type LoadBalancer.
    infrastructure_provider: "vsphere"
    contour:
      image:
        repository: projects.registry.vmware.com/tkg
    envoy:
      image:
        repository: projects.registry.vmware.com/tkg
        tag: v1.17.3_vmware.1
      service:
        type: "LoadBalancer"
    Note: It is recommended that you specify the Envoy image version v1.17.3_vmware.1 so that you do not use Envoy image version v1.16.2_vmware.1 which has a CVE. For more information, see the Release Notes.
  3. Update the Contour data values secret.
    kubectl create secret generic contour-data-values --from-file=values.yaml=contour-data-values.yaml -n tanzu-system-ingress -o yaml --dry-run | kubectl replace -f-
    The Contour extension is reconciled with the new data values.
    Note: By default, kapp-controller will sync apps every 5 minutes. The update should take effect in 5 minutes or less. If you want it to take effect immediately, change syncPeriod in contour-extension.yaml to a lesser value and redeploy the extension using kubectl apply -f contour-extension.yaml.
  4. Check the status of the app.
    kubectl get app contour -n tanzu-system-ingress

    The status should change to Reconcile Succeeded once Contour is updated.

  5. View detailed status.
    kubectl get app contour -n tanzu-system-ingress -o yaml
  6. Troubleshoot if necessary. See Troubleshoot Contour Ingress Deployment.

Delete the Contour Extension

Delete the Contour extension from a Tanzu Kubernetes cluster.

Note: Complete the steps in order. Do not delete the namespace, service account, and role objects before the Contour Ingress controller app is fully deleted. Doing so can lead to system errors.
  1. Change directory to the Contour extension.
    cd extensions/ingress/contour/
  2. Delete the Contour Ingress controller app.
    kubectl delete app contour -n tanzu-system-ingress

    Expected result: app.kappctrl.k14s.io "contour" deleted.

  3. Verify that the Contour Ingress controller app is deleted.
    kubectl get app contour -n tanzu-system-ingress

    Expected result: apps.kappctrl.k14s.io "contour" not found.

  4. Delete the tanzu-system-ingress namespace and the Contour extension service account and role objects.
    kubectl delete -f namespace-role.yaml

Upgrade the Contour Extension

If you have an existing Contour extension deployed, you can upgrade it to the latest version.
  1. Export the Contour configmap and save it as backup.
    kubectl get configmap contour -n tanzu-system-ingress -o 'go-template={{ index .data "contour.yaml" }}' > contour-configmap.yaml
  2. Delete the existing Contour deployment. See Delete the Contour Extension.
  3. Deploy the latest Contour extension. See Deploy the Contour Extension.

Configure the Contour Extension

The Contour Ingress controller configuration values are set in /extensions/ingress/contour/vsphere/contour-data-values.yaml.
Table 1. Contour Ingress Configuration Parameters
Parameter Description Type Default
infrastructure_provider Infrastructure Provider. Supported Values: vsphere, aws, azure string Mandatory parameter
contour.namespace Namespace where contour will be deployed string tanzu-system-ingress
contour.config.requestTimeout Client request timeout to be passed to Envoy time.Duration 0s

See Route Timeout for File Downloads.

contour.config.server.xdsServerType XDS Server type to use: Supported Values: contour or envoy string Null
contour.config.tls.minimumProtocolVersion Minimum TLS version that Contour will negotiate string 1.1
contour.config.tls.fallbackCertificate.name Name of secret containing fallback certificate for requests that don’t match SNI defined for a vhost string Null
contour.config.tls.fallbackCertificate.namespace Namespace of secret containing fallback certificate string Null
contour.config.tls.envoyClientCertificate.name Name of the secret to use as client certificate, private key for TLS connection to backend service string Null
contour.config.tls.envoyClientCertificate.namespace Namespace of the secret to use as client certificate, private key for TLS connection to backend service string Null
contour.config.leaderelection.configmapName Name of configmap to be used for contour leaderelection string leader-elect
contour.config.leaderelection.configmapNamespace Namespace of contour leaderelection configmap string tanzu-system-ingress
contour.config.disablePermitInsecure Disables ingressroute permitInsecure field boolean false
contour.config.accesslogFormat Access log format string envoy
contour.config.jsonFields Fields that will be logged array of strings https://godoc.org/github.com/projectcontour/contour/internal/envoy#JSONFields
contour.config.useProxyProtocol https://projectcontour.io/guides/proxy-proto/ boolean false
contour.config.defaultHTTPVersions HTTP versions that Contour should program Envoy to serve array of strings "HTTP/1.1 HTTP2"
contour.config.timeouts.requestTimeout The timeout for an entire request time.Duration Null (timeout is disabled)
contour.config.timeouts.connectionIdleTimeout The time to wait before terminating an idle connection time.Duration 60s
contour.config.timeouts.streamIdleTimeout The time to wait before terminating an request or stream with no activity time.Duration 5m
contour.config.timeouts.maxConnectionDuration The time to wait before terminating an connection irrespective of activity or not time.Duration Null (timeout is disabled)
contour.config.timeouts.ConnectionShutdownGracePeriod The time to wait between sending an initial and final GOAWAY time.Duration 5s
contour.config.cluster.dnsLookupFamily dns-lookup-family to use for upstream requests to externalName type services from an HTTPProxy route string Null (Supported Values: auto, v4, v6)
contour.config.debug Turn on contour debugging boolean false
contour.config.ingressStatusAddress The address to set on status of every Ingress resource string Null
contour.certificate.duration Duration for contour certificate time.Duration 8760h
contour.certificate.renewBefore Duration before contour certificate should be renewed time.Duration 360h
contour.deployment.replicas No of contour replicas integer 2
contour.image.repository Location of the repository with the Contour image. The default is the public VMware registry. Change this value if you are using a private repository (e.g., air-gapped environment). string projects.registry.vmware.com/tkg
contour.image.name Name of contour image string contour
contour.image.tag Contour image tag. This value may need to be updated if you are upgrading the Contour version. string v1.11.0_vmware.1
contour.image.pullPolicy Contour image pull policy string IfNotPresent
envoy.image.repository Location of the repository with the Envoy image. The default is the public VMware registry. Change this value if you are using a private repository (e.g., air-gapped environment). string projects.registry.vmware.com/tkg
envoy.image.name Name of envoy image string envoy
envoy.image.tag Envoy image tag. This value may need to be updated if you upgrading the Envoy version. string

v1.17.3_vmware.1

Note: Do not use Envoy image v1.16.2_vmware.1 due to a CVE. For more information, see the Release Notes.
envoy.image.pullPolicy Envoy image pull policy string IfNotPresent
envoy.hostPort.enable Flag to expose envoy ports on host boolean true
envoy.hostPort.http Envoy HTTP host port integer 80
envoy.hostPort.https Envoy HTTPS host port integer 443
envoy.service.type Type of service to expose envoy. Supported Values: ClusterIP, NodePort, LoadBalancer string Mandatory parameter for vSphere: NodePort or LoadBalancer, AWS: LoadBalancer, Azure: LoadBalancer
envoy.service.annotations Envoy service annotations Map (Key-values) Empty Map
envoy.service.externalTrafficPolicy External traffic policy of envoy service. Supported Values: Local, Cluster string Cluster
envoy.service.nodePort.http Desired nodePort for service of type NodePort used for http requests integer Null - Kubernetes assigns a dynamic node port
envoy.service.nodePort.https Desired nodePort for service of type NodePort used for HTTPS requests integer Null - Kubernetes assigns a dynamic node port
envoy.deployment.hostNetwork Run envoy on hostNetwork boolean false
envoy.service.aws.LBType AWS LB type to be used for exposing envoy service. Supported Values: classic, nlb string classic
envoy.loglevel Log level to use for envoy string info

Route Timeout for File Downloads

The parameter contour.config.requestTimeout defines the Contour route timeout. The default value is 0s. For most use cases, this setting is appropriate. However, if you are attempting to use Contour with Envoy for file transfer, this value requires further explanation.

According to the Contour documentation, a timeout value of 0s will be treated as if the field were not set, that is, Contour will defer to Envoy and use its default behavior. According to the Envoy documentation, by default Envoy has a 15 second timeout. In addition, Envoy expects the entire request-response operation to be completed in 15 seconds. For large file transfers, this may not be enough time. To disable the Envoy timeout, set the contour.config.requestTimeout value to 0.