Ingress can be used to route traffic from an endpoint (or name) to a service which is then forwarded to a pod with matching labels. However, an ingress does not expose arbitrary ports or protocols, which is why services need to be either of type LoadBalancer
or NodePort
.
So far, so good. I followed a guide to install Traefik as an ingress controller and everything is up and running, but I don't understand why it even works. This question is not related to Traefik; I saw this pattern many times.
The first manifest consists of the ingress deployment and a service called traefik-ingress-service
of type LoadBalancer
(works with NodePort
as well).
---
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
name: traefik-ingress-controller
labels:
k8s-app: traefik-ingress-lb-dep
spec:
replicas: 1
selector:
matchLabels:
k8s-app: traefik-ingress-lb
template:
metadata:
labels:
k8s-app: traefik-ingress-lb
name: traefik-ingress-lb
spec:
terminationGracePeriodSeconds: 60
containers:
- image: traefik:v1.7
name: traefik-ingress-lb
ports:
- name: http
containerPort: 80
- name: admin
containerPort: 8080
args:
- --api
- --kubernetes
- --logLevel=INFO
---
kind: Service
apiVersion: v1
metadata:
name: traefik-ingress-service
spec:
selector:
k8s-app: traefik-ingress-lb
ports:
- protocol: TCP
port: 80
name: web
- protocol: TCP
port: 8080
name: admin
# type: NodePort (works as well, but don't forget to add port to uri)
type: LoadBalancer
In order to expose Traefik's UI there is another manifest including a second service (type: default) traefik-web-ui
and an Ingress which connects traffic from /
to traefik-web-ui
.
apiVersion: v1
kind: Service
metadata:
name: traefik-web-ui
spec:
#type: NodePort
selector:
k8s-app: traefik-ingress-lb
ports:
- name: web
port: 80
targetPort: 8080
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: traefik-web-ui
annotations:
kubernetes.io/ingress.class: traefik
spec:
rules:
- host: dashboard.localhost #optional, otherwise cluster's ip
http:
#- http:
paths:
- path: /
backend:
serviceName: traefik-web-ui
servicePort: web
I don't understand why this is working, because service traefik-web-ui
should not be reachable from external. The other service traefik-ingress-service
is, but they are not connected. So, how does this work?
Moreover, I'm curious why I would not just create one service traefik-web-ui
of type NodePort
or LoadBalancer
?
That's how an ingress controller is supposed to work.
You have one load balancer managed by the ingress controller. Each time you create an ingress resource, the traefik configuration (running in your traefik pod) is updated accordingly to route the traffic to your services internally (traefik-web-ui
service in your case).
This image, taken from this very good article, is quite illustrative. The ingress controller (the service + deployment in your first manifest) is the big Ingress box, routing the traffic to the internal services.