Kubernetes Ingress - 将外部路径引用到服务中的另一条路径

Kubernetes Ingress - referring external path to another path in service

我有多个使用不同服务的名称空间
其中一些服务公开了相同的路径,即 /ready

我想为每个 namespace/service 创建一个入口规则,这样 namespaceA/ready 外部 路径实际上会转到 [=12] 下的服务=] 在 /ready 路径

我阅读了有关 rewrite 的内容,但如果我理解正确,它会在全局范围内将 namespaceA/ready 重定向到 /ready,这意味着它的行为就好像路径是 /ready,与命名空间无关。

我不确定。但是大家可能对rewriteredirect有点误解。重写规则不会导致重定向,它会重写请求然后将其发送到特定的后端。配置两个重写规则将两个后缀相同的路径重写到两个不同的后端是完全合理和常见的。

改写如下:

$ curl mydomain.io/test/moretest
404 page not found

$ kubectl logs test-server
Request method=GET path=/moretest status=404 user-agent=curl/7.29.0

重定向然而,工作是这样的:

# curl mydomain.io/test/moretest
Moved Permanently
# curl mydomain.io/moretest
404 page not found

$ kubectl logs test-server
Request method=GET path=/test/moretest status=302 user-agent=curl/7.29.0
Request method=GET path=/moretest status=404 user-agent=curl/7.29.0

我对 Nginx 不熟悉。不过,我知道如何使用 Traefik 实现这一目标。例如,这个 yaml 文件将执行:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: myappA
  namespace: namespaceA
  annotations:
    traefik.ingress.kubernetes.io/rule-type: PathPrefixStrip
spec:
  rules:
  - host: mydomain.io
    http:
      paths:
      - path: /namespaceA
        backend:
         serviceName: myapp
         servicePort: 80
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: myappB
  namespace: namespaceB
  annotations:
    traefik.ingress.kubernetes.io/rule-type: PathPrefixStrip
spec:
  rules:
  - host: mydomain.io
    http:
      paths:
      - path: /namespaceB
        backend:
         serviceName: myapp
         servicePort: 80
  • /namespaceA/ready的所有请求将被重写为/ready,然后发送到namespaceA中的myapp

  • /namespaceB/ready的所有请求将被重写为/ready,然后在namespaceB中发送到myapp

除了Lentil1016 , here is the example of the same rewrite solution for nginx-ingress-controller

---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    ingress.kubernetes.io/ssl-redirect: 'false'
    nginx.ingress.kubernetes.io/force-ssl-redirect: 'false'
    nginx.ingress.kubernetes.io/rewrite-target: /
  name: myapp
  namespace: namespaceA
spec:
  rules:
  - host: mydomain.io
    http:
      paths:
      - backend:
          serviceName: myapp
          servicePort: 80
        path: /namespaceA(/|$)(.*)
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    ingress.kubernetes.io/ssl-redirect: "false"
    nginx.ingress.kubernetes.io/force-ssl-redirect: "false"
    nginx.ingress.kubernetes.io/rewrite-target: /
  name: myapp
  namespace: namespaceB
spec:
  rules:
  - host: mydomain.io
    http:
      paths:
      - backend:
          serviceName: myapp
          servicePort: 80
        path: /namespaceB(/|$)(.*)

例如,上面的入口定义将导致以下重写:

对于命名空间 namespaceA 中的目标服务 myapp:

mydomain.io/namespaceA rewrites to mydomain.io/ 
mydomain.io/namespaceA/ rewrites to mydomain.io/
mydomain.io/namespaceA/ready/ rewrites to mydomain.io/ready/

对于命名空间 namespaceB 中的目标服务 myapp:

mydomain.io/namespaceB rewrites to mydomain.io/
mydomain.io/namespaceB/ rewrites to mydomain.io/
mydomain.io/namespaceB/ready/ rewrites to mydomain.io/ready/

注意:您可能需要为 nginx-ingress-controller 使用 nginx-config ConfigMap to completely switch off ssl-redirect
注意: nginx-ingress-controller 有两种,kubernetes and nginxinc. ConfigMap options and annotations 可能不同。

kind: ConfigMap
apiVersion: v1
metadata:
  name: nginx-config
  namespace: nginx-ingress  # <--- or ingress-nginx, depends on your installation
data:
  redirect-to-https: "false"
  ssl-redirect: "false"