開發與維運

当egg遇见K8s会发生什么?

Egg介绍:
Egg 奉行『约定优于配置』,按照一套统一的约定进行应用开发,团队内部采用这种方式可以减少开发人员的学习成本,开发人员不再是『钉子』,可以流动起来。没有约定的团队,沟通成本是非常高的,比如有人会按目录分栈而其他人按目录分功能,开发者认知不一致很容易犯错。但约定不等于扩展性差,相反 Egg 有很高的扩展性,可以按照团队的约定定制框架。使用 Loader可以让框架根据不同环境定义默认配置,还可以覆盖 Egg 的默认约定。

K8s介绍:
Kubernetes是Google开源的一个容器编排引擎,简称K8s,它支持自动化部署、大规模可伸缩、应用容器化管理。在生产环境中部署一个应用程序时,通常要部署该应用的多个实例以便对应用请求进行负载均衡。在K8s中,我们可以创建多个容器,每个容器里面运行一个应用实例,然后通过内置的负载均衡策略,实现对这一组应用实例的管理、发现、访问,而这些细节都不需要运维人员去进行复杂的手工配置和处理。

目前公司某项目使用了egg框架,运维团队部署该项目使用了k8s集群,今天出现了一个奇怪的问题,我们的打包后的docker 镜像,在单独的ECS上可以正常该服务,但是部署到k8s的时候,启动失败,

这个问题看似很诡异,一模一样的镜像,一模一样的网络权限,软件层面上完全一样的,为啥启动不成功。今天运维部门对k8s扩容过,添加过一个8核的work节点,难道是这个节点导致的,但是这个节点上也运行了很多容器,不单单只有该项目。

带着这个思考,和同事沟通后,结果确实是添加的新的node节点间接导致了这个问题,了解到他用egg的时候,没有去定义work进程的数量,egg就会自动去创建work进程,创建的进程数据是基于获取的物理系统的CPU线程数来决定的。

01.png

如上图所示,该项目所运行的容器的宿主机的CPU线程数是8,通过观察,发现该项目会自动启动8个进程,如果我们采用32线程的CPU,那它就会在容器中启动32个进程,但是容器的资源是做过限制的,虽然你看到这么多CPU线程,但不是给你一个容器用的,一下子请求这么多资源,肯定会启动失败的。而且容器的思想是一个容器运行一个进程,只干一件事,这在物理机上部署egg或许这个特性比较方法,但是容器上部署就会出现这种坑。

解决方法:

让egg和pm2启动进程的方式一样,固定运行的进程数,不要动态获取CPU信息,去一厢情愿的启动进程,和docker的资源隔离起冲突。

02.png

总结:
1.无论使用什么新框架新技术,使用前必须深入了解和研究;
2.启动服务的时候,都不能用默认配置,研发和运维沟通后做一个合适的参数,因为本地环境和生产环境还是会有资源容量上的差异,避免各做各的;

Leave a Reply

Your email address will not be published. Required fields are marked *