当前位置: 首页 > news >正文

devops平台建设-总体设计文档

一、背景

什么是devops

所谓devops,拆开来看就是 Development+Operations,从最白话的角度来说其实就是讲开发团队和运维团队协作的文化和模式。相信很多人都或多或少听说过这个名词,有些人可能觉得这个东西非常高大上、大厂标配,或者认为这个东西就是简单的开发干运维的事,我觉得有必要聊一下我对于它的看法:

早期瀑布模式

/Users/cds-dn-764/Desktop/瀑布.jpeg

这是最早期的模式(现在也有很多公司仍然适用),这类业务场景偏私有化、定制,或者是一些政企项目,他们的特点是需求稳定、访问量不高、强调软件完整可用,所以迭代周期长,如果把软件比喻成飞机,那么一开始就要设计好所有螺丝的结构,至于最后是否顺利起航,中间要做很多的测试工作。每个人被划分在独立的工种,关注的视角全不相同。如技术团队只关心代码、文档,运维(有的甚至没有专门的运维)关注的是系统服务资源,如机器、网络等,大家的"语言"不一样,但由于对持续集成和持续交付需求量不大,所以简单的ssh/ftp 即可满足对于部署和交付的需求。

敏捷开发

/Users/cds-dn-764/Desktop/瀑布.jpeg

如果还是造飞机,那么敏捷可能不会一下就造出一架完整的飞机,而是由业务专家做需求和模块拆分,增量迭代的发布一些基本可用的功能,比如第一周我先把飞机发动机造出来,第二周设计机舱……每个任务被划分到独立的单元里(Sprint),由敏捷团队冲刺交付。这个时候,技术团队不再专注于写代码和测试,需要关注服务的部署,甚至需要自己来完成这个事情,因为飞机被拆分成了不同的单元,每一天都要做多轮的集成测试(CICD),才能确保最后合并在一起的螺丝和谐的工作。这个时候,可能有的项目已经开始做微服务化,原来的项目一生二、二生三,如细胞分裂般被拆分成了多个独立进程,所以容器化和云原生应运而生,以我过去的工作经历举例我们可能每周有上万个容器被创建和销毁,那么这时候开发和运维的"跨语言"交流的痛点就显现了出来:运维团队求稳,需要的是一个稳定的线上环境,讨厌变更;开发团队需要不断的push代码,变更线上运行逻辑;两个团队天生是一个对立的局面。开发需要关注线上部署,但却不一定熟悉运维知识;运维需要支撑开发迭代,但却因为没有直接对接业务而导致理解会有出入。这个时候可能会有一些自动化工具如Jenkins、GitlabCI来辅助产研完成交付。但这不是devops,只是dev+ops。 本质上大家还是各做各的事,对各自的一亩三分地了如指掌,缺乏全局的系统意识。

当前的痛点

这里引用一下之前我在[《架构问题&治理》]中梳理的我们公司的技术和运维流程:

image.png

这种模式是一个典型的Jenkins敏捷开发的工作模式。且不提是否所有人都对这其中的工作流程很清楚,单纯从一个新人的角度去理解它,存在几个很明显的问题:

  1. 缺乏版本管理: 由于流水线的特性,一个流水线绑定一个源代码分支(比如dev绑定dev,stage绑定stage),最终的镜像制品格式为 {仓库地址}/{项目}:{环境},对于非生产环境还好,但是生产环境永远都是prod tag,光是看这一个信息,相信没有人能知道这个当前运行的容器究竟上了什么需求、是哪一天上的、谁开发的,回滚就尤为困难,对于快速定位问题来说带来很大的困扰。

  2. 数据孤岛:且看下面这张图

/Users/cds-dn-764/Desktop/数据孤岛.jpeg

