中通快递关键业务和复杂架构挑战下的 Kubernetes 集群服务暴露实践
本文是上海站 Meetup 讲师王文虎根据其分享内容整理的文章。
KubeSphere 社区的小伙伴们,大家好。我是中通快递容器云平台的研发工程师王文虎,主要负责中通快递容器云平台开发、应用容器化推广、容器平台运维等工作。非常感谢 KubeSphere 社区的邀请,让我有机会跟大家分享中通快递关键业务和复杂架构挑战下的 Kubernetes 集群服务暴露实践。
ZKE 容器管理平台
首先介绍一下中通的容器云管理平台 ZKE。ZKE 平台是基于 KubeSphere 开发的,现在管理的中通内部集群超过十个,包含开发、测试、预发布、生产等环境,所有用户都通过 ZKE 平台管理容器应用。

Kubernetes 集群服务暴露方案
根据中通的实际业务需求和一些探索,梳理出了中通 kubernetes 集群服务暴露的几种方案。

Dubbo 服务之间访问
中通大部分应用都是基于 Java 语言开发的,使用的微服务框架为 Dubbo。在上容器之初,我们考虑到虚拟机和容器并存的场景可能会持续很长时间,所以在规划 Kubernetes 集群的时候,通过把容器网络和物理网络打通的方式,来解决 Dubbo 服务在容器和虚拟机混布的场景下互相调用的问题。
- 如何打通 Kubernetes 容器网络和物理网络?
我们内部环境中 Kubernetes 集群网络组件使用 calico BGP 模式,数据中心物理网络也开启了 BGP 路由协议,通过在物理网络上开启 BGP RR(Route Reflector),避免后期集群规模太大导致 BGP 宣告路由条目过多的问题。BGP RR 和 Kubernetes 集群节点建立 EBGP 邻居,互相学习路由。

泛域名方式访问
在初步推广开发和测试容器化时,我们遇到最多的问题就是用户在应用发布到容器环境后如何访问。
用户在 ZKE 平台上创建 Ingress 以后,该域名是不能访问的,必须要运维把域名指向集群 Ingress Controller,而且公司申请域名需要走 OA 流程,所以这就使得我们的容器环境在初始推广阶段进度很慢。
我们收集了部分用户的反馈,加上自己的思考,终于探索出了一条开发/测试环境比较高效的 Ingress 使用之路:
通过给每个集群分配一个三级泛域名,在公司 DNS 上配置把对应泛域名指向集群的 Ingress Controller,用户后续创建业务域名时可以直接在 ZKE 界面上创建 Ingress,该域名便会立即生效,省去了很大部分测试和开发环境上容器的时间,因为公司安全管理要求,Ingress 只提供了暴露 HTTP 协议的功能,但是这一措施也还是很大程度加快了测试开发容器化的推广速度。

自定义域名访问
泛域名可以帮我们解决大部分开发/测试环境的域名需求,但是针对生产环境、项目域名需要使用 HTTPS 协议、项目需要自定义域名这些场景时,用户除了需要创建 Ingres 之外,还是需要通过 OA 流程进行审批的。

