「如何实现流动式软件发布」线上课堂开课啦,快来报名参与课堂抽奖吧~ 了解详情
写点什么

在 Kubernetes 上部署和伸缩 Jenkins

2020 年 4 月 23 日

在Kubernetes上部署和伸缩Jenkins

在本教程中,我们将使用 Rancher 在 Kubernetes 上部署和伸缩 Jenkins。按照本文的步骤一步步来,你将会使用到我们用来测试实际构建作业的 master-agent 体系结构,创建出功能齐全的 Jenkins。


介绍

Jenkins 是一个开源的持续集成和持续交付工具,它可以用来自动构建、测试和部署软件。在全世界有超过一百万的用户在使用 Jenkins,它是目前最流行的自动化服务器。Jenkins 的优势包括:


  • 是一个拥有庞大社区支持的开源软件

  • 基于 Java 的代码库,使其可以移植到所有主要平台

  • 有超过 1000 个插件的丰富生态系统


Jenkins 能够与主流的源代码管理系统(Git、SVN、Mercurial 以及 CVS)、主流的构建工具(Ant、Maven、Grunt)、shell 脚本和 Windows 批处理命令、测试框架、报表生成器的都良好地协同工作。Jenkins 的插件还提供了对 Docker 和 Kubernetes 的支持,Docker 和 Kubernetes 能够创建、部署基于云的微服务环境,并且把它们投入到测试和生产部署中。


Jenkins 支持 master-agent 体系结构(许多 build agents/构建代理根据 master 服务器调度来完成任务),使其具有高度的可伸缩性。Master 的工作是安排构建作业,将作业分发给代理实际执行,监视这些代理并获得构建的结果。除此之外,master 服务器还可以直接执行构建作业。


代理的任务是构建从 master 服务器发送过来的作业。作业可以配置在指定类型的代理商运行,如果没有特别需求,Jenkins 就简单地选择下一个可用代理。


Jenkins 的可伸缩性可以带来许多便利:


  • 并行运行多个构建方案

  • 自动地挂载和移除代理,节约开销

  • 分配负载


当然,尽管 Jenkins 包含了这种开箱即用的可伸缩性特性,配置它的过程却并不是很简单。有许多能够扩展 Jenkins 的选择,而其中一种强大的选择就是使用 Kubernetes。


Kubernetes 是什么?

Kubernetes 是一个开源的容器编排工具。它主要用来帮助操作人员部署、伸缩、更新和维护服务,以及提供服务发现机制来管理节点集群上的容器化应用程序。你可以查看官方文档,了解更多关于 Kubernetes 的内容和用途:


https://kubernetes.io/docs/concepts/overview/what-is-kubernetes/


Kubernetes 是管理可伸缩的、基于容器的工作负载的最佳工具之一。包括 Jenkins 在内的大多数应用程序都可以进行容器化,而这也使得 Kubernetes 成为了非常好的选择。



项目目标

在我们开始之前,先花一点时间描述一下我们将要构建的系统。


我们首先会将 Jenkins master 实例部署到 Kubernetes 集群上。我们将使用 Jenkins 的 kubernetes 插件。我们将使用 Jenkins 的 kubernetes 插件,通过提供动态代理来适配当前的工作负载,在集群上扩展 Jenkins。该插件基于具体的 Docker 镜像启动代理,为每个构建创建一个 Kubernetes pod。在构建完成后,Jenkins 将删除 pod 来节省资源。代理则使用 JNLP(Java Network Launch Protocol,Java 网络启动协议)启动,因此容器能够在启动和运行之后自动连接到 Jenkins master。


前期准备和安装

你需要准备这些东西来完成本教程:


Linux 机器用于运行 Rancher:我们还会使用它构建自定义的 Jenkins 镜像。可以按照 Rancher 安装入门指南在主机上安装 Docker 和 Rancher:


https://rancher.com/quick-start/


Docker Hub 账户:我们需要一个带有容器镜像仓库的账户,为 Jenkins master 和代理推送自定义镜像。


