DEV Community

François
François

Posted on • Originally published at blog.lepape.me on

Local kubernetes cluster with ingress

For a local cluster, I stopped using Minikube and now only use KinD (Kubernetes in Docker), that use docker containers as kubernetes nodes.

To install, just have a look here

Customize KinD to have Ingress

You can choose to start you KinD cluster with a simple: kind create cluster, but it is getting interesting to give it some custom YAML config in order to connect your localhost to the cluster (official documentation)

# kind-local.yaml
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
  - containerPort: 443
    hostPort: 443
    protocol: TCP
Enter fullscreen mode Exit fullscreen mode

Start a local cluster with the config:

kind create kind create cluster --config=cluster-kind.yaml.

Ingress

You now can apply the ingress files to your cluster:

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/kind/deploy.yaml

# To wait for the creation to finish:
kubectl wait --namespace ingress-nginx --for=condition=complete job --selector=app.kubernetes.io/component=admission-webhook --timeout=120s
kubectl wait --namespace ingress-nginx --for=condition=ready pod --selector=app.kubernetes.io/component=controller --timeout=120s
Enter fullscreen mode Exit fullscreen mode

Once it is done, it should be easy to access it from your localhost.

Here is a simple app I use to test if it is working:

# Apply it with saving this a file and run `kubectl apply -f my-test-pod.yaml`
---
kind: Pod
apiVersion: v1
metadata:
  name: test-app
  labels:
    app: test-app
spec:
  containers:
  - name: test-app
    image: hashicorp/http-echo:0.2.3
    args:
    - "-text=Hello World!"
---
kind: Service
apiVersion: v1
metadata:
  name: test-service
spec:
  selector:
    app: test-app
  ports:
  - port: 5678
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: test-ingress
spec:
  rules:
  - http:
      paths:
      - pathType: Prefix
        path: "/test-app"
        backend:
          service:
            name: test-service
            port:
              number: 5678
---
Enter fullscreen mode Exit fullscreen mode

You should now be able to reach it with using your browser: http://127.0.0.1.nip.io/test-app. The ingress will notice the endpoint and redirect you to the corresponding service.

And here you are! Now you can test your applications deployments with a local URL, without using production/staging/any cluster and without having to add a custom entry to /etc/hosts.

A bit more about the 127.0.0.1.nip.io magic on their website: https://nip.io/, or with other DNS:

"nip.io maps <anything>[.-]<IP Address>.nip.io in "dot", "dash" or "hexadecimal" notation to the corresponding <IP Address>"

Pretty useful :)

Bash script to tie everything together

And here is a full script to automatically run the steps above:

#!/bin/bash
echo -e '\n[BOOSTRAPING CLUSTER]\n'
kind create cluster --config=cluster-kind.yaml

echo -e '\n[Ingress]\n'
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/kind/deploy.yaml
echo "› Waiting for Ingress to be ready..."
kubectl wait --namespace ingress-nginx --for=condition=complete job --selector=app.kubernetes.io/component=admission-webhook --timeout=120s
kubectl wait --namespace ingress-nginx --for=condition=ready pod --selector=app.kubernetes.io/component=controller --timeout=120s
echo "› Done!"
Enter fullscreen mode Exit fullscreen mode

Deletion

kind delete cluster will clean your entire cluster (therefore the bash script is quite useful to recreate the cluster with the ingress).

Top comments (0)