Istio 使用经验总结
Mercari 使用 Istio 概述
Mercari 是一个 C2C 二手物品交易平台,拥有 200 多个微服务,高峰期 API 网关处理 10 万 RPS,使用 Google Kubernetes Engine (GKE) 集群。Mercari 于 2019 年 9 月开始 Istio 试点,2021 年 2 月首次在生产环境发布,截至 2020 年底,约 25% 的生产服务和 50% 的开发服务迁移至 Istio,最终 100% 服务迁移至 Istio。目前使用的 Istio 功能包括 HTTP/2 负载均衡、流量转移和 mTLS,正在调查重试和断路器功能。
Istio 稳定化挑战与解决方案
Istio sidecar 代理规范
所有入站流量必须首先通过 pod 中的 sidecar 代理,所有出站流量必须在离开 pod 前通过 sidecar 代理。
Kubernetes sidecar 容器缺点
-
容器生命周期控制:Kubernetes 缺乏良好的控制 API 来自定义 pod 中容器的生命周期,无法确保 sidecar 代理在应用容器之前启动或之后停止。
- 解决方案:使用
postStart 和 preStop 生命周期钩子。
postStart 钩子在 istio-proxy 容器中启动 Envoy。
preStop 钩子在应用容器中停止 Envoy,并等待连接 draining 完成。
- 调整
terminationGracePeriodSeconds 以确保连接 draining 完成。
-
多容器 pod 自动扩展:Kubernetes 的 HorizontalPodAutoscaler (HPA) 在扩展多容器 pod 时表现不佳。
- 解决方案:将 Istio sidecar 资源纳入 HPA 计算范围。
- 使用
ContainerResource 资源定义来固定 HPA 目标。
- 调整 HPA 阈值以匹配原始 CPU 绝对目标。
处理 Istio 的准备情况
成功采用 Istio 需要专用资源、内部网络知识、耐心以及提高 Istio 可靠性的机制。
选择合适的战斗,从小处着手
从简单的功能(如注入 sidecar 和 HTTP/2 负载均衡)开始,逐步建立信心和理解,然后逐步推广。
全 mesh 是乌托邦,只知所需
全 mesh 观察性和可达性虽然理想,但在大规模部署时会导致控制平面过载、代理 OOM 和 CPU 频繁被限流。
- 解决方案:使用 Sidecar CRD 限制每个代理的资源暴露。
- Sidecar CRD 允许基于命名空间或标签控制 mesh 配置的暴露范围。
- 主要缺点是服务必须知道其依赖关系,并更新文档。
Istio 的安全措施
- 使用 linters (conftest) 在 CI 级别捕获问题。
- 使用 admission webhooks (OPA Gatekeeper) 保护资源和检查无法在 linter 级别检查的内容。
Istio 采用挑战与策略
采用挑战
- 将 HTTP/2 负载均衡从客户端移至 Envoy:Mercari 使用 gRPC 严重依赖客户端负载均衡库和 Headless Services,但 Istio 的 HTTP/2 负载均衡导致 headless services 问题,因此迁移至 ClusterIP services。
- 标签选择器更新:Istio 需要应用和版本标签,但 Kubernetes 标签不可变,需要创建新的 Deployment 并更新 Service。
- Istio 默认重试策略:所有 HTTP 请求默认重试两次,无法禁用或更改,Mercari 通过 fork Istio 临时解决。
- Istio 代理性能和容量:sidecar 代理增加延迟和计算资源,需要根据工作负载进行资源调整和性能测试。
- 抽象 Istio 功能:为用户提供自动化和管理的抽象层,提高开发体验和运维可维护性。
采用策略
- 使用 ClusterIP services 替代 Headless services,并制定迁移计划。
- 使用自动化管道自动更新 Deployment 标签。
- fork Istio 修改默认重试策略。
- 通过性能测试和资源调整优化 sidecar 大小。
- 使用 Terraform 和 Cuelang 构建抽象层,实现自动化 onboarding 和管理。
总结
Mercari 的 Istio 采用经验表明,虽然 Istio 提供了强大的网络功能,但也带来了稳定性和采用方面的挑战。通过解决 Kubernetes 缺点、合理配置资源、使用自动化工具和抽象层,可以有效地提高 Istio 的稳定性和采用率。建议从简单功能开始,逐步推广,并注意性能测试和资源调整。