基于 Kubernetes 的 CICD 基础设施即代码

在上一篇基于 Kubernetes 的基础设施即代码一文中,我概要地介绍了基于 Kubernetes 的 .NET Core 微服务和 CI/CD 动手实践工作坊 使用的基础设施是如何使用代码描述的,以及它的自动化执行过程。

如果要查看基于 Kubernetes 的基础设施即代码架构全图,以及实现代码,请回到文章基于 Kubernetes 的基础设施即代码。

本文,我们深入探讨其中 CI/CD 软件部分的“基础设施即代码”的实现原理。

变量模板引擎

在工作坊中,由于所有与会者使用的都是同一个 Kubernetes 集群,因此我们需要一种方法来标识当前用户。Kubernetes 的命名空间提供的逻辑隔离功能可以很轻松地实现这个效果。因此,我们要为每个工作坊与会者创建他的一批命名空间:

  • cicd-<suffix> 用于部署 CI/CD 软件

  • dev-<suffix> 作为“开发环境”,部署微服务

  • stage-<suffix> 作为“预生产环境”,部署微服务

显然,对于每一个与会者来说,这里的 suffix 会有所不同,因此它是一个变量。除了在启动安装 CI/CD 软件时需要使用,这个变量还需要以某种形式保存到 Jenkins 上,因为当 Jenkins 运行部署任务时,它也需要知道目标命名空间的名字。

为了处理变量,我们自己发明了一个小型的“模板引擎”。其作用是,使用变量文件中指定的值,替换各个文件中的变量,输出最终的内容。这个模板引擎以双美元符号 $$ 作为变量起始字符。打开 cicd-infra/jenkins.yaml 并搜索 $$ 就可以发现其中大量地引用了各个变量。

模板引擎的实现位于 ./tmpl.sh 脚本文件,它能从指定的变量文件和环境变量读入各个变量的值,并将待处理文件中的变量占位符替换为对应的值,最后向标准输出(stdout)打印最终的文件内容。借助流水线指令 |,这些内容随后被 kubectl apply -f - 命令读取,用于安装配置对应的 Kubernetes 资源。

在 kubelet 1.14 及以上的版本中,新增加了 kustomize 子命令。它提供更多编写模板化、嵌套式 Yaml 文件的方法。在工作坊中,我们需要兼容支持低一些版本的 kubelet,就不得不借助这样的模板引擎。

自动化安装 Jenkins

打开 cicd-infra/jenkins.yaml 会发现接近 600 行,可以说不短了。其中包含如下几个关键的 Kubernetes 资源:

  • ServiceAccount jenkins 是 Jenkins 本身,以及 Jenkins 用于生成容器镜像并部署微服务时所用的 Pod 要使用的集群账号

  • RoleBinding jenkins_edit 为上述集群账号赋予相应权限

  • Service jenkins-jnlp 供 Jenkins 构建运行器(Slave)启动期间连接 Jenkins 主机(Master)时用的集群 Service

  • Service jenkins 是供 Ingress 用于把 Jenkins Web 界面暴露给用户用的集群 Service

  • Ingress jenkins-ingress 是负责把用户请求转发到集群 Service 的流量入口处理规则

  • ConfigMap jenkins-jobs 可挂载为 Jenkins 内置任务的配置

  • ConfigMap jenkins 一系列用于初始化 Jenkins 的配置

  • Deployment jenkins 用于部署 Jenkins Web 服务

这里需要重点介绍的是 configmap/jenkins,以及 deployment/jenkins。后者挂载前者,以文件的方式读入内容并完成 Jenkins 的初始化配置工作。具体来说,deployment/jenkins 声明了两个容器,在这两个容器上共享多个存储卷,以实现共享文件的目的:

  1. 在 Jenkins 启动之前运行的初始化容器 installer,它按照 plugins.txt 先将插件安装到磁盘上,并为工作坊的所有微服务创建内置 Jenkins 任务

  2. 在 installer 运行完成之后才启动的容器 jenkins,它就是 Jenkins Web 服务本身所在的容器

从 deployment/jenkins 的 yaml 配置中,我们不难发现,installer 运行的具体过程位于脚本文件 /var/jenkins_config/apply_config.sh 中,它的内容是从 configmap/jenkins 挂载而来的。这个脚本中还将用到很多其他文件,比如安装插件用的 plugins.txt,它们都是从这个 configmap/jenkins 挂载而来。为了加速 Jenkins 插件的安装过程,我们在 installer 容器里使用 JENKINS_UCJENKINS_UC_DOWNLOAD 这两个环境变量来让它从国内的服务器源下载插件。

configmap/jenkins/plugins.txt 定义了工作坊中我们需要用到的插件列表:

  • git

  • dashboard-view

  • pipeline-stage-view

  • workflow-aggregator

  • kubernetes:1.20.0

