A bit of background
I have an interest in learning more about writing software, learning Golang, and contributing to open source. Over the last few weeks, from a suggestion by Marky Jackson, I've decided to get involved with Project Sigstore. In doing so, I've learned about Tekton, and have decided to include that in my learning toolkit. Tekton is comprised of a few major parts, one of which is the Dashboard
. Since Tekton is cloud native, it runs entirely within a Kubernetes cluster. Many of the docs for Tekton and, if I'm not mistaken, Sigstore, mention the use of Kubernetes in Docker, also known as KinD. KinD was new to me, so I spent some time this week working to get it configured and ready for use. If you're not familiar with KinD, I included a link, but it's a means to running a Kubernetes cluster on your local machine by doing so inside of Docker. Docker can be installed on Linux, Mac, and Windows.
There may be other configurations supported by the tools mentioned here, but I have not explored them. If you are using Podman instead of Docker, I do believe KinD supports running clusters in there as well.
Areas of focus for this post
- Installing and configuring KinD
- Deploying Tekton:
- Pipelines
- Triggers
- Dashboard
- Installing and configuring ingress-nginx
Installing and Configuring KinD
I'm assuming you have Docker installed, if not please visit the Docker installation documentation here
I'm using my Mac at the moment, so to install with homebrew we execute:
brew install kind
You can see other installation instructions for Windows and Linux here
In order to install and make use of the ingress controller, we need to create a cluster using kind with a particular configuration. We will reference a YAML
configuration that includes extraPortMappings
that allows us to expose port 80
and 443
. The below configuration is the one I used. The KinD documentation mentions if you're not using Linux to include the listenAddress
value to send traffic from your machine to the node.
This creates a cluster called
tekton-cluster
. You can change the name to fit what you would like.
cat <<EOF | kind create cluster --name tekton-cluster --config=-
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
kubeadmConfigPatches:
- |
kind: InitConfiguration
nodeRegistration:
kubeletExtraArgs:
node-labels: "ingress-ready=true"
extraPortMappings:
- containerPort: 80
hostPort: 80
protocol: TCP
listenAddress: "127.0.0.1"
- containerPort: 443
hostPort: 443
protocol: TCP
listenAddress: "127.0.0.1"
EOF
After running the above, you should have output that looks like this:
Creating cluster "tekton-cluster" ...
โ Ensuring node image (kindest/node:v1.21.1) ๐ผ
โ Preparing nodes ๐ฆ
โ Writing configuration ๐
โ Starting control-plane ๐น๏ธ
โ Installing CNI ๐
โ Installing StorageClass ๐พ
Set kubectl context to "kind-tekton-cluster"
You can now use your cluster with:
kubectl cluster-info --context kind-tekton-cluster
Have a nice day! ๐
Deploying Tekton
Deploying the Tekton components is pretty straight forward, we're just going to run the following commands. Now, I'm using Tekton because it's what I am currently working on, but you can follow along with a different application or even a demo app.
Install Tekton Pipelines
kubectl apply \
--filename https://storage.googleapis.com/tekton-releases/pipeline/latest/release.yaml
Install Tekton Triggers
kubectl apply \
--filename https://storage.googleapis.com/tekton-releases/triggers/latest/release.yaml
I did run into an issue when running this config where I got a
connection refused
error during install. I reran the command a couple times and it eventually was successful. I haven't dug in here, but wanted to note if you see the same thing.
Install Tekton Dashboard
kubectl apply \
--filename https://storage.googleapis.com/tekton-releases/dashboard/latest/tekton-dashboard-release.yaml
All three of these should now be successfully installed. If we run kubectl -n tekton-pipelines get all
we should see the resources that were created.
kubectl -n tekton-pipelines get all
NAME READY STATUS RESTARTS AGE
pod/tekton-dashboard-5d44ff59bd-ps9fq 1/1 Running 0 40s
pod/tekton-pipelines-controller-956886f78-2kds9 1/1 Running 0 3m37s
pod/tekton-pipelines-webhook-6c6446886c-hjghs 1/1 Running 0 3m37s
pod/tekton-triggers-controller-7455cbc998-t2fkx 1/1 Running 3 3m26s
pod/tekton-triggers-webhook-86b7dd88c6-jt4lz 1/1 Running 3 3m26s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/tekton-dashboard ClusterIP 10.96.99.10 <none> 9097/TCP 40s
service/tekton-pipelines-controller ClusterIP 10.96.42.125 <none> 9090/TCP,8008/TCP,8080/TCP 3m37s
service/tekton-pipelines-webhook ClusterIP 10.96.185.10 <none> 9090/TCP,8008/TCP,443/TCP,8080/TCP 3m37s
service/tekton-triggers-controller ClusterIP 10.96.161.31 <none> 9000/TCP 3m26s
service/tekton-triggers-webhook ClusterIP 10.96.233.161 <none> 443/TCP 3m26s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/tekton-dashboard 1/1 1 1 40s
deployment.apps/tekton-pipelines-controller 1/1 1 1 3m37s
deployment.apps/tekton-pipelines-webhook 1/1 1 1 3m37s
deployment.apps/tekton-triggers-controller 1/1 1 1 3m26s
deployment.apps/tekton-triggers-webhook 1/1 1 1 3m26s
NAME DESIRED CURRENT READY AGE
replicaset.apps/tekton-dashboard-5d44ff59bd 1 1 1 40s
replicaset.apps/tekton-pipelines-controller-956886f78 1 1 1 3m37s
replicaset.apps/tekton-pipelines-webhook-6c6446886c 1 1 1 3m37s
replicaset.apps/tekton-triggers-controller-7455cbc998 1 1 1 3m26s
replicaset.apps/tekton-triggers-webhook-86b7dd88c6 1 1 1 3m26s
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
horizontalpodautoscaler.autoscaling/tekton-pipelines-webhook Deployment/tekton-pipelines-webhook <unknown>/100% 1 5 1 3m37s
Installing and configuring ingress-nginx
First, we are going to install the ingress-nginx controller:
kubectl apply --filename https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/provider/kind/deploy.yaml
Then, we are going to wait for it to become ready by running:
kubectl wait --namespace ingress-nginx \
--for=condition=ready pod \
--selector=app.kubernetes.io/component=controller \
--timeout=90s
When ready, you should see similar output:
pod/ingress-nginx-controller-674cb6ff57-zpxdb condition met
So, moving forward we are going to configure ingress. Before we do so, we're going to create a DNS name that allows us to access our application. I'm going to use a service called nip.io that enables DNS that points to the listening post of our node, in this case 127.0.0.1
. With nip.io
my domain is 127-0-0-1.nip.io
. This is very useful as you don't have to edit your /etc/config
every time you want to test an app. I'm going to point to a subdomain of tekton
for the following configuration, which combined, gives us tekton.127-0-0-1.nip.io
. This domain name will direct to my localhost.
Let's create a file called tekton-ingress.yml
with the following contents:
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: tekton-dashboard
annotations:
ingress.kubernetes.io/ssl-redirect: "false"
nginx.ingress.kubernetes.io/ssl-redirect: "false"
spec:
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: tekton-dashboard
port:
number: 9097
host: tekton.127-0-0-1.nip.io
Now we'll apply the config using the following:
kubectl -n tekton-pipelines apply -f tekton-ingress.yml
Which will output the following when successful:
ingress.networking.k8s.io/tekton-dashboard created
That's it!
We've configured the KinD cluster, installed Tekton components, and configured ingress. You can plug the domain name into your browser and access the Tekton Dashboard.
I hope this was helpful!