Local kubernetes cluster with ingress
Tags: docker, kubernetes, devops
Published: 2022-01-29 17:11:02

---
title: Local kubernetes cluster with ingress
published: true
date: 2022-01-29 00:00:00 UTC
tags: ['docker', 'kubernetes', 'devops']
canonical_url: https://blog.lepape.me/local-kubernetes-cluster-with-ingress
---

For a local cluster, I stopped using Minikube and now only use [KinD](https://kind.sigs.k8s.io/docs/user/quick-start/) (Kubernetes in Docker), that use docker containers as kubernetes nodes.

To install, just have a look [here](https://kind.sigs.k8s.io/docs/user/quick-start/#installation)

## 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](https://kind.sigs.k8s.io/docs/user/ingress/#create-cluster))

```yaml
# 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
```

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:

```bash
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
```

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:

```yaml
# 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
---
```

You should now be able to reach it with using your browser: [http://127.0.0.1.nip.io/test-app](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:

```bash
#!/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!"
```

## Deletion

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