是否可以从另一个名称空间将入口点指向服务?

Is it possible to have an Ingress point to a Service from another namespace?

我想要做的是在 default 命名空间中有一个服务,并在我的其他命名空间中有入口,它指向该服务。我尝试实现如下所示的服务和 Ingress,但没有成功。

kind: Service
apiVersion: v1
metadata:
  name: serviceX
  namespace: default
spec:
  type: ExternalName
  externalName: serviceX.default.svc.cluster.local
ports:
- port: 123


kind: Ingress
apiVersion: extensions/v1beta1
metadata:
  name: web-ingress-test-vpndev
  namespace: my-namespace
spec:
  tls:
  - hosts:
    - abc.my-namespace.domain.com
    secretName: tls-secret-my-namespace
  rules:
  - http:
      paths:
      - path: "/"
        backend:
          serviceName: serviceX
          servicePort: 123
status:
  loadBalancer:
    ingress: {}

我知道我可以在每个命名空间中实现该服务,但我想知道是否可以只提供一个服务。如果我尝试在入口的 backend->serviceName 处理程序中键入服务的 externalName,我会收到错误消息,指出服务名称只能包含数字、字母和“-”。

我不认为这是可能的,也不认为这是个好主意。 Ingress 不是集群级别的资源。每个命名空间都应该有自己的实例。

我不得不说这不是一个好方法。因为不同 NS 中的所有 ingress 都会转换为 Nginx 规则并在 ingress-controller pod 中生效。

如果你看一下 Nginx 规则(nginx.conf in ingress-controller pod),你会看到 nginx.conflocation 的每个块都有变量 set $namespace "****"; 这意味着入口已被 NS

隔离

此外,如果您仍然想实现您的想法,可能需要修改 ingress-contoller。

我使用 Istio 实现了这一点。这不是我们使用它的主要原因,但流量管理功能允许这种事情。

+--Namespace A-------------------------------+
|                                            |
|  +-------+   +-------+   +--------------+  |
|  |Ingress+--->Service+--->VirtualService|  |
|  +-------+   +-------+   +------+-------+  |
|                                 |          |
+--------------------------------------------+
                                  |
                  +---------------+
                  |
                  |      +--Namespace B---------+
                  |      |                      |
                  |      |  +-------+    +---+  |
                  +--------->Service+---->Pod|  |
                         |  +-------+    +---+  |
                         |                      |
                         +----------------------+

使用 Istio,您可以将入口放在一个命名空间中,一个没有选择器的服务(因为这里没有 pod)和一个将 service.namespaceA 上的流量路由到 service.namespaceB 的虚拟服务。

我正在使用它来实现蓝绿部署。想象一下与上面相同的原理,但有 3 个命名空间:

  • 命名空间-A(带有入口、服务和虚拟服务)
  • Namespace-B-blue(有蓝色服务和pods)
  • Namespace-B-green(有绿色服务和pods)

蓝绿版本的切换由namespace-A中的virtualService管理。好处是绿色版(smoke test)可以在发布给大家之前使用istio的路由特性进行测试

只是打算 post 到这里来帮助将来的其他人。这适用于 AWS,但可能不适用于其他云基础设施。如果您希望单个 ALB 连接到与其自身不同命名空间中的服务,您可以创建两个 k8s ingress,但将它们组合在一起。

命名空间 A

apiVersion: v1
kind: Service
metadata:
  name: service-1
  namespace: A
spec:
  type: NodePort
  ports:
  - name: http
    port: 8080
    protocol: TCP
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
      "alb.ingress.kubernetes.io/group.name": "group"
      "alb.ingress.kubernetes.io/group.order": "1"
  namespace: A
spec:
  rules:
  - host: latest.example.com
    http:
      paths:
      - backend:
          serviceName: service-1
          servicePort: 8080
        path: /

命名空间 B

apiVersion: v1
kind: Service
metadata:
  name: service-2
  namespace: B
spec:
  type: NodePort
  ports:
  - name: http
    port: 8080
    protocol: TCP
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
      "alb.ingress.kubernetes.io/group.name": "group"
      "alb.ingress.kubernetes.io/group.order": "2"
  namespace: B
spec:
  rules:
  - host: other.example.com
    http:
      paths:
      - backend:
          serviceName: service-2
          servicePort: 8080
        path: /

为简洁起见,我删除了许多注释,但这将创建一个 ALB,其中包含两个入口资源,使同一域能够指向跨不同名称空间的不同服务。