Guide on how to set up Traefik 2.2 with ingressRoutes and whoami service on non-standard entryPoint (e.g. 9001).
Traefik Custom Resource Definitions
--- apiVersion: apiextensions.k8s.io/v1beta1 kind: CustomResourceDefinition metadata: name: ingressroutes.traefik.containo.us spec: group: traefik.containo.us version: v1alpha1 names: kind: IngressRoute plural: ingressroutes singular: ingressroute scope: Namespaced --- apiVersion: apiextensions.k8s.io/v1beta1 kind: CustomResourceDefinition metadata: name: middlewares.traefik.containo.us spec: group: traefik.containo.us version: v1alpha1 names: kind: Middleware plural: middlewares singular: middleware scope: Namespaced --- apiVersion: apiextensions.k8s.io/v1beta1 kind: CustomResourceDefinition metadata: name: ingressroutetcps.traefik.containo.us spec: group: traefik.containo.us version: v1alpha1 names: kind: IngressRouteTCP plural: ingressroutetcps singular: ingressroutetcp scope: Namespaced --- apiVersion: apiextensions.k8s.io/v1beta1 kind: CustomResourceDefinition metadata: name: ingressrouteudps.traefik.containo.us spec: group: traefik.containo.us version: v1alpha1 names: kind: IngressRouteUDP plural: ingressrouteudps singular: ingressrouteudp scope: Namespaced --- apiVersion: apiextensions.k8s.io/v1beta1 kind: CustomResourceDefinition metadata: name: tlsoptions.traefik.containo.us spec: group: traefik.containo.us version: v1alpha1 names: kind: TLSOption plural: tlsoptions singular: tlsoption scope: Namespaced --- apiVersion: apiextensions.k8s.io/v1beta1 kind: CustomResourceDefinition metadata: name: tlsstores.traefik.containo.us spec: group: traefik.containo.us version: v1alpha1 names: kind: TLSStore plural: tlsstores singular: tlsstore scope: Namespaced --- apiVersion: apiextensions.k8s.io/v1beta1 kind: CustomResourceDefinition metadata: name: traefikservices.traefik.containo.us spec: group: traefik.containo.us version: v1alpha1 names: kind: TraefikService plural: traefikservices singular: traefikservice scope: Namespaced --- kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1beta1 metadata: name: traefik-ingress-controller rules: - apiGroups: - "" resources: - services - endpoints - secrets verbs: - get - list - watch - apiGroups: - extensions resources: - ingresses verbs: - get - list - watch - apiGroups: - extensions resources: - ingresses/status verbs: - update - apiGroups: - traefik.containo.us resources: - middlewares - ingressroutes - traefikservices - ingressroutetcps - ingressrouteudps - tlsoptions - tlsstores verbs: - get - list - watch --- kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1beta1 metadata: name: traefik-ingress-controller roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: traefik-ingress-controller subjects: - kind: ServiceAccount name: traefik-ingress-controller namespace: default
Deploy Traefik Deployment
--- apiVersion: apps/v1 kind: Deployment metadata: labels: app.kubernetes.io/instance: traefik app.kubernetes.io/name: traefik name: traefik namespace: default spec: progressDeadlineSeconds: 600 replicas: 1 revisionHistoryLimit: 10 selector: matchLabels: app.kubernetes.io/instance: traefik app.kubernetes.io/name: traefik strategy: rollingUpdate: maxSurge: 1 maxUnavailable: 1 type: RollingUpdate template: metadata: labels: app.kubernetes.io/instance: traefik app.kubernetes.io/name: traefik spec: containers: - args: - --global.checknewversion - --entryPoints.traefik.address=:9000/tcp - --entryPoints.web.address=:8000/tcp - --entryPoints.websecure.address=:8443/tcp - --entryPoints.who.address=:9001/tcp - --api.dashboard=true - --ping=true - --providers.kubernetescrd - --providers.kubernetesingress - --certificatesresolvers.myresolver.acme.tlschallenge=true - --certificatesresolvers.myresolver.acme.email=<email@address.com> - --certificatesresolvers.myresolver.acme.storage=/data/acme.json # Please note that this is the staging Let's Encrypt server. # Once you get things working, you should remove that whole line altogether. - --certificatesresolvers.myresolver.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory image: traefik:2.2.8 imagePullPolicy: IfNotPresent livenessProbe: failureThreshold: 3 httpGet: path: /ping port: 9000 scheme: HTTP initialDelaySeconds: 10 periodSeconds: 10 successThreshold: 1 timeoutSeconds: 2 name: traefik ports: - containerPort: 9000 name: traefik protocol: TCP - containerPort: 8000 name: web protocol: TCP - containerPort: 8443 name: websecure protocol: TCP - containerPort: 9001 name: who protocol: TCP readinessProbe: failureThreshold: 1 httpGet: path: /ping port: 9000 scheme: HTTP initialDelaySeconds: 10 periodSeconds: 10 successThreshold: 1 timeoutSeconds: 2 resources: {} securityContext: capabilities: drop: - ALL readOnlyRootFilesystem: true runAsGroup: 65532 runAsNonRoot: true runAsUser: 65532 terminationMessagePath: /dev/termination-log terminationMessagePolicy: File volumeMounts: - mountPath: /data name: data - mountPath: /tmp name: tmp dnsPolicy: ClusterFirst restartPolicy: Always schedulerName: default-scheduler securityContext: fsGroup: 65532 serviceAccount: traefik serviceAccountName: traefik terminationGracePeriodSeconds: 60 volumes: - emptyDir: {} name: data - emptyDir: {} name: tmp
Notice that “who” entryPoint and containerPort was added.
Deploy Traefik service
--- apiVersion: v1 kind: Service metadata: labels: app.kubernetes.io/instance: traefik app.kubernetes.io/name: traefik name: traefik namespace: default spec: externalTrafficPolicy: Cluster ports: - name: web nodePort: 31463 port: 80 protocol: TCP targetPort: web - name: websecure nodePort: 31496 port: 443 protocol: TCP targetPort: websecure - name: who nodePort: 31498 port: 9001 protocol: TCP targetPort: who selector: app.kubernetes.io/instance: traefik app.kubernetes.io/name: traefik sessionAffinity: None type: LoadBalancer
Notice again the extra “who” port. Chose a random nodePort.
An extra dashboard service is not required anymore.
Deploy Traefik Dashboard IngressRoute
--- apiVersion: traefik.containo.us/v1alpha1 kind: IngressRoute metadata: name: traefik-dashboard spec: entryPoints: - websecure routes: - match: Host(`traefik.example.com`) kind: Rule services: - name: api@internal kind: TraefikService middlewares: - name: auth tls: certResolver: myresolver --- # Redirect to https apiVersion: traefik.containo.us/v1alpha1 kind: Middleware metadata: name: redirect-to-https spec: redirectScheme: scheme: https permanent: true --- apiVersion: traefik.containo.us/v1alpha1 kind: Middleware metadata: name: auth spec: basicAuth: secret: authsecret --- apiVersion: v1 kind: Secret metadata: name: authsecret namespace: default data: users: |2 <base64 encoded user|password>
Deploy whoami Deployment, Service and IngressRoute
--- kind: Deployment apiVersion: apps/v1 metadata: namespace: default name: whoami labels: app: whoami spec: replicas: 2 selector: matchLabels: app: whoami template: metadata: labels: app: whoami spec: containers: - name: whoami image: containous/whoami ports: - name: web containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: whoami spec: ports: - protocol: TCP name: web port: 80 selector: app: whoami --- apiVersion: traefik.containo.us/v1alpha1 kind: IngressRoute metadata: name: whoamitls spec: entryPoints: - who routes: - match: Host(`who.example.com`) kind: Rule services: - name: whoami port: 80
Notice that the entryPoint is set to “who”, therefore the service is exposed on port 9001.