站在开发的视角,看似做到了CICD,但业务运维所需的一切数据是分散的,作为服务的负责人,需要在多个平台间反复跳转,收集信息,再进行大脑风暴,显然无助感是必然存在的,尤其是一些没有权限的人,需要口口相传才能获取到一些片段信息,对于业务运维来说非常低效。

  1. 权限难题: 每个人在进入公司之后,都需要有权限。这个权限可能是业务的,可能是技术的,在技术侧,对于权限的需求是频繁存在的。比如你不可能让一个后端的开发没有查看k8s集群的权限,这样他写出来的代码是有可能犯错的(比如进程锁或者本地缓存在单一pod情况下是ok的,但是如果是多个副本就会有很大的问题)。但是站在运维的角度,开权限这个事情是需要谨慎的,打个比方我可能可以给你查看集群的权限,但是我又不希望把集群的秘钥过多的开放给许多人,这是安全和灵活的博弈。权限开大了,容易出现不可控的事;权限开小了,开发的不得劲,就是这么简单。

  2. 云集成困难: jenkins能很好的完成ci工作,却不是一个合格的cd工具。比如它对于k8s、网关等的集成能力较弱,导致我们有许多业务部门需要依赖 ack hook完成服务的发布(说是发布,其实是重启,这也和第一点问题衔接上了),但由于hook是公网,所以它的安全性非常差。当然我们可以在Jenkins寻找许多开源插件或者自己写脚本去支持,解决问题的方法会有很多种,我们需要的是最优解。

  3. 发布质量: 由jenkins流水线控制的发版,对于自动化测试、代码质量审核,很难做卡点;没权限的人着急忙慌的丢给你一个PR让你去merge,真正能耐心去看代码逻辑的有多少呢,很难。况且是一个几百个diff的PR就更难了。

  4. 灰度发布: 生产环境发布没有灰度能力,仿佛是在开盲盒。以前没有问题不代表没问题,有些问题是看不见的,灰度能力可以把风险控制在一个范围内,提高发版的质量。

  5. 难以推进devops: 很简单的道理,我曾在许多夜晚即将入睡的时候,收到组内同时帮忙合并一个代码、部署一个服务的需求,在很多场景下,因为那个需求我并没有参与,我只是有代码合并和发布的权限,所以沦为了"工具人",虽然这只是一个"小忙",却恰恰反映出一个现状-- 开发的人只关注代码,却没办法全流程跟进需求上线,将服务发布的隐性风险转移给了有权限的人,这样对于不懂服务底层运行原理的人一直不懂,有权限的人只会在日复一日"帮个小忙"的模式下丧失对代码review的兴趣以及线上的敬畏之心。

一言以蔽之: 所有缺乏工具约束的规范,最终只会沦为纸上的规范。

二、目标

基于以上的痛点,我在去年年末有了一个新devops平台开发的开发想法,在我看来,当前迫切的需要一个全新的平台去解决这些事情,这个平台至少要有以下能力:

/Users/cds-dn-764/Desktop/devops架构设计.jpeg

平台核心能力列表:

  1. 多语言持续ci: jenkins能做的,平台也要能做。并且要支持多语言,每个语言多版本,从设计层面上做到开闭,确保要新增语言支持响应快。

  2. 多云CD: k8s能力平台直接托管,利用helm、acr、kubectl等能力,支持公有云和私有云等混合模式的轻松接入,做到平台层用户无感。

  3. 权限独立管理:默认与公司组织架构保持同步,比如蝉选的负责人,可以查看和操作所有蝉选相关集群的能力,并且支持细粒度的授权,屏蔽底层的安全隐患,又保留灵活性。

  4. 灰度发布: 同时支持流量灰度和业务灰度,嵌在生产环境环节中,用户只需简单几步点击配置,即可完成灰度发布,不写脚本、不写代码。

  5. 应用观测: 轻松接入观测能力,无需自建、跳转平台即可全览服务数据和健康度。

  6. 需求迭代管控: 取消分支和固定tag,以开发PR粒度的完成CICD,每个上线的版本留有release历史,做到问题快速定位和回滚。

  7. 基建能力管理: 对于各部门的资源独立管理,服务发布完全使用所属部门基建,支持k8s混合云、网关混合云、镜像仓库等统一管理。

  8. AIOPS: 结合大模型能力,能解决开发过程中的常规业务运维需求,如chat运维、代码review等能力轻松接入。

  9. 安全审计: 对于所有的操作皆有迹可循,全程留痕。

  10. 自动化测试: 支持接口自动化测试嵌入测试节点,为服务安全上线保驾护航。