其中的 kubernetes 插件让我们的 Jenkins 可以与它所在的 Kubernetes 集群集成,从而实现几乎能把任何容器镜像作为构建运行器(Slave)节点来使用,并且这些节点将以独立的 Pod 的方式“按需”在 Kubernetes 集群中运行,并自动连接到 Jenkins。这大大简化了 Jenkins 的运行器节点的维护工作。如果进一步研读 configmap/jenkins/config.xml 配置内容可以发现,我们的 Jenkins 将内置支持 dotnet 和 image-builder 两种 Slave 节点。

阅读 configmap/jenkins/apply_config.sh 可以看到,它使用了 Jenkins 支持的多种自动化配置功能:

  • 运行 /usr/local/bin/install-plugins.sh 脚本文件可以预先安装指定的插件

  • 在 /var/jenkins_home/init.groovy.d 目录中创建的 groovy 脚本将在 Jenkins 启动后自动运行,我们这里用来向 Jenkins 中植入容器镜像注册表的登录信息

  • 通过预先定义 /var/jenkins_home/config.xml 及其他 xml 文件可以定制 Jenkins 的各类全局系统设置

  • /var/jenkins_jobs 目录下的子目录将自动被视为内置任务自动被 Jenkins 加载

上面第一种自动化功能,是内置在 Jenkins 安装包中的一个实用工具,它的源代码位于 GitHub 上。第二种自动化功能是 Jenkins 的初始化脚本,它支持以 Groovy 语言为 Jenkins 开发自动运行的脚本钩子。后面两种自动化功能则是根据 Jenkins 的配置存储机制而预先写入配置来达到内置配置和任务的目的。

deployment/jenkins 还让这两个容器共享 jenkins-home 和 plugin-dir 这两个存储卷,这样就可以让 jenkins 容器从 installer 容器继承已经初始化完成的 Jenkins 配置和插件。这样就确保 Jenkins 主容器运行起来时,就已经具备了已经下载好的插件,以及正确的全局配置。

自动化安装 Gogs 和 Nexus

比起 Jenkins 自动化的过程,Gogs 和 Nexus 的自动化安装就简单得多了。虽然 Gogs 需要 Postgre 数据库的支持,我们在工作坊环境中,还是为数据库配置了 emptyDir 类型的临时存储。因此并不提供持久化存储的支持。给 Nexus 提供的存储也一样用的是 emptyDir 临时存储。

值得一提的是这两个软件启动后的初始化操作。在工作坊的自动化脚本中,分别对这两个软件执行了如下自动化初始化:

  • 在 Gogs 中自动创建账号,从 GitHub 导入各个微服务的源代码库,并配置 WebHook

  • 修改 Nexus 的默认登录信息为 admin/admin

这些过程,都是借助独立的集群任务 cicd-installer 完成的。在该任务中,它首先读入当前 Kubernetes 环境给定的 Service Account 凭据,配置好 kubectl 命令行工具。接着执行以下工作:

  1. 等待 gogs-postgresql 和 gogs 部署完成,调用 Gogs 的 RESTful API 接口,完成用户注册和代码库导入工作

  2. 等待 nexus 部署完成,调用 Nexus 的 Scripting API(脚本编程)接口,完成管理员密码的修改

不难发现,虽然都是自动化配置,却使用了不同的技术。比起 RESTful API 接口,Nexus 的脚本编程接口由于是直接注入脚本,似乎功能会更灵活和强大。不过,过于强大的功能也通常会带来额外的安全风险。

总结

简单总结一下,在上面的讲解中,用到过的自动化技术有:

  1. 基于 Deployment 实现容器应用自动化部署(自动化部署 Jenkins、Gogs、Nexus 和 Sonarqube 等软件)

  2. 借助 Pod 的初始化容器(initContainer)实现提前运行自动化任务(在 Jenkins 主容器启动之前,在 initContainer 中安装插件)

  3. 借助 Pod 多容器共享存储卷来跨容器共享文件(在 initContainer 中安装插件后,由 Jenkins 主容器直接使用)

  4. 借助 Pod 环境变量向应用注入预置的配置(为 Jenkins 指定插件下载源)

  5. 借助 ConfigMap 向应用中直接挂载预置的配置文件(为 Jenkins 预设配置)

  6. 借助 Pod 就绪探针和存活探针,配合 kubectl rollout status 跟踪检测应用部署状态(等待 Gogs、Nexus 部署完成)

  7. 借助 Job 执行一次性任务(cicd-installer)

  8. 使用 Dockerfile 构建容器镜像(Jenkins 上的自定义 Slave 节点)

  9. 调用应用准备好的脚本自动完成配置(使用 Jenkins 提供的 install-plubins.sh 安装插件)

  10. 调用应用的 RESTful API 接口导入数据(为 Gogs 注册用户并自动导入代码库)

  11. 调用应用的 Script API 编程接口自动配置(向 Jenkins 和 Nexus 设置登录凭据)

  12. 使用模板引擎替换变量引用

