系列文章:


总目录索引:九析带你轻松完爆 istio 服务网格系列教程

目录

1 前言

2 邀约

3 虚拟服务(Virtual Service)

4 虚拟服务跟 K8s 服务的关系

5 虚拟服务实例

    5.1 k8s 资源

    5.2 Istio 资源

    5.3 Istio 注入

    5.4 创建客户端和客户端 Istio 注入


1 前言

        如果你对博客有任何疑问,请告诉我。第十九章 九析带你轻松完爆 service mesh - Istio virtual service_第1张图片


2 邀约

        你可以从 b 站搜索 “九析”,获取免费的、更生动的视频资料:第十九章 九析带你轻松完爆 service mesh - Istio virtual service_第2张图片


3 虚拟服务(Virtual Service)

        虚拟服务(Virtual Service)以及目标规则(Destination Rule)是 Istio 流量路由的两大基石。虚拟服务可以将流量路由到 Istio 服务网格中的服务。每个虚拟服务由一组路由规则组成,这些路由规则按顺序进行评估。

        如果没有 Istio virtual service,仅仅使用 k8s service 的话,那么只能实现最基本的流量负载均衡转发,但是就不能实现类似按百分比来分配流量等更加复杂、丰富、细粒度的流量控制了。


4 虚拟服务跟 K8s 服务的关系

        虚拟服务相当于 K8s 服务的 sidecar,在原本 K8s 服务的功能之上,提供了更加丰富的路由控制。


5 虚拟服务实例

        以下介绍使用 “虚拟服务(virtual service)+目标规则(destination rule)” 实现一个流量分流的例子。本示例共需要四种资源,k8s 和 istio 各两种:

        k8s 资源介绍如下:

1 两个 deployment,一个 tomcat,一个 nginx

2 一个 service 关联上面这两个 deployment

        Istio 资源介绍如下:

1 一个 destination rule,设置目标规则定义

2 一个 virtual service 关联上面的 service,用来设置分流权重(weight)和设置分流目标规则定义)

5.1 k8s 资源

        k8s 资源共有两类,分别为 deployment 和 service,其中 deployment 资源文件明细如下:

# jiuxi-deploy.yaml

apiVersion: apps/v1

kind: Deployment

metadata:

    name: nginx-deploy

spec:

    replicas: 1

    selector:

        matchLabels:

            type: web

            app: nginx

    template:

        metadata:

        labels:

            type: web

            app: nginx

        spec:

            containers:

            -  image: nginx:1.14-alpine

                imagePullPolicy: IfNotPresent

                name: nginx

                ports:

                -  containerPort: 80

                    name: port

                    protocol: TCP

---

apiVersion: apps/v1

kind: Deployment

metadata:

    name: tomcat-deploy

spec:

    replicas: 1

    selector:

        matchLabels:

            type: web

            app: tomcat

    template:

        metadata:

            labels:

                type: web

                app: tomcat

        spec:

            containers:

            -  image: docker.io/kubeguide/tomcat-app:v1

                imagePullPolicy: IfNotPresent

                name: tomcat

                ports:

                -  containerPort: 8080

                    name: port

                    protocol: TCP

        部署上面的 jiuxi-deploy.yaml 文件,语句如下:

kubectl apply -f jiuxi-deploy.yaml

        service 资源文件明细如下:

# jiuxi-svc.yaml

apiVersion: v1

kind: Service

metadata:

    name: web-svc

spec:

    ports:

    -  name: port

        port: 8080

        protocol: TCP

        targetPort: 8080

    selector:

        type: web

        部署上面的 service 文件,语句如下:

kubectl apply -f jiuxi-svc.yaml

        自此,k8s 层面的资源文件准备完毕,现在通过访问 service,可以发现自动实现了RoundBin的负载均衡策略,即分配到 tomcat 和 nginx 的流量各为 50%。

