基于 Kubernetes 的基础设施即代码

11 月 9、10 号两天,.NET 社区第一次以“.NET 大会”为品牌在上海召开了第一届峰会,现场与会者达到 600 人规模。大会的第 1 天是各类演讲分享,第 2 天有多个动手实践课。张善友队长、 刘腾飞 和我一起策划了基于 Kubernetes 的 .NET Core 微服务和 CI/CD 动手实践工作坊,一共有现场 30 多位,外加线上 200 多位人士参与了这个工作坊。

在基于 Kubernetes 的 .NET Core 微服务和 CI/CD 动手实践工作坊中,我们使用一系列脚本,尽可能地对所有环境的安装和配置工作进行了自动化。工作坊中的每一个与会者都只要按照说明,执行几个脚本,就可以自动地准备好自己的一整套 CI/CD 和微服务部署基础设施,

“基础设施即代码”指的是,使用代码描述所有基础设施的安装和配置过程,包括这些基础设施软件的各项设置和日常使用数据,都要使用代码进行描述。从而享受基于代码的版本管理和自动化执行等能力。这一概念强调,不仅软件本身的生产(持续集成即代码)和部署过程(持续部署即代码)可由代码来描述,用于托管并运行软件的基础设施(即服务器环境本身)的创建和配置过程也要能以代码的方式描述并维护。

概要介绍

在工作坊中,现场参与的每个人,都基于提前准备好的 Kubernetes 集群搭建了可供开发用的 Git 服务器和 CI/CD 工具体系,并成功部署了微服务。工作坊还带着与会者体验了将 .NET Core 应用从 IDE 代码开发、把代码提交到 Git 服务器,经过 CI/CD 自动编译、发布容器镜像,并最终自动部署到 Kubernetes 平台的完整过程。

支持这一过程的基础设施的整体示意图为:

具体实现代码、脚本和配置,都在这个 GitHub 仓库:https://github.com/netconf-cn2019-workshop/dev-services/ 其中各个微服务,请回到上一级别,自行下载。

整个代码库的结构如下:

 123456789
10
11
12
13
14
15
16
17
.
├── cicd-infra                 # 存放 CI/CD 软件部署代码的目录
│   ├── cicd-installer.yaml    # 用于 CI/CD 软件的初始化配置
│   ├── gogs.yaml              # 安装 Gogs 的 Kubernetes 配置
│   ├── jenkins.yaml           # 安装 Jenkins 的 Kubernetes 配置
│   ├── nexus.yaml             # 安装 Nexus 的 Kubernetes 配置
│   ├── sonarqube.yaml         # 安装 Sonarqube 的 Kubernetes 配置
│   └── vars                   # 定义安装 CI/CD 软件过程中的变量
├── provision-cicd.sh          # 启动安装 CI/CD 软件的脚本文件
├── provision-infra.sh         # 启动安装微服务公用基础设施的脚本文件
├── provision-services.sh      # 启动安装微服务的脚本文件
├── service-infra              # 存放微服务公用基础设施部署代码的目录
│   └── infra.yaml             # 用于安装微服务公用基础设施的 Kubernetes 配置
├── services                   # 存放微服务部署代码的目录
│   ├── service-list           # 定义部署的微服务及其镜像版本的变量
│   └── vars                   # 定义安装微服务过程中使用的变量
└── tmpl.sh                    # 读入变量值并将其应用到使用变量的文件

本文,我们概要地探讨这整个过程的原理和大致步骤。还有两篇文章分别介绍 CI/CD 部分及微服务部署部分的实现原理。

CI/CD 软件

一般来说,一个典型的团队 CI/CD 基础设施包含下列内容:

  • 代码服务器,用于存储各个产品的源代码,以及日常工作中使用的各类脚本和配置。

  • 持续集成软件,用于自动地对产品源代码进行一系列自动化处理,比如安装依赖、编译、单元测试、格式检查等,并最终产生可以直接运行的二进制格式软件。

  • 制成品产物(发布物)存储软件,用于存储最终生成的二进制格式软件。

  • 容器注册表,用于存储软件的容器镜像(包含二进制格式软件、软件依赖的操作系统和第三方软件与配置等内容)的存储软件。

基本上,社区中关于这些软件的选用已经有了一些“偏好” 。基于社区的偏好,我们在工作坊中做了这样一些选择:

软件选择
代码服务器国人开发的优秀 Git 服务器软件 Gogs
持续集成软件广为使用的 Jenkins
发布物存储软件广为使用的 Nexus
容器注册表Coding 制品库容器镜像服务

由于要在 Kubernetes 集群中安装,所以上述这些软件,我们都需要使用它们的容器版本。容器注册表的安装和配置比较麻烦,为了简化工作坊现场的流程,所以我们选用现成的外部容器注册表服务。

