最近 Istio 成功发布了 1.0,并宣称生产就绪。我们的 SRE 团队对 Istio 1.0 生产状态进行了全面分析,最后提出了我们的建议。
本文结构:
Istio 构建在微服务架构基础之上,其中的应用网络由多个服务构成:
更多细节可移步浏览官方文档。
安装过程比较方便。支持不同的环境(例如 Docker),但是 Kubernetes 是最适合我们需要的。
安装方法支持列表:
本文只是一次评估,因此使用了第一种方式。
用静态 YAML 部署的 Istio 1.0:
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
deploy/grafana 1 1 1 1 20h
deploy/istio-citadel 1 1 1 1 20h
deploy/istio-egressgateway 1 1 1 1 20h
deploy/istio-galley 1 1 1 1 20h
deploy/istio-ingressgateway 1 1 1 1 20h
deploy/istio-pilot 1 1 1 1 20h
deploy/istio-policy 1 1 1 1 20h
deploy/istio-sidecar-injector 1 1 1 1 20h
deploy/istio-statsd-prom-bridge 1 1 1 1 20h
deploy/istio-telemetry 1 1 1 1 20h
deploy/istio-tracing 1 1 1 1 20h
deploy/prometheus 1 1 1 1 20h
deploy/servicegraph 1 1 1 1 20hNAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
hpa/istio-egressgateway Deployment/istio-egressgateway <unknown> / 55% 1 5 1 20h
hpa/istio-ingressgateway Deployment/istio-ingressgateway <unknown> / 55% 1 5 1 20hNAME DESIRED SUCCESSFUL AGE
jobs/istio-cleanup-secrets 1 1 20h
jobs/istio-grafana-post-install 1 1 20h
jobs/istio-mixer-post-install-1.0 1 1 20hNAME READY STATUS RESTARTS AGE
po/grafana-67b5df5b97-d685n 1/1 Running 0 20h
po/istio-citadel-65df4cf668-xspff 1/1 Running 0 20h
po/istio-egressgateway-6678667b46-pmfmx 1/1 Running 0 20h
po/istio-galley-7c64c8c948-8npwp 1/1 Running 27 20h
po/istio-ingressgateway-6dfd7fc84-w6snd 1/1 Running 0 3h
po/istio-pilot-6cc9f4f7c6-552h4 2/2 Running 0 20h
po/istio-policy-5476f99674-sqn7h 2/2 Running 0 20h
po/istio-sidecar-injector-5f47598cd7-8qlq6 1/1 Running 0 20h
po/istio-statsd-prom-bridge-5d44ddb7cf-lrc8t 1/1 Running 0 20h
po/istio-telemetry-654bfd8487-bmdwv 2/2 Running 0 20h
po/istio-tracing-5fbd79cc-pnq5n 1/1 Running 0 20h
po/prometheus-7b6f8b9996-t4t92 1/1 Running 0 20h
po/servicegraph-7d7ccc9b7f-b86c4 1/1 Running 0 20hNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
svc/grafana ClusterIP 10.0.18.159 <none> 3000/TCP 20h
svc/istio-citadel ClusterIP 10.0.228.1 <none> 8060/TCP,9093/TCP 20h
svc/istio-egressgateway ClusterIP 10.0.217.249 <none> 80/TCP,443/TCP 20h
svc/istio-galley ClusterIP 10.0.131.153 <none> 443/TCP,9093/TCP 20h
svc/istio-ingressgateway LoadBalancer 10.0.72.147 13.66.222.246 80:31380/TCP,443:31390/TCP,31400:31400/TCP,15011:30223/TCP,8060:31415/TCP 20h
svc/istio-pilot ClusterIP 10.0.67.90 <none> 15010/TCP,15011/TCP,8080/TCP,9093/TCP 20h
svc/istio-policy ClusterIP 10.0.135.115 <none> 9091/TCP,15004/TCP,9093/TCP 20h
svc/istio-sidecar-injector ClusterIP 10.0.158.161 <none> 443/TCP 20h
svc/istio-statsd-prom-bridge ClusterIP 10.0.17.41 <none> 9102/TCP,9125/UDP 20h
svc/istio-telemetry ClusterIP 10.0.139.187 <none> 9091/TCP,15004/TCP,9093/TCP,42422/TCP 20h
svc/jaeger-agent ClusterIP None <none> 5775/UDP,6831/UDP,6832/UDP 20h
svc/jaeger-collector ClusterIP 10.0.172.142 <none> 14267/TCP,14268/TCP 20h
svc/jaeger-query ClusterIP 10.0.51.47 <none> 16686/TCP 20h
svc/prometheus ClusterIP 10.0.156.162 <none> 9090/TCP 20h
svc/servicegraph ClusterIP 10.0.163.81 <none> 8088/TCP 20h
svc/tracing ClusterIP 10.0.111.218 <none> 80/TCP 20h
svc/zipkin ClusterIP 10.0.89.198 <none> 9411/TCP 20h
Istio 的功能集随着每次发布逐步增长,运维需求也自然是水涨船高。要运维 Istio,不仅要有对 Istio 组件和配置的基本理解,还需要对 Kubernetes 有深入的认识。Istio 1.0 中包含了 51 个 CRD,比 0.8 版本又多出了 8 个。
正如 Sebastein Goasguen 在 Twitter 中说的:如果你觉得 Kubernetes 很难,来看看(理解和维护)Istio 和他的 43 个 API 对象吧。
运维的复杂性,在未来可以用 Galley 对服务和客户端的配置管理来进行简化。Galley 是 1.0 中新引入的组件,在 Istio 中,承担配置的导入、处理和分发任务。这一组件的主要目标是应对现有的配置方面的挑战,例如检测、组件之间的复用、配置错误和验证等问题。这样就可以提供更好的运维体验,同时降低对 Istio 各组件深入理解的需求。Galley 负责把其它 Istio 组件和从底层平台获取用户配置的细节中隔离开来。它其中包含了 Kubernetes 的 CRD 监听器,用来收集配置;还有一个网格配置协议(Mesh Config Protocol-MCP)服务器用于配置分发;以及一个用于验证的 Webhook,使用 Kubernetes API Server 对配置进行前置检查。
Galley 在 Istio 1.0 中可以禁用,并且在 AWS EKS 中必须和 Sidecar 的自动注入一起禁用,这是因为 EKS 不支持启用准入控制器,例如这里要用到的修改和验证 Webhook。加入 Google Group 阅读 Galley 概要设计文档 可以获得更多信息。
在 v1alpha3 中, Istio Gateway 和 VirtualService 一起,替换了 Kubernetes 的原生 Ingress。相对于 Kubernetes 的原生 Ingress,这一组合提供了更多高级配置。然而这些资源只是定义,真正的流量管理是由 Ingress Gateway 完成的。
Ingress Gateway 是一个 Istio proxy(Envoy),它会根据 Gateway 和 VirtualService 定义响应网格外发来的入站流量。缺省的安装只包含一个 ingressgateway
pod 并且只使用 LoadBalancer 服务申请了一个公共 IP。要注意下面的限制:
VirtualService
的路径不可重叠。如果有多个独立团队使用 Istio 的话可能会出现问题。这两个限制都可以通过部署多个 ingressgateway
pod 来监听多个公共 IP 的方式来解决。遗憾的是,对多个 ingressgateway
实例的管理不太简单,需要自行定义合适的选择器。
可以使用标准的 kubectl
命令配置 Istio,也可以选择使用原生的 istioctl
工具。两种方法会得到同样的结果——在 Kubernetes 中创建 CRD。
注意:只有
istioctl
会在把定义文件发送给 Kubernetes API Server 之前对 CRD 进行验证。
Kubernetes 中部署的 Istio Webhook 会进行第二次验证,但是他只会对配置的结构进行验证,功能验证目前还没有实现。因为只做语义验证不做功能验证,上面提到的路径叠加问题会很容易遇到。
Istio 1.0 在 istioctl
命令中加入很多状态和健康状态方面的改进。istioctl proxy-status
命令会获取 Pilot 和 Envoy 之间最新发送和接收的 xDS 同步信息,并提供一个状态概览:
istioctl proxy-status
PROXY CDS LDS EDS RDS PILOT VERSION
details-v1-7bcdcc4fd6-9p7sr.default SYNCED SYNCED SYNCED (100%) SYNCED istio-pilot-6cc9f4f7c6-552h4 1.0.0
istio-egressgateway-6678667b46-pmfmx.istio-system SYNCED SYNCED SYNCED (100%) NOT SENT istio-pilot-6cc9f4f7c6-552h4 1.0.0
istio-ingressgateway-6dfd7fc84-w6snd.istio-system SYNCED SYNCED SYNCED (100%) SYNCED istio-pilot-6cc9f4f7c6-552h4 1.0.0
kad-5f89bf94fc-b48z2.kad SYNCED SYNCED SYNCED (100%) SYNCED istio-pilot-6cc9f4f7c6-552h4 1.0.0
productpage-v1-8584c875d8-9mlbr.default SYNCED SYNCED SYNCED (100%) SYNCED istio-pilot-6cc9f4f7c6-552h4 1.0.0
ratings-v1-54cf9dc8f8-hthzx.default SYNCED SYNCED SYNCED (100%) SYNCED istio-pilot-6cc9f4f7c6-552h4 1.0.0
reviews-v1-59cbdd7959-2ng8m.default SYNCED SYNCED SYNCED (100%) SYNCED istio-pilot-6cc9f4f7c6-552h4 1.0.0
reviews-v2-dccb4cfc9-rp6rx.default SYNCED SYNCED SYNCED (100%) SYNCED istio-pilot-6cc9f4f7c6-552h4 1.0.0
reviews-v3-5465dc97bc-k9rdb.default SYNCED SYNCED SYNCED (100%) SYNCED istio-pilot-6cc9f4f7c6-552h4 1.0.0
Headless 服务是没有 IP 的,服务中的各个实例通常会用点对点的形式进行访问,因此在服务网格中,这种服务是个难于应对的问题。要给这种服务配置 mTLS 认证,流量的检测和处理都可能遇到问题。
Kubernetes StatefulSet 经常和 Headless 服务一同使用。在服务实例之间进行通信时,我们也发现了问题。我们用 StatefulSet 运行 Cassandra 集群,第二个实例出现了如下问题:
INFO 13:44:05 Handshaking version with cassandra-0.cassandra.sre.svc.cluster.local/10.244.4.33INFO 13:44:05 Cannot handshake version with cassandra-0.cassandra.sre.svc.cluster.local/10.244.4.33
要解决这个问题,要把 Cassandra 移出网格,或者修改 mTLS 认证策略。这一问题在目前正在跟踪之中。
https://github.com/istio/istio/issues/5005
https://github.com/istio/istio/pull/6885
https://github.com/istio/istio/issues/1277
Kubernetes 会进行 Pod 检测,查看 Pod 的存活和就绪状态。检测方法有多种实现方式,TCP 和 HTTP 是最常见的。当 Kubelet 能够通过 HTTP 请求或者 TCP 连接访问到 Pod,就会判定 Pod 检测成功。当服务间的 mTLS 启用时,Kubelet 却并非网格的一部分,因此就无法访问 Pod 了。
要解决这一问题:
Istio 从 0.8 开始支持单控制平面下的多集群部署。博客中提供了 0.8 中运行多集群 Istio 的详细介绍。Google 还在上一次 KubeCon 上做了一次演示(视频)。1.0 版本中加入了为数众多的安全和性能方面的改进,其中包括远程集群的 Sidecar 自动注入能力。这方面可以参考详细设计文档。
不幸的是这一功能在我们的生产环境上也是有问题的,现列举如下:
Istio 是第一个生产就绪的版本,多数核心组件都已稳定,我们对其稳定性基本满意,运维方面还存在一些问题,在生产环境中的应用很有挑战性。
迄今为止,Istio 获得了巨大成就。如果是对系统缺乏深入理解的用户,要在生产环境中操作 Kubernetes 还是有一定难度的。我们认为,Istio 1.0 的完成度是合乎要求的,目前的用户多数都要归为超级用户的类别。短期之内,需要托管的 Istio 产品来满足消费市场的需要。还需要持续关注性能、伸缩以及策略处理方面的进展。