在做这件事之前,其实调研过不少市面上的开源/商业软件,比如github搜索devops,可以看到很多类似的平台项目,但都不太满意,其中比较核心的一个问题就是-- 这些所谓devops平台,其实设计的面向对象是运维人员,而非开发人员。比如kubeadmin、rancher、kubesphere、argocd、gitlabci,包括云效、git action等等,他们都提供了灵活的丰富的流水线、项目协同的工具,但无一例外都是运维平台。由于组织架构和角色划分,运维和产研作为不同的职能组,站的角度不一样所关注的资源类型也不一样。产研关注的是项目交付,关注一个个项目为维度,从流量、配置、代码仓库等多个应用层的资源,他们并不需要过多的去理解什么是k8s deployment、service、config/secret、pvc,网络模型、机器资源,cpu/gpu,从一个开发的角度而言,我希望看到的是比如用户中心/user-center,它的负责人是xxx,开发是xx,测试是xx,最近发布了几次需求,与哪一些prd、技术方案建联,它有哪一些出入网流量,最近的SLA是几个9,发版质量、回滚频率等等信息,而不是user-service-deployment(正反亲和性、污点、标签、pv挂载策略)、user-service-svc(cluster还是LB)、user-service-ingress(是nginx、mse,路径重写匹配策略、请求头策略),这些是基础运维需要关注的。什么是业务运维,业务是重点,运维为次,所以如果只是要做一款k8s管理平台、脚本流水线管理平台,确实照搬开源的就可以了,但许多互联网公司都选择了自己做,除了他们有这个人才储备之外,重要的一点是对于devops的认知:devops,重点是dev,而非ops,所有不是为了产研团队设计的devops都很容易变成k8s管理平台、流水线编排工具,但这些是基础运维,不是他们不够好,而是设计目标不一样,这也是为什么会有sre这个岗位的出现,sre是懂运维的开发,而不是做开发的运维。

三、项目原型

项目原型地址:
后续补充

三、问题拆解

CI和CD

在做项目的最开始,需要考虑的就是如何把CI和CD的能力集成进来,如果没有这两个能力,devops也就是一句空谈。CI表示的是持续集成,集成要干的事至少要包含3个点:代码拉取、编译打包、镜像制作推送。每一个项目,在每个环境下都必须要经历这3个过程,关于这3个问题,可以有对应的解法:

  1. 代码拉取: 在编译环境内,需要有git能力的支持,这个可以在基础镜像中预先安装好,而代码拉取的凭证,可以直接使用公司统一的 “业务开发部-部署专用账号”的访问凭证,一并安装在基础镜像中。

  2. 编译打包:由于每个语言的编译指令不同,如go需要使用go mod tidy &go build,java需要使用maven做mvn clean package,所以针对不同的语言和版本,需要制作不同的基础镜像。

  3. 镜像制作推送: 服务运行在容器里,容器依赖镜像,有了产物之后就需要把产物放到一个专门的镜像里作为启动访问项。这个也好解决,每个项目只要默认有Dockerfile,就可以轻易的在CI流程里执行docker build完成镜像制作。而推送的目的地,可以先使用limayao的私服,如我们下面要提及的资源独立,每个部门有自己的limayao仓库,比如蝉选 docker.limayao.com/chanxuan, 后面可以加入环境和仓库名作为多级仓库名称,tag就使用实际发布的版本作为tag。

这里是一个基础镜像go 1.22的dockerfile:

FROM alpine:3.19# 设置时区
ENV TZ=Asia/Shanghai# 安装基础工具和依赖
RUN apk add --no-cache \curl \wget \git \ca-certificates \gnupg \docker \docker-cli \docker-cli-compose \gcc \libc-dev \make \pkgconfig \librdkafka-dev \openssh-client \bash# 安装 kubectl
RUN curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" \&& chmod +x kubectl \&& mv kubectl /usr/local/bin/# 安装 Helm
RUN wget https://get.helm.sh/helm-v3.14.2-linux-amd64.tar.gz \&& tar -zxvf helm-v3.14.2-linux-amd64.tar.gz \&& mv linux-amd64/helm /usr/local/bin/helm \&& rm -rf linux-amd64 helm-v3.14.2-linux-amd64.tar.gz# 安装 Go 1.22
RUN wget https://golang.org/dl/go1.22.0.linux-amd64.tar.gz \&& tar -C /usr/local -xzf go1.22.0.linux-amd64.tar.gz \&& rm go1.22.0.linux-amd64.tar.gz# 设置 Go 环境变量
ENV PATH=$PATH:/usr/local/go/bin
ENV GOPATH=/go
ENV PATH=$PATH:$GOPATH/bin# 创建工作目录
WORKDIR /workspace# 验证安装
RUN go version \&& docker --version \&& kubectl version --client \&& helm version# 创建 .ssh 目录
RUN mkdir -p /root/.ssh && chmod 700 /root/.ssh# 添加 SSH 密钥
COPY ./id_rsa /root/.ssh/id_rsa
COPY ./known_hosts /root/.ssh/known_hosts# 设置适当的权限
RUN chmod 600 /root/.ssh/id_rsa \&& chmod 644 /root/.ssh/known_hosts# 验证 Git 配置
RUN git config --global user.email "cicd@xxx.com" \&& git config --global user.name "CICD Bot" \&& git config --global url."git@xxx:".insteadOf "https://xxx/"# 设置 Go 环境变量
ENV GO111MODULE=on \GOPROXY="https://goproxy.cn,direct" \GOPRIVATE="*xxx" \CGO_ENABLED=1WORKDIR /workspace# 测试 Git 连接(可选)
RUN ssh -T xxxCMD ["sh"]

而CD强调的是持续交付,也就是说需要把镜像安装到对应k8s集群上,这一点可以通过在基础镜像中预先安装kubectl和helm工具提供底层的支持,但是kubectl需要凭证,每个部门有各自的集群,那就不能把凭证安装在基础镜像里,而且每个语言可能在k8s资源上关于注解和标签会有一些细微的差距,所以在基础镜像之上,由再度孵化出执行器镜像,比如go-1.22,java-1.8,就是独立的一个执行器镜像。具体流程可以看下图:

/Users/cds-dn-764/Desktop/cicd镜像执行器流程.jpeg

这样的设计有几个好处:

  1. 调度是真正分布式的,不会因为某个部署机器挂掉而所有任务都阻塞等待,而且理论上机器越多,可同时在线构建部署的任务越多,甚至只需要一台机器,然后其余使用ECI弹性池,就可以完成海量的任务调度工作。

  2. 关于部署这个动作,不依赖触发器,而使用helm做k8s包管理工具,可以很方便的一键迁移、卸载和安装应用,只依赖标准的apiserver接口,不与任何云商绑定,只要愿意,任何支持k8s协议的云服务提供商都可以直接接入。

  3. 始终坚持 镜像和配置分离的原则,如job运行期所需的一切秘钥,都通过调度系统动态的挂载,减少了安全问题;服务运行所需的配置和资源,通过自建的Apollo配置中心只在配置拉取这一地方完成初始化,最后依然通过configMap进行一键安装,这样一来,配置中心的高可用问题迎刃而解,即使配置中心宕机,服务依然可以正常启动。

  4. cicd每次都是一次全新的job容器,不用担心宿主机环境污染和秘钥泄漏等问题,如果部署失败也会自动结束进程和完成垃圾回收动作。

  5. 彻底践行devops: 现在有了平台的托管和约束,通过ai review代码、自动化测试、灰度发布三道关卡,每个人都可以独立完成服务上线,做到了真正的业务运维。

资源独立

这一点很简单了,参考第一步,每个接入的部门只需要让运维做一次信息录入即可,部署的时候会自动选择对应的集群。

权限管控

使用RBAC模型,功能权限控制用户系统的权限,数据权限控制用户修改的权限,这里也不再过多赘述,非常容易。并且接入了钉钉api,定时同步人员组织架构,做权限的自动化下发。

三、核心概念

在开始接入和开发之前,有必要阐述一下各个核心概念,帮助大家更好的理解devops平台。

3.1 基础概念

k8s

一个由go写的分布式的容器编排系统,自带服务治理、故障转移、修复、配置存取、扩容等功能,我们所有的服务都是由k8s调度后进行安装到主机上的。

helm

k8s的包管理器,通过 Charts(预定义模板)简化应用部署和版本管理。利用helm,可以很轻松的完成部署和回滚的动作。

