Install the Nginx ingress controller on K3s - or Kind - and deploy a web app
Here is how to quickly install Kubernetes with ingress on your laptop. I use this to test and create operators with the Operator Framework. Still learning though.
I was first using K3s but then I discovered Kind which seems to be even faster, deployment wise. Also it leaves a smaller footprint because it runs in a Docker container. (Didn't manage to run it with podman yet). So I quickly added a paragraph about Kind if you scroll down this post.
K3s
When running K3s, by default Traefik is installed as an ingress controller. You need an ingress controller to expose (web) applications to the outside world. I am however more comfortable with the Nginx ingress controller so let's just install that instead.
In this post I will first install K3s, then install the Nginx ingress controller. Finally I will deploy a little go application (which is going to be fabulous later).
Install K3s with Nginx ingress
1curl -sfL https://get.k3s.io | sh -s - --write-kubeconfig-mode 644 --disable traefik
Wait a bit. When done, we can copy the config file so we can use kubectl.
1mkdir ~/.kube
2sudo cp /etc/rancher/k3s/k3s.yaml ~/.kube/config
Now we are ready to install Nginx ingress:
1kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/provider/baremetal/deploy.yaml
With running kubectl get pods --all-namespaces -w
we can check the progress
1[vagrant@centos02 ~]$ kubectl get pods --all-namespaces -w
2NAMESPACE NAME READY STATUS RESTARTS AGE
3kube-system coredns-66c464876b-2f5gq 1/1 Running 0 21m
4kube-system local-path-provisioner-7ff9579c6-ms2qx 1/1 Running 0 21m
5kube-system metrics-server-7b4f8b595-2kxvv 1/1 Running 0 21m
6ingress-nginx ingress-nginx-controller-7474996559-79ztf 0/1 ContainerCreating 0 21s
7ingress-nginx ingress-nginx-admission-patch-km6v8 0/1 Completed 0 21s
8ingress-nginx ingress-nginx-admission-create-6jqz4 0/1 Completed 0 21s
Great, we have an ingress controller now. But, we do not have a load balancer. So we need to enable the ingress controller to use port 80 and 443 on the host. Let's patch the ingress controller.
Create the patch first:
1cat > ingress.yaml <<EOF
2spec:
3 template:
4 spec:
5 hostNetwork: true
6EOF
Then patch the ingress controller deployment like so:
1kubectl patch deployment ingress-nginx-controller -n ingress-nginx --patch "$(cat ingress.yaml)"
If you now run curl localhost
we see at there is a web server running. That means success!
1[vagrant@centos02 ~]$ curl localhost
2<html>
3<head><title>404 Not Found</title></head>
4<body>
5<center><h1>404 Not Found</h1></center>
6<hr><center>nginx</center>
7</body>
8</html>
Expose a web page
I am working on an application at the moment called 'carolyne'. You can find it here: https://gitlab.com/jacqinthebox/carolyne. I already pushed a container to the Docker hub, so we can just use that for now. Carolyne runs happily on port 4000.
Let's create a deployment and a service object quickly.
1k create namespace apps
Then create the deployment
1cat <<EOF | kubectl apply -f -
2apiVersion: apps/v1
3kind: Deployment
4metadata:
5 name: carolyne
6 namespace: apps
7 labels:
8 app: carolyne
9spec:
10 replicas: 1
11 selector:
12 matchLabels:
13 app: carolyne
14 template:
15 metadata:
16 labels:
17 app: carolyne
18 spec:
19 containers:
20 - name: carolyne
21 image: jacqueline/carolyne:latest
22 ports:
23 - containerPort: 4000
24EOF
Let's create the service
1cat <<EOF | kubectl apply -f -
2apiVersion: v1
3kind: Service
4metadata:
5 name: carolyne-service
6 namespace: apps
7 labels:
8 app: carolyne
9spec:
10 ports:
11 - port: 4000
12 selector:
13 app: carolyne
14EOF
Finally, let's create the ingress rules.
1cat <<EOF | kubectl apply -f -
2apiVersion: networking.k8s.io/v1
3kind: Ingress
4metadata:
5 annotations:
6 kubernetes.io/ingress.class: nginx
7 nginx.ingress.kubernetes.io/rewrite-target: /\$1
8 name: apps-ingress-rules
9 namespace: apps
10spec:
11 rules:
12 - host: carolyne.moonstreet.local
13 http:
14 paths:
15 - backend:
16 service:
17 name: carolyne-service
18 port:
19 number: 4000
20 path: /(.*)
21 pathType: Prefix
22EOF
Need to add the hostname to my hostfile:
1# sudo vim /etc/hosts
2127.0.0.1 localhost carolyne.moonstreet.local
And now we can browse to that lovely web application I just crafted.
And now with Kind!
Install Kind:
1curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.9.0/kind-linux-amd64
2chmod +x ./kind
3sudo mv ./kind /usr/local/bin/kind
Create a Kind cluster like so:
1cat <<EOF | kind create cluster --name sandbox01 --config=-
2kind: Cluster
3apiVersion: kind.x-k8s.io/v1alpha4
4nodes:
5- role: control-plane
6 kubeadmConfigPatches:
7 - |
8 kind: InitConfiguration
9 nodeRegistration:
10 kubeletExtraArgs:
11 node-labels: "ingress-ready=true"
12 extraPortMappings:
13 - containerPort: 80
14 hostPort: 80
15 protocol: TCP
16 - containerPort: 443
17 hostPort: 443
18 protocol: TCP
19EOF
Install Ingress:
1kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/provider/kind/deploy.yaml
And create Carolyne (in the meantime I made a quick manifest):.
1kubectl create namespace apps
2kubectl apply -f https://gitlab.com/jacqinthebox/carolyne/-/raw/master/deploy.yaml