MOSN 作为 Istio 的数据平面

本文将介绍如何使用 MOSN 在 Istio 框架下搭建 Service Mesh 的开发环境,并验证 MOSN 的一些基础路由能力、负载均衡能力等。

MOSN 从 v1.0.0 版本开始 已通过 Istio 1.10.6 的 Bookinfo 测试,关于最新版 Istio 的支持情况可关注 MOSN Istio WG

本文介绍的内容将包括 :

  • MOSN 与 Istio 的关系
  • 部署 Istio 与 MOSN
  • Bookinfo 实验

MOSN 与 Istio 的关系

我们曾在 MOSN 介绍 中介绍过,MOSN 是一款采用 Go 语言开发的 Service Mesh 数据平面代理。

下图是 Istio 整体框架下,MOSN 的工作示意图。

MOSN 介绍

部署 Istio 与 MOSN

注意:Istio 1.10.6 不支持在 arm64 上运行 Kubernetes 的集群 。 Istio Issues%5D)

安装 kubectl 命令行工具

kubectl 是用于针对 Kubernetes 集群运行命令的命令行接口,安装参考 kubectl doc

安装 Kubernetes 平台

安装 Istio,首先需要根据实际需求选择安装平台,可参考 Istio 官方文档推荐的方式 Platform Setup。 后文中,我们假定选择的是minikube的安装方式,方便进行介绍。

安装minikube 流程:

1、根据本机环境选择下载地址 Minikube 官网,下面用的系统是macOS x86系统。

  1. $ curl -LO https://storage.googleapis.com/minikube/releases/v1.22.0/minikube-darwin-amd64
  2. $ sudo install minikube-darwin-amd64 /usr/local/bin/minikube

2、启动 minikube

  1. $ minikube start --memory=7851 --cpus=4 --image-mirror-country='cn'

注意:内存必须大于4GB,且镜像为cn(国内)

3、安装成功后,查看Pod情况

  1. $ minikube kubectl -- get pods -A
  2. NAMESPACE NAME READY STATUS RESTARTS AGE
  3. kube-system coredns-64897985d-vw7b8 1/1 Running 2 (16h ago) 7d20h
  4. kube-system etcd-minikube 1/1 Running 2 (16h ago) 7d20h
  5. kube-system kube-apiserver-minikube 1/1 Running 2 (16h ago) 7d20h
  6. kube-system kube-controller-manager-minikube 1/1 Running 2 (16h ago) 7d20h
  7. kube-system kube-proxy-cmjcq 1/1 Running 2 (16h ago) 7d20h
  8. kube-system kube-scheduler-minikube 1/1 Running 2 (16h ago) 7d20h
  9. kube-system storage-provisioner 1/1 Running 5 (16h ago) 7d20h

安装 Istio,使用 MOSN 作为数据面

1、下载对应的 Istio Release 版本,可以在 Istio release 页面下载与您操作系统匹配的压缩文件,或者使用官方提供的下载方式

  1. VERSION=1.10.6 # istio version
  2. export ISTIO_VERSION=$VERSION && curl -L https://istio.io/downloadIstio | sh -

2、下载完成以后(或者解压完成),切换到对应的目录,同时可以设置对应的 istioctl 命令行工具到环境变量,方便配置自定义 Istio 控制平面和数据平面配置参数。

  1. $ cd istio-$ISTIO_VERSION/
  2. $ export PATH=$PATH:$(pwd)/bin

3、执行默认安装 istioctl install

  1. $ istioctl install
  2. This will install the Istio 1.14.1 default profile with ["Istio core" "Istiod" "Ingress gateways"] components into the cluster. Proceed? (y/N) y
  3. Istio core installed
  4. Istiod installed
  5. Ingress gateways installed
  6. Installation complete
  7. Making this installation the default for injection and validation.
  8. Thank you for installing Istio 1.10. Please take a few minutes to tell us about your install/upgrade experience! https://forms.gle/KjkrDnMPByq7akrYA

4、创建 istio 命名空间,并且设置 MOSN proxyv2 镜像为数据面镜像

