Istio Destinationrule规则定义后不生效(跨命名空间)

Destinationrule规则定义后不生效(跨命名空间)

现象

  • 配置subset后无法正常访问nginx资源(default命名空间)
  • 将vs/gw/dr配置到默认的default空间后可以正常访问

gw和vs配置如下

apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  name: bookinfo-gateway
  namespace: istio
spec:
  selector:
    istio: ingressgateway
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "*"
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: nginx
  namespace: istio
spec:
  hosts:
  - "*"
  exportTo: # *,生成的规则让其他网格内访问时也生效
  - "*"
  gateways:
  - bookinfo-gateway
  http:
  - match:
    route:
    - destination:
        host: nginx.default.svc.cluster.local
        port:
          number: 80

访问测试,可以发现是可以正常访问的

╰─ curl http://192.168.0.15 -I -H "Host:test.com"
HTTP/1.1 200 OK
server: istio-envoy
date: Sat, 08 Apr 2023 15:24:24 GMT
content-type: text/html
content-length: 615
last-modified: Tue, 28 Dec 2021 15:28:38 GMT
etag: "61cb2d26-267"
accept-ranges: bytes
x-envoy-upstream-service-time: 1

由于nginx这个应用有多个版本,需要配置subset,但是配置后,却无法访问,报503,ingress-gateway报: “HEAD / HTTP/1.1” 503 NC cluster_not_found - “-” 0 0 0 - “172.16.0.1” “curl/7.87.0” “8e119892-3e5d-9edf-8856-265112809263” “192.168.0.15” “-” - - 172.16.0.15:8080 172.16.0.1:37165 - -

# vs&dr配置重,即使将exporTo暴露到所有命名空间,也无法正常访问
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: nginx
  namespace: istio
spec:
  hosts:
  - "*"
  exportTo:
  - "*"
  gateways:
  - bookinfo-gateway
  http:
  - match:
    route:
    - destination:
        host: nginx.default.svc.cluster.local
        port:
          number: 80
        subset: v1
---
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: nginx
  namespace: istio
spec:
  host: nginx.default.svc.cluster.local
  exportTo:
  - "*"
  subsets:
  - name: v1
    labels:
      app: nginx
      
# 访问,可见无法正常访问后面的nginx
╰─ curl http://192.168.0.15  -I
HTTP/1.1 503 Service Unavailable
date: Sat, 08 Apr 2023 15:51:49 GMT
server: istio-envoy
transfer-encoding: chunked

# 查看cluster,cluster=outbound|80|v1|nginx.default.svc.cluster.local 在管理业务无法找到,这也就是为什么ingress-gateway报:`NC cluster_not_found` 
	outbound|80|v1|nginx.default.svc.cluster.local

原因

