内容简介:知乎容器化构建系统设计和实践
较低的应用接入成本,较高的定制能力:写一个构建系统配置文件成本要尽可能简单方便,或者可以通过模板一键创建,但又要能满足应用的各种定制化的需求。
具备语言开放性和部署多样性:平台需要能支撑业务技术选型上的多语言,同时,要能满足应用不同的部署类型,如单纯的打包发布,或者进一步部署到物理机、容器、离线任务平台等。
构建快和稳定,复现问题成本低:每次构建都在干净的容器中,减少非应用本身问题带来的构建异常。同时,如果构建出现问题,在权限控制的前提下,要能方便开发者自己调试和排查。
推动业界标准以及最佳实践,同时在代码合并之前就能更好把控住质量。
整个集群高可用,可扩展,以及具备较低的运维成本。
每个开发者都需要去理解 Jenkins 的基本配置和触发逻辑,使得配置创建和维护成本高。
构建在物理机上进行,每个应用可能有着不同的版本依赖,构建时会遇到版本冲突,甚至上线之后发现行为不一致导致故障等。
构建一旦失败,需要开发者能登录 Jenkins Slave 所在的物理机进行调试,权限控制成为了一个问题。
只有 Master 分支的代码可以用于线上部署,但支持指定任意的分支进行构建。
所有对 Master 分支的修改必须通过 Merge Request 来进行。为了避免潜在代码冲突导致测试结果不准的情况,对 Merge Request 上的代码进行构建前,会模拟跟 Master 分支的代码做一次合并。
开发者提交代码到 GitLab。
GitLab 通过 Webhook 通知到 ZAE(Zhihu App Engine, 知乎的私有云平台)。
ZAE 将构建的上下文信息,如 GitLab 仓库 ID,ZAE 应用信息给到构建系统 Lavie。目前只处理用户提交 MR 以及合并到 Master 分支的事件。
构建系统 Lavie 读取应用仓库中的配置文件后生成配置,触发一个构建。在构建过程中获取动态生成的 Jenkinsfile,生成 Dockerfile 构建出应用的镜像,并跑起容器,在容器中执行构建,测试等应用指定的步骤。
测试成功之后,分别往物理机部署平台,容器部署平台,离线任务平台上传 Artifact,注册待发布版本的信息,并 Slack 通知用户结果。
构建结束,用户在 ZAE 上可以进行后续操作,如选择一个候选版本进行部署。
base_image: python2/jessie
build:
- buildout
test:
unittest:
- bin/test --cover-package=pin --with-xunit --with-coverage --cover-xml
base_image: py_node/jessie
deps:
- libffi-dev
build:
- buildout
- cd admin && npm install && gulp
test:
deps:
- mysql:5.7
unittest:
- bin/test --cover-package=lived,liveweb --with-xunit --with-coverage
coverage_test:
report_fpath: coverage.xml
post_build:
scripts:
- /bin/bash scripts/release_sentry.sh
artifacts:
targets:
- docker
- tarball
cache:
directories:
- admin/static/components
- admin/node_modules
image,基础镜像,需要指明已提前准备好的语言镜像
deps,dependencies 的简写,声明使用的系统依赖以及对应的版本
build,构建的步骤,如 buildout,npm install,或者执行一个脚本
test,测试环节,应用需要声明构建的步骤,也可以在这里定制使用的 MySQL 以及对应的版本。构建系统会每次为其创建新的数据库,将关键信息 export 为环境变量。
post build,最后一个环节,如发包,发 Slack 、邮件通知,或发布一个 Sentry release 等
Tarball:构建系统会将整个应用 Workspace 打包上传到 HDFS 用于后续的物理机部署
Docker:镜像会被 push 到私有的 Docker Registry 用于容器部署
static:应用指定的路径打包后会被上传到 HDFS,用于后续的静态资源部署
offline:应用指定的文件会被上传到离线平台,用于离线任务的执行
我们会事先准备好系统的基础镜像。
在系统镜像的基础上,会构建出不同的语言镜像供应用使用,如 Python,Golang,Java,Node,Rust 的各种版本以及混合语言的镜像。
在应用指定的 image 语言镜像之上,会安装上 deps 指定的系统依赖,再构建出应用的镜像,应用会在这个环境里面进行构建测试等。
完善内部不同语言的源
在不同语言的基础镜像中放入优先使用内部源的配置
搭建 HTTP Proxy,提供给以上覆盖不到的场景
配置文件中强制要有测试环节。
应用测试结束之后,取到代码覆盖率的报告并打点。在提交的 Merge Request 评论中会给出现在的值和主分支的值的比较,以及最近主分支代码覆盖率的变化趋势。
在知乎有应用重要性的分级,对于重要的应用,构建系统会对其要求有测试覆盖率报告,以及更高的测试覆盖率。
两个 Jenkins Master 是否可用,当前的排队数量情况。
集群里面所有 Jenkins Node 的在线状态,Node 被命中的情况。
Jenkins Job 的执行时间,是否有不合理的过长构建或者卡住。
以及集群机器的 CPU,内存,磁盘使用情况。
Jenkins Slave 能更根据集群的负载情况进行动态扩容。
一个节点故障时能自动下掉并重新分配已经在上面执行的任务。一个 Master down 掉能被主动探测到并发生切换。
在 Merge Request 的构建环节推动更多的质量保证标准实施,如更多的接口自动化测试,减少有问题的代码被合并到主分支。
以上所述就是小编给大家介绍的《知乎容器化构建系统设计和实践》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。