Ingress

This guide covers setting up ingresson a kind cluster.

Setting Up An Ingress Controller

We can leverage KIND's extraPortMapping config option whencreating a cluster to forward ports from the hostto an ingress controller running on a node.

We can also setup a custom node label by using node-labelsin the kubeadm InitConfiguration, to be usedby the ingress controller nodeSelector.

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
  1. cat <<EOF | kind create cluster --config=-
  2. kind: Cluster
  3. apiVersion: kind.x-k8s.io/v1alpha4
  4. nodes:
  5. - role: control-plane
  6. kubeadmConfigPatches:
  7. - |
  8. kind: InitConfiguration
  9. nodeRegistration:
  10. kubeletExtraArgs:
  11. node-labels: "ingress-ready=true"
  12. authorization-mode: "AlwaysAllow"
  13. extraPortMappings:
  14. - containerPort: 80
  15. hostPort: 80
  16. protocol: TCP
  17. - containerPort: 443
  18. hostPort: 443
  19. protocol: TCP
  20. EOF

Contour

Deploy Contour components.

  1. kubectl apply -f https://projectcontour.io/quickstart/contour.yaml

Apply kind specific patches to forward the hostPorts to theingress controller, set taint tolerations andschedule it to the custom labelled node.

  1. {
  2. "spec": {
  3. "template": {
  4. "spec": {
  5. "nodeSelector": {
  6. "ingress-ready": "true"
  7. },
  8. "tolerations": [
  9. {
  10. "key": "node-role.kubernetes.io/master",
  11. "operator": "Equal",
  12. "effect": "NoSchedule"
  13. }
  14. ]
  15. }
  16. }
  17. }
  18. }

Apply it by running:

  1. kubectl patch daemonsets -n projectcontour envoy -p '{"spec":{"template":{"spec":{"nodeSelector":{"ingress-ready":"true"},"tolerations":[{"key":"node-role.kubernetes.io/master","operator":"Equal","effect":"NoSchedule"}]}}}}'

Now the Contour is all setup to be used.Refer to Using Ingress for a basic example usage.

Additional information about Contour can be found at: projectcontour.io

Ingress NGINX

Apply the mandatory ingress-nginx components

  1. kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.27.0/deploy/static/mandatory.yaml

and expose the nginx service using NodePort.

  1. kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.27.0/deploy/static/provider/baremetal/service-nodeport.yaml

Apply kind specific patches to forward the hostPorts to theingress controller, set taint tolerations andschedule it to the custom labelled node.

  1. {
  2. "spec": {
  3. "template": {
  4. "spec": {
  5. "containers": [
  6. {
  7. "name": "nginx-ingress-controller",
  8. "ports": [
  9. {
  10. "containerPort": 80,
  11. "hostPort": 80
  12. },
  13. {
  14. "containerPort": 443,
  15. "hostPort": 443
  16. }
  17. ]
  18. }
  19. ],
  20. "nodeSelector": {
  21. "ingress-ready": "true"
  22. },
  23. "tolerations": [
  24. {
  25. "key": "node-role.kubernetes.io/master",
  26. "operator": "Equal",
  27. "effect": "NoSchedule"
  28. }
  29. ]
  30. }
  31. }
  32. }
  33. }

Apply it by running:

  1. kubectl patch deployments -n ingress-nginx nginx-ingress-controller -p '{"spec":{"template":{"spec":{"containers":[{"name":"nginx-ingress-controller","ports":[{"containerPort":80,"hostPort":80},{"containerPort":443,"hostPort":443}]}],"nodeSelector":{"ingress-ready":"true"},"tolerations":[{"key":"node-role.kubernetes.io/master","operator":"Equal","effect":"NoSchedule"}]}}}}'

Now the Ingress is all setup to be used.Refer Using Ingress for a basic example usage.

Using Ingress

The following example creates simple http-echo servicesand an Ingress object to route to these services.

  1. kind: Pod
  2. apiVersion: v1
  3. metadata:
  4. name: foo-app
  5. labels:
  6. app: foo
  7. spec:
  8. containers:
  9. - name: foo-app
  10. image: hashicorp/http-echo
  11. args:
  12. - "-text=foo"
  13. ---
  14. kind: Service
  15. apiVersion: v1
  16. metadata:
  17. name: foo-service
  18. spec:
  19. selector:
  20. app: foo
  21. ports:
  22. # Default port used by the image
  23. - port: 5678
  24. ---
  25. kind: Pod
  26. apiVersion: v1
  27. metadata:
  28. name: bar-app
  29. labels:
  30. app: bar
  31. spec:
  32. containers:
  33. - name: bar-app
  34. image: hashicorp/http-echo
  35. args:
  36. - "-text=bar"
  37. ---
  38. kind: Service
  39. apiVersion: v1
  40. metadata:
  41. name: bar-service
  42. spec:
  43. selector:
  44. app: bar
  45. ports:
  46. # Default port used by the image
  47. - port: 5678
  48. ---
  49. apiVersion: extensions/v1beta1
  50. kind: Ingress
  51. metadata:
  52. name: example-ingress
  53. annotations:
  54. ingress.kubernetes.io/rewrite-target: /
  55. spec:
  56. rules:
  57. - http:
  58. paths:
  59. - path: /foo
  60. backend:
  61. serviceName: foo-service
  62. servicePort: 5678
  63. - path: /bar
  64. backend:
  65. serviceName: bar-service
  66. servicePort: 5678
  67. ---

Apply the contents

  1. kubectl apply -f https://kind.sigs.k8s.io/examples/ingress/usage.yaml

Now verify that the ingress works

  1. # should output "foo"
  2. curl localhost/foo
  3. # should output "bar"
  4. curl localhost/bar