istio访问网格外部服务

概述

设想一个这样的场景需求:cluster1集群处在网格mesh1管理下,default命名空间下部署有应用sleep, cluster2处在另一网格mesh2下,它的default命名空间下部署有helloworld应用。现sleep应用希望能以域名test.external.helloworld的形式访问cluster2中的helloworld。这不属于istio的四种多集群部署模型之一,服务之间的调用需要另做配置。

配置

版本备注

kubernetes 1.23.3
istio 1.12

  1. 暴露cluster2中的helloworld服务

    # 为helloworld创建gateway,virtualservice
    apiVersion: networking.istio.io/v1beta1
    kind: Gateway
    metadata:
      name: helloworld-gateway
      namespace: default
    spec:
      selector:
        istio: ingressgateway
      servers:
      - hosts:
        - 'test.external.helloworld'
        port:
          name: haha
          number: 15443     
          protocol: HTTP
          
    ---
    apiVersion: networking.istio.io/v1beta1
    kind: VirtualService
    metadata:
      name: helloworld
      namespace: default
    spec:
      gateways:
      - helloworld-gateway
      hosts:
      - 'test.external.helloworld'
      http:
      - match:
        - uri:
            exact: /hello
        route:
        - destination:
            host: helloworld
            port:
              number: 5000
    

    这里端口特意用15443,以此说明它并非共东西网关专用,只要协议对了任意端口都可以。

    验证服务暴露成功, 在cluster1的宿主机执行

    # 这里10.0.2.4是cluster2中svc ingressgateway的externalIP
    curl test.external.helloworld:15443/hello --resolve test.external.helloworld:15443:10.0.2.4
    
    Hello version: v2, instance: helloworld-v2-5b46bc9f84-mq9vg
    
    

    PS: 如cluster2不在istio网格管理下,可以使用NodePort,ingress等手段暴露。

  2. 为cluster1配置ServiceEntry

    apiVersion: networking.istio.io/v1beta1
    kind: ServiceEntry
    metadata:  
      name: helloworld-se
      namespace: default
    spec:
      hosts:
      - test.external.helloworld
      ports:
      - name: http
        number: 15443
        protocol: HTTP
      resolution: STATIC
    
  3. 重启sleep应用,进入容器中测试访问

    kubectl delete pod sleep-xxx-xxx 
    
    kubectl exec -it sleep-84f96ffddc-bnw22 -- sh
    $ curl test.external.helloworld:15443/hello
    Hello version: v2, instance: helloworld-v2-5b46bc9f84-mq9vg
    

    通了。

问题记录

  1. 报错域名无法解析

    curl: (6) Could not resolve host: test.external.helloworld

    可能会发现,前述自定义test.external.helloworld域名替换成使用公共域名如www.baidu.com,就可以正常访问到cluster2的helloworld服务,但是换成自定义的就会报无法解析。

    猜测发起curl请求时,istio的组件会先检查域名是否可以解析,能解析(即便解析到了外网的服务)后在进一步根据serviceEntry的信息找到helloworld服务,而如果dns解析失败则直接返回报错,所以会产生这种奇怪现象。

    参考github issues 35992问答解决,其中有一句:

    do you enable DNS proxy? https://istio.io/latest/docs/ops/configuration/traffic-management/dns-proxy/

    参考DNS proxy配置后可以解决。

  2. 配置过程中经常会需要新增某个网格配置,并用istioctl执行install,例如DNS proxy的配置:

    cat <

    这会导致istio重新安装,并且只有上述yaml中的几项配置参数,其他的都用默认值。导致istio其他的配置参数如network等失效,而此时get 配置

    kubectl get IstioOperator -o yaml
    

    拿到的配置信息看起来又是符合预期的(即原来的配置和新增的配置参数都还在),这时集群出现未知的症状就会很令人迷惑。

    所以要注意,可能这也是istioctl的一个bug。

你可能感兴趣的:(服务网格,k8s,kubernetes,容器,云原生)