开发者社区> 容器小师妹> 正文

伊对云原生CI_CD改造历程

简介:  持续周期:2020年4月~2021年12月 涉及人力:运维 * 2;php开发 * 1 关键词:自下而上;循序渐进;不影响业务开发
+关注继续查看
作者:关陞阳 米连科技运维开发工程师

公司背景

北京米连科技有限公司成立于2015年9月份,国家高新技术企业及中关村高新技术企业。2019全年营业额接近10亿人民币,主营业务为通过自主研发的视频社交产品-伊对APP服务单身恋爱社交人群。公司已获近亿美元级B轮融资。

伊对是当前飞速成长的恋爱社交平台,当前活跃红娘40000+,每月撮合近1000万场相亲,仍在快速增长中。伊对APP拥有更真实的恋爱社区,以真实的社交网络,创造更多恋爱机会。注册用户2020年12月就突破1亿,平台每月可以为1500万多对单身男女创造恋爱机会,每天撮合50万多次视频相亲,活跃红娘、月老超40,000人,用户的日均使用时长达到了40分钟。

伊对是用户价值与商业价值统一协调的大众市场,恋爱新物种,陌生人社交领域的阳光荷尔蒙,与婚恋赛道全完不同,我们的红娘全部来自于伊对用户,并不是我们的员工。

非容器时代

go代码仓库:1

痛点

网关层上线没有滚动

每次网关部署都会造成大量报错,放到现在都是P0级别的事故。

微服务相互调用写死

没有负载均衡,没有健康检查,每次微服务上线都会引起大量报错;增减某个服务的实例数量需要改动所有调用方的配置。

yd-BB=IP-BB-1;IP-BB-2
yd-CC=IP-CC-1
yd-DD=IP-DD-1,IP-DD-2

没有配置管理

配置分布在各个ECS上,经常会出现同一个服务的配置在不同服务器上不一致;

不到30个微服务出现了4种配置文件格式:ini、yaml、toml、xml;

配置文件内部不统一,例如多个地址的分隔符,有逗号和分号。

go代码仓库单一

一个go项目中按照文件目录区分服务,实现自动打包很麻烦。

上线缺少标准化流程

上线部署流程控制在一个在线表格维护,依赖人去手动维护,经常漏写错写。

1.png

无法确认线上代码以及配置的版本

当时的部署方式是手动在打包服务器拉取代码,打包之后通过ansible命令推送二进制包到对应ECS,再进行文件替换之后重启supervisor;

日志服务里面无法体现当前代码的版本,经常需要查看具体运行的二进制文件的md5值判断线上的代码具体是哪个commit产生的。

docker时代

go代码仓库:50+

为了解决非容器时代的痛点,我们做了这些事

代码仓库拆分

由业务研发组长实施,基于业务模块使用gitlab的group以及subgroup拆分出来多个单一功能的微服务代码仓库以及公共模块仓库。

半自动打包上线

在每个代码仓库中使用gitlab-ci进行打包。

# 项目所属组
  GROUP_NAME: go
  # 项目所属子组
  SUBGROUP_NAME: user_info
  # 配置管理项目地址
  CONFIG_PROJECT: go-config
  # 自动部署时目标机器组标签
  DEPLOY_HOST_GROUP: user-info
stages:
    - build
    - deploy
    - dev

在一个独立的gitlab仓库管理配置

2.png

服务器环境由supervisor切换到docker,docker的镜像可以确定具体代码和版本,日志服务改为采集容器日志,可以看到产生日志的镜像。

基于gitlab-ci实现自动构建docker镜像,构建完成后基于ansible脚本更新线上ECS,镜像的tag由分支-代码commit-配置commit组成。

每次打包基于commit,每次部署基于镜像,实现简单标准化上线。回滚是执行上一次部署。

3.png

网关层滚动部署

