kubesphere安装Istio

KubeSphere 服务网格基于Istio,将微服务治理和流量管理可视化。它拥有强大的工具包,包括熔断机制、蓝绿部署、金丝雀发布、流量镜像、链路追踪、可观测性和流量控制等。KubeSphere 服务网格支持代码无侵入的微服务治理,帮助开发者快速上手,Istio 的学习曲线也极大降低。KubeSphere 服务网格的所有功能都旨在满足用户的业务需求。

kubesphere安装Istio

登录控制台

kubesphere已经更新到4.2.0版本,Istio已经解耦出来,作为扩展组件安装,可以直接从控制台扩展中心安装,可参考官方文档:安装扩展组件 - KubeSphere,这里不再赘述。

由于我的kubesphere是3.3.2版本,此版本集成了Istio,在控制台修改一下参数就可以自动安装:

登录控制台,左上角点击平台管理-集群管理:

在定制资源定义,搜索clusterconf

点进这个ClusterConfiguration之后:

末尾servicemesh修改参数:

1
2
3
4
5
6
7
8
9
servicemesh:
enabled: true # 将“false”更改为“true”。
istio: # Customizing the istio installation configuration, refer to https://istio.io/latest/docs/setup/additional-setup/customize-installation/
components:
ingressGateways:
- name: istio-ingressgateway # 将服务暴露至服务网格之外。默认不开启。
enabled: false
cni:
enabled: false # 启用后,会在 Kubernetes pod 生命周期的网络设置阶段完成 Istio 网格的 pod 流量转发设置工作。

确定保存后,即可检查Istio组件的安装过程:

1
kubectl logs -n kubesphere-system $(kubectl get pod -n kubesphere-system -l 'app in (ks-install, ks-installer)' -o jsonpath='{.items[0].metadata.name}') -f

安装完成后,日志输出如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Waiting for all tasks to be completed ...
task network status is successful (1/5)
task openpitrix status is successful (2/5)
task multicluster status is successful (3/5)
task monitoring status is successful (4/5)
task servicemesh status is successful (5/5)
**************************************************
Collecting installation results ...
#####################################################
### Welcome to KubeSphere! ###
#####################################################

Console: http://192.168.88.20:30880
Account: admin
Password: P@88w0rd

NOTES:
1. After you log into the console, please check the
monitoring status of service components in
"Cluster Management". If any service is not
ready, please wait patiently until all components
are up and running.
2. Please change the default password after login.

这就代表完成了Istio的安装及初始化。不需要理会这个原始密码,重新登录还是要用已经更改的密码

验证Istio组件安装情况

在WebUI可以看到:

系统组件中已经出现了Istio组件。但是点进去发现:

此时不但Istio异常,连带之前正常的Prometheus也一并异常了:

等待一段时间,等他拉取镜像,启动容器即可。

我的是能直接启动成功,有人反馈说容易一直卡在容器创建中,一直启动不了