到目前,我们详细地解读了如何有机地结合使用各种自动化技术,让工作坊的各个 CI/CD 软件在 Kubernetes 上完成启动之后,自动地完成各项自动化配置。由于 Kubernetes 部署 Yaml 文件以及各类自动化配置脚本都是文本文件,因此我们上一篇文章基于 Kubernetes 的基础设施即代码中关于“基础设施即代码”的两个要求仍然成立。

最后,工作坊的自动化脚本还没有提供存储支持,在实际的项目中应该会有对应的需求;基本上,只要在你的 Kubernetes 集群中配置好集群的存储类和自动存储供给支持,要支持存储并不困难。

相关文章:

  • 基于 Kubernetes 的基础设施即代码

  • (译)An introduction to Kubernetes

  • 程序员修神之路--kubernetes是微服务发展的必然产物

  • 深入探究Kubernetes - 初识容器

  • 使用Helm将ASP.NET Core应用程序部署到Kubernetes容器集群

  • Kubernetes攻略之新手上路

  • Hello Kubernetes快速交互实验手册

  • 十分钟了解Kubernetes

原文链接:https://blog.jijiechen.com/post/cicd-infra-as-code-on-kubernetes/


.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/312559.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Azure Arc:微软是怎么玩多云游戏的?

混合云在竞争性云提供商的基础上提供了来自云提供商的服务&#xff0c;从而使组织能够以不同方式一起使用来自不同供应商的云服务。例如&#xff0c;组织可以使用将数据存储在一个云中存储上的功能&#xff0c;而另一个云服务商则在该应用程序或数据之上运行。因此&#xff0c;…

当我们在谈 .NET Core 跨平台时,我们在谈些什么?--学习笔记

摘要.NET Framework在过去十多年在跨平台上的尝试。.NET Core跨平台的实现有何不同&#xff1f;基于 .NET Standard的平台兼容性是如何实现的&#xff1f;讲师介绍历史枷锁.NET Framework FCL CLR"跨平台"的 .NET Framework完全独立&#xff0c;各自为政复用之殇由…

IdentityServer4学习笔记汇总(实现传送门在底部)

前言互联网时代,对信息和资源的保护越发苛刻,在所有应用中授权和认证是必不可少缺少的一部分。如果一个应用没有授权和认证那么这个应用就是不完整或者说不安全的应用。在.Net平台给我们提供了一套完整的授权认证框架,那就是IdentityServer4。它实现了OpenId Connect和OAuth2.0…

多库操作2:终于实现多个数据库操作

▼更多精彩推荐&#xff0c;上午10点到达▼圣诞节快乐在上周的文章【多库操作&#xff1a;多个数据库的动态切换&#xff08;一&#xff09;】中&#xff0c;我们简单说了说&#xff0c;如何切换数据库&#xff0c;虽然实现了大部分的功能&#xff0c;但是最后也遗留了小问题&a…

服务发现技术是如何演进出来的?

昨天写了一篇<微服务的时间和成本去哪儿了>&#xff0c;有人在底下留言&#xff1a;我的回答是&#xff1a;"微服务可以不用服务发现和负载均衡吗&#xff1f;它是微服务一个核心组件。怎么能说没有关系&#xff1f;"我觉得有必要来思考和总结一下服务发现技术…

3分钟搞懂前后端开发的区别

上周末见了好多开发的年轻朋友&#xff0c;问了我一个问题&#xff1a;“前后端的区别和要求是什么&#xff1f;”分不清前后端开发的区别和要求&#xff0c;一种是因为前后端都了解&#xff0c;号称“全栈工程师”&#xff0c;但又什么都不是很精通&#xff1b;另一种是前端的…

基于 Kubernetes 的微服务部署即代码

在基于 Kubernetes 的基础设施即代码一文中&#xff0c;我概要地介绍了基于 Kubernetes 的 .NET Core 微服务和 CI/CD 动手实践工作坊使用的基础设施是如何使用代码描述的&#xff0c;以及它的自动化执行过程。如果要查看基于 Kubernetes 的基础设施即代码架构全图&#xff0c;…

使用Arduino开发ESP32开发环境搭建

1.打开Arduino IDE&#xff0c;选择文件->首选项->设置 复制下方的ESP32板管理网址&#xff0c;添加到附加开发板管理器中&#xff1a; https://dl.espressif.com/dl/package_esp32_index.json 2.选择&#xff1a;工具->开发板->开发板管理器 在弹出的对话框中搜索…

.NET ORM FreeSql 第一个正式版本发布 v1.0.0

