Install a Kubernetes Ingress
This is for my own understanding. It might be wrong but reflects my current understanding.
Install an Ingress controller
Create a Cluster
(using kind
)
cat <<EOF | kind create cluster --name kind-ingress --config=-
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
extraPortMappings:
- containerPort: 80
hostPort: 80
protocol: TCP
- containerPort: 443
hostPort: 443
protocol: TCP
EOF
This setup maps ports 80 and 443 from localhost to the ingress. It's like having to map ports in virtual box, back when that was a thing.
Install the nginx Ingress Controller
Apply the official nginx ingress manifest from Kubernetes:
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/kind/deploy.yaml
That deployment
configures the controller. If you look at the URL, it's specific to kind
. There are versions for cloud providers, too.
3. Verify
kubectl get pods -n ingress-nginx
You should an ingress-nginx-controller
pod in the Running
state.
4. Create the ingress
Resource
So, we have the cluster and ingress installed. This is akin to having a server and nginx or apache set up, but no app
behind it. So, if you loaded the URL, you'd only get a stock/default page. We need an app for it to refer to, and set up the routing since the files won't be on the same machine as the server.
This is just some standard hello-world
sample image:
kubectl create deployment hello-world --image=gcr.io/google-samples/hello-app:1.0
kubectl expose deployment hello-world --port=8080
Example Ingress YAML:
cat <<EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: hello-world-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: "hello-world.local"
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: hello-world
port:
number: 8080
EOF
5. Test
Add an entry to your /etc/hosts
file so your local machine routes traffic to the kind cluster:
sudo echo "127.0.0.1 hello-world.local" >> /etc/hosts
Now, you can access the service:
curl http://hello-world.local
Add TLS support
1. Generate TLS Certificates
To test with TLS, a self-signed certificate is needed. For production, you would use something like Let's Encrypt
.
Generate a TLS certificate and key locally:
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout tls.key -out tls.crt \
-subj "/CN=hello-world.local/O=hello-world"
Apply the certificate to the cluster as a secret:
kubectl create secret tls hello-world-tls \
--cert=tls.crt --key=tls.key
2. Update the Ingress Resource
The configuration needs to be updated to reflect the secret.
Updated Ingress YAML:
cat <<EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: hello-world-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
tls:
- hosts:
- hello-world.local
secretName: hello-world-tls # TLS secret created earlier
rules:
- host: hello-world.local
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: hello-world
port:
number: 8080
EOF
3. Verify
Apply the updated Ingress resource:
kubectl apply -f hello-world-ingress.yaml
Check the status of the Ingress:
kubectl describe ingress hello-world-ingress
4. Test as https
Your /etc/hosts
should already have the entry for hello-world.local
but if not, add it.
Now, access the service via HTTPS (the --insecure
hides the self-signed security warning):
curl --insecure https://hello-world.local