看pod的events如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 43m default-scheduler Successfully assigned istio-system/istiod-1-11-2-54dd699c87-99krn to zhiyong-ksp1
Warning FailedCreatePodSandBox 43m kubelet Failed to create pod sandbox: rpc error: code = Unknown desc = failed to setup network for sandbox "5d0a3bdb6dea937aa5b118bbd00305a1542111c97af84a3cbdd8f188b1681687": plugin type="calico" failed (add): error getting ClusterInformation: connection is unauthorized: Unauthorized
Warning FailedCreatePodSandBox 43m kubelet Failed to create pod sandbox: rpc error: code = Unknown desc = failed to setup network for sandbox "ff84de82acfd944be7f3804c96f39ab976ae4d6810b7e0364c90560a4b4070e7": plugin type="calico" failed (add): error getting ClusterInformation: connection is unauthorized: Unauthorized
Warning FailedCreatePodSandBox 42m kubelet Failed to create pod sandbox: rpc error: code = Unknown desc = failed to setup network for sandbox "6337bea6f7c16cd9adcff0d2b75238beb4365dc4b880d4c8e4f4535885d59d30": plugin type="calico" failed (add): error getting ClusterInformation: connection is unauthorized: Unauthorized
Warning FailedCreatePodSandBox 42m kubelet Failed to create pod sandbox: rpc error: code = Unknown desc = failed to setup network for sandbox "42e08603d4d7e7d1713eecbb21af258022e3fb50c6f5611808b3e2755d50d980": plugin type="calico" failed (add): error getting ClusterInformation: connection is unauthorized: Unauthorized
Warning FailedCreatePodSandBox 42m kubelet Failed to create pod sandbox: rpc error: code = Unknown desc = failed to setup network for sandbox "51a6b5b8ea5a63f4be828a0c855802e42640324c440fcc3487c535123d7b3372": plugin type="calico" failed (add): error getting ClusterInformation: connection is unauthorized: Unauthorized
Warning FailedCreatePodSandBox 42m kubelet Failed to create pod sandbox: rpc error: code = Unknown desc = failed to setup network for sandbox "dada948b2a416a0ec925b7f67a101b8fd48fdad9fb20d6c41eaf1bbad0a18e57": plugin type="calico" failed (add): error getting ClusterInformation: connection is unauthorized: Unauthorized
Warning FailedCreatePodSandBox 41m kubelet Failed to create pod sandbox: rpc error: code = Unknown desc = failed to setup network for sandbox "df3487e020c1e7eb527cc0fce1fe990873bd20f46cbf04de99005e0da5896abe": plugin type="calico" failed (add): error getting ClusterInformation: connection is unauthorized: Unauthorized
Warning FailedCreatePodSandBox 41m kubelet Failed to create pod sandbox: rpc error: code = Unknown desc = failed to setup network for sandbox "92e739549a96aa03ea864188abc1b91c9a45394dae28ad97234fa1caf4d52240": plugin type="calico" failed (add): error getting ClusterInformation: connection is unauthorized: Unauthorized
Warning FailedCreatePodSandBox 41m kubelet Failed to create pod sandbox: rpc error: code = Unknown desc = failed to setup network for sandbox "bc5d1999a2d5ad4d7cf5c1e1c3c7c1a80dee02b806d0be2e15c326e2d82f4af5": plugin type="calico" failed (add): error getting ClusterInformation: connection is unauthorized: Unauthorized
Warning FailedCreatePodSandBox 3m2s (x176 over 41m) kubelet (combined from similar events): Failed to create pod sandbox: rpc error: code = Unknown desc = failed to setup network for sandbox "be41a317c2e14b4096f2f8f0d4bfaa8a80572f7365ab3d92c20be75fe97304f4": plugin type="calico" failed (add): error getting ClusterInformation: connection is unauthorized: Unauthorized

出现了网络没有认证通过的问题,根据报错日志,基本上确定是Calico的问题。

解决:把/etc/cni/net.d/目录下的calico-kubeconfig10-calico.conflist文件移到另一个目录下备份,然后重启机器刷新Calico的配置。

等待容器启动完成即可。

自制应用

kubesphere的服务网格功能是在企业空间的自制应用里使用的,所以我们先要创建企业空间,然后把项目加到企业空间里,再创建一个自制应用,这个自制应用就是我们部署的整个系统,然后再把各个微服务通过标签加入到这个自制应用里。

创建自制应用

基本信息

要启用应用治理才可以使用Istio功能

服务设置

无状态服务为deployment,有状态服务为StatefulSet

填名称,镜像,存储等等信息

路由设置

注:这里只创建了Ingress,这样是访问不了集群内部的,需要启用网关,用nodeport的方式会有一个nodeport

把这个域名解析到任意一个k8s节点,然后就可以域名+nodeport的方式访问:

或者如果部署了ingress-nginx-controller的话:

在ingress里加入ingressClassName: nginx

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
kind: Ingress
apiVersion: networking.k8s.io/v1
metadata:
name: bookinfo-ingress
namespace: bookinfo
labels:
app.kubernetes.io/name: bookinfo
app.kubernetes.io/version: v1
annotations:
kubesphere.io/creator: admin
nginx.ingress.kubernetes.io/upstream-vhost: productpage.bookinfo.svc.cluster.local
spec:
ingressClassName: nginx #加入这个参数
rules:
- host: bookinfo.keyfel.com
http:
paths:
- path: /
pathType: ImplementationSpecific
backend:
service:
name: productpage
port:
number: 9080

