Istio Proxy用于连接虚拟机应用所在的数据平面与ASM提供的控制平面。本文介绍如何在虚拟机节点上安装和部署Istio Proxy,从而实现虚拟机应用(非Kubernetes容器应用)的网格化。

前提条件

背景信息

Istio Proxy运行在虚拟机节点中,负责与ASM通信获取xDS信息、劫持非容器应用流量并执行网格化操作,例如流量管理、请求安全认证、上报链路追踪数据等。为了支持跨操作系统,Istio Proxy以Docker镜像的方式进行分发。

步骤一:准备元数据

准备虚拟机加入服务网格时需要的元数据。

  1. 在浏览器中打开Cloud Shell,或者在OpenAPI开发者门户中打开命令行操作界面。
  2. 获取虚拟机加入服务网格的证书。
    1. 登录ASM控制台
    2. 在左侧导航栏,选择服务网格 > 网格管理
    3. 网格管理页面,找到待配置的实例,单击实例的名称或在操作列中单击管理
    4. 在网格详情页面左侧导航栏选择数据平面(服务发现) > 虚拟机
    5. 虚拟机页面单击目标虚拟机右侧操作列下的证书
    6. 证书信息面板单击复制以下证书内容,然后单击确定
  3. 将上文复制的证书保存到ECS实例的/opt/avp/garden/root-cert.pem文件中。
  4. 获取虚拟机加入服务网格的令牌。
    1. 登录ASM控制台
    2. 在左侧导航栏,选择服务网格 > 网格管理
    3. 网格管理页面,找到待配置的实例,单击实例的名称或在操作列中单击管理
    4. 在网格详情页面左侧导航栏选择数据平面(服务发现) > 虚拟机
    5. 虚拟机页面单击目标虚拟机右侧操作列下的工作负载身份令牌
    6. 工作负载身份令牌面板选择命名空间,然后单击确定
      说明 工作负载身份令牌的命名空间需要与虚拟机上应用挂载的命名空间一致。
    7. 工作负载身份令牌面板单击复制以下工作负载身份令牌内容,然后单击确定
  5. 将上文复制的工作负载身份令牌保存到ECS实例的/var/run/secrets/kubernetes.io/serviceaccount/token文件中。
  6. 使用以下内容,在ECS实例中创建并编辑/opt/avp/garden/avp.out文件。
    XDS_ROOT_CA=/opt/avp/garden/root-cert.pem
    CA_ROOT_CA=/opt/avp/garden/root-cert.pem
    POD_NAMESPACE=default
    SERVICE_ACCOUNT=default
    CANONICAL_SERVICE=productpage
    POD_NAME=productpage-avp
    ISTIO_META_CLUSTER_ID=c88810be***
    JWT_POLICY=first-party-jwt
    ISTIO_META_DNS_CAPTURE=true
    ISTIO_META_ISTIO_VERSION=1.8.3
    SERVICE_CIDR=172.21.0.0/20,240.240.0.0/16

    SERVICE_CIDR的第一个值为创建ACK集群时设置的Service CIDR,第二个值是一个固定值,用于DNS智能代理。

