Testing Kind Kubernetes cluster in your virtual machine
I created a VPS with 16GB of RAM and 6 CPU to test my applications in a Kubernetes cluster.
First you need to install Docker and Kind.
For docker you can use this useful script:
# Add Docker's official GPG key:
sudo apt-get update
sudo apt-get install ca-certificates curl gnupg
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
# Add the repository to Apt sources:
echo \
"deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \
"$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
Add your user to docker group:
sudo usermod -aG docker $USER
Now create a file with Kind configuration:
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
extraPortMappings:
- containerPort: 30167
hostPort: 80
- containerPort: 30794
hostPort: 443
kubeadmConfigPatches:
- |
kind: InitConfiguration
nodeRegistration:
kubeletExtraArgs:
node-labels: "ingress-ready=true"
name: kindly
networking:
ipFamily: ipv4
apiServerAddress: 192.168.1.88
Install Kind
curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.20.0/kind-linux-amd64
chmod +x ./kind
sudo mv ./kind /usr/local/bin/kind
And create the cluster:
kind create cluster --config kind.yaml
Install Kubectl:
sudo apt-get update && sudo apt-get install -y apt-transport-https gnupg2
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
echo "deb https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee -a /etc/apt/sources.list.d/kubernetes.list
sudo apt-get update
sudo apt-get install -y kubectl
Install Krew and some good plugins:
(
set -x; cd "$(mktemp -d)" &&
OS="$(uname | tr '[:upper:]' '[:lower:]')" &&
ARCH="$(uname -m | sed -e 's/x86_64/amd64/' -e 's/\(arm\)\(64\)\?.*/\1\2/' -e 's/aarch64$/arm64/')" &&
KREW="krew-${OS}_${ARCH}" &&
curl -fsSLO "https://github.com/kubernetes-sigs/krew/releases/latest/download/${KREW}.tar.gz" &&
tar zxvf "${KREW}.tar.gz" &&
./"${KREW}" install krew
)
The plugins (you can install more here):
k krew install ns
k krew install ctx
k krew install tree
k krew install view-secret
k krew install modify-secret
...
Install helm:
curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash
MetalLB instalation for LoadBalancer:
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.13.7/config/manifests/metallb-native.yaml
You have to wait for the pods to be ready:
kubectl get pods -n metallb-system
NAME READY STATUS RESTARTS AGE
controller-789c75c689-x8rd9 1/1 Running 0 100s
speaker-cxw6j 1/1 Running 0 100s
Traefik installation:
k create ns traefik && k ns traefik
helm repo add traefik https://helm.traefik.io/traefik
helm repo update
helm install traefik traefik/traefik
If the load balancer is not ready, you need to check the ports:
k get svc -n traefik
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
traefik LoadBalancer 10.96.145.19 <pending> 80:32699/TCP,443:30199/TCP 3m32s
And now you will need to change the ports in the Traefik configuration:
You need to put the ports 80 and 443 in the ports 30167 and 30794:
k edit svc traefik -n traefik
Finally we only need to adjust the metallb configuration:
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: example
namespace: metallb-system
spec:
addresses:
- 172.18.255.200-172.18.255.250
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
name: empty
namespace: metallb-system
Let’s publish a simple web to check if everything is working:
First we are going to allow traefik to across the namespace:
kubectl edit deploy traefik -n traefik
Add this line to args
...
- --providers.kubernetescrd.allowCrossNamespace=true
...
Create a namespace:
kubectl create ns tests && kubectl ns tests
A deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
name: apache-deployment
spec:
selector:
matchLabels:
app: apache2
replicas: 1 # tells deployment to run 2 pods matching the template
template:
metadata:
labels:
app: apache2
spec:
containers:
- name: apache2
image: httpd
ports:
- containerPort: 80
The service:
apiVersion: v1
kind: Service
metadata:
labels:
app.kubernetes.io/instance: traefik
name: apache2
spec:
type: ClusterIP
internalTrafficPolicy: Cluster
ipFamilies:
- IPv4
ipFamilyPolicy: SingleStack
ports:
- port: 80
selector:
app: apache2
And the ingress:
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
labels:
app.kubernetes.io/instance: traefik
name: 213.136.89.166
namespace: traefik
spec:
entryPoints:
- web
routes:
- kind: Rule
match: Host(`213.136.89.166`)
services:
- kind: Service
name: apache2
namespace: tests
port: 80
Beautiful screen when you go to the IP: