非容器应用指某种特殊场景下不支持容器的应用。本文将使用Istio官方示例Bookinfo,介绍如何通过ASM网格化ECS虚拟机(VM)内的非容器应用。

前提条件

步骤一:部署数据平面

  1. 创建Bookinfo命名空间。
    1. 删除Bookinfo命名空间。
      kubectl delete namespace bookinfo
    2. 创建Bookinfo命名空间。
      kubectl create ns bookinfo
    3. 将Bookinfo命名空间设置为自动注入Sidecar。
      kubectl label ns bookinfo istio-injection=enabled
  2. 部署Bookinfo示例。
    1. 进入Istio目录,部署Bookinfo组件。
      ISTIO_HOME={本地istio路径}
      cd $ISTIO_HOME
      kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml -n bookinfo
    2. 查看Bookinfo命名空间下的服务。
      kubectl get services -n bookinfo -o wide
      NAME          TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)    AGE   SELECTOR
      details       ClusterIP   172.**.*.*     <none>        9080/TCP   20s   app=details
      productpage   ClusterIP   172.1*.*.**    <none>        9080/TCP   19s   app=productpage
      ratings       ClusterIP   172.19.*.***   <none>        9080/TCP   19s   app=ratings
      reviews       ClusterIP   172.19.*.***  <none>        9080/TCP   19s   app=reviews
    3. 查看Bookinfo命名空间下的Pod,确保READY的值是2/2。
      kubectl get pods -n bookinfo -o wide
      NAME                              READY   STATUS    RESTARTS   AGE   IP             NODE                       NOMINATED NODE   READINESS GATES
      details-v1-5974b67c8-tmhwq        2/2     Running   0          54s   172.18.*.***   cn-beijing.192.168.0.244   <none>           <none>
      productpage-v1-64794f5db4-lxdbd   2/2     Running   0          54s   172.18.*.***   cn-beijing.192.168.0.244   <none>           <none>
      ratings-v1-c6cdf8d98-z67t4        2/2     Running   0          54s   172.18.*.***   cn-beijing.192.168.0.246   <none>           <none>
      reviews-v1-7f6558b974-pxm2g       2/2     Running   0          54s   172.18.*.***    cn-beijing.192.168.0.243   <none>           <none>
      reviews-v2-6cb6ccd848-nm5pk       2/2     Running   0          54s   172.1*.*.**    cn-beijing.192.168.0.243   <none>           <none>
      reviews-v3-cc56b578-zf76z         2/2     Running   0          54s   172.18.*.***   cn-beijing.192.168.0.244   <none>           <none>
  3. 验证Bookinfo示例部署是否成功。
    kubectl -n bookinfo exec "$(kubectl -n bookinfo get pod -l app=ratings -o jsonpath='{.items[0].metadata.name}')" -c ratings -- curl -s productpage:9080/productpage | grep -o "<title>.*</title>"
    以下为预期结果。
    <title>Simple Bookstore App</title>

步骤二:部署控制平面

  1. 创建Bookinfo命名空间。
    1. 删除Bookinfo命名空间。
      kubectl --kubeconfig ~/shop_config/asm_bj delete namespace bookinfo
    2. 创建Bookinfo命名空间。
      kubectl --kubeconfig ~/shop_config/asm_bj create ns bookinfo
    3. 将Bookinfo命名空间设置为自动注入Sidecar。
      kubectl --kubeconfig ~/shop_config/asm_bj label ns bookinfo istio-injection=enabled
  2. 部署入口网关。
    ISTIO_HOME={本地istio路径}
    cd $ISTIO_HOME
    kubectl --kubeconfig ~/shop_config/asm_bj apply -f samples/bookinfo/networking/bookinfo-gateway.yaml -n bookinfo
  3. 获取对外服务路径。
    export INGRESS_HOST=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
    export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].port}')
    export GATEWAY_URL=$INGRESS_HOST:$INGRESS_PORT
    echo http://"$GATEWAY_URL/productpage"
  4. 在浏览器中输入对外服务路径,访问对外路径。多次刷新页面后,每次页面显示不同内容,分别显示没有星星、黑色星星、红色星星的页面。
    以下为此时的微服务的架构图,可以看到从ProductPage发向Reviews的请求,将会均匀地路由到Reviews的3个版本的节点上。服务网关