制品仓库

每个语言编译后的产物,都需要一个单独的地方来存储,比如maven、npm,

镜像仓库

容器镜像所存放的地方,提供镜像拉取和推送的功能。

网关

系统的流量入口,处理路由、负载均衡、鉴权等(如 Nginx、Kong、Spring Cloud Gateway、和各种云原生网关)。

配置中心

提供系统配置统一存储和下发的中间件,通常具备热更新、灰度、数据隔离和权限管控功能,在本平台中,内嵌了Apollo配置中心(下面会理解为什么是它)。

git仓库

一个分布式的代码版本管控系统,常用实现有github、gitlab、云效等。

3.2 平台概念

应用

一个应用对应一个git仓库,是平台所有运维工作的入口。

版本

版本可以对应为一个需求,比如开发接到一个xxx需求,对应的动作是在master上checkout出一个feature-xxx的开发分支,开发完需要上线,那么就需要新建一个版本,这个版本去关联这个PR,由cicd执行器在job中完成merge和发布,最终发布上线平台会自动merge gitlab代码和生成对应的镜像tag。

服务

可以简单的理解为是一个入口文件,比如main.go,通常一个服务下只有一个main文件,那就对应 一个服务。

环境

每个应用默认会有4个环境:dev 面向开发人员 stage: 预发环境 prod:线上环境。

集群

衔接服务的概念,可能在prod环境,同样的一套代码,需要提供给不同的用户人群、或者部署在不同的地域,如smb和ka客户、厦门和上海地域,那就需要引入集群的概念,每个服务在每个环境下系统都会自动化初始一个默认集群,注意此集群和k8s集群有些许不同。比如蝉鸣直播业务的线上发版,就利用了多集群的功能。

实例

部署的最小单元,应用+环境+集群+服务四者合一形成的,物理形态就是对应一个k8s的deployment,理解这一个概念对于参与开发贡献特别重要。

调度中心

平台是一个web系统,也是一个调度中心,负责应用数据串联和底层资源的访问入口,在cicd中它就相当于是一个调度中心,只做调度,不去完成实际的终端操作。

执行器

真正在cicd中发挥作用的是执行器,每个语言和不同的版本都是一套执行器,使用go语言编写,具备体积小、启动快、资源消耗低的特性,以k8s job的形式被创建出来。

可观测

服务的基建指标和应用指标、日志、链路等功能集成在arms上,平台开发者只需要开启参数开关,即可在cicd的时候自动注入对应语言探针而无需去过多人工处理,最终的看板仍在devops平台上。

灰度发布

介于黑与白之间的一种状态,用来形象的比喻软件需求迭代中的临时过渡阶段,比如某个需求在线上发布的时候,希望先给部分地区、特征的人群使用,其余用户仍然访问老版本,待验证通过才会正式上线,平台也做了友好的集成。

image.png

ai review

/Users/cds-dn-764/Desktop/aireview.jpeg

利用大模型的能力做代码质量审核和评分,平台内置的能力,只需要在新建应用的时候勾选上对应的开关,每一次代码PR变更,都会及时的推送到指定钉钉群里,同时会严格的根据评分结果卡ci流程(之前已分享过的能力,集成在平台内)。

ai ops

同样利用大模型的能力以chat的方式集成在平台上,将平台的知识库进行RAG、提供常用的业务运维tools,来辅助用户排查和执行一些日常的运维工作。

helm仓库

此helm仓库非彼helm仓库,对应的是一次成功的版本发布验收过后产生的一个平台仓库,记录了版本的完整生命周期,提供快速排查问题和回滚的功能。

三、架构设计

/Users/cds-dn-764/Desktop/devops技术架构.jpeg

四、代码贡献

欢迎所有对devops感兴趣的小伙伴参与提交代码贡献,本项目命名为odyssey,源自荷马史诗,象征着充满挑战与智慧的远征之旅。正如史诗中的英雄历经艰险终达目标,我们的DevOps平台旨在:

  1. 突破技术险阻 - 像奥德修斯穿越未知海域般突破传统研发效能瓶颈

  2. 连接研发孤岛 - 建立开发、测试、运维的「伊萨卡岛」式统一王国

  3. 智能导航系统 - 内置AI辅助决策,如同雅典娜女神指引正确航向

  4. 持续价值交付 - 让每次发布都成为值得传颂的技术史诗。