步骤二:配置iptables

  1. 执行以下命令,加载元数据到系统环境变量,并验证变量SERVICE_CIDR取值正确。
    . /opt/avp/garden/avp.out
    echo "SERVICE_CIDR=$SERVICE_CIDR"

    预期输出:

    SERVICE_CIDR=172.21.0.0/20,240.240.0.0/16
  2. 使用istio-clean-iptables参数启动Istio Proxy。
    1. 执行以下命令,使用istio-clean-iptables参数启动Istio Proxy,清除虚拟机iptables的配置。
      version=1.8.3
      PROXY_IMAGE=registry-vpc.cn-beijing.aliyuncs.com/acs/proxyv2:${version}
      docker run --rm \
          --name=istio-init \
          --network=host \
          --cap-add=NET_ADMIN \
          $PROXY_IMAGE istio-clean-iptables
    2. 执行以下命令,查看当前虚拟机iptables的配置。
      iptables -t nat -L -v

      预期输出:

      Chain PREROUTING (policy ACCEPT 87 packets, 4331 bytes)
       pkts bytes target     prot opt in     out     source               destination
       4865  248K DOCKER     all  --  any    any     anywhere             anywhere             ADDRTYPE match dst-type LOCAL
      
      Chain INPUT (policy ACCEPT 87 packets, 4331 bytes)
       pkts bytes target     prot opt in     out     source               destination
      
      Chain OUTPUT (policy ACCEPT 32 packets, 2241 bytes)
       pkts bytes target     prot opt in     out     source               destination
        304 18240 DOCKER     all  --  any    any     anywhere            !localhost/8          ADDRTYPE match dst-type LOCAL
      
      Chain POSTROUTING (policy ACCEPT 32 packets, 2241 bytes)
       pkts bytes target     prot opt in     out     source               destination
          0     0 MASQUERADE  all  --  any    !docker0  172.17.0.0/16        anywhere
      
      Chain DOCKER (2 references)
       pkts bytes target     prot opt in     out     source               destination
          0     0 RETURN     all  --  docker0 any     anywhere             anywhere
  3. 使用istio-iptables参数启动Istio Proxy。
    1. 执行以下命令,使用istio-iptables参数启动Istio Proxy,设置虚拟机iptables的配置。
      version=1.8.3
      PROXY_IMAGE=registry-vpc.cn-beijing.aliyuncs.com/acs/proxyv2:${version}
      docker run --rm \
          --name=istio-init \
          --network=host \
          --cap-add=NET_ADMIN \
          $PROXY_IMAGE istio-iptables \
          -p 15001 -z 15006 -u 1337 -m REDIRECT -i "$SERVICE_CIDR" -x '' -b '*' -d 15020
    2. 执行以下命令,查看当前虚拟机iptables的配置。
      iptables -t nat -L -v

      预期输出:

      Chain PREROUTING (policy ACCEPT 2 packets, 64 bytes)
       pkts bytes target     prot opt in     out     source               destination
       4887  248K DOCKER     all  --  any    any     anywhere             anywhere             ADDRTYPE match dst-type LOCAL
          7   284 ISTIO_INBOUND  tcp  --  any    any     anywhere             anywhere
      
      Chain INPUT (policy ACCEPT 9 packets, 348 bytes)
       pkts bytes target     prot opt in     out     source               destination
      
      Chain OUTPUT (policy ACCEPT 1 packets, 76 bytes)
       pkts bytes target     prot opt in     out     source               destination
        304 18240 DOCKER     all  --  any    any     anywhere            !localhost/8          ADDRTYPE match dst-type LOCAL
          0     0 ISTIO_OUTPUT  tcp  --  any    any     anywhere             anywhere
      
      Chain POSTROUTING (policy ACCEPT 1 packets, 76 bytes)
       pkts bytes target     prot opt in     out     source               destination
          0     0 MASQUERADE  all  --  any    !docker0  172.17.0.0/16        anywhere
      
      Chain DOCKER (2 references)
       pkts bytes target     prot opt in     out     source               destination
          0     0 RETURN     all  --  docker0 any     anywhere             anywhere
      
      Chain ISTIO_INBOUND (1 references)
       pkts bytes target     prot opt in     out     source               destination
          0     0 RETURN     tcp  --  any    any     anywhere             anywhere             tcp dpt:15008
          0     0 RETURN     tcp  --  any    any     anywhere             anywhere             tcp dpt:ssh
          0     0 RETURN     tcp  --  any    any     anywhere             anywhere             tcp dpt:15020
          7   284 ISTIO_IN_REDIRECT  tcp  --  any    any     anywhere             anywhere
      
      Chain ISTIO_IN_REDIRECT (3 references)
       pkts bytes target     prot opt in     out     source               destination
          7   284 REDIRECT   tcp  --  any    any     anywhere             anywhere             redir ports 15006
      
      Chain ISTIO_OUTPUT (1 references)
       pkts bytes target     prot opt in     out     source               destination
          0     0 RETURN     all  --  any    lo      localhost            anywhere
          0     0 ISTIO_IN_REDIRECT  all  --  any    lo      anywhere            !localhost            owner UID match 1337
          0     0 RETURN     all  --  any    lo      anywhere             anywhere             ! owner UID match 1337
          0     0 RETURN     all  --  any    any     anywhere             anywhere             owner UID match 1337
          0     0 ISTIO_IN_REDIRECT  all  --  any    lo      anywhere            !localhost            owner GID match 1337
          0     0 RETURN     all  --  any    lo      anywhere             anywhere             ! owner GID match 1337
          0     0 RETURN     all  --  any    any     anywhere             anywhere             owner GID match 1337
          0     0 RETURN     all  --  any    any     anywhere             localhost
          0     0 ISTIO_REDIRECT  all  --  any    any     anywhere             172.21.0.0/20
          0     0 ISTIO_REDIRECT  all  --  any    any     anywhere             240.240.0.0/16
          0     0 RETURN     all  --  any    any     anywhere             anywhere
      
      Chain ISTIO_REDIRECT (2 references)
       pkts bytes target     prot opt in     out     source               destination
          0     0 REDIRECT   tcp  --  any    any     anywhere             anywhere         

