> 文章列表 > Istio Destinationrule规则定义后不生效(跨命名空间)

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

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

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

现象

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

gw和vs配置如下

apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:name: bookinfo-gatewaynamespace: istio
spec:selector:istio: ingressgatewayservers:- port:number: 80name: httpprotocol: HTTPhosts:- "*"
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:name: nginxnamespace: istio
spec:hosts:- "*"exportTo: # *,生成的规则让其他网格内访问时也生效- "*"gateways:- bookinfo-gatewayhttp:- match:route:- destination:host: nginx.default.svc.cluster.localport: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: nginxnamespace: istio
spec:hosts:- "*"exportTo:- "*"gateways:- bookinfo-gatewayhttp:- match:route:- destination:host: nginx.default.svc.cluster.localport:number: 80subset: v1
---
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:name: nginxnamespace: istio
spec:host: nginx.default.svc.cluster.localexportTo:- "*"subsets:- name: v1labels: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.localtrafficPolicy: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: nginxnamespace: istio
spec:hosts:- "*"exportTo:- "*"gateways:- bookinfo-gatewayhttp:- match:route:- destination:host: nginx.default.svc.cluster.localport:number: 80subset: v1
---
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:name: nginxnamespace: istio-system    # 将命名空间修改为istio所在命名空间
spec:host: nginx.default.svc.cluster.localexportTo:- "*"subsets:- name: v1labels: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: nginxnamespace: istio
spec:hosts:- "*"exportTo:- "*"gateways:- bookinfo-gatewayhttp:- match:route:- destination:host: nginx.default.svc.cluster.localport:number: 80subset: v1
---
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:name: nginxnamespace: default     # 将命名空间设置被调用方的命名空间
spec:host: nginx.default.svc.cluster.localexportTo:- "*"subsets:- name: v1labels: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: nginxnamespace: default
spec:exportTo:- "."hosts: # 由于跨了命名空间,所以fqdn- nginx-version-all.default.svc.cluster.localgateways:- meshhttp:- match:route:- destination:host: nginx-version-all.default.svc.cluster.localport:number: 80subset: v1weight: 100
---
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:name: nginxnamespace: default
spec:host: nginx-version-all.default.svc.cluster.localexportTo:- "*"subsets:- name: v1labels:app: nginxversion: v1