下载 MOSN proxyv2 的镜像,并设置其为 Istio 的 proxy 镜像。 --set .values.global.proxy.image=${MOSN IMAGE} 也可以通过手动去创建 proxy 镜像 (MOSN 与 Istio 的 proxyv2 镜像 build 方法介绍)。 以下将使用我们提供的镜像版本 mosnio/proxyv2:v1.0.0-1.10.6

  1. $ kubectl create namespace istio-system
  2. $ istioctl manifest apply --set .values.global.proxy.image=mosnio/proxyv2:v1.0.0-1.10.6 --set meshConfig.defaultConfig.binaryPath="/usr/local/bin/mosn"

注意:当你失败时,可以通过 minikube ssh 进入虚机所构建的集群内部,并通过 docker pull mosnio/proxyv2:v1.0.0-1.10.6 来获取镜像

5、验证 Istio 相关 POD 服务是否部署成功

  1. $ kubectl get pod -n istio-system
  2. NAME READY STATUS RESTARTS AGE
  3. istio-ingressgateway-6b7fb88874-rgmrj 1/1 Running 0 102s
  4. istiod-65c9767c55-vjppv 1/1 Running 0 109s

如果 pod 显示所有容器 READY,并且 STATUS 为 Running,则表示 Istio 安装成功

Bookinfo 实验

MOSN 已经通过 Istio 1.10.6 的 Bookinfo 测试,可以通过 MOSN with Istio 的教程来进行 Bookinfo 示例的演示操作,另外在该教程中您也可以找到更多关于使用 MOSN 和 Istio 的说明。 更多的使用场景可以参考 Istio 官方 Example。 MOSN 目前并没有支持 Istio 的所有场景,如果您在运行实验过程中有遇到不支持的情况,请给我们提出 issue,欢迎贡献代码。

Bookinfo 介绍

Bookinfo 是一个类似豆瓣的图书应用,它包含四个基础服务:

  • Product Page:主页,由 python 开发,展示所有图书信息,它会调用 Reviews 和 Details 服务
  • Reviews:评论,由 java 开发,展示图书评论,会调用 Ratings 服务
  • Ratings:评分服务,由 nodejs 开发
  • Details:图书详情,由 ruby 开发

bookinfo

部署 Bookinfo 应用并注入 MOSN

详细过程可以参考 Bookinfo doc

通过 kube-inject 的方式实现 Sidecar 注入:

  1. istioctl kube-inject -f samples/bookinfo/platform/kube/bookinfo.yaml > bookinfo.yaml
  2. # sed -i '' is the MacOS command, if you are in linux, use sed -i instead.
  3. sed -i '' "s/\/usr\/local\/bin\/envoy/\/usr\/local\/bin\/mosn/g" ./bookinfo.yaml

部署注入 Sidecar 后的 Bookinfo 应用:

  1. $ kubectl apply -f bookinfo.yaml

验证部署是否成功:

  1. $ kubectl get services
  2. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
  3. details ClusterIP 192.168.248.118 <none> 9080/TCP 5m7s
  4. kubernetes ClusterIP 192.168.0.1 <none> 443/TCP 25h
  5. productpage ClusterIP 192.168.204.255 <none> 9080/TCP 5m6s
  6. ratings ClusterIP 192.168.227.164 <none> 9080/TCP 5m7s
  7. reviews ClusterIP 192.168.181.16 <none> 9080/TCP 5m6s

等待所有的 pod 等成功运行起来:

  1. $ kubectl get pods
  2. NAME READY STATUS RESTARTS AGE
  3. details-v1-77497b4899-67gfn 2/2 Running 0 98s
  4. productpage-v1-68d9cf459d-mv7rh 2/2 Running 0 97s
  5. ratings-v1-65f97fc6c5-npcrz 2/2 Running 0 98s
  6. reviews-v1-6bf4444fcc-9cfrw 2/2 Running 0 97s
  7. reviews-v2-54d95c5444-5jtxp 2/2 Running 0 97s
  8. reviews-v3-dffc77d75-jd8cr 2/2 Running 0 97s

当上述状态为 Running 后,可通过如下方式确认 Bookinfo 应用是否正常运行:

  1. kubectl exec -it $(kubectl get pod -l app=ratings -o jsonpath='{.items[0].metadata.name}') -c ratings -- curl productpage:9080/productpage | grep -o "<title>.*</title>"

访问 Bookinfo 服务

开启 gateway 模式。

  1. $ kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml
  2. $ kubectl get gateway
  3. NAME AGE
  4. bookinfo-gateway 6s