CI/CD 软件的安装过程在脚本文件 provision-cicd.sh 中,这是一个 Bash 脚本文件。这个脚本文件既可用于 CI/CD 软件的部署(deploy),也可以用于整个工作坊环境的清理(delete)。当以部署模式(deploy)运行时,脚本会首先在 Kubernetes 集群上创建多个命名空间(namespace),并在 cicd 命名空间中依次启动安装 Jenkins、Nexus、Gogs 和 Sonarqube 等软件,最后会在 cicd 命名空间中启动一个初始化脚本(cicd-installer)。cicd-installer 初始化脚本将负责等待软件完成安装,并向它们导入必要的初始化数据。

在安装过程中,会用到一些“变量”,比如表示当前用户的 deploy_suffix 等。在我们为各个软件编写的 Kubernetes 安装文件(.yaml)中的相应位置上均引用了变量。而在 provision-cicd.sh 脚本文件中,在执行 kubectl apply 之前,它借助 tmpl.sh 脚本文件完成变量的填充,变量的值声明在 cicd-infra/vars 文件中。这也要求,在部署之前,工作坊的参与者需要提前编辑这个变量文件,确保其中的各个值都是正确的。

微服务的部署

微服务的部署分成了两部分:微服务公用基础设施和各个微服务本身。之所以要分成两个部分,是因为对于特定的部署环境(如 dev)来说,公用基础设施只需要部署一次;而各个微服务则有可能随着代码的持续更新而需要经常部署。

微服务公用基础设施

工作坊的微服务依赖一些公用的基础软件,比如 Redis 缓存服务和 SqlServer 数据库服务。

这些基础设施的安装过程在脚本文件 provision-infra.sh 中,这也是一个 Bash 脚本文件。它的原理很简单,而且微服务基础设施的安装过程没有变量。所以,它直接在在相应部署环境对应的命令空间(如 dev)执行 kubectl apply ./service-infra/infra.yaml 就完成了安装。安装动作之后,脚本会等待安装完成,确保数据库处于运行状态之后,再执行数据库表结构的初始化操作,并向其中导入种子数据。

微服务的部署

各个微服务的部署本来应该是相当直观的,不过由于涉及到微服务的容器版本,所以实际过程却要稍微麻烦一点。

微服务的部署脚本文件是 provision-services.sh 中,这又是一个 Bash 脚本文件。脚本会从 services/service-list 文件中读入要部署的微服务的信息(容器镜像名称及标签),并逐个调用对应微服务所在项目目录中的 k8s.yaml 文件来执行部署。在部署过程中,也会涉及前面讲过的类似的变量处理过程,即读入 services/vars 文件,用于为微服务部署过程提供变量值。所以,同样,工作坊的参与者需要提前编辑这个变量文件,确保其中的各个值都是正确的。

由于将待部署的微服务列表使用单独的配置文件 services/service-list,因此不管是手工执行脚本部署,或是工作坊中练习的使用 CI 进行自动化部署,都可以通过编辑这个文件来指定要部署的微服务列表和版本。

环境初始化

在工作坊中,我们实现了一种“预配置”的效果。也就是,当工作坊与会者打开刚刚安装完成的 Jenkins 之后,会发现微服务的流水线已经创建完成了;当他们打开 Gogs 时,会发现上面已经预置了各个微服务的代码仓库。实际上,诸如此类的始化工作还有很多。而且,最重要的是,这些初始化工作也是由代码来描述的。

在工作坊的准备过程中,为了实现自动完成这些初始配置工作,我们结合使用了多种技术。这里先简单列举其中用到的几种技术,后面另外会写文章重点解读特定环节的实现原理:

  1. Jenkins 的预置流水线是用 Jenkins 写入配置文件实现的

  2. Gogs 的预置代码仓库是用 Gogs 的 RESTful API 导入的

  3. Nexus 修改内置密码是用基于 RESTful API 的脚本接口完成的

  4. SqlServer 的表结构是通过直接在 Pod 上执行指定的命令行程序实现的

通过结合使用这些技术,我们不光用 yaml 文件描述了这些软件的安装过程,还能够以代码的方式描述在这些软件上需要完成的配置。

总结

整个工作坊的基础环境就是由这几个部分构成的,各个部分都是使用代码来描述的。这里所讲的代码包含各种类型的代码,有供 Kubernetes 集群用的 yaml 文件,有 Bash 脚本文件,还有变量文件等。这些代码文件都有两个特点:

  1. 都是文本文件,可以由源代码版本管理工具管理

  2. 都以某种形式参与到自动化的执行过程中

符合这两个特点,最终部署出一个“基于 Kubernetes 的基础设施环境”,也就实现了基于 Kubernetes 的基础设施即代码。

事实证明,这个实践为可靠地重复创建工作坊环境提供了充分的保障,为工作坊的顺利举办和后期持续优化建立了不错的基础。

原文地址:https://blog.jijiechen.com/post/infrastructure-as-code-on-kubernetes/



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

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

相关文章

最小生成树Prim和Kruskal算法

两种算法都是基于贪心的方法。 Prim算法: 适用于稠密图。时间复杂度为O(V^2)。(V为顶点数) 与Dijkstra算法相似,每次选择离离原点最近的点,加入到现有的生成树中。 Kruskal算法: 适用于稀疏图。时间复杂度为O(E*logE)…