步骤三:启动Istio Proxy

  1. 查看ASM控制平面地址。
    1. 登录ASM控制台
    2. 在左侧导航栏,选择服务网格 > 网格管理
    3. 网格管理页面,找到待配置的实例,单击实例的名称或在操作列中单击管理
    4. 在网格管理详情页面基本信息区域Istio Pilot地址右侧查看ASM控制平面地址。
  2. 执行以下命令,将ASM控制平面地址写入虚拟机hosts文件。
    echo "<控制平面地址> istiod.istio-system.svc" > /opt/avp/garden/avp.hosts
  3. 执行以下命令,启动Istio Proxy。
    说明 envoy_bootstrap.json的示例,请参见envoy_bootstrap.json
    version=1.8.3
    PROXY_IMAGE=registry-vpc.cn-beijing.aliyuncs.com/acs/proxyv2:${version}
    docker run -d \
        --name=istio-proxy \
        --network=host \
        --env-file /opt/avp/garden/avp.out \
        -v /opt/avp/garden:/opt/avp/garden \
        -v /var/run/secrets/kubernetes.io/serviceaccount:/var/run/secrets/kubernetes.io/serviceaccount \
        $PROXY_IMAGE proxy \
        --templateFile=/opt/avp/garden/envoy_bootstrap.json

步骤四:启用DNS智能代理

启用DNS智能代理,具体操作,请参见启用服务网格中的DNS代理

说明
  • 如果您的ASM实例为1.9及以上版本,您可以通过启用DNS代理的方式简化虚拟机网格化配置中的DNS配置,例如使用helloworld.sample.svc域名时,无需手动修改/etc/hosts文件,Istio Proxy内置的智能代理可以自动解析。
  • 如果您的ASM实例为1.9以下版本,您需要手动将域名与虚拟机上的hosts文件绑定。

结果验证

查看Istio Proxy on VM日志

执行以下命令,查看Istio Proxy on VM容器的日志,从而获知当前的执行状态。
docker logs istio-proxy
预期输出:
2021-03-29T08:34:33.736997Z info  sds resource:default pushed key/cert pair to proxy
2021-03-29T08:34:34.133533Z info  cache Loaded root cert from certificate ROOTCA
2021-03-29T08:34:34.133735Z info  sds resource:ROOTCA pushed root cert to proxy
查看ASM实例的全部工作负载的proxy状态
  1. 登录ASM控制台
  2. 在控制台左侧导航栏单击概览,在概览页面可以查看到当前服务网格实例的全部工作负载的proxy状态。
    proxy状态
验证出向流量
启动Istio Proxy后,ECS虚拟机上的服务可以访问容器内的服务。出向流量
  1. 在ACK集群内部署Hello World服务。
    1. 执行以下命令,创建名为sample的命名空间。
      kubectl create namespace sample
    2. 创建名为helloworld的YAML文件。关于YAML文件的具体内容,请参见helloworld
    3. 执行以下命令,创建Hello World服务。
      kubectl apply -n sample -f samples/helloworld/helloworld.yaml
  2. 执行以下命令,在虚拟机上部署sleep容器。
    SLEEP_REPO=governmentpaas/curl-ssl
    docker run -d \
        --name=sleep \
        --network=host \
        $SLEEP_REPO /bin/sleep 3650d
  3. 执行以下命令,让虚拟机上的sleep容器请求ACK集群内的Hello World服务。
    # sleep[vm] -> helloworld[ack]
    docker exec sleep curl -s helloworld.sample.svc:5000/hello

    预期输出:

    Hello version: v1, instance: helloworld-v1-5b75657f75-55255
    
    Hello version: v2, instance: helloworld-v2-7855866d4f-bhxqw
