MOSN 作为 Istio 的数据平面
本文将介绍如何使用 MOSN 在 Istio 框架下搭建 Service Mesh 的开发环境,并验证 MOSN 的一些基础路由能力、负载均衡能力等。
MOSN 从 v1.0.0 版本开始 已通过 Istio 1.10.6 的 Bookinfo
测试,关于最新版 Istio 的支持情况可关注 MOSN Istio WG。
本文介绍的内容将包括 :
- MOSN 与 Istio 的关系
- MOSN 与 Istio 的 proxyv2 镜像 build 方法
- 部署 Istio 与 MOSN
- Bookinfo 实验
MOSN 与 Istio 的关系
我们曾在 MOSN 介绍 中介绍过,MOSN 是一款采用 Go 语言开发的 Service Mesh 数据平面代理。
下图是 Istio 整体框架下,MOSN 的工作示意图。
MOSN 与 Istio 的 proxyv2 镜像 build 方法
本文的完整构建镜像方法均是基于 MacOS 和 Istio 1.10.6 版本进行的构建,在其他操作系统 Istio 版本上可能存在部分细节差异,需要进行调整。 除了完整构建方式外,如果仅有 MOSN 代码发生变化,还可以使用仅更新 MOSN 的方式构建镜像。 通常情况下,您不需要额外构建镜像,可直接用我们提供的镜像 mosnio/proxyv2:${MOSN-VERSION}-${ISTIO_VERSION}
,如docker pull mosnio/proxyv2:1.0.0-1.10.6
完整的镜像构建(基于 MacOS 和 Istio 1.10.6)
1、下载完整的 istio 源代码,并且切换到对应的版本
git clone git@github.com:istio/istio.git
cd istio
git checkout 1.10.6
2、由于目前 Istio 默认会加载 wasm,我们需要将相关逻辑注释掉,再重新编译镜像,避免一些不必要的错误。详细的改动可见 istio-diff
3、编译 MOSN 二进制,MOSN 提供了镜像编译的方式可直接编译 linux 的二进制;同时由于在 MacOS 上构建的过程中,Istio 还会下载一个 MacOS 版本,因此还需要编译一个 MacOS 的二进制
4、将编译好的二进制,使用 tar 方式进行打包,并且打包路径需要是usr/local/bin
cd ${MOSN Project Path}
mkdir -p usr/local/bin
make build # build mosn binary on linux
cp build/bundles/${MOSN VERSION}/binary/mosn usr/local/bin
tar -zcvf mosn.tar.gz usr/local/bin/mosn
cp mosn.tar.gz mosn-centos.tar.gz # copy a renamed tar.gz file
make build-local # build mosn binary on macos
cp build/bundles/${MOSN VERSION}/binary/mosn usr/local/bin
tar -zcvf mosn-macos.tar.gz usr/local/bin/mosn
5、将生成的mosn-macos.tar.gz
mosn-centos.tar.gz
mosn.tar.gz
上传到一个编译环境可访问的存储服务中,可用 Go 语言简单快速在本地环境搭建一个
func main() {
address := "" // an address can be reached when proxyv2 image build. for example, 0.0.0.0:8080
filespath := "" // where the .tar.gz files stored.
http.ListenAndServe(address, http.FileServer(http.Dir(filespath)))
}
6、指定参数,开始编译 proxyv2 镜像
address=$1 # your download service address
export ISTIO_ENVOY_VERSION=$2 # MOSN Version, can be any value.
export ISTIO_ENVOY_RELEASE_URL=http://$address/mosn.tar.gz
export ISTIO_ENVOY_CENTOS_RELEASE_URL=http://$address/mosn-centos.tar.gz
export ISTIO_ENVOY_MACOS_RELEASE_URL=http://http://$address/mosn-macos.tar.gz
export ISTIO_ENVOY_MACOS_RELEASE_NAME=mosn-$2 # can be any value
export SIDECAR=mosn
make clean # clean the cache
make docker.proxyv2 \
SIDECAR=$SIDECAR \
ISTIO_ENVOY_VERSION=$ISTIO_ENVOY_VERSION \
ISTIO_ENVOY_RELEASE_URL=$ISTIO_ENVOY_RELEASE_URL \
ISTIO_ENVOY_CENTOS_RELEASE_URL=$ISTIO_ENVOY_CENTOS_RELEASE_URL \
ISTIO_ENVOY_MACOS_RELEASE_URL=$ISTIO_ENVOY_MACOS_RELEASE_URL \
ISTIO_ENVOY_MACOS_RELEASE_NAME=$ISTIO_ENVOY_MACOS_RELEASE_NAME
7、编译完成以后,可以将镜像打上新的 Tag 并且上传(如个人测试 dockerhub 的地址),确保 istio 使用时可访问即可
单独更新 MOSN 版本
1、重新编译 MOSN 二进制
cd ${MOSN Project Path}
make build # build mosn binary on linux
2、直接基于现有 MOSN 的 proxyv2 镜像更新二进制
FROM mosnio/proxyv2:v1.0.0-1.10.6
COPY build/bundles/${MOSN VERSION}/binary/mosn /usr/local/bin/mosn
docker build --no-cache --rm -t ${your image tag}
3、将新镜像上传,确保 istio 使用时可访问即可
部署 Istio 与 MOSN
安装 kubectl 命令行工具
kubectl 是用于针对 Kubernetes 集群运行命令的命令行接口,安装参考 kubectl doc。
安装 Kubernetes 平台
安装 Istio,首先需要根据实际需求选择安装平台,可参考 Istio 官方文档推荐的方式 Platform Setup。 后文中,我们假定选择的是minikube
的安装方式,方便进行介绍。
安装 Istio,使用 MOSN 作为数据面
1、下载对应的 Istio Release 版本,可以在 Istio release 页面下载与您操作系统匹配的压缩文件,或者使用官方提供的下载方式
VERSION=1.10.6 # istio version
export ISTIO_VERSION=$VERSION && curl -L https://istio.io/downloadIstio | sh -
2、下载完成以后(或者解压完成),切换到对应的目录,同时可以设置对应的istioctl
命令行工具到环境变量,方便配置自定义 Istio 控制平面和数据平面配置参数。
cd istio-$ISTIO_VERSION/
export PATH=$PATH:$(pwd)/bin
3、创建 istio 命名空间,并且设置 MOSN proxyv2 镜像为数据面镜像
kubectl create namespace istio-system
istioctl manifest apply --set .values.global.proxy.image=${MOSN IMAGE} --set meshConfig.defaultConfig.binaryPath="/usr/local/bin/mosn"
4、验证 Istio 相关 POD 服务是否部署成功
kubectl get pod -n istio-system
NAME READY STATUS RESTARTS AGE
istio-ingressgateway-6b7fb88874-rgmrj 1/1 Running 0 102s
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
应用并注入 MOSN
详细过程可以参考 Bookinfo doc
通过 kube-inject 的方式实现 Sidecar 注入:
istioctl kube-inject -f samples/bookinfo/platform/kube/bookinfo.yaml > bookinfo.yaml
# sed -i '' is the MacOS command, if you are in linux, use sed -i instead.
sed -i '' "s/\/usr\/local\/bin\/envoy/\/usr\/local\/bin\/mosn/g" ./bookinfo.yaml
部署注入 Sidecar 后的 Bookinfo 应用:
$ kubectl apply -f bookinfo.yaml
验证部署是否成功:
$ kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
details ClusterIP 192.168.248.118 <none> 9080/TCP 5m7s
kubernetes ClusterIP 192.168.0.1 <none> 443/TCP 25h
productpage ClusterIP 192.168.204.255 <none> 9080/TCP 5m6s
ratings ClusterIP 192.168.227.164 <none> 9080/TCP 5m7s
reviews ClusterIP 192.168.181.16 <none> 9080/TCP 5m6s
等待所有的 pod 等成功运行起来:
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
details-v1-77497b4899-67gfn 2/2 Running 0 98s
productpage-v1-68d9cf459d-mv7rh 2/2 Running 0 97s
ratings-v1-65f97fc6c5-npcrz 2/2 Running 0 98s
reviews-v1-6bf4444fcc-9cfrw 2/2 Running 0 97s
reviews-v2-54d95c5444-5jtxp 2/2 Running 0 97s
reviews-v3-dffc77d75-jd8cr 2/2 Running 0 97s
当上述状态为 Running 后,可通过如下方式确认 Bookinfo 应用是否正常运行:
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 模式。
$ kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml
$ kubectl get gateway
NAME AGE
bookinfo-gateway 6s
设置 GATEWAY_URL
参考文档
$ export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}')
$ export INGRESS_HOST=$(minikube ip)
$ export GATEWAY_URL=$INGRESS_HOST:$INGRESS_PORT
验证 gateway 是否生效,输出 200
表示成功。
$ curl -o /dev/null -s -w "%{http_code}\n" http://$GATEWAY_URL/productpage
200
观察页面情况
访问 http://$GATEWAY_URL/productpage
(注意: $GATEWAY_URL
需要替换成你设置的地址),正常的话通过刷新会看到如下所示 Bookinfo
的界面,其中 Book Reviews 有三个版本,刷新后依次会看到(可以查看 samples/bookinfo/platform/kube/bookinfo.yaml 中的配置发现为什么是这三个版本)版本一的界面。
版本二的界面。
版本三的界面。
验证 MOSN 按 version 路由能力
首先为 Bookinfo
的 service 创建一系列的 destination rules。
$ kubectl apply -f samples/bookinfo/networking/destination-rule-all.yaml
指定 reviews 服务只访问 v1 版本。
$ kubectl apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml
访问 http://$GATEWAY_URL/productpage
发现 reviews 固定在如下版本一的页面不再变化。
验证 MOSN 按 weight 路由能力
我们通过下面操作将 v1 和 v3 版本各分配 50% 的流量。
$ 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 文件)。
$ kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-test-v2.yaml
访问 http://$GATEWAY_URL/productpage
时:
以 jason 身份登陆,会看到 v2 版本。
以其他身份登录,始终在 v1 版本。
卸载 Bookinfo
可以使用下面的命令来完成应用的删除和清理工作:
删除路由规则,并销毁应用的 Pod。
$ sh samples/bookinfo/platform/kube/cleanup.sh
确认 Bookinfo
应用已经关停:
$ kubectl get virtualservices #-- there should be no virtual services
$ kubectl get destinationrules #-- there should be no destination rules
$ kubectl get gateway #-- there should be no gateway
$ kubectl get pods #-- the Bookinfo pods should be deleted
卸载 Istio
执行如下命令,删除 Istio 相关 CRD 以及 pod 等资源:
$ istioctl manifest generate | kubectl delete -f -
确认 Istio 是否成功卸载:
$ kubectl get namespace istio-system
修改于 2022年5月11日: fix the istio-diff links (#199) (143cd05)