王国庆 分布式实验室 


跨境时尚电商SHEIN基于Kubernetes的DevOps实践_Java

SHEIN PaaS参考了很多优秀的社区实践方案,最终使用了基于GitLab + Jenkins + Kubernetes + Harbor 的一套CI/CD工具集,一年多以来,总结开发出了一套公司自己的持续集成和发布的方案。本文着重介绍DevOps实践中几个比较值得分享的经验总结。
PaaS 平台介绍

跨境时尚电商SHEIN基于Kubernetes的DevOps实践_Java_02


PaaS 平台主要围绕 Dockerfile 和 DeployYml 这两个核心元数据,实现应用管理和流程管理等功能,目前完成了代码扫描,镜像构建,发布单审核,应用发布,流量控制,应用回滚,日志查看,运行状态查看,多集群管理 等功能。(Kubernetes 高可用集群搭建参考了优秀的社区项目:https://github.com/easzlab/kubeasz)

跨境时尚电商SHEIN基于Kubernetes的DevOps实践_Java_03

PaaS
对发布到PaaS的项目代码没有额外的限制(不需要在代码的指定路径包含 Dockerfile、Jenkinsfile 等构建依赖)。充分利用 Dockerfile 的多阶段构建功能,在 Dockerfile 中包含三个阶段:克隆、编译、运行(运行环境只包含构建结果,实现了镜像的最小化)。同时借助 PaaS 提供的基础镜像构建功能,开发人员可以将项目依赖添加到编译镜像中进行缓存,实现镜像构建加速。这样在保证构建灵活性的同时又保证了构建效率。

跨境时尚电商SHEIN基于Kubernetes的DevOps实践_Java_04

应用 Dockerfile 示例
因为 Dockerfile 多阶段构建功能的使用,很多构建逻辑不需要在 Jenkinsfile 实现,复杂度降低,为提高可扩展性,减少因为逻辑变更带来的维护成本,PaaS 支持传参触发构建,也支持更新 job xml 配置增加参数等,更重要的是使用 jenkins library 功能,项目构建 job 中只包含传参和函数入口调用等极少的代码,真正的处理逻辑在 jenkins library 中实现,这样在保证了可扩展性的同时又减少了维护成本。

跨境时尚电商SHEIN基于Kubernetes的DevOps实践_Java_05

jenkins-library 示例
通过图形化配置生成的 Deployment 等 yaml, 没有在 Jenkins 中发布,而是存储在数据库并直接调用 Kubernetes 接口部署,这样构建和发布分离,有很多使用方式上的考虑,比如,构建一次修改发布多次;只有构建没有发布(借助 Dockerfile 的多阶段构建,将编译结果发布到仓库,用于后续物理部署[特例]);快速回滚(从数据库中直接取出历史版本直接发布即可实现);蓝绿发布、流量控制等复杂逻辑(在平台代码中实现,比使用 Jenkinsfile 增加了复杂度更合适)。

跨境时尚电商SHEIN基于Kubernetes的DevOps实践_Java_06

配置应用

跨境时尚电商SHEIN基于Kubernetes的DevOps实践_Java_07

应用回滚
发布到 PaaS 上的应用,可以使用多种方式去了解服务状态,比如:查看重启次数及上一次失败原因(error或者oom),查看启动事件(了解应用为什么 pending 或者启动失败),查看控制台日志,查看落盘日志(即使服务没有成功也可以看异常日志),进入容器查看进程状状态及配置(用于测试外部依赖的连通性等)。


跨境时尚电商SHEIN基于Kubernetes的DevOps实践_Java_08启动次数原因

跨境时尚电商SHEIN基于Kubernetes的DevOps实践_Java_09

启动事件跨境时尚电商SHEIN基于Kubernetes的DevOps实践_Java_10
控制台日志查看跨境时尚电商SHEIN基于Kubernetes的DevOps实践_Java_11


落盘日志查看跨境时尚电商SHEIN基于Kubernetes的DevOps实践_Java_12


进入容器
因为集群的差异性,目前还需要用户在不同集群单独创建应用,才可以构建发布到不同的集群。当然,理想的状态是,更抽象的定义应用,屏蔽集群差异,任意指定集群发布。这方面还有很长的路要走。

跨境时尚电商SHEIN基于Kubernetes的DevOps实践_Java_13

多集群管理(参考 Wayne)
告警管理平台介绍

跨境时尚电商SHEIN基于Kubernetes的DevOps实践_Java_02


告警管理平台:主要围绕告警规则和告警群组进行开发。支持添加企业微信、电话、短信告警群;告警规则和抓取规则的图形化配置;支持多集群。

跨境时尚电商SHEIN基于Kubernetes的DevOps实践_Java_15

告警规则配置

跨境时尚电商SHEIN基于Kubernetes的DevOps实践_Java_16

抓取规则导入

跨境时尚电商SHEIN基于Kubernetes的DevOps实践_Java_17

企业微信告警
如下是集群管理员和用户日常查看的监控图:(后续将用户常看的服务指标在 PaaS 中直接展示)

跨境时尚电商SHEIN基于Kubernetes的DevOps实践_Java_18

集群视角

跨境时尚电商SHEIN基于Kubernetes的DevOps实践_Java_19

节点视角

跨境时尚电商SHEIN基于Kubernetes的DevOps实践_Java_20

Pod 视角
提升集群稳定性实践

跨境时尚电商SHEIN基于Kubernetes的DevOps实践_Java_02


在集群搭建运行一年多以来,目前已趋于稳定,期间遇到了很多问题,这里做了些能够增加集群稳定性的总结。
1、配置资源限额可以有效的提高节点和集群稳定性,需要创建应用时为每个服务添加默认资源限额。同时创建 limit-range,为每个没有指定资源配额的服务增加默认限制。
2、低版本内核存在诸多已知问题,比如,3.10 内核集群, calico node 频繁重启解决:sysctl -w net.ipv4.tcp_tw_recycle=0,目前使用内核 4.18.16 版本,稳定运行半年未发现内核相关异常。
3、Pod 长时间 terminating 状态,可能导致 kubelet 状态异常,登陆宿主机,kill -9 对应容器进程临时解决。需要添加 terminating 状态监控,并使用 my_init 改造 Dockerfile,解决因为僵尸进程等进程回收失败导致的无法删除问题。
4、真正做到平滑升级,需要服务:配置就绪探针、配置存活探针、配置 sleep 10 的终止前钩子(如果注入了 istio sidecar,sidecar 也需要配置终止前钩子)、代码处理 SIGTERM 信号主动中断连接。另外如果使用执行命令进行健康检查,所执行的命令不能太耗资源性能,否则可能导致服务异常时,节点负载过高。
5、设置 kubelet 资源预留时,谨慎配置系统资源预留,发现在 Master 节点为 kubelet 配置资源预留导致 Master 组件频繁重启故障。
6、添加节点线程数,打开文件句柄数监控,提前发现异常服务,防止主机资源耗尽。
查看进程子进程数:

find /proc/*/task -maxdepth 0 -type d |while read dir; do count=$(ls "$dir" | wc -l); echo "$dir : $count"; done


查看进程打开文件句柄数:

find /proc/*/fd -maxdepth 1 -type d | while read dir; do count=$(find