在后台运行ingress 网关,通过1234端口转发到80端口。参考文档

  1. kubectl port-forward -n istio-system --address 0.0.0.0 service/istio-ingressgateway 1234:80 >/dev/null 2>&1 &

验证 gateway 是否生效,输出 200 表示成功。

  1. $ curl -o /dev/null -s -w "%{http_code}\n" http://127.0.0.1:1234/productpage
  2. 200

观察页面情况

访问 http://$GATEWAY_URL/productpage (注意: $GATEWAY_URL 需要替换成你设置的地址,如:127.0.0.1:1234),正常的话通过刷新会看到如下所示 Bookinfo 的界面,其中 Book Reviews 有三个版本,刷新后依次会看到(可以查看 samples/bookinfo/platform/kube/bookinfo.yaml 中的配置发现为什么是这三个版本)版本一的界面。

版本一

版本二的界面。

版本二

版本三的界面。

版本三

验证 MOSN 按 version 路由能力

首先为 Bookinfo 的 service 创建一系列的 destination rules。

  1. $ kubectl apply -f samples/bookinfo/networking/destination-rule-all.yaml

指定 reviews 服务只访问 v1 版本。

  1. $ kubectl apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml

访问 http://$GATEWAY_URL/productpage 发现 reviews 固定在如下版本一的页面不再变化。

版本一

验证 MOSN 按 weight 路由能力

我们通过下面操作将 v1 和 v3 版本各分配 50% 的流量。

  1. $ kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-50-v3.yaml

访问 http://$GATEWAY_URL/productpage 这次 v1 和 v3 各有 1/2 几率出现。

验证 MOSN 按照特定 header 路由能力

Bookinfo 系统右上角有一个登陆的入口,登陆以后请求会带上 end-user 这个自定义,值是 user name,Mosn 支持根据这个 header 的值来做路由。比如,我们尝试将 jason 这个用户路由到 v2 版本,其他的路由到 v1 版本(用户名和密码均是:jason,为什么是这个用户可以查看对应的 yaml 文件)。

  1. $ kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-test-v2.yaml

访问 http://$GATEWAY_URL/productpage 时:

以 jason 身份登陆,会看到 v2 版本。

登录

以其他身份登录,始终在 v1 版本。

版本一

验证 MOSN 的故障注入功能

初始状态准备 运行以下命令来初始化 Bookinfo 应用程序版本路由信息:

  1. kubectl apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml
  2. kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-test-v2.yaml

经过上面的配置后,其请求链路如下所示:

productpage → reviews:v2 → ratings (针对 jason 用户) productpage → reviews:v1 (其他用户)

注入延时故障

执行下面的命令将会为用户 jason 在 reviews:v2 和 ratings 服务之间注入一个 7 秒的延迟:

  1. kubectl apply -f samples/bookinfo/networking/virtual-service-ratings-test-delay.yaml

访问 http://$GATEWAY_URL/productpage

此时发现使用 jason 这个用户登录访问会有延时, Reviews 部分显示了错误消息:

Error fetching product reviews! Sorry, product reviews are currently unavailable for this book.

注入 abort 故障

执行下面的命令将会为用户 jason 访问 ratings 微服务时引入一个 HTTP abort:

  1. kubectl apply -f samples/bookinfo/networking/virtual-service-ratings-test-abort.yaml

访问 http://$GATEWAY_URL/productpage

此时发现使用 jason 这个用户登录访问时, 此时 Book Reviews 中会显示如下错误消息:

Ratings service is currently unavailable

卸载 Bookinfo

可以使用下面的命令来完成应用的删除和清理工作:

删除路由规则,并销毁应用的 Pod。

  1. $ samples/bookinfo/platform/kube/cleanup.sh <<EOF Y; EOF

确认 Bookinfo 应用已经关停:

  1. $ kubectl get virtualservices #-- there should be no virtual services
  2. $ kubectl get destinationrules #-- there should be no destination rules
  3. $ kubectl get gateway #-- there should be no gateway
  4. $ kubectl get pods #-- the Bookinfo pods should be deleted

卸载 Istio

执行如下命令,删除 Istio 相关 CRD 以及 pod 等资源:

  1. $ istioctl manifest generate | kubectl delete -f -

确认 Istio 是否成功卸载:

  1. $ kubectl get namespace istio-system

修改于 2022年12月2日: Bump tar from 4.4.8 to 4.4.19 in /themes/docsy/userguide (942c999)