我无法配置 Traefik ingress 按预期工作。
我想看到 3 个不同的服务在路径
/
、/api-server
和 /hermes
上运行。但无论出于何种原因,我在所有路径中都只看到一个应用程序 (theia-svc)。
k8.ingress-traefik.yml:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
ingress.kubernetes.io/force-ssl-redirect: "false"
ingress.kubernetes.io/ssl-redirect: "true"
cert-manager.io/cluster-issuer: letsencrypt
# traefik.ingress.kubernetes.io/rewrite-target: "/"
# traefik.ingress.kubernetes.io/rule-type: "PathPrefixStrip"
traefik.ingress.kubernetes.io/app-root: "/"
# traefik.ingress.kubernetes.io/frontend-entry-points: "http,https"
name: traefik-ingress
spec:
ingressClassName: traefik
rules:
- host: dev.mywebsite.io
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: theia-svc
port:
number: 80
- path: /api-server
pathType: Prefix
backend:
service:
name: api-server-svc
port:
number: 8082
- path: /hermes
pathType: Exact
backend:
service:
name: hermes-svc
port:
number: 8000
- path: /hermes2/
pathType: Exact
backend:
service:
name: hermes-svc
port:
number: 8000
- path: /hermes3/
pathType: Prefix
backend:
service:
name: hermes-svc
port:
number: 8000
tls:
- hosts:
- dev.mywebsite.io
secretName: tls-secret
kubectl get service
抓取IP进行测试:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
api-server-svc LoadBalancer 10.104.36.20 23.29.118.63 8082:32017/TCP 137m app=api-server-pod
hermes-svc ClusterIP 10.106.25.215 <none> 8000/TCP 67m app=hermes-pod
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 5h36m <none>
theia-svc ClusterIP 10.96.41.226 <none> 80/TCP 5h7m app=theia-pod
curl 10.106.25.215:8000
测试 hermes-svc:
<!DOCTYPE html><html>...</html>
浏览器中的结果:
- https://dev.mywebsite.io/api-server => 404
- https://dev.mywebsite.io/ => theia-svc
- https://dev.mywebsite.io/hermes => theia-svc
- https://dev.mywebsite.io/hermes/ => theia-svc
- https://dev.mywebsite.io/hermes2 => theia-svc
- https://dev.mywebsite.io/hermes2/ => 404
- https://dev.mywebsite.io/hermes3 => theia-svc
- https://dev.mywebsite.io/hermes3/ => 404
我发现我阅读了错误的文档,因此使用了错误的清单语法。我能够修复路由问题,但现在我没有看到应用 TLS (https) 证书,而之前的清单中路由损坏的情况就是如此。
新的k8.ingress-traefik.yml:
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: traefik-ingressroute
spec:
entryPoints:
- web
- websecure
routes:
- match: Host(`dev.mywebsite.io`) && PathPrefix(`/api-server`)
kind: Rule
services:
- name: api-server-svc
port: 8082
middlewares:
- name: stripprefix
- match: Host(`dev.mywebsite.io`) && PathPrefix(`/hermes`)
kind: Rule
services:
- name: hermes-svc
port: 8000
middlewares:
- name: stripprefix
tls:
certResolver: myresolver
options:
name: traefik-tls-option
---
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: stripprefix
spec:
stripPrefix:
prefixes:
- /api-server
- /hermes
---
apiVersion: traefik.containo.us/v1alpha1
kind: TLSOption
metadata:
name: traefik-tls-option
spec:
minVersion: VersionTLS12
cipherSuites:
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
- TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
- TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
- TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
curvePreferences:
- CurveP521
- CurveP384
sniStrict: true
您的入口资源存在多个问题。
首先,正如我在评论中指出的,规则是按顺序处理的。如果您的第一条规则是匹配 /
的前缀规则,那么它将匹配
everything;其他规则并不重要。 接下来,您对前两个
Exact
路径使用
/hermes*
规则,但尾部斜杠的使用不一致。你有:
/hermes
/hermes2/
/hermes3/
/
的使用不一致。这意味着:
对/hermes
/hermes
的规则。对 /hermes/
/hermes2
/hermes2/
/hermes2/
的规则。对 /hermes3
/hermes3/
/hermes3/
的规则。对 /hermes3/foo
/hermes3/
的规则。
/hermes
和
/hermes/
去同一个地方...好吧,欢迎来到 Traefik 问题#5159(以及#563、#4521、#3330、#4804、#3852) 、#1037 等)。 根据您的要求,最简单的解决方案可能是将您的
Exact
规则替换为
Prefix
规则。如果我们改为编写(我已删除 SSL 配置,因为它与这些测试无关):apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: traefik-ingress
spec:
ingressClassName: traefik
rules:
- host: dev.mywebsite.io
http:
paths:
- path: /api-server
pathType: Prefix
backend:
service:
name: api-server-svc
port:
number: 8082
- path: /hermes
pathType: Prefix
backend:
service:
name: hermes-svc
port:
number: 8000
- path: /
pathType: Prefix
backend:
service:
name: theia-svc
port:
number: 80
然后我们得到:
- http://dev.mywebsite.io/api-server => api
- http://dev.mywebsite.io/ => theia
- http://dev.mywebsite.io/hermes => hermes
- http://dev.mywebsite.io/hermes/ => hermes
- http://dev.mywebsite.io/hermes2 => hermes
- http://dev.mywebsite.io/hermes2/ => hermes
- http://dev.mywebsite.io/hermes3 => hermes
- http://dev.mywebsite.io/hermes3/ => hermes
当然,这也意味着我们得到:
- http://dev.mywebsite.io/hermes113 => hermes
- http://dev.mywebsite.io/hermes_was_dog => hermes
等等
或者,您可以通过引入一些正则表达式中间件来解决尾部斜杠问题。鉴于这些清单:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
traefik.ingress.kubernetes.io/router.middlewares: example-add-trailing-slash@kubernetescrd
labels:
app: traefik-example
name: traefik-ingress
spec:
ingressClassName: traefik
rules:
- host: dev.mywebsite.io
http:
paths:
- backend:
service:
name: api-server-svc
port:
number: 8082
path: /api-server
pathType: Prefix
- backend:
service:
name: hermes-svc
port:
number: 8000
path: /hermes/
pathType: Exact
- backend:
service:
name: hermes-svc
port:
number: 8000
path: /hermes2/
pathType: Exact
- backend:
service:
name: hermes-svc
port:
number: 8000
path: /hermes3/
pathType: Prefix
- backend:
service:
name: theia-svc
port:
number: 80
path: /
pathType: Prefix
---
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
labels:
app: traefik-example
name: add-trailing-slash
spec:
redirectRegex:
permanent: true
regex: ^https?://(.*)/(hermes[23]?)$
replacement: /${2}/
我们得到以下行为:
- http://dev.mywebsite.io/api-server => api
- http://dev.mywebsite.io/ => theia
- http://dev.mywebsite.io/hermes => hermes
- http://dev.mywebsite.io/hermes/ => hermes
- http://dev.mywebsite.io/hermes/foo => theia
- http://dev.mywebsite.io/hermes2 => hermes
- http://dev.mywebsite.io/hermes2/ => hermes
- http://dev.mywebsite.io/hermes2/foo => theia
- http://dev.mywebsite.io/hermes3 => hermes
- http://dev.mywebsite.io/hermes3/ => hermes
- http://dev.mywebsite.io/hermes3/foo => hermes
- http://dev.mywebsite.io/hermes113 => theia
- http://dev.mywebsite.io/hermes_was_a_dog => theia
:请注意,在引用中间件时,Traefik 要求您添加部署 Ingress 的命名空间;我将上述清单部署到名为 example
的命名空间中,因此
add-trailing-slash
中间件被引用为 example-add-trailing-slash
。在上面的示例中,请注意 /hermes
和
/hermes/
都转到 hermes-svc
,但 /hermes/foo
不,因为您使用的是
Exact
路径规则(对于 /hermes2
也类似)。 这对于 /hermes3/foo
来说不是这样,因为在该规则中您使用的是
Prefix匹配。 我已经整理了一个完整的示例here为了处理您最近的评论,我假设我们应该将所有内容都匹配为
Prefix
,而不是使用
Exact
,这样:
http://dev.mywebsite.io/api-server/a/b/c
api-server
,路径为 /a/b/c
http://dev.mywebsite.io/hermes/a/b/c
hermes
,路径为 /a/b/c
http://dev.mywebsite.io/hermes2/a/b/c
hermes
,路径为 /a/b/c
http://dev.mywebsite.io/hermes3/a/b/c
hermes
,路径为 /a/b/c
stripPrefix
中间件
,如下所示:
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: strip-prefix
spec:
stripPrefix:
forceSlash: false
prefixes:
- /api-server
- /hermes2
- /hermes3
- /hermes
并像这样编写我们的 Ingress:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: traefik-ingress
annotations:
traefik.ingress.kubernetes.io/router.middlewares: example-add-trailing-slash@kubernetescrd,example-strip-prefix@kubernetescrd
spec:
ingressClassName: traefik
rules:
- host: dev.mywebsite.io
http:
paths:
- path: /api-server
pathType: Prefix
backend:
service:
name: api-server-svc
port:
number: 8082
- path: /hermes
pathType: Prefix
backend:
service:
name: hermes-svc
port:
number: 8000
- path: /hermes2
pathType: Prefix
backend:
service:
name: hermes-svc
port:
number: 8000
- path: /hermes3
pathType: Prefix
backend:
service:
name: hermes-svc
port:
number: 8000
- path: /
pathType: Prefix
backend:
service:
name: theia-svc
port:
number: 80
请注意,我们在本例中同时使用了
add-trailing-slash
和
strip-prefix
中间件。我已经更新了链接的存储库