istio 官网入门案例

发布时间 2023-06-26 13:22:43作者: coreylin

在 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