步骤三:在虚拟机部署MySQL

  1. 安装MySQL。
    # alios | centos
    yum install -y mariadb-server
    
    # ubuntu
    apt-get install -y mariadb-server
  2. 启动MySQL。
    systemctl start mariadb
  3. 配置MySQL。
    mysql
    GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' IDENTIFIED BY 'password' WITH GRANT OPTION;
    quit;
    以下为预期结果。
    MariaDB [(none)]> GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' IDENTIFIED BY 'password' WITH GRANT OPTION;
    Query OK, 0 rows affected (0.00 sec)
    
    MariaDB [(none)]> quit;
    Bye
  4. 重启MySQL,使配置生效。
    systemctl restart mariadb
  5. 初始化示例数据。
    1. 创建并拷贝以下内容到ECS节点的mysqldb-init.sql文件中。
      CREATE DATABASE test;
      USE test;
      
      CREATE TABLE `ratings` (
        `ReviewID` INT NOT NULL,
        `Rating` INT,
        PRIMARY KEY (`ReviewID`)
      );
      INSERT INTO ratings (ReviewID, Rating) VALUES (1, 5);
      INSERT INTO ratings (ReviewID, Rating) VALUES (2, 4);
    2. 创建test数据库和ratings数据表,并在ratings数据表中插入两条数据。
      mysql -u root -ppassword < mysqldb-init.sql
    3. 查询test数据库的ratings数据表,验证上述操作。
      mysql -u root --ppassword test -e "select * from ratings;"
      +----------+--------+
      | ReviewID | Rating |
      +----------+--------+
      |        1 |      5 |
      |        2 |      4 |
      +----------+--------+

步骤四:网格化MySQL

执行以下命令,创建MySQLdb相关的Service、ServiceEntry、WorkloadEntry。
说明 以下命令中需要使用到aliyun servicemesh命令,详情请参见安装和使用ASM CLI
MESH_ID={服务网格实例ID}
VM={ECS节点IP}
aliyun servicemesh AddVmAppToMesh \
  --ServiceMeshId "$MESH_ID" \
  --Namespace vm \
  --ServiceName mysqldb \
  --Ips "$VM" \
  --Ports mysql:3306 \
  --Labels app=mysql-workload
# mysqldb.vm.svc.cluster.local

步骤五:更新数据平面

创建v2-mysql-vm版本的Ratings。

ISTIO_HOME=~/shop/istio-1.6.9
cd $ISTIO_HOME
kubectl apply -f samples/bookinfo/platform/kube/bookinfo-ratings-v2-mysql-vm.yaml -n bookinfo

步骤六:更新控制平面

  1. 创建Ratings的VirtualService和Reviews的VirtualService。
    ISTIO_HOME=~/shop/istio-1.6.9
    cd $ISTIO_HOME
    kubectl --kubeconfig ~/shop_config/asm_bj apply -f samples/bookinfo/networking/virtual-service-ratings-mysql-vm.yaml -n bookinfo
  2. 创建全部Pod的DestinationRule。
    ISTIO_HOME=~/shop/istio-1.6.9
    cd $ISTIO_HOME
    kubectl --kubeconfig ~/shop_config/asm_bj apply -f samples/bookinfo/networking/destination-rule-all.yaml -n bookinfo

结果验证

  1. 获取对外服务路径。
    export INGRESS_HOST=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
    export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].port}')
    export GATEWAY_URL=$INGRESS_HOST:$INGRESS_PORT
    echo http://"$GATEWAY_URL/productpage"
  2. 在浏览器中输入对外服务路径,访问对外路径。多次刷新页面后,页面没有变化。页面的Reviewer1区域显示5颗星星,Reviewer2区域显示4颗星星。
    以下为此时的微服务的架构图,可以看到从ProductPage发向Reviews的请求,Reviews只会路由到v3版本、Ratings只会路由到v2-mysql-vm版本。v3
  3. 更新数据库。
    mysql -u root -ppassword test -e  "update ratings set rating=1 where reviewid=1;select * from ratings;"
    [root@iZ2zedxgqw4190znx2wv9wZ ~]# mysql -u root -ppassword test -e  "update ratings set rating=3 where reviewid=1;select * from ratings;"
    +----------+--------+
    | ReviewID | Rating |
    +----------+--------+
    |        1 |      3 |
    |        2 |      4 |
    +----------+--------+
  4. 在浏览器中输入对外服务路径,访问对外路径。多次刷新页面后,页面没有变化。页面的Reviewer1区域显示3颗星星,Reviewer2区域显示4颗星星。
    11