GCP 账户:我们将在 GCP 上部署 Kubernetes 集群。谷歌云平台的 free-tier 应该能够完成这项工作。您实际使用其他公有云,操作也是一样的。


为 Jenkins 组件构建自定义的镜像

那么我们先从给 Jenkins 组件构建自定义镜像开始,将它们推送到 Docker Hub。


登录到 Linux 服务器,在那里你就可以运行 Rancher 并构建镜像。如果还没有安装 Docker 和 Rancher,请按照 Rancher 快速入门指南在主机上安装 Docker 和 Rancher。主机准备好后,我们就可以准备 dockerfile 了。


编写 Jenkins Master Dockerfile

我们先在当前文件夹下创建一个名为 Dockerfile-jenkins-master 的文件,来定义 Jenkins master 镜像:



在文件内部,加入下面 Dockerfile 构建命令。这些命令使用主 Jenkins Docker 镜像作为基础,配置我们用于部署到 Kubernetes 集群的插件:



完成后,保存并关闭文件


编写 Jenkins 代理的 Dockerfiles

接下来,我们就可以为 Jenkins 代理创建 Dockerfile 文件了。我们将创建两个代理镜像,演示 Jenkins 如何正确识别为每个作业准备的正确代理。


在当前目录中创建一个空文件。我们将把它复制到镜像中作为正在构建的每个代理的标识符:



现在,为第一个代理镜像创建 Dockerfile



该镜像将把空文件复制到一个唯一的名称,标记所使用的代理。



完成之后保存并关闭文件


最后,定义第二个代理。这个和前一个代理相同,不过使用了不同的文件标识符:



保存并关闭文件


现在你的工作目录看起来应该是这样的:



构建镜像并 Push 到 Docker Hub

有了准备好的 Dockerfile,我们现在就准备构建和 push 镜像到 Docker Hub 啦。


首先构建 Jenkins master 的镜像:


注意:下面的命令中,将 <dockerhub_user>替换成自己的 Docker Hub 账户名


[root@rancher-instance jenkins-kubernetes]# docker build -f Dockerfile-jenkins-master -t <dockerhub_user>/jenkins-master .
复制代码


当命令的结果返回之后,查看新创建的镜像:



使用账户凭证登录到 Docker Hub:


[root@rancher-instance jenkins-kubernetes]# docker loginLogin with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.Username:Password: Login Succeeded
复制代码


现在,将镜像推送到 Docker Hub:


注意:下面的命令中,同样注意替换成自己的 Docker Hub 账户



你可能还需要同样的命令来构建第二个镜像给 Jenkins JNLP 代理:


注意:下面的命令中,注意将<dockerhub_user>替换成自己的 Docker Hub 账户名



如果一切顺利,你就能在 Docker Hub 账户中看到下图这个状态:



使用 Rancher 部署集群

现在我们的镜像已经发布,就可以使用 Rancher 来帮助部署 GKE 集群了。如果您之前安装了 Rancher,通过 web 浏览器访问服务器的 ip 地址就能登录到实例了。


接下来,创建新的 GKE 集群。这里为了创建具有访问权限的服务账户,你需要登录到谷歌云账户。使用其他的公有云服务所需的步骤也是相似的,具体可以参考文档学习如何创建服务账号,以及如何与 Rancher 一起部署集群:


https://rancher.com/docs/rancher/v2.x/en/cluster-provisioning/hosted-kubernetes-clusters/


在集群上部署 Jenkins

在集群准备好之后,我们就可以部署 Jenkins master 和创建一些服务了。如果你对 kubectl 比较熟悉,你可以直接用命令行来实现;不过通过 Rancher 的 UI,你也能很容易地部署所有需要的组件。


无论你选择何种方式将工作负载添加到集群上,都需要在本地计算机上创建下面的文件来定义需要创建的对象。


首先创建一个文件定义 Jenkins 部署:



在文件里粘贴下面的内容:


注意:下面的内容中将<dockerhub_user>替换成自己的 Docker Hub 账户名