在特定命名空间中设置 DestinationRule 的可见性并不能保证会使用该规则。将 DestinationRule 导出到其他命名空间可以使您在其它命名空间中使用它,但是要在请求时真正应用该 DestinationRule ,命名空间也必须位于 DestinationRule 查找路径上:

  1. 客户端命名空间
  2. 服务命名空间
  3. Istio 根配置命名空间(默认是 istio-system

例如,以下 YAML 文件用于为 ns1 命名空间中的 myservice 服务定义目标规则。该host字段表示 myservice 服务是在 default 命名空间中定义的。

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: myservice
spec:
  host: myservice.default.svc.cluster.local
  trafficPolicy:
    connectionPool:
      tcp:
        maxConnections: 100
  • 如果使用驻留在 ns1 命名空间中的客户端调用 myservice 服务,则调用成功,因为 Istio 在 ns1 命名空间中找到 myservice 服务的目标规则,并使用目标规则路由调用请求
  • 如果使用驻留在 ns2 命名空间中的客户端调用 myservice 服务,调用将失败。Istio 根据以下过程搜索目标规则
    • 用于调用 myservice 服务的客户端驻留在 ns2 名称空间中。Istio在 ns2 命名空间中搜索目标规则。但是,找不到目标规则,因为它不存在于 ns2 命名空间中
    • 要调用的 myservice 服务驻留在 default 命名空间中。Istio在默认命名空间中搜索目标规则。但是,找不到目标规则,因为它不存在于默认命名空间中
    • Istio的根命名空间固定为 istio-system。Istio 在 istio-system 命名空间中搜索目标规则。但是,找不到目标规则,因为它不存在于 istio-system 命名空间中。
  • 即使将 myservice 服务导出到所有命名空间,并因此在 ns2 中可见,并且 DestinationRule 也导出到包括 ns2 在内的所有命名空间。来自 ns2 的请求依然不会应用该规则,因为它不在查找路径上的任何命名空间中

​ 您可以通过在与相应服务相同的命名空间(在此示例中为 default)中创建 DestinationRule 来避免此问题。然后,它将应用于任何命名空间中的客户端请求。您也可以将 DestinationRule 移至 istio-system 命名空间,即查找路径上的第三个命名空间,尽管不建议这样做,除非 DestinationRule 是适用于所有命名空间的全局配置,并且这需要管理员权限。

Istio 使用这种受限制的 DestinationRule 查找路径有两个原因:

  1. 防止定义覆盖完全不相关的命名空间中的服务行为的 DestinationRule
  2. 当同一host有多个 DestinationRule 时,可以有一个清晰的查找顺序。

解决方案

为服务定义目标规则时,请在以下命名空间之一中定义目标规则:

  • Istio的根命名空间
  • 服务所在的命名空间
  • 调用服务的客户端所在的命名空间

Istio-system部署DR

---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: nginx
  namespace: istio
spec:
  hosts:
  - "*"
  exportTo:
  - "*"
  gateways:
  - bookinfo-gateway
  http:
  - match:
    route:
    - destination:
        host: nginx.default.svc.cluster.local
        port:
          number: 80
        subset: v1
---
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: nginx
  namespace: istio-system    # 将命名空间修改为istio所在命名空间
spec:
  host: nginx.default.svc.cluster.local
  exportTo:
  - "*"
  subsets:
  - name: v1
    labels:
      app: nginx

# 可以访问了
╰─ curl http://192.168.0.15  -I
HTTP/1.1 200 OK
server: istio-envoy
date: Sat, 08 Apr 2023 16:07:52 GMT
content-type: text/html
content-length: 615
last-modified: Tue, 28 Dec 2021 15:28:38 GMT
etag: "61cb2d26-267"
accept-ranges: bytes
x-envoy-upstream-service-time: 1

被调用方命名空间部署DR

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: nginx
  namespace: istio
spec:
  hosts:
  - "*"
  exportTo:
  - "*"
  gateways:
  - bookinfo-gateway
  http:
  - match:
    route:
    - destination:
        host: nginx.default.svc.cluster.local
        port:
          number: 80
        subset: v1
---
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: nginx
  namespace: default     # 将命名空间设置被调用方的命名空间
spec:
  host: nginx.default.svc.cluster.local
  exportTo:
  - "*"
  subsets:
  - name: v1
    labels:
      app: nginx

# 访问测试,能正常访问
╰─ curl http://192.168.0.15  -I
HTTP/1.1 200 OK
server: istio-envoy
date: Sat, 08 Apr 2023 16:14:05 GMT
content-type: text/html
content-length: 615
last-modified: Tue, 28 Dec 2021 15:28:38 GMT
etag: "61cb2d26-267"
accept-ranges: bytes
x-envoy-upstream-service-time: 0

调用方命名空间

  • 适用于东西流量,下面monitor夸命名空间去访问nginx,还是访问到二个版本流量,default命名空间访问正常,原因未知
# 未将ds设置到monitor命名空间之前访问nginx,vs/dr如下(不配置gateway,将其设置mesh,仅在网格内部生效)
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: nginx
  namespace: default
spec:
  exportTo:
  - "."
  hosts: # 由于跨了命名空间,所以fqdn
  - nginx-version-all.default.svc.cluster.local
  gateways:
  - mesh
  http:
  - match:
    route:
    - destination:
        host: nginx-version-all.default.svc.cluster.local
        port:
          number: 80
        subset: v1
      weight: 100
---
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: nginx
  namespace: default
spec:
  host: nginx-version-all.default.svc.cluster.local
  exportTo:
  - "*"
  subsets:
  - name: v1
    labels:
      app: nginx
      version: v1

你可能感兴趣的:(Istio,istio,运维,kubernetes,容器,k8s)