服务暴露方案踩坑实践
以下内容是我们在使用 Kubernetes 的过程中服务暴露以及网络相关踩的坑,供大家参考以避坑。
Ingress Nginx Controller 服务踩坑实践
下图是我根据 Ingress Nginx Controller 代码启动流程,画的启动流程图(关于启动流程以及这个问题更详细分析可以查看链接:https://mp.weixin.qq.com/s/Pw9-_cPXxhfrd6btSXUrqA)。

Ingress Nginx Controller 启动流程与一个通用的 K8S Controller 的类似,但是真正执行把 K8S Ingress 及其相关资源同步到 Nginx 配置文件的业务逻辑是从 n.syncIngress 函数开始的,这个留到下面说。
该问题是我们测试环境使用过程中踩过的一个坑,用户通过 ZKE 管理平台创建 Ingress 时触发了集群 Ingress Controller 故障。我们在做故障分析时发现了故障复现的条件,如下图所示:

前面说到 n.syncIngress 函数是 Ingress Nginx Controller 业务逻辑的入口,从该入口到本次故障最终调用函数中间的调用链 PPT 中也有提供,最终的问题点落在了 extractTLSSecretName 函数。

根据代码逻辑再分析一下原因:
- createServers 函数会遍历
ing.Spec.Rules,当ing.Spec.TLS字段不为空时会把rule.Host、ingress 以参数形式传入extractTLSSecretName函数; extractTLSSecretName函数首先会遍历ing.Spec.TLS,校验tls.Hosts中是否包含 host,如果包含直接返回tls.SecretName;- 当
tls.Hosts中不包含 host 时,会把tls.SecretName对应的 secret 资源转为*ingress.SSLCert类型并且校验 host 是否匹配证书中的 SAN 或 CN 属性。然而当配置的 secret 为非 TLS 类型证书时,cert.Certificate值为 nil,就会导致cert.Certificate.VerifyHostname(host) 处代码会报 panic 导致主程序异常,然后 nginx controller 就挂了;
修复措施分两部分:
- 平台用户操作层面避免这种情况:主要是通过用户创建 ingress 选择证书时过滤掉非 TLS 类型的 secret,保证绝大部分通过平台使用者不会触发此类问题;
- 修复代码逻辑根治此问题:增加判断
cert.Certificate是否为nil的逻辑。
Calico 关闭 natOutgoing 配置
这个配置发生的背景是在 Dubbo 应用生产容器化过程中,生产环境 Zookeeper 对单个 IP 连接限制数比节点上 Pod 数小,导致节点上容器里的 Dubbo 应用经常会出现连接 Zookeeper 被拒绝的问题。再因为容器网络和物理网络已经打通,通过 calico 配置 natOutgoing 参数为 false,这个问题就迎刃而解了。

本文由博客一文多发平台 OpenWrite 发布!
中通快递关键业务和复杂架构挑战下的 Kubernetes 集群服务暴露实践的更多相关文章
- Kubernetes 集群日志 和 EFK 架构日志方案
目录 第一部分:Kubernetes 日志 Kubernetes Logging 是如何工作的 Kubernetes Pod 日志存储位置 Kubelet Logs Kubernetes 容器日志格式 ...
- 初试 Kubernetes 集群中使用 Traefik 反向代理
初试 Kubernetes 集群中使用 Traefik 反向代理 2017年11月17日 09:47:20 哎_小羊_168 阅读数:12308 版权声明:本文为博主原创文章,未经博主允许不得转 ...
- (转)在Kubernetes集群中使用JMeter对Company示例进行压力测试
背景 压力测试是评估应用性能的一种有效手段.此外,越来越多的应用被拆分为多个微服务而每个微服务的性能不一,有的微服务是计算密集型,有的是IO密集型. 因此,压力测试在基于微服务架构的网络应用中扮演着越 ...
- linux运维、架构之路-Kubernetes集群部署
一.kubernetes介绍 Kubernetes简称K8s,它是一个全新的基于容器技术的分布式架构领先方案.Kubernetes(k8s)是Google开源的容器集群管理系统(谷歌内部 ...
- 中通快递股份有限公司.net高级面试题
中通快递分布式技术开发 gc垃圾回收原理 .net中,托管代码的内存管理是自动的,由GC进行管理,而对于非托管代码,则需要.net手动处理 CLR运行时,内存分为:托管堆和栈,其中栈用于存储值类型 ...
- 【转载】浅析从外部访问 Kubernetes 集群中应用的几种方式
一般情况下,Kubernetes 的 Cluster Network 是属于私有网络,只能在 Cluster Network 内部才能访问部署的应用.那么如何才能将 Kubernetes 集群中的应用 ...
- kubernetes集群中的pause容器
昨天晚上搭建好了k8s多主集群,启动了一个nginx的pod,然而每启动一个pod就伴随这一个pause容器,考虑到之前在做kubelet的systemd unit文件时有见到: 1 2 3 4 5 ...
- 解决项目迁移至Kubernetes集群中的代理问题
解决项目迁移至Kubernetes集群中的代理问题 随着Kubernetes技术的日益成熟,越来越多的企业选择用Kubernetes集群来管理项目.新项目还好,可以选择合适的集群规模从零开始构建项目: ...
- 如何在 Kubernetes 集群中玩转 Fluid + JuiceFS
作者简介: 吕冬冬,云知声超算平台架构师, 负责大规模分布式机器学习平台架构设计与功能研发,负责深度学习算法应用的优化与 AI 模型加速.研究领域包括高性能计算.分布式文件存储.分布式缓存等. 朱唯唯 ...
- ingress-nginx 的使用 =》 部署在 Kubernetes 集群中的应用暴露给外部的用户使用
文章转载自:https://mp.weixin.qq.com/s?__biz=MzU4MjQ0MTU4Ng==&mid=2247488189&idx=1&sn=8175f067 ...
随机推荐
- 中国的AI领域发展的重大不足 —— 数据缺少,尤其是自然语言领域(NLP)、大模型领域
全世界公开可用的语言文本中绝大部分是英文文本,其中中文文本只有1.5% 相关: China's Betting Big On Artificial Intelligence. Could The US ...
- 【转载】 miniImageNet数据集介绍
版权声明:本文为CSDN博主「miguemath」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明.原文链接:https://blog.csdn.net/wangkai ...
- 最新版gym-0.26.2下Atari环境的安装以及环境版本v0,v4,v5的说明
强化学习的游戏仿真环境可以分为连续控制和非连续控制两类,其中连续控制的以mujoco为主,而非连续控制的以Atari游戏为主,本文对gym下的Atari环境的游戏环境版本进行一定的介绍. 参考:[转载 ...
- Git报错解决:OpenSSL SSL_read: Connection was reset, errno 10054 错误解决
1.背景 最近因项目上需要,想借鉴一下spring里面的一下架构设计,在拉取spring源码是报错如下: 初步判定,估计是访问国外的网站,网速受限的原因..... 2.解决方案 打开Git命令页面,执 ...
- SMU Autumn 2023 Round 4(Div.1+2)
SMU Autumn 2023 Round 4(Div.1+2) A. Access Denied 通过分析样例可以得知如果所猜字符串与答案字符串长度不同,则只要\(5ms\),且答案最多\(20\) ...
- grpc断路器之hystrix
上一章介绍了grpc断路器sentinel, grpc断路器之sentinel 但是由于公司线上系统用的告警与监控组件是prometheus,而sentinel暂时还没有集成prometheus,所以 ...
- P4823 [TJOI2013] 拯救小矮人
感觉这个题的操作很新奇,做个记录. P4823 [TJOI2013] 拯救小矮人 大概题面: 一群小矮人掉进了一个很深的陷阱里,由于太矮爬不上来,于是他们决 定搭一个人梯.即:一个小矮人站在另一小矮人 ...
- C# WinForm 解除资源文件的占用并删除
1.删除未解除占用的资源时 2.调用Windows API函数 解除文件占用 [DllImport("kernel32.dll", SetLastError = true)] [r ...
- chrome.tabs.sendMessage和chrome.runtime.sendMessage的用法及区别
在 Chrome 扩展开发中,chrome.tabs.sendMessage 和 chrome.runtime.sendMessage 是用于不同目的的消息发送 API,它们的主要区别在于消息的目标对 ...
- SimpleTranslationAIAgent:基于C#与LLM的翻译AI Agent
基于C#与LLM通过简单对话即可实现文件到文件的翻译任务 该软件是MIT协议完全开源免费的,但是调用LLM的API可能需要费用,但是没关系,赛博菩萨硅基流动与智谱AI等都有免费的模型可调了. 这个Tr ...