apiVersion: extensions/v1beta1kind: Deploymentmetadata:  name: jenkinsspec:  replicas: 1  template:    metadata:      labels:        app: jenkins    spec:      containers:        - name: jenkins          image: <dockerhub_user>/jenkins-master          env:            - name: JAVA_OPTS              value: -Djenkins.install.runSetupWizard=false          ports:            - name: http-port              containerPort: 8080            - name: jnlp-port              containerPort: 50000          volumeMounts:            - name: jenkins-home              mountPath: /var/jenkins_home      volumes:        - name: jenkins-home          emptyDir: {}
复制代码


下面,创建一个文件配置我们需要的两个服务。


一个是 LoadBalancer 服务,它将提供一个公开的 IP 地址便于我们在 Internet 上访问 Jenkins。另一个是 ClusterIP 服务,用于在 master 和代理之间的内部通信,之后会用到该服务:



在文件内,复制下面的 YAML 结构:


apiVersion: v1kind: Servicemetadata:  name: jenkinsspec:  type: LoadBalancer  ports:    - port: 80      targetPort: 8080  selector:    app: jenkins
---
apiVersion: v1kind: Servicemetadata: name: jenkins-jnlpspec: type: ClusterIP ports: - port: 50000 targetPort: 50000 selector: app: jenkins
复制代码


在 Rancher 上,点击自己管理的集群(例子中名为 jenkins)。在左上角的菜单中,选择 Default 项目,然后选择 Workloads 选项卡。



现在,点击 Import YAML 。在接下来的页面中,点击右上角的 Read from a file 按钮。选择在本地创建的 deployment.yml 文件并点击 Import



Rancher 将在集群上面部署一个基于你 Jenkins master 镜像的 pod



接下来,我们需要在 Jenkins master 上配置访问 UI 的方式。


在 Load Balanced 选项卡中,按照先前导入文件一样的操作。单击 Import YAML 按钮,接着点 Read from a file 按钮。然后从自己的电脑中选择 service.yml 文件,点击 Import 按钮。



Rancher 会开始创建你的服务。部署负载均衡会花费一些时间。



在 service 状态成为 Active 后,你可以点击在负载均衡器行后侧的三个垂直点,选择 View/Edit YAML 来找到它的公共 IP 地址。在这里,向下滚动界面找到在 status->loadBalancer->ingress->ip 下的 IP 地址。



这样我们就可以通过该 IP 地址在 web 浏览器中访问 Jenkins UI 了。



配置动态的构建代理

有了 Jenkins master 启动运行后,我们可以进一步配置动态构建代理,以在必要的时候可以自动启动 Pods。


禁用默认 Master 构建代理

Jenkins UI 中左侧的 Build Executor Status 下,默认配置了两个 Executor,等待执行构建作业,它们是由 Jenkins master 提供的。


主实例应该只负责调度构建作业、将作业分发给代理以供执行、监视代理并获取构建结果。因为我们不希望主实例执行构建,因此要禁用这些。


点击 Manage Nodes 之后的 Manage Jenkins



单击与 master 行上的齿轮图标。



接下来的页面中,把 # of executors 设置成 0,点击 Save



这两个空闲的 executors 将从 UI 左侧的 Build Executor Status 中删除。


收集配置信息

为了在 Kubernetes 集群上自动部署构建代理,我们需要一些信息来配置 Jenkins。我们需要三条来自 GCP 账户的信息以及一条来自 ClusterIP 服务中的信息。


在你的 GCP 账户中,选择 Kubernetes Engine,接着是 Clusters,然后点击集群的名称。在 Detail 列中,复制端点 IP 供之后使用。这是我们需要让 Jenkins 连接到集群的 URL:



下一步,点击端点右侧的 Show credentials 。复制 UsernamePassword



现在,切换到 Rancher UI。在左上角菜单中,选择 Jenkins 集群上的 Default 项目。在上方的导航窗口中选择 Workloads 选项卡,然后单击页面上的 Service Discovery 选项卡:



点击 jenkins-jnlp 行上垂直的三个点,然后单击 View/Edit YAML 。复制 spec > clusterIP 以及 spec > ports > port 中的值备用。