就可以直接用域名访问

创建完成

这样创建的deploy,svc,StatefulSet,Ingress等等都会自动加入匹配此自制应用的标签以及注解:

Ingress:

svc:

deploy:

已运行资源加入自制应用

但是由于我们之前已经在运行的微服务,并没有这些标签,所以我们需要在已经存在的资源加入这些标签及注解,以加入此自制应用来使用Istio功能。

  1. Deployment 有 app version 这两个 label;Service 有 app Label;且 Deploy 与 service 的 App Label 一致,等于 Service Name(Istio 需要)
  2. 在一个应用内,所有资源需要有这两个标签 app.kubernetes.io/name=, app.kubernetes.io/version=(Application 需要)
  3. Deployment Name 为 Service Name 后面加 v1;如 Serevice 为 nginx, deployment 为 nginx-v1
  4. Deployment Template 中有相应 Annotation (Istio Sidecar 自动注入需要)
1
2
3
4
template:
metadata:
annotations:
sidecar.istio.io/inject: "true"

​ 5.Service/Deployment 有相应 Annotation (KubeSphere CRD Controller 会自动将 Service 同步为 Virtual Service/DestinationRules,CRD controller 需要)

1
2
3
4
5
6
7
8
9
10
11
# Service
kind: Service
metadata:
annotations:
servicemesh.kubesphere.io/enabled: "true"

# Deployment
kind: Deployment
metadata:
annotations:
servicemesh.kubesphere.io/enabled: "true"

即:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
deployment需要加:
metadata:
labels:
app: $SERVICE
app.kubernetes.io/name: $自制应用名称
app.kubernetes.io/version: v1
version: v1
annotations:
servicemesh.kubesphere.io/enabled: 'true'
spec:
template:
metadata:
annotations:
sidecar.istio.io/inject: 'true'

svc需要加:
metadata:
labels:
app: $SERVICE
app.kubernetes.io/name: $自制应用名称
app.kubernetes.io/version: v1
annotations:
servicemesh.kubesphere.io/enabled: "true"
spec:
ports:
- name: http-web #要加这个name,不然灰度发布不能选择按参数策略

Ingress需要加:
metadata:
labels:
app.kubernetes.io/name: $自制应用名称
app.kubernetes.io/version: v1
annotations:
nginx.ingress.kubernetes.io/upstream-vhost: $SERVICE.$NAMESPACE.svc.cluster.local

使用Istio

部署实例应用bookinfo演示Istio功能

部署完成:

可以点击流量监控查看拓扑图:

以及链路追踪:

熔断功能:

点击具体的微服务,右边有个流量管理,我们点击启用熔断器,确认就可以使用熔断功能,会自动更新相关的VirtualService和DestinationRule:

查看DestinationRule:

金丝雀发布

点击灰度发布,选择金丝雀发布:

选择哪个微服务需要灰度发布:

配置要灰度的版本信息:

配置灰度策略:

按比例或者指定参数:

创建完发布任务之后就灰度版本就发布了,VirtualService和DestinationRule会自动调整,可以查看验证一下:

VirtualService:

DestinationRule:

验证灰度结果:

刷新可以看到两个版本在切换:

v1版本:

gray版本:

回到控制台,点击发布任务:

可以点进去查看当前版本和灰度版本的流量,请求成功率等等信息,以及调整灰度比例:

灰度版本有问题的话可以回滚到v1版本,灰度版本验证没问题需要全量发布的话可以选择gray版本接管流量。

因为直接用灰度版本去接管全部流量的话,每次灰度发布都会创建不同的deploy,因为我的CI/CD用jenkins发布,写死了deploy的名称,所以我的做法是验证完灰度版本没问题,先把gray版本接管所有流量,然后把v1版本的镜像改为灰度版本的镜像,等容器启动完之后,现在两个版本都是gray版本的镜像,再把v1版本接管所有流量,然后再把发布任务删除(必须要有一个版本接管全部流量之后才删的了灰度发布任务),这样也就相当于是gray版本全量发布了。

删除灰度发布任务后,非接管流量的那个版本对应的deploy等等资源也会自动删除。

Thank you for your accept. mua!
-------------本文结束感谢您的阅读-------------