参与贡献的要求:

  1. 热爱– 这是做这件事的最大前提,技术不熟悉可以熟悉,不懂的理论可以去弥补,唯独热爱,才是充要条件。

  2. 问题反馈:通过gitlab issues形式在仓库中发言,提bug、需求,讲出你当前的痛点,期望平台有什么机制去承接,或者直接联系我,问题反馈也是参与项目贡献的重要步骤。

  3. 代码贡献: 前往源代码库,clone 下来,checkout你的feature分支,本地修改完,再提交一个新的MR,我会定时review和处理,每个feature请写清楚你的需求背景。


文章转载自:

http://qTPNhFXp.rbsmm.cn
http://yiKGOXnF.rbsmm.cn
http://kgQnJtOB.rbsmm.cn
http://BykbqdsT.rbsmm.cn
http://HYLHdknE.rbsmm.cn
http://5xucNqeH.rbsmm.cn
http://6UISCyKa.rbsmm.cn
http://vPtz06Hb.rbsmm.cn
http://uI7WPGUH.rbsmm.cn
http://VpO10iU9.rbsmm.cn
http://iYxC2PCo.rbsmm.cn
http://IVK7aG3L.rbsmm.cn
http://gwJJJ4GF.rbsmm.cn
http://wbzKdzFb.rbsmm.cn
http://AMA2PuwN.rbsmm.cn
http://nUwPhbgq.rbsmm.cn
http://mWNKxbiC.rbsmm.cn
http://wPQxrrCi.rbsmm.cn
http://HKOzaoLL.rbsmm.cn
http://axwa5Lc4.rbsmm.cn
http://E3QU9bZH.rbsmm.cn
http://ItHTbGG6.rbsmm.cn
http://yK1m20c9.rbsmm.cn
http://l6Wg2m97.rbsmm.cn
http://JQJ5PbpR.rbsmm.cn
http://fRKOVZ2L.rbsmm.cn
http://sCr2W27K.rbsmm.cn
http://hZKodsAt.rbsmm.cn
http://GLDqh40m.rbsmm.cn
http://pQBxmXQA.rbsmm.cn
http://www.dtcms.com/a/387777.html

相关文章:

  • 大数据七大业务架构横向比对分析
  • C#面试题及详细答案120道(21-30)-- 集合与泛型
  • 如何对AI代理的决策进行审计和监督?
  • .NET驾驭Word之力:玩转文本与格式
  • NLP中Subword算法:WordPiece、BPE、BBPE、SentencePiece详解以及代码实现
  • 解决Dify部署痛点:Docker镜像源优化配置指南
  • 达梦数据库模式
  • Pytorch笔记
  • SQL 数值函数速查:ROUND、CEIL、FLOOR、MOD 怎么用?
  • GPT-5-Codex 正式发布:迈向真正的“自主编程”时代
  • 直播美颜灯MCU控制方案开发设计分享
  • 数据结构(C语言篇):(十六)插入排序
  • 点亮第一个LED灯
  • Python环境》开发环境搭建
  • 【猛犸AI科技】无人机UAV边缘计算MEC实验
  • 【Datawhale25年9月组队学习:llm-preview+Task1:大模型介绍与环境配置】
  • 【MySQL】体系结构
  • Gated Attention 论文阅读
  • Git 命令行教程:配置 SSH 密钥高效克隆与管理项目
  • 机器学习和数据科学的开源 Python 库-Streamlit
  • Roo Code 的Enhance Prompt「增强提示」功能详解
  • 检测IP是否正常的方法
  • JMeter线程组
  • Flink基于Paimon的实时湖仓解决方案的演进
  • 29、生成模型入门-从数据重构到智能创造
  • Dokcer的安装(ubuntu-20.04.6):
  • 梳理Axios请求的过程和 Vite 代理配置
  • 元宇宙与电竞产业:沉浸式交互重构电竞全链条生态
  • 【pycharm】index-tts2:之二 :ubuntu24.04重建UV虚拟环境
  • 点评项目(Redis中间件)数据操作相关知识总结