Kubernetes Ingress 按服务标签路由

Kubernetes Ingress routing by service label

是否可以根据服务标签而不是服务名称来路由 Ingress 请求?

我想要 2 个名称相同但标签值不同的服务。 Ingress 可以像这样路由流量吗?

service-name.labelA.com -> service with label = A
service-name.labelB.com -> service with label = A

可以吗? 因为在 Docs 它使用服务名称和端口路由(无标签):

spec:
  rules:
  - http:
      paths:
      - path: /testpath
        backend:
          serviceName: test
          servicePort: 80

Kubernetes 不允许您创建两个同名的服务

$ cat service_A.yaml apiVersion: v1
kind: Service
metadata: 
  name: portfwd-srv-a 
spec: 
  ports: 
    - 
      nodePort: 30010
      port: 88
      name: knp1
  selector: 
    app: nginx
  type: NodePort

cat service_B.yaml apiVersion: v1
kind: Service
metadata: 
  name: portfwd-srv-a 
spec: 
  ports: 
    - 
      nodePort: 30011
      port: 88
      name: knp1
  selector: 
    app: nginx
  type: NodePort

$ kubectl create -f service_A.yaml 
service/portfwd-srv-a created

$ kubectl create -f service_B.yaml 
Error from server (AlreadyExists): error when creating "service_B.yaml": services "portfwd-srv-a" already exists

$  kubectl get svc -o wide
NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)                      AGE    SELECTOR
kubernetes           ClusterIP   10.0.0.1     <none>        443/TCP                      6d3h   <none>
portfwd-srv-a        NodePort    10.0.5.233   <none>        88:30010/TCP                 3m     app=nginx
web                  NodePort    10.0.4.73    <none>        8080:31881/TCP               3d     run=web

但是,可以针对相同的服务(或您选择的任何 Ingress 服务)。 下面的示例受 Ingress 文档的影响。

$ cat ingress_namebased.yaml 
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: name-virtual-host-ingress
spec:
  rules:
  - host: foo.bar.com
    http:
      paths:
      - backend:
          serviceName: web
          servicePort: 8080
  - host: bar.foo.com
    http:
      paths:
      - backend:
          serviceName: web
          servicePort: 8080

这里我使用 web 服务发送到 foo.bar.combar.foo.com 的请求:


$ kubectl get ingress 
NAME                        HOSTS                     ADDRESS         PORTS   AGE
name-virtual-host-ingress   foo.bar.com,bar.foo.com   35.186.*.*      80      134m

$ kubectl get svc -o wide
NAME       TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)               AGE    SELECTOR
web        NodePort    10.0.4.73    <none>        8080:31881/TCP        3d     run=web
...

那点数pods/end_points:

$ kubectl get pods -o wide
NAME                     READY   STATUS    RESTARTS   AGE     IP          NODE                    NOMINATED NODE   READINESS GATES
web-ddb799d85-7x2v4      1/1     Running   0          3d      10.12.0.6   cluster-1-pool-1-6v3n   <none>           <none>
web-ddb799d85-p2cq8      1/1     Running   0          2d21h   10.12.1.8   cluster-1-pool-1-m7z8   <none>           <none>

$ kubectl get ep -o wide
NAME                 ENDPOINTS                       AGE
web                  10.12.0.6:8080,10.12.1.8:8080   3d

这里是从“最终用户”的角度来看它如何工作的示例(循环法,因为我有 2 个端点):

$ curl foo.bar.com
Hello, world!
Version: 1.0.0
Hostname: web-ddb799d85-7x2v4

$ curl foo.bar.com
Hello, world!
Version: 1.0.0
Hostname: web-ddb799d85-p2cq8

curl bar.foo.com
Hello, world!
Version: 1.0.0
Hostname: web-ddb799d85-p2cq8

$ curl bar.foo.com
Hello, world!
Version: 1.0.0
Hostname: web-ddb799d85-7x2v4