Steeltoe 2.4新增代码生成工具、全新入门指南等,助力.NET微服务开发

Steeltoe框架现可帮助.NET开发人员创建云原生应用。随着其功能的扩充,该框架越来越受欢迎,下载量达到580万(并且仍在增加),这其中大部分的功能创新都源自于用户反馈、社区贡献和.NET运行环境各方面的改进。但这些还不够…

AcWing 自动补全 二分

题目链接 先上AC代码。 参开代码&#xff1a; #include<bits/stdc.h> #include<unordered_map> using namespace std; #define INF 0x3f3f3f3f typedef long long ll;string s[100005]; unordered_map<string, int> m; bool check(string a, string b) {if…

2019 年终回顾:不忘初心,负重前行

点击上方蓝字关注“汪宇杰博客”导语2019 年就要接近尾声&#xff0c;这一年对于我来说&#xff0c;有许多有意义的事件。我成长了许多&#xff0c;并依然保持着对技术的热情。在辞旧迎新之际&#xff0c;我想回顾一下我这一年中有意义的事件与收获&#xff0c;期待与大家一起在…

机试真题1 反序输出 cin判断读取结束

题目链接 解题思路 这题是纯纯的送分题&#xff0c;但我忘记了怎么判断读取结束。应该用&#xff1a; while (cin >> s){}在Windows中&#xff0c;CtrlZ输出输入结束符号。 参考代码 #include<bits/stdc.h> using namespace std;void print(string s) {int len…

【C#】设计模式的学习征途系列文章目录(2019版)

Photo &#xff1a;Design Patterns文 | Edison Zhou2017年&#xff0c;我开始系统学习设计模式&#xff0c;参考了《大话设计模式》、《设计模式的艺术》等书籍&#xff0c;并通过C#语言写了各种模式的代码示例&#xff08;已经放到了我的github上并收获了120个star&#xff0…

机试真题2 进制转换 高精度除法

题目链接 解题思路 这题需要通过高精度加除法来解决。原本以为高校机试题最多考到高精度的加减法&#xff0c;没想到还会考高精度和低精度的乘除法&#xff0c;不亏是你清的题。 需要注意的是&#xff0c;一开始存储需要是逆序存储&#xff0c;方便后面的操作&#xff0c;同时…

原创 | 为什么年终奖是一个彻头彻尾的职场圈套?

0前言之前写过几篇职场专题的文章&#xff0c;反响不错&#xff0c;也先后被不少公众号转载过&#xff0c;这几天来了不少新朋友&#xff0c;如果之前没阅读过&#xff0c;可以在后台回复“职场”2个字&#xff0c;查看系列文章。转眼又到年底了&#xff0c;不知道有多少人在心…

机试真题3 进制转换2 高精度除法

题目链接 解题思路 这题还是通过高精度的除法来做&#xff0c;思路与上一篇文章类似&#xff0c;区别就是输入输出的进制位数不是固定的。对于输入的进制m&#xff0c;在divide函数中更新余数的时候乘以的数字改成m&#xff1b;对于输出的进制n&#xff0c;在divide函数中取余…

Blazor 机制初探以及什么是前后端分离,还不赶紧上车?

上一篇文章发了一个 BlazAdmin 的尝鲜版基于 Blazui 的 Blazor 后台管理模板 BlazAdmin 正式尝鲜&#xff0c;这一次主要聊聊 Blazor 是如何做到用 C# 来写前端的&#xff0c;传送门&#xff1a;https://www.cnblogs.com/wzxinchen/p/12057171.html飚车前需要说明的一点是&…

机试真题4 成绩排序

题目链接 解题思路 题目非常简单&#xff0c;就是需要注意一下直接用sort方法做的话&#xff0c;会导致同分时输出的人名顺序与输入时不一致&#xff0c;这是因为sort函数是不稳定的算法&#xff08;sort排序为了提升性能&#xff0c;会根据不同的情况选用不同的排序算法&…

云原生

一、云原生概念的诞生云原生&#xff08;Cloud Native&#xff09;的概念&#xff0c;由来自Pivotal的MattStine于2013年首次提出&#xff0c;被一直延续使用至今。这个概念是Matt Stine根据其多年的架构和咨询经验总结出来的一个思想集合&#xff0c;并得到了社区的不断完善&a…

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

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

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…

数据结构作业1

1.给定NNN的三维数组A&#xff0c;则在不改变数组的前提下&#xff0c;查找最小元素的时间复杂度是&#xff1a;D A.O(N​2​​) B.O(NlogN) C.O(N​3​​logN) D.O(N​3​​) 2.For the following piece of code for(i0; i<n; i)for(ji; j>0; j/2)printf(“%d\n”, j);…

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

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

7-5 两个有序链表序列的合并 (20 分)

已知两个非降序链表序列S1与S2&#xff0c;设计函数构造出S1与S2合并后的新的非降序链表S3。 输入格式: 输入分两行&#xff0c;分别在每行给出由若干个正整数构成的非降序序列&#xff0c;用−1表示序列的结尾&#xff08;−1不属于这个序列&#xff09;。数字用空格间隔。 …