Hi - I am configuring Traefik v2 (installed by k3s) to run two Traefik load-balancer services, each assigned their own external IP address defined as address-pools in MetalLB.
The problem I have is similiar to the forum post:
Using multiple metallb IP address pools with Traefik - Traefik / Traefik v2 (latest) - Traefik Labs Community Forum.
I have created two traefik ingress load-balancer services and they are assigned the IP addresses intended:
$ kubectl get -n kube-system svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
traefik LoadBalancer 10.43.114.151 192.168.10.30 9140:31141/TCP,9143:30527/TCP,9151:30031/TCP 14d
traefik-test LoadBalancer 10.43.83.219 192.168.10.32 80:32533/TCP,443:31146/TCP 94m
Note - traefik
is the default ingress LB service setup by k3s, and traefik-test
is the LB I created as an ingress for applications in the test
namespace.
Apologies about the long-winded description - I'm hoping more details is better ...
The issue:
When I try accessing 2 CluserIP service (the apple-service
and banana-service
services) via the fruit-ingress
IngressRoute I get the error - 'failed: No route to host'
:
$ wget http://test.web.local/apple
--2023-08-28 05:00:00-- http://test.web.local/apple
Resolving test.web.local (test.web.local)... 192.168.10.32
Connecting to test.web.local (test.web.local)|192.168.10.32|:80... failed: No route to host.
$ wget http://test.web.local/banana
--2023-08-28 05:00:05-- http://test.web.local/banana
Resolving test.web.local (test.web.local)... 192.168.10.32
Connecting to test.web.local (test.web.local)|192.168.10.32|:80... failed: No route to host.
The fruit-ingress
IngressRoute which performs HTTP routing is:
$ kubectl get -n test ingressroute
NAME AGE
fruit-ingress 136m
The ClusterIP services the traefik-test
LB should route to are:
$ kubectl get -n test svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
apple-service ClusterIP 10.43.16.73 <none> 5678/TCP 97m
banana-service ClusterIP 10.43.215.131 <none> 5678/TCP 97m
These ClusterIP services are associated with the following pods:
$ kubectl get -n test po
NAME READY STATUS RESTARTS AGE
apple-app 1/1 Running 0 97m
banana-app 1/1 Running 0 97m
Please let feel free to provide advice on troubleshooting and resolving this issue :).
Below is some more details about my configuration and troubleshooting I have performed.
Configuration
The k8s manifest for test
applications and services I am trying to route to using the traefik-test
LB service are :
apiVersion: v1
kind: Namespace
metadata:
name: test
---
kind: Pod
apiVersion: v1
metadata:
name: apple-app
namespace: test
labels:
app: apple
spec:
containers:
- name: apple-app
image: hashicorp/http-echo
args:
- "-text=apple2"
---
kind: Service
apiVersion: v1
metadata:
name: apple-service
namespace: test
spec:
selector:
app: apple
ports:
- port: 5678
---
kind: Pod
apiVersion: v1
metadata:
name: banana-app
namespace: test
labels:
app: banana
spec:
containers:
- name: banana-app
image: hashicorp/http-echo
args:
- "-text=banana2"
---
kind: Service
apiVersion: v1
metadata:
name: banana-service
namespace: test
spec:
selector:
app: banana
ports:
- port: 5678
The manifest used for the IngressRoute to route requests to these services is:
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: fruit-ingress
namespace: test
labels:
app.kubernetes.io/instance: traefik
app.kubernetes.io/name: traefik
spec:
entryPoints:
- test-http
routes:
- match: Host(`test.web.local`) && Path(`/apple`)
kind: Rule
services:
- name: apple-service
port: 5678
- match: Host(`test.web.local`) && Path(`/banana`)
kind: Rule
services:
- name: banana-service
port: 5678
The manifest for the traefik-test
LB service used for the test.web.local
domain (IP address 192.168.10.32) is:
apiVersion: helm.cattle.io/v1
kind: HelmChartConfig
metadata:
name: traefik
namespace: kube-system
spec:
valuesContent: |-
ports:
test-http:
port: 9140
protocol: TCP
expose: true
exposedPort: 9140
test-https:
port: 9143
protocol: TCP
expose: true
exposedPort: 9143
The manifest defining the MetalLB ip address pools used by the Traefik LB services are:
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: pool-default
namespace: metallb-system
spec:
addresses:
- 192.168.2.30/32
---
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: pool-test
namespace: metallb-system
spec:
addresses:
- 192.168.2.32/32
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
name: default-l2advertisement
namespace: metallb-system
spec:
ipAddressPools:
- pool-default
- pool-test
Troubleshooting
Traefik appears to have recognised the HelmChartConfig file I placed in the k3s manifects folder and updated the traefik
deployment with the requested settings:
$ kubectl describe -n kube-system deployments.apps traefik
Name: traefik
Namespace: kube-system
...
Replicas: 1 desired | 1 updated | 1 total | 1 available | 0 unavailable
...
Service Account: traefik
Containers:
traefik:
Image: rancher/mirrored-library-traefik:2.9.4
Ports: 9100/TCP, 9140/TCP, 9143/TCP, 9000/TCP, 8000/TCP, 8443/TCP
Host Ports: 0/TCP, 0/TCP, 0/TCP, 0/TCP, 0/TCP, 0/TCP, 0/TCP
Args:
--global.checknewversion
--global.sendanonymoususage
--entrypoints.metrics.address=:9100/tcp
--entrypoints.test-http.address=:9140/tcp
--entrypoints.test-https.address=:9143/tcp
--entrypoints.traefik.address=:9000/tcp
--entrypoints.web.address=:8000/tcp
--entrypoints.websecure.address=:8443/tcp
--api.dashboard=true
--ping=true
--metrics.prometheus=true
--metrics.prometheus.entrypoint=metrics
--providers.kubernetescrd
--providers.kubernetesingress
--providers.kubernetesingress.ingressendpoint.publishedservice=kube-system/traefik
--entrypoints.websecure.http.tls=true
...
I inspected the logs for both the traefik
and traefik-test
LB services and no errors were displayed:
$ kubectl logs -n kube-system svc/traefik-test
(No log events displayed)
$ kubectl logs -n kube-system svc/traefik
time="2023-08-28T03:20:00Z" level=info msg="Configuration loaded from flags."
I created an busybox pod in the test
namespace to verify connectivity between the ClusterIP services and the associated services - and the tests were successful. Tests run inside busybox pod shell were:
# Send request to `apple-service` cluser IP service.
$ wget -O- http://10.43.215.131:5678
Connecting to 10.43.215.131:5678 (10.43.215.131:5678)
writing to stdout
banana2
- 100% |************************************************************************| 8 0:00:00 ETA
# Send request to `banana-service` cluser IP service.
$ wget -O- http://10.43.16.73:5678
Connecting to 10.43.16.73:5678 (10.43.16.73:5678)
writing to stdout
apple2
- 100% |************************************************************************| 7 0:00:00 ETA