目标
在阿里云容器服务 Kubernetes 集群上部署 Istio 服务网格
实践灰度发布, 故障注入, 熔断等 Istio 流量管理特性
准备工作
安装和设置 kubectl 客户端, 请参考不同的操作系统, 如果已经安装请忽略:
- macOS
- curl -LO https://kubectl.oss-cn-hangzhou.aliyuncs.com/macos/kubectl
- chmod +x ./kubectl
- sudo mv ./kubectl /usr/local/bin/kubectl
- kubectl --help
- Linux
- curl -LO https://kubectl.oss-cn-hangzhou.aliyuncs.com/linux/kubectl
- chmod +x ./kubectl
- sudo mv ./kubectl /usr/local/bin/kubectl
- kubectl --help
- Windows
把 https://kubectl.oss-cn-hangzhou.aliyuncs.com/windows/kubectl.exe 放到系统 PATH 路径下
kubectl --help
配置 kubectl 连接 Kubernetes 集群的配置, 可参考文档 通过 kubectl 连接 Kubernetes 集群
实验步骤
部署 Istio
登录容器服务控制台, 在集群列表中选择一个集群, 打开更多 - 部署 Istio
保持默认配置, 点击 "部署 Istio"
等待完成后, Istio 已经成功部署在 Kubernetes 集群中
使用 kiali 查看服务网格可视化
kubectl port-forward -n istio-system "$(kubectl get -n istio-system pod --selector=app=kiali -o jsonpath='{.items..metadata.name}')" 20001
在本地浏览器中访问 http://localhost:20001 , 使用默认账户 admin/admin 登录
灰度发布
创建命名空间并开启 Sidecar 自动注入: 单击左侧导航栏中的集群> 命名空间, 进入命令空间页面, 创建一个名称为 demo 的命名空间, 并为其添加一个
istio-injection:enabled
的标签
单击左侧导航栏中服务网格> 虚拟服务, 进入虚拟服务 (Virtual Service) 页面, 点击创建, 创建一个简单的示例应用, 指定应用名称为 istio-App, 指定应用版本为 v1, 选择刚刚创建的命名空间 demo
配置应用容器, 使用如下镜像:
registry.cn-beijing.aliyuncs.com/test-node/node-server:v1
配置服务, 服务名称为 istio-App-svc, 类型为虚拟集群 IP , 服务端口和容器端口均为 8080
提交应用配置, 将会自动创建 Deployment,Service,DestinationRule,VirtualService
单击导航栏中的应用> 容器组, 确认所有的 Pod 都已经正确的定义和启动
创建服务客户端测试应用
- kubectl apply -n demo -f - <<EOF
- apiVersion: v1
- kind: Service
- metadata:
- name: sleep
- labels:
- App: sleep
- spec:
- ports:
- - port: 80
- name: http
- selector:
- App: sleep
- ---
- apiVersion: extensions/v1beta1
- kind: Deployment
- metadata:
- name: sleep
- spec:
- replicas: 1
- template:
- metadata:
- labels:
- App: sleep
- spec:
- containers:
- - name: sleep
- image: pstauffer/curl
- command: ["/bin/sleep", "3650d"]
- imagePullPolicy: IfNotPresent
- EOF
在测试应用的 Pod 中访问 Istio 应用: 登录到 sleep 应用的 Pod 中
kubectl exec -it -n demo "$(kubectl get -n demo pod --selector=app=sleep -o jsonpath='{.items..metadata.name}')" sh
执行如下命令调用之前部署的 Istio 应用:
- for i in `seq 1000`
- do
- curl http://istio-app-svc.demo:8080;
- echo '';
- sleep 1;
- done;
可以看到返回的信息:
- Hello from v1
- Hello from v1
- Hello from v1
单击左侧导航栏中服务网格> 虚拟服务, 进入虚拟服务 (Virtual Service) 页面, 找到 istio-App-svc 服务, 点击管理, 在版本管理中, 点击增加灰度版本, 新的版本指定为 v2
在容器配置中使用以下镜像:
registry.cn-beijing.aliyuncs.com/test-node/node-server:v2
在灰度策略中选择基于流量比例发布, 流量比例 50%
提交灰度发布后, 查看 sleep 应用的调用结果, 可以看到, v1 和 v2 版本的返回结果
- Hello from v1
- Hello from v2
- Hello from v1
- Hello from v1
- Hello from v2
- Hello from v1
在 kiali 中查看, 可以确认, 调用被分发到两个版本中
故障注入
目前应用工作正常, 我们为 istio-App-svc 注入故障, 以测试整个应用的弹性. 在 istio-App-svc 的管理界面中, 打开故障注入策略, 选择注入中断故障, 百分比 50%, 状态码 503
提交后, 继续查看 sleep 应用的调用结果, 即可看到 istio-App-svc 服务约有 50% 的概率无法访问, 输出 fault filter abort.
- Hello from v1
- Hello from v1
- Hello from v1
- fault filter abort
- fault filter abort
- fault filter abort
- Hello from v1
- Hello from v2
- fault filter abort
- Hello from v2
- Hello from v2
同时, 在 kiali 可视化界面中, 也可以看到 sleep 服务对 istio-App-svc 服务的调用有 50% 左右的失败比例
除此之外, 我们也可以为服务注入时延故障, 例如在上述界面中, 选择时延故障, 为 50% 的请求添加 5s 的时延
确认提交之后, 我们可以看到, 部分调用的耗时显著增加. 在 kiali 中也可以查看调用的平均请求耗时
删除故障注入策略和灰度版本 v2
熔断
在 DestinationRule 中设置熔断规则
- kubectl delete destinationrule -n demo istio-App-svc
- kubectl apply -n demo -f - <<EOF
- apiVersion: networking.istio.io/v1alpha3
- kind: DestinationRule
- metadata:
- name: istio-App-svc
- spec:
- host: istio-App-svc
- trafficPolicy:
- connectionPool:
- tcp:
- maxConnections: 1
- http:
- http1MaxPendingRequests: 1
- maxRequestsPerConnection: 1
- subsets:
- - labels:
- version: v1
- name: v1
- - labels:
- version: v2
- name: v2
- EOF
部署一个 HTTP 客户端, 用于负载测试
kubectl apply -n demo -f https://raw.githubusercontent.com/istio/istio/master/samples/httpbin/sample-client/fortio-deploy.yaml
在上面的熔断设置中指定了 maxConnections: 1 以及
http1MaxPendingRequests: 1
. 这意味着如果超过了一个连接同时发起请求, Istio 就会熔断, 阻止后续的请求或连接. 因此我们以并发数为 3, 发出 100 个请求:
- FORTIO_POD=$(kubectl -n demo get pod | grep fortio | awk '{ print $1 }')
- kubectl -n demo exec -it $FORTIO_POD -c fortio /usr/bin/fortio -- load -c 3 -qps 0 -n 100 -loglevel Warning http://istio-App-svc:8080
从结果中, 可以看到, 有超过 40% 的请求被 Istio 阻断了.
- Code 200 : 57 (57.0 %)
- Code 503 : 43 (43.0 %)
- Response Header Sizes : count 100 avg 130.53 +/- 113.4 min 0 max 229 sum 13053
- Response Body/Total Sizes : count 100 avg 242.14 +/- 0.9902 min 241 max 243 sum 24214
- All done 100 calls (plus 0 warmup) 0.860 ms avg, 2757.6 qps
在 kiali 中观察可以发现, 这部分请求并没有真正到达 istio-App-svc 的 Pod
通过查询 istio-proxy 的状态, 可以获得更多信息,
upstream_rq_pending_overflow
的值即为被熔断策略阻止的请求数
- kubectl -n demo exec -it $FORTIO_POD -c istio-proxy -- sh -c 'curl localhost:15000/stats' | grep istio-App-svc | grep pending
- cluster.outbound|8080|v1|istio-App-svc.demo-ab.svc.cluster.local.upstream_rq_pending_active: 0
- cluster.outbound|8080|v1|istio-App-svc.demo-ab.svc.cluster.local.upstream_rq_pending_failure_eject: 0
- cluster.outbound|8080|v1|istio-App-svc.demo-ab.svc.cluster.local.upstream_rq_pending_overflow: 99
- cluster.outbound|8080|v1|istio-App-svc.demo-ab.svc.cluster.local.upstream_rq_pending_total: 199
清理实验环境
执行以下命令:
kubectl delete ns demo
来源: https://yq.aliyun.com/articles/705694