VirtualService 和 DestinationRule Istio 资源的正确命名空间

Right namespace for VirtualService and DestinationRule Istio resources

我正在尝试了解与应该定义的命名空间相关的 VirtualService 和 DestinationRule 资源,以及它们是否真的是命名空间资源,或者它们也可以被视为集群范围的资源。

我有以下场景:

在前端命名空间中,我有网络前端部署和相关服务如下:

apiVersion: v1
kind: Namespace
metadata:
  name: frontend
  labels:
    istio-injection: enabled
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-frontend
  namespace: frontend
  labels:
    app: web-frontend
spec:
  replicas: 1
  selector:
    matchLabels:
      app: web-frontend
  template:
    metadata:
      labels:
        app: web-frontend
        version: v1
    spec:
      containers:
        - image: gcr.io/tetratelabs/web-frontend:1.0.0
          imagePullPolicy: Always
          name: web
          ports:
            - containerPort: 8080
          env:
            - name: CUSTOMER_SERVICE_URL
              value: 'http://customers.backend.svc.cluster.local'
---
kind: Service
apiVersion: v1
metadata:
  name: web-frontend
  namespace: frontend
  labels:
    app: web-frontend
spec:
  selector:
    app: web-frontend
  type: NodePort
  ports:
    - port: 80
      name: http
      targetPort: 8080

我通过定义以下网关和虚拟服务资源公开了 Web 前端服务:

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: gateway-all-hosts
  # namespace: default # Also working
  namespace: frontend
spec:
  selector:
    istio: ingressgateway
  servers:
    - port:
        number: 80
        name: http
        protocol: HTTP
      hosts:
        - "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: web-frontend
  # namespace: default # Also working
  namespace: frontend
spec:
  hosts:
    - "*"
  gateways:
    - gateway-all-hosts
  http:
    - route:
        - destination:
            host: web-frontend.frontend.svc.cluster.local
            port:
              number: 80

在后端命名空间中,我有客户 v1 和 v2 部署以及相关服务,如下所示:

apiVersion: v1
kind: Namespace
metadata:
  name: backend
  labels:
    istio-injection: enabled
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: customers-v1
  namespace: backend
  labels:
    app: customers
    version: v1
spec:
  replicas: 1
  selector:
    matchLabels:
      app: customers
      version: v1
  template:
    metadata:
      labels:
        app: customers
        version: v1
    spec:
      containers:
        - image: gcr.io/tetratelabs/customers:1.0.0
          imagePullPolicy: Always
          name: svc
          ports:
            - containerPort: 3000
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: customers-v2
  namespace: backend
  labels:
    app: customers
    version: v2
spec:
  replicas: 1
  selector:
    matchLabels:
      app: customers
      version: v2
  template:
    metadata:
      labels:
        app: customers
        version: v2
    spec:
      containers:
        - image: gcr.io/tetratelabs/customers:2.0.0
          imagePullPolicy: Always
          name: svc
          ports:
            - containerPort: 3000
---
kind: Service
apiVersion: v1
metadata:
  name: customers
  namespace: backend
  labels:
    app: customers
spec:
  selector:
    app: customers
  type: NodePort
  ports:
    - port: 80
      name: http
      targetPort: 3000

我创建了以下 DestinationRule 和 VirtualService 资源以仅将流量发送到 v1 部署。

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: customers
  #namespace: default # Not working
  #namespace: frontend # working
  namespace: backend # working
spec:
  host: customers.backend.svc.cluster.local
  subsets:
    - name: v1
      labels:
        version: v1
    - name: v2
      labels:
        version: v2
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: customers
  #namespace: default # Not working
  #namespace: frontend # working
  namespace: backend # working
spec:
  hosts:
    - "customers.backend.svc.cluster.local"
  http:
  ## route  - subset: v1
  - route:
      - destination:
          host: customers.backend.svc.cluster.local
          port:
            number: 80
          subset: v1

请求期间实际应用的 DestinationRule 需要在目标规则查找路径上:

-> client namespace
-> service namespace
-> the configured meshconfig.rootNamespace namespace (istio-system by default)

在您的示例中,“web-frontend”客户端位于 frontend 命名空间 (web-frontend.frontend.svc.cluster.local),“customers”服务位于 backend 命名空间 (customers.backend.svc.cluster.local),因此应在以下命名空间之一中创建 customers DestinationRule:frontend后端istio-system。此外,请注意,不推荐使用 istio-system 命名空间,除非目标规则确实是适用于所有命名空间的全局配置。

为了确保应用目标规则,我们可以对 web-frontend Pod 使用 istioctl proxy-config cluster 命令:

$ istioctl proxy-config cluster web-frontend-69d6c79786-vkdv8 -n frontend | grep "customers.backend.svc.cluster.local"
SERVICE FQDN                                            PORT      SUBSET     DESTINATION RULE
customers.backend.svc.cluster.local                     80        -          customers.frontend
customers.backend.svc.cluster.local                     80        v1         customers.frontend
customers.backend.svc.cluster.local                     80        v2         customers.frontend

default 命名空间中创建目标规则时,在请求期间不会应用它:

$ istioctl proxy-config cluster web-frontend-69d6c79786-vkdv8 -n frontend | grep "customers.backend.svc.cluster.local"
SERVICE FQDN                                            PORT      SUBSET    DESTINATION RULE
customers.backend.svc.cluster.local                     80        -        

有关详细信息,请参阅 Control configuration sharing in namespaces 文档。