istio 官网入门案例
在 docker-desktop 上体验 istio 入门案例
安装&命令
从官网安装 docker-desktop,选择安装 k8s, 配置资源 4c8g
部署bookinfo应用
参考官方文档,部署bookinfo应用, 下面为从中摘取的关键部分
# download istio
curl -L https://istio.io/downloadIstio | sh -
# set path(for istioctl)
cd istio-1.18.0
export PATH=$PWD/bin:$PATH
# install istio
istioctl install --set profile=demo -y
# enable sidecar
kubectl label namespace default istio-injection=enabled
# run bookinfo (dir: istio-1.18.0)
kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
使用 docker-desktop 时,gateway地址是127.0.0.1, 因此,经过上述命令后,就能安装上 istio,并启动 bookinfo 服务。可以通过 kubectl get pods 查看对应的服务是否启动,正常情况为:
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
details-v1-558b8b4b76-2llld 2/2 Running 0 2m41s
productpage-v1-6987489c74-lpkgl 2/2 Running 0 2m40s
ratings-v1-7dc98c7588-vzftc 2/2 Running 0 2m41s
reviews-v1-7f99cc4496-gdxfn 2/2 Running 0 2m41s
reviews-v2-7d79d5bd5d-8zzqd 2/2 Running 0 2m41s
reviews-v3-7dbcdcbc56-m8dph 2/2 Running 0 2m41s
此时,可以通过 http://127.0.0.1/productpage 访问页面
此时的页面是随机调用到三个不同版本的 reviews,多刷新几次页面,会发现这里显示不一样(没有配置任何规则,所以是随机落到任意一个服务后端)
使用 VirtualService, DestinationRule 进行流量控制
参考:
# 定义 review 的目标规则(DestinationRule,简称 DR)
kubectl apply -f - << EOF
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: reviews
spec:
host: reviews
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
- name: v3
labels:
version: v3
EOF
# 定义 review 的虚拟服务(VirtualService, 简称 VS)
kubectl apply -f - << EOF
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews
http:
- route:
- destination:
host: reviews
subset: v1
EOF
上述 vs 将所有的流量都走到了 reviews v1 的版本,可以通过刷新页面,观察到页面不会再显示评价(固定到了 v1 版本)
下面理解下这两个文件声明的含义:
目的规则(DR) 本质上,就是讲同一个目的地址的请求,分成几个子集(subset),通过标签划分子集的范围。是一个 “实际后端服务(pod)” 与 “目的规则的子集” 的映射关系
- metadata.name 表示的是这个目的路由的名字,一般与host相同,表示是针对host的DR,但不是一定的,其任意方便理解的名字即可
- spec.host 这里的 review 是一个“引用”,表示的的目的地址的 host,也就是说,当请求的 host 等于review 时,才会进行匹配的目的路由
- spec.subsets 声明不同子集的范围,这里的labels具体值,同样是一个引用,对应的是 Pod 的 label(注意,不是deployment,也不是service,由于这几个资源的labels经常重叠,容易混淆),表示选中这部分后端服务
上面的例子,相当于根据 pod 的 version 这个label,将同一个reviews服务分成三个不同的子集,然后分别给每个子集起了一个名字(v1,v2,v3),后续 VirtualService 则可以通过子集的方式,对同一个服务的不同版本进行细分的路由
虚拟服务(VirtualService)本质上就是根据不同的路由规则,选择走同一个服务的不同子集,是一个 “匹配规则” 与 “子集” 的映射关系
- metadata.name 表示的是这个虚拟服务的名字,一般与host相同,表示是针对 reviews 这个服务的VS,但不是一定的,其任意方便理解的名字即可(使用相同名字这点,对于初学理解概念时,容易造成混淆,但在实际使用时,则很容易知道几个资源的对应关系)
- spec.hosts 这里是个列表,可以匹配一个或多个host,这里的 reviews 则是一个 “引用”,表示的是请求的host,即请求的目的地址(服务)
- http.route.destination 表示将符合上面匹配规则的 http 请求,转发到对应的子集(subset)中,这里需要 host + subset 才能唯一确定某一个DR的子集, 所以,这里的 host 和 subset 是对DR的引用, host 对应的是 DR 中 spec.host, subset 对应 spec.subsets[].name
通过上述的例子,可以看出, istio 的路由,就是先通过 “host+匹配规则” 找到一个 “抽象的集合(subset in DR)”,在通过这个“subset” 找到 一组 pod。从而实现了请求到目的地址的选路过程。在 k8s 中, service 也同样具有指定一组 pod 为一个集合功能,但在概念上有所不同, service 有逻辑上(架构上)的意义,也就是提供相同服务的一组 pod 为一个集合,用来进行不同服务间的相互访问。对于另一个服务B来说,它只是需要访问 A服务,关注的是A服务本身,并不会在意是A服务的哪个小版本(否则架构则会变得复杂)。因此,VS+DR 合起来实现了一个更细粒度的 Service,这大概也就是叫“虚拟服务”这个名字的原因。
灰度发布
参考:
使用 DestinationRule 和 HttpRoute 进行流量控制
HttpRoute 是实验性特性,需要先安装对应的CRD
$ kubectl kustomize "github.com/kubernetes-sigs/gateway-api/config/crd/experimental?ref=v0.6.2" | kubectl apply -f -
customresourcedefinition.apiextensions.k8s.io/gatewayclasses.gateway.networking.k8s.io created
customresourcedefinition.apiextensions.k8s.io/gateways.gateway.networking.k8s.io created
customresourcedefinition.apiextensions.k8s.io/grpcroutes.gateway.networking.k8s.io created
customresourcedefinition.apiextensions.k8s.io/httproutes.gateway.networking.k8s.io created
customresourcedefinition.apiextensions.k8s.io/referencegrants.gateway.networking.k8s.io created
customresourcedefinition.apiextensions.k8s.io/tcproutes.gateway.networking.k8s.io created
customresourcedefinition.apiextensions.k8s.io/tlsroutes.gateway.networking.k8s.io created
customresourcedefinition.apiextensions.k8s.io/udproutes.gateway.networking.k8s.io created
安装完成后,再进行如下的配置
# Http路由(HttpRoute)
kubectl apply -f - << EOF
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
name: reviews
spec:
parentRefs:
- kind: Service
name: reviews
port: 9080
rules:
- backendRefs:
- name: v1
port: 9080
weight: 50
- name: v3
port: 9080
weight: 50
EOF