建地方的网站前景,php网站开发软件编程,12306网站开发语言,wordpress高仿都市头条主题大家好,我是来自阿里云容器服务团队的华相。首先简单解释一下何为 Kubernetes 来帮助大家理解。Kuberentes 是一个生产可用的容器编排系统。Kuberentes 一方面在集群中把所有 Node 资源做一个资源池#xff0c;然后它调度的单元是 Pod#xff0c;当然 Pod 里面可以有多个容器…
大家好,我是来自阿里云容器服务团队的华相。首先简单解释一下何为 Kubernetes 来帮助大家理解。Kuberentes 是一个生产可用的容器编排系统。Kuberentes 一方面在集群中把所有 Node 资源做一个资源池然后它调度的单元是 Pod当然 Pod 里面可以有多个容器。 就像一个人左手抓着 ECS 资源或计算资源右手抓容器然后把它们两个匹配起来这样它就可以作为一个容器的编排系统。 而 Cloudnative 这个概念现在会经常被大家提起很多人迷惑 Cloudnative 又与 Kuberentes 有什么关联我们又该如何判断一个应用是 Cloudnative 呢我认为有以下三个判断标准 第一它能够给资源做池化 第二应用可以快速接入池的网络。在 Kuberentes 里面有一层自己的独立网络然后只需要知道我要去访问哪个服务名就可以就是各种服务发现的一些功能它可以通过 service mesh 去做一个快速地访问 第三是有故障转移功能如果一个池子里面有一台主机或者某一个节点 down 掉了然后整个应用就不可用了这肯定不算是 Cloudnative 的应用。 比较这三点就可以发现 Kuberentes 做的非常好。首先我们看一个资源池的概念Kuberentes 一个大的集群就是一个资源池我们再也不用去关心说我这个应用要跑在哪台主机上了我只要把我们部署的 yaml 文件往 Kuberentes 上发布就可以了它会自动做这些调度并且它可以快速地接入我们整个应用的网络然后故障转移也是自动。接下来我就来分享如何基于 Kuberentes 实现一个弹性的 CI/CD 系统。
CI/CD 的现状
首先了解一下 CI/CD 的现状。CI/CD 这个概念实际上已经提出很多年了但是随着技术地演进和新工具地不断推出它在整个流程和实现方式上逐渐丰富。而我们通常最早接触 CI/CD 就是代码提交随之触发一个事件然后在某个 CI/CD 系统上做自动构建。
下图可以反映目前 CI/CD 的现状 另外还有 Gitlab CI它主要特点是与 Gitlab 代码管理工具结合地比较好。Jenkins 2.0 开始引入 pipeline as code 特性pipeline as code 可以帮我们自动生成一个 jenkins file。 在 Jenkins 1.0 时如果我们想要配置一条流水线需要先登录 Jenkins 建一个项目然后在里面写一些 shell。这样虽然能达到同样的效果但是它有一个最大的弊端就是可复制性和迁移性不好。而且它与 Devops 有天然地割裂比如一般是由运维人员来管理 Jenkins 系统开发人员编写代码但是这个代码怎么去构建发布到哪里开发人员完全不知道。这就造成了开发和运维地割裂。但 pipeline as code 方式出现了之后jenkins file 与代码源码可以放在同样的仓库里面。 首先它有一个非常大的好处是发布的流程也可以纳入版本管理这样对一个错误就可追溯。这是一个非常大地改动但是实际上我们在与客户沟通中发现虽然很多人在 Jenkins 上都已经升到 2.0 系列了但是它们的用法还是完全在 1.0 系列很多用户都没有把 jenkins file 这种方式用起来。另外一个就是对容器地支持大概 2016 年左右那时对容器的支持是非常弱的在容器里面运行 Jenkins同时构建的产物也是 Docker 会非常麻烦。 但是 Drone 对容器的支持力度就非常好。首先它完全用 Docker 方式来运行就是说你的构建环境也在一个容器里你需要构建一个 Docker build 镜像然后在推送出去的时候它也在容器里面运行然后它需要一个 privilege 权限。它这种方式有几个特别好的地方首先它不会对宿主机产生任何残留比如说你这个容器一销毁构建中产生的一些中间文件完全都跟着销毁了但是你如果用 Jenkins 的话随着用的时间越来越久会沉淀出很多临时文件它占的空间会越来越大。你需要定期做一些清理而且清理过程中你又不能直接一键清空所以这是很麻烦的过程。 然后插件的管理 Jenkins 还有一个特别让人头疼的地方就是它的插件升级。首先你在 Jenkins 登录进去然后就做插件升级。如果说我想临时在一个新的环境里面起一个 Jenkins 先测试一下或做一些调试可能每新建一个环境都需要把这些插件升级一次。而且刚才我们说的在 Jenkins 里面做的所有配置也都需要重新配置一遍这是一个非常繁琐的一个过程。 但是 Drone 这个工具它有一个特别好的地方就是所有的插件都是 Docker 容器比如说你在 pipeline 里用这个插件你只要声明用这个插件就可以了你不用去自己管理把插件下载到哪里然后怎么安装它这个一切都是全自动只要说你网络能把插件容器镜像访问到就可以了这非常便利。 然后关于生态的构建Jenkins 的最大的优势就是它的插件非常多就是你想用的各种东西都有而且它基础的底座非常好你的插件可以实现的能力非常的强。比如说 pipeline 就是这种方式它从 1.0 到 2.0 虽然有了但是它完全是通过插件来实现的。但是现在 Jenkins 的发展又开始有点第二春的感觉。他开始对 Kuberentes 的支持力度明显的加大了很多首先从 JenkinsX 开始它融合了一些 Kuberentes 生态相关的一些工具比如 Harbor、Helm 它可以非常便利地在 Kuberentes 集群上来做一些构建并且把一些做服务的固化的一些编排文件放到 Helm 里面。 另外现在它有一个新的子项目叫 config as code也就是说他把所有 Jenkin 里面做了一些配置都可以输出成一个 code 的形式就是对整个 Jenkins 的迁移或者说复制都是一个很便利的改进。 讲了那么多实际上最后我们选择的东西还是 Jenkins因为最重要的是生态的构建他们已经很好了。今天我们要讲的在做一个弹性在 CI/CD 这个 Jenkins 上已经有这个插件了但是在 Drone 的社区里面有人提这个事但是现在还没有看到。
CI/CD 工具的选择
接下来我们看一下 CI/CD 这些工具的选择和他们的发展。首先最老牌的肯定是 Jenkins。实际上在容器技术兴起之前CI/CD 简直约等于 Jenkins。但是在出现容器技术之后很多新生 CI/CD 的工具也应运而生比如说图中 Drone 工具它是一个完全基于容器来实现的 CI/CD 工具。它与容器地结合地非常好并且它的构建过程是完全在容器中实现的。 第三个是 Gitlab CI它主要特点是与 Gitlab 代码管理工具结合地比较好。Jenkins 2.0 时开始引入 pipeline as code 特性什么叫 pipeline as codepipeline as code 可以帮我们自动生成一个 jenkins file。在 Jenkins 1.0 时如果我们想要配置一条流水线需要先登录 Jenkins然后建一个项目然后在里面写一些 shell。这样虽然能达到同样的效果但是它有一个最大的弊端就是可复制性和迁移性不好。而且它与 Devops 有天然地割裂比如一般是运维人员来管理 Jenkins 这个系统。开发人员编写代码但是这个代码怎么去构建发布到哪里他是完全不知道的是运维人员在Jenkins 里面配的。这个就造成了开发和运维地割裂。但 pipeline as code 这种方式出现了之后我们可以把 jenkins file 跟代码源码放在同样的仓库里面。 首先它有一个非常大的好处就是我们发布的流程也可以纳入版本管理这样对一个错误就可追溯。这是一个非常大地改动但是实际上我们在与客户沟通中发现虽然很多人在 Jenkins 上都已经升到 2.0 系列了但是它们的用法还是完全在 1.0 系列很多用户都没有把 jenkins file 这种方式用起来。另外一个就是对容器地支持大概 2016 年左右那时对容器的支持是非常弱的在容器里面运行 Jenkins同时构建的产物也是 Doker 会非常麻烦。 但是 Drone 对容器的支持力度就非常好。首先它完全用 Doker 方式来运行就是说你的构建环境也在一个容器里你需要构建一个 Doker build 镜像然后在推送出去的时候它也在容器里面运行然后它需要一个 privilege 权限。它这种方式有几个特别好的地方首先它不会对宿主机产生任何残留比如说你这个容器一销毁构建中产生的一些中间文件完全都跟着销毁了但是你如果用 Jenkins 的话随着用的时间越来越久会沉淀出很多临时文件它占的空间会越来越大。你需要定期做一些清理而且清理过程中你又不能直接一键清空所以这是很麻烦的过程。然后插件的管理 Jenkins 还有一个特别让人头疼的地方就是它的插件升级。首先你在 Jenkins 登录进去然后就做插件升级。如果说我想临时在一个新的环境里面起一个 Jenkins 先测试一下或做一些调试可能每新建一个环境都需要把这些插件升级一次。而且刚才我们说的在 Jenkins 里面做的所有配置也都需要重新配置一遍这是一个非常繁琐的一个过程。 但是 Drone 这个工具它有一个特别好的地方就是所有的插件都是 Doker 容器比如说你在 pipeline 里用这个插件你只要声明用这个插件就可以了你不用去自己管理把插件下载到哪里然后怎么安装它这个一切都是全自动只要说你网络能把插件容器镜像访问到就可以了这非常便利。 然后关于生态的构建Jenkins 的最大的优势就是它的插件非常多就是你想用的各种东西都有而且它基础的底座非常好你的插件可以实现的能力非常的强。比如说 pipeline 就是这种方式它从 1.0 到 2.0 虽然有了但是它完全是通过插件来实现的。但是现在 Jenkins 的发展又开始有点第二春的感觉。他开始对 Kuberentes 的支持力度明显的加大了很多首先从 JenkinsX 开始它融合了一些 Kuberentes 生态相关的一些工具比如 Harbor、Helm 它可以非常便利地在 Kuberentes 集群上来做一些构建并且把一些做服务的固化的一些编排文件放到 Helm 里面。 另外现在它有一个新的子项目叫 config as code也就是说他把所有 Jenkin 里面做了一些配置都可以输出成一个 code 的形式就是对整个 Jenkins 的迁移或者说复制都是一个很便利的改进。 讲了那么多实际上最后我们选择的东西还是 Jenkins因为最重要的是生态的构建他们已经很好了。今天我们要讲的在做一个弹性在 CI/CD 这个 Jenkins 上已经有这个插件了但是在 Drone 的社区里面有人提这个事但是现在还没有看到。
CI/CD的系统业务场景
然后我们看一下 CI/CD 它的系统的业务场景它有一个比较典型的场景与特点首先它面向开发人员这是比较少见的因为开发人员一般都比较挑剔一点。所以你要是这个系统做的不够稳健了或者说响应时间比较长一点的话会被经常吐槽。 然后就是有时效性要求因为我们代码写完之后往上提交我们都不希望在这个代码的构建中一直排队我们希望马上就开始进行构建并且资源足够丰富。另外一个就是它的资源占用的波峰波谷是非常明显的。就因为开发人员不可能时时刻刻都在提交代码有的人可能一天提交几次有的人会提交很多次。 因为我之前看过有一个分享有一个人画了一条反映自家公司构建任务的曲线。他们公司大概是每天下午三、四点的时候代码提交量最高其他时间都比较平缓。这说明他们公司三、四点的时候程序员提交代码开始划水了。然后随着 CI/CD 资源地需求越来越高构建集群是一个必须要做的一件事情。就是提高负载能力缩短任务的排队时间。当然真正的集群有一个让人觉得很不太好的地方就是它的 Master 实际上只有一个当然这个也可以通过插件来做改进。 容器可以给我们 CI/CD 系统来注入新的能力就是环境隔离的能力。我们可以通过 Kubernetes 来为 CI/CD 系统注入更多的能力然后矛盾点就出现了。开发人员总是希望 CI/CD 系统能够快速地响应代码提交的一个事件但是每个公司资源都不可能是无限的。因为就像上面提到的如果每天下午三、四点的时候是一个代码提交的高峰这个时候可能需要 30 或 40 台机器才能满足构建的任务。但是我不可能每天就开着 30 或 40 台机器在这里就为了每天下午三、四点可能会构建一、两个小时。 Kubernetes 可以为 jenkins 注入新的能力让 CI/CD 系统实现弹性的能力。我们期望的目标是什么呢有构建任务的时候可以自动为我们资源增加新的机器也好或增加新的运计算能力也好反正就是当我需要的时候可以帮我自动地做一个资源扩张但是同时也在我不需要的时候可以自动把这些资源释放掉。 我们期望的目标就是这样Kuberentes 就可以为 Jenkins 来做这样的能力。Kuberentes 作为一个容器编排的系统它所能提供的能力它可以快速地弹出一些新的实例并且把它们自动调度到空闲的机器上做一个资源池在资源池里面做一个调度并且他执行完任务之后它可以做一个回收。而且如果把这 Jenkins Master 也部署在 Kuberentes 之上它可以对 Master 做一个故障转移就是说如果我们系统可以容忍的话Master 就算挂了我可以快速把它调到另外一台机器上这个响应时间不会很长。
Kuberentes-plugin
这里面也是用一个插件来实现这个插件名字比较直接叫 Kuberentes-plugin它这个插件所能提供的能力就是说他直接管理一个 Kuberentes 集群它在 Jenkins 里面安装之后它可以监听 Jenkins 的构建任务。有构建任务在等待资源的时候它就可以向 Kuberenetes 去申请一个新的资源申请一个新的 Pod 去做自动地构建完之后它就会自动的清理。
先简单介绍一下它的能力因为这个插件安装完之后它对 pipeline 的语法也有一个改造,一会我们来看一下实例。但是就算到了这一步还是不行的。首先Kuberentes 的集群规划还是一个问题。比说我有个集群有 30 个节点真正的 master 部署在这上面然后装了那些插件做了一个管理之后我们可以发现来了一个新的任务它就起一个新的 Pod把这个构建任务给执行制定完。 执行完之后这 Pod 自动销毁不占集群的资源。 平时我们可以在这集群上做一些别的任务但这个终究还是有一点不好就是我们这个集群到底规划多大并且这个集群我们平时不做构建任务的时候可以在上面做一些别的任务。但是如果正在做任务突然来了一些构建任务它可能会出现资源的冲突问题。
Kubernetes Autoscaler
总的来说还是有一些不完美的地方那么我们可以利用 Kuberentes 一些比较没那么常见的特性来解决我们刚才说的这个问题。这两个东西一个是叫 Autoscaler一个叫 Virtual node。我们先看一下 AutoscalerAutoscaler 是一个 Kubernetes 官方的一个组件。在 Kuberentes 的 group 下面支持三种能力:
Cluster Autoscaler可以对集群节点做自动伸缩Vertical Pod Autoscaler对集群的 Pod 竖直方向的资源伸缩。因为 Kuberentes 本身里面就带着 HPA 可以做水平方向的 Pod 伸缩、节点数量的伸缩这个特性还不是生产可用的特性Addone Resizer是 Kuberentes 上那些 addone 比如说 Ingress Controler、 DNS 可以根据 Node 的数量来对资源的分配做调整。
Cluster autoscaler
我要讲的是 Cluster autoscaler是对集群 node 节点数量做一个扩缩容。 首先我们看一下这个是在阿里云我们容器服务上所实现的 Autoscaler 的一个方式。我们看一下这个图这个是 HPA 和 Autoscler 做结合使用的一个场景。
HPA 监听监控的事件时发现资源使用率上升到一定程度了之后HPA 会自动通知 workload来弹出一个新的 Pod弹出一个新的 Pod可能这时候集群资源就已经不够了所以这个 Pod 可能就会 pending 在这里。它就会触发 Autoscaler 的事件Autoscaler 就会根据我们之前配置好的 ESS 这个模板来去弹出来一台新的 Node然后自动地把 Node 加入到我们集群里面。 它是利用了 ESS 定制的模板功能并且它可以支持多种的 Node 实例的类型可以支持普通实例支持 gpu还有抢占式实例。
Virtual node
然后第二种是 Virtual nodeVirtual node 实现方式是基于微软开源的 Virtual Kubelet 这个项目。它做了一个虚拟的 Kubelet然后向 Kubernetes 集群里面去注册上面。但如果不太好理解的话可以想象一下 MySQL proxy 然后他把自己伪装成一个MySQL server然后后端可能管理着非常多的 MySQL server并且它可以帮你自动的做一些 SQL 查询的路由或者拼接。
Virtual kubelet 做的也是类似的工作就是说它本身向着 Kubernetes 注册说我是一个节点但实际上它后端管理的可能是整个公有云上的非常多的资源他可能对接公有云的一些 ECI 或者说对接的这些 VPC这是一个它的大体的示意图。 在阿里云上他们对接的是阿里云的 ECI 做一个弹性的容器实例它响应时间就非常快因为它不需要把 Node 去加入到集群里面它是大概能够到一分钟一百个 Pod 左右这种性能。而且我们可以在 Pod 上声明这种资源的使用情况这是一个非常快的响应速度时间。 然后刚才说我们利用这两种方式就可以对我们 CI/CD 弹性的系统做出新的改造我们不用非常早规划好我们集群的规模我们可以让集群规模在需要的时候自动的做一些伸缩的动作。但是你做了这些动作之后我们做了这些把真正的放在容器里面的这些动作之后引入了一些新的门槛docker-outside-of-docker 和 docker in docker。 我们在 Docker 中运行 Jenkins 时通常有两种方式一个是把宿主机的 docker.sock 挂载到容器里面让 Jenkins 通过这个文件来和本机的 docker daemon 做一个通信然后它在这里面做 docker build 构建镜像或者把这些镜像 push 到远程的仓库里面所以它中间产生的所有镜像都会堆积在本机上这是一个问题。 在一些 serverless 的那些场景上使用它就会有一些限制因为 serverless 本身就不允许把 socket 文件给挂在进去。另外一个就是 docker in docker 这种方式它的优点就在于在容器里面它启动一个新的 Docker daemon它所有的中间产物、构建产物随着容器都一起销毁但是它有问题它就是需要 privilege 的权限。 很多时候我们是尽量不要用它。另外一个就是说你做 docker build 的时候能在宿主机上做的时候它如果有已经有镜像了它会直接就使用这个镜像但是你用 docker in docker 这种方式来使用的它每次都会重新拉进项拉镜像也是需要一定时间这个取决于我们各个使用场景来判断。
新的构建工具——Kaniko
这时又引入了一个谷歌开源的新工具——Kaniko。它做的东西是 docker in docker 的方式。它有一个非常大的好处就是不依赖 Docker而且所以它不需要 privilege 权限就可以在容器里面用用户态的模式来完全构建 docker image。用户态执行 Dockerfile 的命令它把这个镜像完全构建出来。 这算是一个比较期望的弹性的 CI/CD 系统。然后这个时候就是说从真正的节点到底层的计算资源全部是弹性扩缩的而且满足交付的需求可以非常精细化地管理我们的资源。
Demo 演示
然后我们可以看一下 Demo 演示https://github.com/hymian/webdemo 这里是我准备好的一个例子重点在这个 Jenkinsfile 文件里面定义了agent 的 pod template包含两个容器一个用来做 golang 的 build一个用来做 image 的 build。 然后我们现在构建它。开始构建了刚开始的因为是现在我们在这环境里面只有一个只有一个 master所以他就是没有不会有构建节点。大家可以看到它现在新启动了一个 Pod这个 Pod 是作为节点加进来的但是因为我在这个 Pod 模板里面定义了一个 label所以它没有这个节点所以它 Pod 状态是 pending 的。所以我们在构建日志里面显示的这个是 agent 节点是离线的。 但是我们在这个集群里面定义了一个弹性伸缩的一个东西当没有节点的时候它会自动做一个新节点分配加入可以看到有一个节点正在加入这个我就可以稍等一下。就是说这段时间可能会有个一分钟两分钟的时间。 这个是异常是因为这个节点正在向集群加入所以它显示是异常这是我们从命令行看一下好已经是四个节点了加了一个节点这时候我们看 Pod这时候在 agent 正在创建这时候大家可能有一个小的细节大家可以看一下就是 0/3 是显示 Pod它有三个容器但是我刚才在这个里面定义的它实际上是 Pod 里面只有两个容器这就是我们刚才 PPT 上写的一个地方。 JNLP 那个容器是 plugin 自动注入的一个容器它通过这个容器实时的向 master 汇报构建的一个中间的状态我把它的日志给发送出去。这个是 agent 的节点在初始化的一个过程一个事情这时候 slave节点已经在运行了。我这边已经输出完了构建完成。我的分享内容就这些谢谢大家。
原文链接 本文为云栖社区原创内容未经允许不得转载。