基于ansible以及阿里云命令行工具实现了一套网关滚动部署流程,逐个把要更新的ECS从SLB的虚拟服务器组中权重调0,再停止服务,更新镜像,自检成功后再把权重恢复。

4.png

服务发现

基于ETCD实现简单服务发现功能,单个微服务扩缩不需要修改其他服务的配置文件,基于ansible实现了滚动部署。

痛点

ECS使用率低,需要手动调度负责

需要手动平衡各个ECS上运行的container,ECS平均规格小,使用率低,数量多,实例扩缩流程繁琐。

必须运维手动||半手动部署

没有自主上线时有一周2个运维加起来一共220次上线部署,那一周我们2个运维无法开展任何其他工作,每天全部的精力都耗费在上线部署,身边随时都有不同的研发围着排队上线,很低效。

定时任务被上线打断

逐渐一些微服务代码仓库出现了同时包含grpc以及定时任务逻辑的情况,在docker环境下往往是通过docker启动脚本传递一个特殊环境变量作为定时任务开关,让定时任务仅在一台ECS上执行。多次出现长执行时间定时任务执行期间被上线部署打断引起的事故。

命令行工具不适合高频率自动化部署

ansible或者kubectl这种命令行工具手动使用很方便,但是在作为自动部署工具时太慢了,每次部署或者回滚都有一个几秒的初始化命令行环境的时间。而且使用命令行工具做部署的话,部署逻辑是在shell脚本中维护的,比较难实现复杂上线功能,例如灰度部署。

缺乏监控告警体系

原生云监控不满足需要,经常漏报错报。

缺少对go服务公共模块依赖的查询

例如common v1.9.2这个版本有个重大更新,研发很难确定哪些微服务引用的common版本低于v1.9.2。

kubernetes时代

go代码仓库:170+

实例组数量:240+

为了解决docker时代的痛点,我们做了这些事

实现运维平台

5.png

在运维平台上实现了一套权限系统,有合适权限的研发可以自己执行部署以及回滚,一切操作都留有记录

6.png

运维平台上线后解放了运维人员大量精力,实现了非特殊部署完全不需要运维参与,让我们运维有时间精力去研究或开发其他运维工具,大大提高整体研发工作效率。最近2个月仅有2.24%的上线单是由运维部署的。运维平台功能完善之后有一天多个业务线同时发版,当天总共上线+回滚次数超过210,全程无运维参与。

迁移至kuberbetes

很幸运阿里云提供的Terway集群完美适配我们docker时代基于ETCD的服务发现逻辑,Pod的ip和ECS ip在同一层,大大减少了迁移的周期,降低了迁移的难度。

抽象出实例组概念,实例组是一个微服务仓库代码的一种运行方式,在运维平台维护,类似与helm的chart。一个微服务仓库可以拥有多个实例组,例如一个微服务仓库代码可以同时启动无状态grpc服务、有状态异步处理服务以及定时任务。每次部署的最小单位是一个实例组。

7.png

8.png

实例组由yaml模板和参数组成,如果一个微服务需要一个罕见配置,可以快速创建一个专用的yaml模板实现,不要求部署逻辑维护全量的k8s控制器结构体,仅维护最通用的参数,这样大大降低了开发成本,在kubernetes集群内使用的ECS节点规格大了很多,使用率也有显著提高。

基于kubernetes api用go实现了一套部署逻辑

api比命令行工具快很多,还能实现很多额外的功能,例如查看Pod事件等,代码也比脚本更容易维护。

9.png

自建prometheus监控以及告警体系

基于prometheus和运维平台实现了秒级监控告警。

go服务依赖查询功能

10.png

每次上线打包时向运维平台上报go.sum,把当前线上环每个微服务的具体依赖存在数据库里面,在运维平台实现查询页面。

k8s服务资源监控以及自动调整

周期性从自建prometheus里面拉取数据,基于服务过去的资源使用量和服务优先级生成新的资源限制。

11.png

痛点