验证入向流量
启动Istio Proxy后,容器内的服务可以访问ECS虚拟机上的服务。入向
  1. 执行以下命令,在虚拟机上部署容器。
    PRODUCTPAGE_REPO=docker.io/istio/examples-bookinfo-productpage-v1:1.16.2
    
    docker run -d \
        --name=productpage \
        -e SERVICES_DOMAIN=bookinfo \
        --network=host \
        $PRODUCTPAGE_REPO
  2. 将productpage添加到ASM中。
    1. 使用以下内容,创建名为productpage-se的YAML文件。
      使用ServiceEntry将productpage添加到网格内部维护的服务注册表。
      apiVersion: networking.istio.io/v1beta1
      kind: ServiceEntry
      metadata:
        name: mesh-expansion-productpage
        namespace: bookinfo
      spec:
        hosts:
          - productpage.bookinfo.svc.cluster.local
          - productpage.bookinfo
        location: MESH_INTERNAL
        ports:
          - name: http-9080
            number: 9080
            protocol: HTTP
        resolution: STATIC
        workloadSelector:
          labels:
            app: productpage
    2. 使用以下内容,创建名为productpage-we的YAML文件。
      使用WorkloadEntry定义productpage的工作负载属性。
      apiVersion: networking.istio.io/v1beta1
      kind: WorkloadEntry
      metadata:
        name: mesh-expansion-productpage-1
        namespace: bookinfo
      spec:
        address: 10.0.**.**
        labels:
          app: productpage
        serviceAccount: bookinfo-productpage
    3. 执行以下命令,创建WorkloadEntry和ServicEntry。
      alias m="kubectl --kubeconfig $MESH_CONFIG"
      m apply -n bookinfo -f productpage-se.yaml
      m apply -n bookinfo -f productpage-we.yaml
  3. 在ACK集群内部署Sleep服务。
    1. 创建名为sleep的YAML文件。关于YAML文件的具体内容,请参见sleep
    2. 执行以下命令,创建Sleep服务。
      alias k="kubectl --kubeconfig $ACK_CONFIG"
      k apply -n bookinfo -f ${ISTIO_HOME}/kube/sleep.yaml
  4. 执行以下命令,让ACK集群内的Sleep请求虚拟机上的productpage。
    SLEEP_POD=$(k -n bookinfo get pod -l app=sleep -o jsonpath='{.items[0].metadata.name}')
    k -n bookinfo exec $SLEEP_POD -c sleep -- curl -sIv productpage.bookinfo:9080/productpage

    预期输出:

    Check productpage:
    *   Trying 240.240.0.2:9080...
    * Connected to productpage.bookinfo (240.240.0.2) port 9080 (#0)
    > HEAD /productpage HTTP/1.1
    > Host: productpage.bookinfo:9080
    > User-Agent: curl/7.69.1
    > Accept: */*
    > 
    HTTP/1.1 200 OK
    content-type: text/html; charset=utf-8
    content-length: 4183
    server: envoy
    date: Wed, 31 Mar 2021 11:51:05 GMT
    x-envoy-upstream-service-time: 111
    
    * Mark bundle as not supporting multiuse
    < HTTP/1.1 200 OK
    < content-type: text/html; charset=utf-8
    < content-length: 4183
    < server: envoy
    < date: Wed, 31 Mar 2021 11:51:05 GMT
    < x-envoy-upstream-service-time: 111
    < 
    * Connection #0 to host productpage.bookinfo left intact

附录

以下为Istio Proxy在虚拟机上的镜像地域列表。

地域 地域名称
cn-hangzhou 华东1(杭州)
cn-shanghai 华东2(上海)
cn-qingdao 华北1(青岛)
cn-beijing 华北2(北京)
cn-zhangjiakou 华北3(张家口)
cn-huhehaote 华北5(呼和浩特)
cn-shenzhen 华南1(深圳)
cn-chengdu 西南1(成都)
cn-hongkong 中国(香港)
ap-southeast-1 新加坡
ap-southeast-2 澳大利亚(悉尼)
ap-southeast-3 马来西亚(吉隆坡)
ap-southeast-5 印度尼西亚(雅加达)
ap-northeast-1 日本(东京)
eu-central-1 德国(法兰克福)
eu-west-1 英国(伦敦)
us-west-1 美国(硅谷)
us-east-1 美国(弗吉尼亚)
ap-south-1 印度(孟买)
me-east-1 阿联酋(迪拜