istio核心功能流量控制概述
作为一个Kubernetes的重度依赖患者,必不可免会遇到一些问题,例如:
- 如何实现灰度发布、金丝雀部署
- 如何在应用层实现Kubernetes的认证与安全
- 部署在k8s上的微服务如何做到异常流量分布式追踪
- …… 最初我使用了SDK和配置分发中心apollo来实现这一切,但在集群越来越大,应用越来越复杂的情况下,一个简单的需求就可能有很大的变动,不得不去寻找更好的方案——istio。
istio是什么?为什么他能解决这些问题?
官方定义:它是一个完全开源的服务网格,作为透明的一层接入到现有的分布式应用中。它也是一个平台,可以与任何日志、遥测和策略系统进行集成。Istio 多样化的特性让你能够成功且高效地运行微服务架构,并提供保护、连接和监控微服务的统一方法。
简单解释一下,作为号称第二代服务网格的istio,它能够轻松的构建起无代码侵入式的服务网格,并提供流量控制、可观察、安全、策略等高级功能,接下来我会详细的介绍具体功能的实现和场景。
流量控制
流量控制是服务网格的核心功能,对于istio也不例外,在这一功能上可以细分如下的主要功能
- 路由、流量转移
- 流量出入控制
- 网络弹性能力
- 镜像、测试相关 那么istio是如何实现这些主要功能的呢,这依赖于他的核心资源:
- 虚拟服务(Virtual Service)
- 目标规则(Destination Rule)
- 网关(Gateway)
- 服务入口(Service Entry)
- 依赖于Envoy实现的Sidecar
虚拟服务(Virtual Service)
首先从虚拟服务和目标规则讲起,他们一般来说都是一起被使用的,虚拟服务来定义路由规则和描述满足条件的请求去哪里,而目标规则则是定义子集和策略,描述到达目标的请求该怎么处理,以图为例。
举个官方的例子:
Virtual Service
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews
http:
- route:
- destination:
host: reviews
subset: v3
目标规则(Destination Rule)
在虚拟服务中使用Hosts配置默认绑定的路由地址,用http.route字段,设置http进入的路由地址,可以看到,他导入到了目标规则为reviews的v3子集,我们来看一下对应的目标规则yaml
Destination Rule
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: reviews
spec:
host: reviews
trafficPolicy:
loadBalancer:
simple: RANDOM
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
- name: v3
labels:
version: v3
可以看到,这个目标规则中制定了loadbalancer规则为随机,绑定了路由到reviews,提供了v1-v3的三个子集版本。
具体还有一些字段我没有配置,如图上所示,可以在官网查询到对应的作用。
网关(Gateway)
至于网关则是一个运行在网格边缘的负载均衡器,主要工作是接受外部请求,转发到内部的服务,还可以配置对外的端口、协议与内部服务的映射关系。
Gateway
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: my-gateway
spec:
selector:
app: my-gateway-controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
在这个yaml里我们配置了一个监听80端口的入口网关,它会将80端口的http流量导入到集群内。 对应的Virtual Service
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews
gateway:
- my-gateway
http:
- route:
- destination:
host: reviews
subset: v3
通过修改之前的虚拟服务yaml,添加了gateway字段,使得这个虚拟服务会收到上一个gateway中所有80端口来的http流量。
服务入口(Service Entry)
接下来我们说一说服务入口(Service Entry),他是作用是添加外部服务到网格内,管理到外部服务的请求。
一般我们在生产环境中会控制内部服务对外界的访问,ServiceEntry就是用来做这个的,我们可以先把内部服务对外部的访问给干掉
$ kubectl get configmap istio -n istio-system -o yaml | sed 's/mode: ALLOW_ANY/mode: REGISTRY_ONLY/g' | kubectl replace -n istio-system -f -
再exec到pod中会发现无法curl www.baidu.com了。
现在配置一下对应的ServiceEntry
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metabase:
name: http-baidu
spec:
hosts:
- www.baidu.com
ports:
- number:80
name: http
protocol: HTTP
resolution: DNS
location: MESH_EXTERNAL
再去curl www.baidu.com会发现可以访问到,这是因为我们已经通过ServiceEntry来注册了 www.baidu.com 在我们的服务中了。
对应的配置项如图,需要解释以下的就是这个location,location中可以配置外部服务和内部服务,一般在网格内的服务我们都会配置成内部服务。
SIDECAR部分由于是istio数据平面最核心的部分,会单独开一期来讲,感谢老铁点赞。