Ingress
This guide covers setting up ingress on a kind cluster.
Setting Up An Ingress Controller
We can leverage KIND’s extraPortMapping
config option when creating a cluster to forward ports from the host to an ingress controller running on a node.
We can also setup a custom node label by using node-labels
in the kubeadm InitConfiguration
, to be used by the ingress controller nodeSelector
.
- Create a cluster
- Deploy an Ingress controller, we document Ingress NGINX here but other ingresses may work including Contour and Kong, you should follow their docs if you choose to use them.
NOTE: You may also want to consider using Gateway API instead of Ingress. Gateway API has an Ingress migration guide.
You can use blixit to test Gateway API with kind https://github.com/kubernetes-sigs/blixt#usage
Create Cluster
Create a kind cluster with extraPortMappings
and node-labels
.
- extraPortMappings allow the local host to make requests to the Ingress controller over ports 80/443
- node-labels only allow the ingress controller to run on a specific node(s) matching the label selector
cat <<EOF | kind create cluster --config=-
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
EOF
Ingress NGINX
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/kind/deploy.yaml
The manifests contains kind specific patches to forward the hostPorts to the ingress controller, set taint tolerations and schedule it to the custom labelled node.
Now the Ingress is all setup. Wait until is ready to process requests running:
kubectl wait --namespace ingress-nginx \
--for=condition=ready pod \
--selector=app.kubernetes.io/component=controller \
--timeout=90s
Refer Using Ingress for a basic example usage.
Using Ingress
The following example creates simple http-echo services and an Ingress object to route to these services.
Note, this example uses an nginx-specific Ingress annotation which may not be supported by all Ingress implementations.
kind: Pod
apiVersion: v1
metadata:
name: foo-app
labels:
app: foo
spec:
containers:
- command:
- /agnhost
- netexec
- --http-port
- "8080"
image: registry.k8s.io/e2e-test-images/agnhost:2.39
name: foo-app
---
kind: Service
apiVersion: v1
metadata:
name: foo-service
spec:
selector:
app: foo
ports:
# Default port used by the image
- port: 8080
---
kind: Pod
apiVersion: v1
metadata:
name: bar-app
labels:
app: bar
spec:
containers:
- command:
- /agnhost
- netexec
- --http-port
- "8080"
image: registry.k8s.io/e2e-test-images/agnhost:2.39
name: bar-app
---
kind: Service
apiVersion: v1
metadata:
name: bar-service
spec:
selector:
app: bar
ports:
# Default port used by the image
- port: 8080
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
rules:
- http:
paths:
- pathType: Prefix
path: /foo(/|$)(.*)
backend:
service:
name: foo-service
port:
number: 8080
- pathType: Prefix
path: /bar(/|$)(.*)
backend:
service:
name: bar-service
port:
number: 8080
---
Apply the contents
kubectl apply -f https://kind.sigs.k8s.io/examples/ingress/usage.yaml
Now verify that the ingress works
# should output "foo-app"
curl localhost/foo/hostname
# should output "bar-app"
curl localhost/bar/hostname