5.2 Istio 资源

        Istio 资源共有两类,分别为虚拟服务(Virtual Service)和目的地规则(Destination Rule)。虚拟服务作用在 k8s 服务之上,并加强了原 k8s 服务的功能:

    • 指定目的地(tomcat 或 nginx)

    • 重新分配流量(即不再是 50% / 50%,而是 75% / 25%)

        目的地规则文件 jiux-dr.yaml 如下:

# jiuxi-dr.yaml

apiVersion: networking.istio.io/v1alpha3

kind: DestinationRule

metadata:

    name: jiuxi-dr

spec:

    host: jiuxi-svc

    subsets:

    -  name: tomcat

        labels:

            app: tomcat

    - name: nginx

        labels:

            app: nginx

        上面的目的地资源文件作用在 jiux-svc 这个 k8s 服务上,通过 labels 字段指定不同的 pod,然后通过 name 字段提供给下面的 virtual service,起到关联到具体 pod 的作用。

        如果这里你不好理解,可以这么来理解。以前 k8s service 跟 pod 关联是一维坐标关联,从上面例子可知,nginx 跟 tomcat 对 svc 而言是没什么区别的,因为都是相同的 labels 指定。但是如果采用了 virtual service 和 destination 相当于对 service 后面的 pod 使用了二维坐标关联,这样就可以明确定义 service 后面的 pod 到底有哪些业务含义了(比如一个是 nginx,另外一个是 tomcat)。这里大家仔细琢磨一下。

        虚拟服务文件 jiuxi-vs.yaml 如下:

# jiuxi-vs.yaml

apiVersion: networking.istio.io/v1alpha3

kind: VirtualService

metadata:

    name: jiuxi-virtual-svc

spec:

    hosts:

    -  jiuxi-svc

    http:

    -  route:

        -  destination:

                host: jiuxi-svc

                subset: nginx

            weight: 25

        -  destination:

                host: jiuxi-svc

                subset: tomcat

            weight: 75

        执行上面这两个资源文件:

kubectl apply -f jiuxi-dr.yaml

kubectl apply -f jiuxi-vs.yaml

        命令执行后的结果如下截图所示:clipboard4.png

5.3 Istio 注入

        执行如下命令进行 Istio 注入:

istioctl kube-inject -f jiuxi-deploy.yaml | kubectl apply -f -

        因为 nginx 默认启动是 80 端口,为了保持跟 tomcat 端口保持一致,这里需要登录到 pod 中修改 nginx 端口,操作方法如下:

# pod 后缀根据实际情况进行修改

kubectl exec -it nginx-deploy-957f689f5-7svdz -- sh

        然后编辑 nginx 配置文件:

vi /etc/nginx/conf.d/default.conf

        修改内容如下截图:第十九章 九析带你轻松完爆 service mesh - Istio virtual service_第3张图片

5.4 创建客户端和客户端 Istio 注入

        创建客户端访问经过 Istio 流控过的 k8s 服务,客户端资源文件如下:

# jiuxi-busybox.yaml

apiVersion: v1

kind: Pod

metadata:

    name: busybox

spec:

    containers:

    -  name: nginx

        image: busybox

        imagePullPolicy: IfNotPresent

        command: ["/bin/sh", "-c", "sleep 3600" ]

        执行如下 Istio 注入命令:

istioctl kube-inject -f jiuxi-busybox.yaml | kubectl apply -f -

        Istio 注入成功后,通过 kubectl exec 登录到 busybox 容器中,然后执行如下语句,验证 virtual service 和 destination rule 功能:

curl http://jiuxi-svc:8080

        注意这里的客户端也必须经过 Istio 注入,因为只有客户端被 Istio 注入,客户端才可以接收到来自 Pilot server 端有关 virtual service 和 destination rule 的配置信息,才可以保证 Istio 的 traffic management 真正生效。

        自此,九析带你轻松完爆 Istio virtual service + Destination Rule 功能。