Installing Contour on a Tanzu Community Edition cluster
Update 2022-10-21: After just one year in the wild VMware announced on Oct 21 2022 that they would no longer update or maintain the TCE project and that by end of 2022 the Github project will be removed. For more information check out my blog post here
Most of the things mentioned in this post (outside of installing TCE) should still be valid for other Kubernetes distributions
In an earlier post I installed MetalLB as a LoadBalancer service provider on a Tanzu Community Edition (TCE) cluster. A LoadBalancer is essential, but to be able to work with L7 and http we need to make use of the Ingress resource in Kubernetes. Ingress objects requires an Ingress Controller to work, and one of the most popular ones are Contour
To install Contour on TCE we will make use of the Tanzu package repository which makes it easy to deploy and manage software installed in the Kubernetes cluster. For clusters running on other platforms use the Contour documentation for installation instructions
For more information on Tanzu packages and how to get started with it on TCE check out the TCE documentation
Tanzu Package Repository
Add available packages
First, let's check out the cluster and then add the TCE package repo to the cluster with the
1tanzu package repository add tce-repo --url projects.registry.vmware.com/tce/main:0.9.1
To verify that the Package repo was added, and to check out which packages are available to us we run the following commands
List available packages
1tanzu package repository list 2tanzu package available list
Verify that the Repository status is Reconcile succeeded, it migh take a few minutes.
Check the details of a package
Let's check the details of the Contour package
1tanzu package available get contour.community.tanzu.vmware.com
We can also list the available versions for the package
1tanzu package available list contour.community.tanzu.vmware.com
When installing a package we can instruct it to use a yaml file with configuration parameters used during the installation. To check which parameters we can use we'll pull it with the
1tanzu package available get contour.community.tanzu.vmware.com/1.18.1 --values-schema
Before we proceed with the installation of Contour we'll take a quick look at cert-manager.
cert-manager is a piece of software that can serve certificates in our cluster which is good for securing the communication between services in our cluster. It can also integrate with other PKI providers (Like Hashicorp Vault, Let's Encrypt etc.), but that's something for a later post.
The installation of cert-manager is quite straightforward
1tanzu package available list cert-manager.community.tanzu.vmware.com 2tanzu package available get cert-manager.community.tanzu.vmware.com/1.5.3 --values-schema 3tanzu package install cert-manager --package-name cert-manager.community.tanzu.vmware.com --version 1.5.3
Deploy Contour package
To deploy Contour we'll use a pretty simple config. We'll configure it to use cert-manager, and we will tell Envoy to use a service type of LoadBalancer. Note that the structure of the settings when compared to the output we saw earlier is to split the settings by the "." and use the parent/child yaml syntax, i.e.
1envoy: 2 service: 3 type: <value>
The full config file used in my simple setup is the following
1certificates: 2 useCertManager: true 3envoy: 4 service: 5 type: LoadBalancer
That's all there's to it.
We can also verify the deployment from the
kubectl side of things
Now let's test the new Ingress capabilities available to us
We'll create a deployment with a nginx pod (like I normally do) and then expose it with a ClusterIP service type
1apiVersion: apps/v1 2kind: Deployment 3metadata: 4 name: nginx 5 labels: 6 app: my-web 7spec: 8 replicas: 1 9 selector: 10 matchLabels: 11 app: my-web 12 template: 13 metadata: 14 labels: 15 app: my-web 16 spec: 17 containers: 18 - name: nginx 19 image: nginx 20 ports: 21 - containerPort: 80
1kubectl apply -f cont-deployment.yaml 2kubectl expose deployment nginx --type=ClusterIP --port=80
Now let's take a look at the definition for a simple Ingress to work with this
1apiVersion: networking.k8s.io/v1 2kind: Ingress 3metadata: 4 name: nginx-ingress 5 labels: 6 app: my-web 7spec: 8 defaultBackend: 9 service: 10 name: nginx 11 port: 12 number: 80
1kubectl apply -f cont-ingress.yaml
Normally we work with host names, but as the asterix reveals this accepts all requests to the IP
Test HTTP routing with HTTPProxy
Contour comes with a CRD,
HTTPProxy, that let's us route based on the URL prefix which can come in handy. This is an evolution of the
IngressRoute that existed in previous versions.
To do a simple test of this we'll have two nginx deployments running with different background color to make it nice and visual.
The first is the "blue" deployment
1apiVersion: v1 2kind: ConfigMap 3metadata: 4 name: nginx-index-b 5data: 6 index.html: | 7 <html> 8 <head><title>The BLUE page</title></head> 9 <body style="background-color: blue"> 10 <h1>Welcome</h1> 11 </br> 12 <h2>Hi! This is the BLUE page</h2> 13 </body> 14 </html> 15--- 16apiVersion: apps/v1 17kind: Deployment 18metadata: 19 name: nginx-deployment-b 20spec: 21 selector: 22 matchLabels: 23 app: nginx-b 24 replicas: 1 25 template: 26 metadata: 27 labels: 28 app: nginx-b 29 spec: 30 containers: 31 - name: nginx-b 32 image: nginx 33 ports: 34 - containerPort: 80 35 volumeMounts: 36 - name: nginx-index-file 37 mountPath: /usr/share/nginx/html/ 38 volumes: 39 - name: nginx-index-file 40 configMap: 41 name: nginx-index-b
Then we'll do the same for the green deployment and we should have two deployments and two services running
To test HTTPProxy we'll instruct Contour to send requests for the path /green to the "green" service and everything else to the "blue" service
1apiVersion: projectcontour.io/v1 2kind: HTTPProxy 3metadata: 4 name: nginx-http-proxy 5 namespace: default 6spec: 7 virtualhost: 8 fqdn: my-ingress-test.rhmlab.local 9 routes: 10 - conditions: 11 - prefix: / 12 services: 13 - name: nginx-deployment-b 14 port: 80 15 - conditions: 16 - prefix: /green 17 pathRewritePolicy: 18 replacePrefix: 19 - replacement: / 20 services: 21 - name: nginx-deployment-g 22 port: 80
Let's verify with a couple of curl requests
And in the browser
There's a lot more capabilities in HTTPProxy and Contour, check out the documentation for more examples