缺少更细粒度的流量控制

目前仅实现了基于流量百分比的灰度,而且大量ab测试逻辑在代码里面,不利于维护。

在gitlab仓库维护的配置文件不够灵活

无法实现热更新,或者环境级别的配置管理。

基于Cronjob实现的定时任务不够灵活

不能方便的实现紧急停止、临时触发等功能。

业务服务总体资源使用不符合阿里云ECS规格

业务服务使用的内存很少,CPU比内存接近4:1,集群内存使用率低。

研发人员对运维平台不熟悉运维平台

功能越来越复杂,很少有研发能充分使用,尤其是新同事。

未来

探索Service mesh

使用nacos

自己实现定时任务逻辑

将一些缓存redis部署到k8s集群

增加运维平台引导

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,大概有三种登录方式:
9662 0
使用SSH远程登录阿里云ECS服务器
远程连接服务器以及配置环境
13421 0
阿里云服务器怎么设置密码?怎么停机?怎么重启服务器?
如果在创建实例时没有设置密码,或者密码丢失,您可以在控制台上重新设置实例的登录密码。本文仅描述如何在 ECS 管理控制台上修改实例登录密码。
20348 0
腾讯云服务器 设置ngxin + fastdfs +tomcat 开机自启动
在tomcat中新建一个可以启动的 .sh 脚本文件 /usr/local/tomcat7/bin/ export JAVA_HOME=/usr/local/java/jdk7 export PATH=$JAVA_HOME/bin/:$PATH export CLASSPATH=.
13896 0
阿里云服务器端口号设置
阿里云服务器初级使用者可能面临的问题之一. 使用tomcat或者其他服务器软件设置端口号后,比如 一些不是默认的, mysql的 3306, mssql的1433,有时候打不开网页, 原因是没有在ecs安全组去设置这个端口号. 解决: 点击ecs下网络和安全下的安全组 在弹出的安全组中,如果没有就新建安全组,然后点击配置规则 最后如上图点击添加...或快速创建.   have fun!  将编程看作是一门艺术,而不单单是个技术。
18626 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,云吞铺子总结大概有三种登录方式: 登录到ECS云服务器控制台 在ECS云服务器控制台用户可以更改密码、更换系统盘、创建快照、配置安全组等操作如何登录ECS云服务器控制台? 1、先登录到阿里云ECS服务器控制台 2、点击顶部的“控制台” 3、通过左侧栏,切换到“云服务器ECS”即可,如下图所示 通过ECS控制台的远程连接来登录到云服务器 阿里云ECS云服务器自带远程连接功能,使用该功能可以登录到云服务器,简单且方便,如下图:点击“远程连接”,第一次连接会自动生成6位数字密码,输入密码即可登录到云服务器上。
33296 0
使用NAT网关轻松为单台云服务器设置多个公网IP
在应用中,有时会遇到用户询问如何使单台云服务器具备多个公网IP的问题。 具体如何操作呢,有了NAT网关这个也不是难题。
35080 0
阿里云服务器安全组设置内网互通的方法
虽然0.0.0.0/0使用非常方便,但是发现很多同学使用它来做内网互通,这是有安全风险的,实例有可能会在经典网络被内网IP访问到。下面介绍一下四种安全的内网互联设置方法。 购买前请先:领取阿里云幸运券,有很多优惠,可到下文中领取。
19010 0
49
文章
1
问答
来源圈子
更多
容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级 Kubernetes 容器化应用的全生命周期管理。容器服务 Kubernetes 版简化集群的搭建和扩容等工作,整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳的 Kubernetes 容器化应用运行环境。
+ 订阅
相关文档: 容器镜像服务 ACR 容器服务 ACK 服务网格 ASM
文章排行榜
最热
最新
相关电子书
更多
JS零基础入门教程(上册)
立即下载
性能优化方法论
立即下载
手把手学习日志服务SLS,云启实验室实战指南
立即下载