一、简介FreeSql 是 .NET 平台下的对象关系映射技术(O/RM)&#xff0c;支持 .NetCore 2.1 或 .NetFramework 4.0 或 Xamarin。从 0.0.1 发布到今历时整整一年的迭代更新&#xff0c;现在终于敢发布第一个正式版。本文内容从简&#xff0c;介绍项目的主要功能框架&#xff0c;以…

Windows上搭建EMQTT服务器

1.官网下载EMQ 2.复制如图文件路径 3.打开终端cmd&#xff0c;输入&#xff1a; 再输入&#xff1a; 4.打开浏览器&#xff0c;进入&#xff1a;http://192.168.1.25:18083/* (localhost可打开终端输入ipconfig查看) 用户名&#xff1a;admin 密码&#xff1a;public

.NET解所有相机RAW格式照片

再聊.NET解相机RAW格式照片上次我发了一篇文章《用.NET解索尼相机ARW格式照片》&#xff0c;提到通过安装 SonyRawFileDecoder的方式&#xff0c;然后调用 WindowsImagingComponents来解析 RAW格式文件。后来我经过进一步研究、探索&#xff0c;发现还有更简单的办法。新的方法…

AspNetCore结合Redis实践消息队列

这是年中首发在博客园上的文章&#xff0c;个人觉得是AspNetCore结合Redis做的一次比较优秀的消息队列重构&#xff0c;其中对于点对点/发布-订阅的思路应该也是面试必考题。引言.Net TPL Dataflow是一个进程内数据流管道&#xff0c;应对高并发、低延迟的要求非常有效&#xf…

提升Azure App Service的几个建议

本文介绍了6个技巧&#xff0c;这些技巧可以改善Azure App Service托管应用程序的性能。其中一些技巧是你现在就可以进行的配置变更&#xff0c;而其他技巧则可能需要对应用程序进行一些重新设计和重构&#xff0c; 本文的几个技巧对于常规企业部署依旧有指引作用。长话短说开发…

单向链表的逆转(数据结构)(c语言)

逆转单向链表的意思是&#xff1a;给定你一个单向链表&#xff0c;一个整数n&#xff08;n为要逆转的结点数&#xff09;&#xff0c;要求你把链表从头结点到第n个结点给逆转过来 图示&#xff1a; 给出一个单向链表&#xff0c;一个整数n4。也就是要求把该链表从头结点&#x…

广东职业教育信息化研究会2019年会暨区块链专题研讨会

兹定于2019年12月28日&#xff08;星期六&#xff09;上午9:30召开广东职业教育信息化研究会2019年会暨专题研讨会&#xff0c;本次会议由广东职业教育信息化研究会主办&#xff0c;华南师范大学网络教育学院协办。会议地址&#xff1a;广州市天河区中山大道西55号华南师范大学…

如何快速融入一个团队?

作者&#xff1a;邹溪源&#xff0c;长沙资深互联网从业者&#xff0c;架构师社区特邀嘉宾&#xff01;一我们难免需要离开一个圈子&#xff0c;加入一个陌生的集体。毋庸置疑&#xff0c;离开熟知的圈子&#xff0c;走向未知的圈子难免会产生许多畏惧甚至情怯&#xff0c;这都…

关于C#异步编程你应该了解的几点建议

前段时间写了一篇关于C#异步编程入门的文章&#xff0c;你可以点击《C#异步编程入门看这篇就够了》查看。这篇文章我们来讨论下关于C#异步编程几个不成文的建议&#xff0c;希望对你写出高性能的异步编程代码有所帮助。注&#xff1a;本文的很多内容都是学习《Effective C#》的…

数据库分区

一、分区原理分区并不是生成新的数据表&#xff0c;而是将表的数据均衡分摊到不同的硬盘&#xff0c;系统或是不同服务器存储介子中&#xff0c;实际上还是一张表。要实现这一功能&#xff0c;首先要了解数据库对水平分区表进行分区存储的原理。数据库分区和分表相似&#xff0…

如何在 C# 平台调用云开发?

▌关于作者苏震巍&#xff0c;云开发Linker计划成员&#xff0c;《微信开发深度解析》作者、Senparc.Weixin 微信 SDK 作者、微软最有价值专家&#xff08;MVP&#xff09;、盛派网络创始人兼首席架构师、微软 Ignite 技术大会讲师、从事软件及互联网研发已有26年&#xff0c;发…

如何打造组织级敏捷,你想知道的都在这里!

“敏捷是适应和响应变化的能力……敏捷组织将变化视为机遇&#xff0c;而不是威胁。” — Jim Highsmith注&#xff1a;Highsmith 在软件开发和 IT 行业有着超过 30 年的经验&#xff0c;曾是敏捷宣言的签署人之一&#xff0c;敏捷联盟的发起人和第一任理事&#xff0c;在很多行…