配置 Jenkins Kubernetes 插件

返回主 Jenkins 仪表盘,点击 Manage Jenkins ,然后选择 Manage Plugins



点击 Installed 选项卡并查看 Kubernetes 插件是否安装:



现在我们来配置插件。前往 Manage Jenkins 并选择 Configure System



滑到页面底部的 Cloud 部分。点击 Add a new cloud ,选择 Kubernetes



在下面的表单中, Kubernetes URL 字段上输入 https://,然后输入从 GCP 账户复制的集群端点 IP 地址。


Credentials 下,点击 Add 按钮,选择 Jenkins 。在出现的表单上,输入从 GCP 账户复制的用户名和密码,单击底部的 Add 按钮。


返回到 Kubernetes 表单,从 Credentials 下拉菜单中选择刚才添加的凭据并单击 Test Connection 按钮。如果配置正确,则会显示“Connection test successful”。


现在,向下滚动到页面底部的 Images 部分,单击 Add Pod Template 按钮,然后选择 Kubernetes Pod Template。 使用唯一值填写“Name”和“Labels”字段,以标识您的第一个代理。 我们将使用标签指定应该使用哪个代理镜像来运行每个构建。


接下来,在 Jenkins tunnel 字段中,输入你在 Rancher UI 中从 jenkins-jnlp 服务检索到的 IP 地址和端口,用冒号分隔:



现在,在 Container 字段中,单击 Add Container 按钮并选择 Container Template,在弹出的内容中填写以下字段:


  • Name: jnlp(这是 Jenkins 代理需要的)

  • Docker image:<dockerhub_user>/Jenkins-slave-jnlp1(确保更改 Docker Hub 用户名)

  • Command to run:删除这里的值

  • Arguments to pass to the command:删除这里的值


其余字段保持原样。



接下来,单击 Add Pod Template 按钮,再次选择 Kubernetes Pod Template 。对创建的第二个代理镜像重复刚才的过程,需要注意的是,在需要的时候要修改那些对应于第二个镜像的值:



单击 Save 按钮保存修改并继续。


测试动态构建作业

现在我们已经完成了配置工作,我们可以创建一些构建作业,保证 Jenkins 能够在 Kubernetes 之上进行伸缩。这里我们将为每个 Jenkins 代理创建 5 个构建作业。


在 Jenkins 主页面,单击左侧的 New Item,为第一个代理的第一个构建输入名称,选择 Freestyle project 并单击 OK 按钮。



在下一页的 Label Expression 字段中,输入你为第一个 Jenkins 代理镜像设置的标签,如果单击字段之外,会出现一条消息,提示标签由云提供服务。



向下滚动到 Build Environment 部分,检查 Color ANSI Console Output。


在 Build 部分,单击 Add build step 并选择 Execute shell 。把下面的脚本粘贴进去。



完成之后单击 Save



给第一个代理创建另外四个工作则是单击 New Item,填写新名称并使用 Copy from 字段来从第一个构建中复制。你可以在无需对第一个构建作更改的情况下保存每个构建。


接下来,为第二个 Jenkins 代理配置第一个作业。单击 New Item,给第二个代理的第一个作业选个名字,再一次从第一个代理中复制作业。这一次我们将在保存之前修改配置页面上的字段。


首先,修改 Label Expression 字段匹配第二个代理的标签。


接着,用下面的脚本替换掉 Build 部分文本框中的脚本:



完成后单击 Save



同样按照刚刚我们的流程,为第二个代理创建另外四个构建。


现在,转回到主页面,单击每行最右边的图标,启动全部刚刚创建的 10 个作业。在启动之后,它们会按照 Build Queue 部分的指示排队等待执行:



大约几秒钟之后,会开始创建 Pods 来执行构建(你可以在 Rancher 的 Workload 选项卡中检验这一点)。Jenkins 会为每个作业创建一个 pod。在每个代理启动时,它连接到 master 并从队列中接收要执行的作业。




代理完成了自己的工作后,它就会自动从集群中删除:



要检查作业的状态,可以单击每个代理中的一项作业。从 Build History 中单击构建,然后点击 Console Output。由第一个代理执行的作业应该指定使用了 jenkins-slave1 Docker 镜像,而由第二个代理执行的构建应该指定使用了 jenkins-slave2 镜像:




如果你得到了上面的输出,那么 Jenkins 的配置就是正确的,而且是按照预期的方式在运行的。现在你就可以开始定制自己的 Kubernetes 的构建系统,帮助自己的团队测试和发布软件啦。


结论

在本文中,我们配置了 Jenkins 来按需自动部署构建代理,将其连接到了 Rancher 管理的 Kubernetes 集群。为此,我们完成了下面的步骤:


  • 使用 Rancher 创建了一个集群

  • 为 Jenkins master 和代理创建了自定义 Docker 镜像

  • 将 Jenkins master 和 L4 LoadBalancer 服务部署在 Kubernetes 集群上

  • 在集群上配置了 Jenkins kubernetes 插件,自动生成动态代理

  • 使用带有专用代理镜像的多个构建作业测试场景


本文着重展现了设置 Jenkins master 和代理体系结构的基本的必要配置。我们了解了 Jenkins 如何使用 JNLP 启动代理,以及容器如何自动连接到 Jenkins master 来接受指令。为了实现这一点,我们使用 Rancher 创建集群、部署工作负载并监控产生的 Pods。在这之后,我们又依靠 Jenkins Kubernetes 插件将所有不同的组件连接在了一起。


2020 年 4 月 23 日 17:22715

评论

发布
暂无评论
发现更多内容

作业

chenzt

透过本质和发展看编程

拈香(曾德政)

架构师 面向对象设计 极客大学架构师训练营 面向对象设计原则

学习总结 -- Week2

吴炳华

极客大学架构师训练营

软件的本质与设计原则

dony.zhang

架构师 0 期 | 架构师怎样实现架构目标?

刁架构

设计模式 极客大学架构师训练营

架构师训练营2 ——框架设计

默默

第 02 周学习总结

夏秋

架构师训练营第二周作业

时来运转

架构师0期week2-作业

小高

7-ELEVEn工作法

wujunmin

管理 零售

【架构师第二周作业】依赖倒置

浪浪

架构师训练营第二周学习总结

whiter

极客大学架构师训练营

江帅帅:精通 Spring Boot 系列 05

奈学教育

Spring Boot

0期架构Week2作业1

Nan Jiang

【漫画】云通信企业公众号,打造私域流量的利器

阿里云Edge Plus

云通信

视频豪横时代,应用如何快速构建视频点播能力?

阿里云Edge Plus

音视频 CDN 直播 点播

京东Java高开岗三面算法+数据库+设计模式,复习1个月成功拿offer

互联网架构师小马

数据库 面试 算法 设计模式 Java 分布式

架构师训练营第二周总结

时来运转

设计一个软件框架的关键点

dony.zhang

设计原则

GalaxyCreater

架构

第 02 周作业

夏秋

极客大学架构师训练营

你不会还不懂依赖倒置吧?赶紧来看看

hellohuan

设计模式 极客大学架构师训练营 设计原则

架构师训练营第二周命题作业

兔狲

作业

设计原则——依赖倒置原则

GalaxyCreater

架构

豆瓣9.0,35万读者“搜不到信息”的神秘作者,我们帮你找到了

华章IT

JVM 虚拟机 深入理解JVM Java 25 周年 周志明

编程的本质

GalaxyCreater

架构

第二周作业

极客大学架构师训练营

银行业数据治理之「数据资产管理」

数据司令

大数据 数据仓库 金融科技 数据治理 数据资产

DIP和SIP的理解和学习

拈香(曾德政)

极客大学架构师训练营 面向对象设计原则 DIP 设计原则 SIP

拼多多市值快 1000 亿美元了

池建强

创业 拼多多

极客时间 - 架构师训练营 - week2 - 作业

毛聪

在Kubernetes上部署和伸缩Jenkins-InfoQ