整合 GitHub、Maven 和 Docker
大家好,欢迎来到我的最新博客!
在这里,我将告诉你如何使用 Docker 容器作为 Jenkins 从节点配置 Jenkins 主从架构。
一定要亲自实践,以获得更好的结果和理解!
什么是 Jenkins
Jenkins 是一个免费的工具,可以帮助软件开发人员更快、更高效地工作。它负责像构建、测试和交付代码这样的重复性任务,使开发人员不必手动完成这些任务。它就像一个有用的助手,关注代码变化并自动启动必要的进程。Jenkins 还能很好地与其他工具配合使用,因为它支持广泛的插件,可以与各种工具和技术无缝集成,方便连接开发过程的不同部分。通过使用 Jenkins,开发人员可以节省时间,顺畅地合作,并确保在将软件发布给用户之前,软件能够正确运行。
Jenkins 主从架构
Jenkins 主从架构是在 Jenkins 中分配工作负载的一种方式。简单来说,就像在公司里有一个老板(主节点)和助手(从节点)。老板管理和协调任务,而助手则处理实际工作。
使用从节点而不是在主节点上完成所有工作有几个好处。首先,它提高了性能和可扩展性。工作负载被分配到多台机器上,允许任务同时执行。这加快了整个过程并使处理更大的工作负载成为可能。
其次,它增强了可靠性和容错性。如果主节点失败,从节点可以继续独立工作。这确保了开发和部署过程不会中断。
最后,它促进了灵活性和资源管理。可以针对特定任务配置不同的从节点,包括特定的软件、硬件或操作系统。这样可以有效利用资源,并使不同作业并行执行。
在 Jenkins 主从架构中,有两种类型的从节点:永久从节点和动态从节点。
让我们了解区别,以及为什么动态从节点通常被认为更好。
永久从节点 在 Jenkins 主从架构中,永久从节点是一台专用机器,始终可用于执行主节点分配的任务。它通常在特定机器上配置,并始终连接到主节点。永久从节点具有固定的资源,并适用于一致的工作负载或需要特定硬件或软件配置的情况。然而,它们可能不像动态从节点那样灵活,不能根据需求创建或释放,因此在资源优化或可扩展性方面可能不如动态从节点。(个人经验🤒)
动态从节点 另一方面,动态从节点更像按需助手。它们在需要时创建,并在完成工作时释放。动态从节点可以在不同的机器上进行配置,包括虚拟机或容器,具体取决于工作负载。它们提供了处理不同工作负载的灵活性和适应性。(一个 Docker 爱好者真的很了解满足感🤩)
那么,为什么动态从节点通常更受欢迎?
主要优点是资源优化。使用动态从节点,根据需求分配资源。当没有待处理的任务时,资源被释放,允许其他作业或任务利用它们。这种动态分配资源确保了可用计算能力的高效利用(一个简单的例子就是 Docker 容器)。
此外,动态从节点支持扩展。如果工作负载增加,可以配置更多的从节点来处理额外的任务(在不到一秒钟的时间内启动整个环境)。一旦工作负载减少,多余的从节点就可以终止,节省资源和成本。这种弹性使得 Jenkins 能够有效地处理工作负载波动。
此外,动态从节点支持并行执行。多个任务可以在不同的从节点上同时运行,大大减少总体执行时间。这种并行性提高了开发过程中的效率和生产力。
现在让我们开始动手吧。
先决条件:
- 我们正在使用 AWS 云。你需要一个账户。
- Jenkins 主节点应该已经配置好。 我为这个演示配置了两个 Amazon EC2 实例——一个用于 Jenkins 主节点,另一个用于启动 Docker 容器→它将成为 Jenkins 从节点。因此,Docker 容器将扮演 Jenkins 从节点的角色。(动态)
我们将运行这个实践的两种方法,
第一种是手动的,这样你就可以正确地理解流程,第二种是使用 Jenkins(这是我们的主要讨论)。
手动 方法
在 Docker 平台上(EC2 实例的名称,我将为其配置 Jenkins 从节点)
我正在使用自己的自定义容器映像进行演示。
docker pull sayantan2k21/simple-jenkins-maven-app
以守护进程模式启动容器。
docker run -dit --name myjavaapp sayantan2k21/simple-jenkins-maven-app
你可以看到容器已经启动。
docker inspect myjavaapp
使用 docker inspect
命令查找为其分配的 IP。
我已经配置了 jenkins 用户,并且 jenkins 用户的密码是 jenkins。
你可能在第一次找不到这个错误,但在我的情况下,我测试了多次,所以它显示了这个错误。
如果你遇到这个错误,只需使用 vim 编辑 /root/.ssh/known_hosts 文件,并删除在相应 IP 上运行的主机,就像我之前使用 docker inspect 命令一样,在我的情况下是(172.17.0.2)
vi /root/.ssh/known_hosts
现在再次检查,现在成功了。
ssh jenkins@172.17.0.2
默认的工作目录是 /home/jenkins。
我们在容器内。检查Java版本,我这里有OpenJDK 11,还要检查maven和git的版本。
现在我们已经克隆了包含我们Java应用程序源代码的存储库。
git clone https://github.com/Sayantan2k24/jenkins-docker-slave-maven-app.git
克隆完成后,你可以看到一个新目录已经出现。
进入该目录,你会看到所有的文件和文件夹。
使用 mvn clean package
命令构建代码并创建包。
你可以看到一个 .jar 文件被创建在
/home/jenkins/jenkins-docker-slave-maven-app/target/
现在在当前目录中检查,另一个目录已经被创建,即 target/。
进入该目录并进行列表查看。
你会看到一个 .jar 文件,现在要查看这个Java应用程序的输出,请使用 java -jar
命令。
java -jar my-app-1.0-SNAPSHOT.jar
完成实践后,你可以删除Docker容器。
所以这就是它的工作流程,希望你已经完全理解了。
下一部分是 -
主要实践👇
使用Jenkins⏭执行此实践
在Jenkins主节点上,我有OpenJDK 17,你也可以安装OpenJDK 11。我有maven的版本是3.0.5。
我的Jenkins正在运行8080端口
现在是Docker平台OS
检查docker-engine的状态。
/usr/lib/systemd/system/docker.service
文件是控制Docker守护进程的systemd单元文件。它告诉systemd如何启动、停止和重新启动Docker守护进程,以及如何管理其资源。
/usr/lib/systemd/system/docker.service
中的-H tcp://0.0.0.0:4243
选项告诉Docker守护进程在TCP端口4243上监听客户端请求。
它允许你从远程机器连接到Docker守护进程。
就像在我的情况下,Docker容器是由Jenkins动态启动并通过ssh连接执行作业的。但是由于容器默认配置为仅允许与主机的本地连接,因此我们必须启用一个端口,即4243,以允许任何人(在我的情况下是Jenkins)从远程机器连接到Docker守护进程。
使用设置编辑ExecStart参数。
然后重新加载守护进程并重新启动服务。
有一个内部防火墙正在运行,它限制了外部世界连接到你的实例。
在Docker平台操作系统的安全组中,我允许每个人的入站流量。但这是非常危险的,最好只允许Jenkins主节点的IP。
现在,从Jenkins主节点连接到Docker平台操作系统,并访问**/version**页面→这是Docker的内部页面,显示版本信息。
我的Jenkins正在运行8080端口。
打开你的浏览器,使用Jenkins主节点的公共IP,并连接到端口8080。``` 希望你已经配置好了Jenkins。输入你的用户名和密码登录。
现在我们需要为Jenkins配置Slave节点。进入“Manage Jenkins”。
点击“Manage Nodes and Clouds”,因为我们没有使用任何永久的Slave,我们使用动态的Slave,在Jenkins世界中,它们也被称为Clouds。
然后进入“configure clouds”。
由于这是我们第一次将Docker与Jenkins集成,我们必须安装必要的Docker插件。
进入“manage Jenkins”->“manage-plugins”安装Docker插件,点击“available plugins”并在搜索栏中搜索“docker”,选择第一个插件“Docker”。Jenkins提供了各种插件来帮助将Jenkins与其他工具集成。
选择Docker作为插件后,点击“download now”和“install after restart”按钮开始下载插件,需要重启才能对Jenkins功能进行更改。
安装开始。
Jenkins重新启动后,再次进入“Manage Jenkins”页面,添加节点和Cloud到体系结构中。
它会自动检测到Docker插件。
提供名称。
提供主机URI,这里的主机是我的Docker平台os的IP。不要忘记使用TCP协议,因为我们已经允许TCP端口4243。
我们必须告诉Jenkins我的Docker平台在哪里。
为了测试连接,你可以点击“Test Connection”以检查与docker的连接性。如果连接正确,它将显示docker版本和API版本。
启用上述设置。
启用基本的docker设置,例如“expose”以允许docker公开。
现在来到Docker Agent模板。
当新任务出现时,Jenkins将连接到docker平台,并启动一个新的Slave,在我的情况下是一个容器。因此,我们必须使用容器镜像,并告诉已配置的用户名和密码。
在子部分中创建一个“docker template”,使用镜像名称,其余参数保持不变。Docker镜像包含所有预先设置的环境,允许ssh到容器中(我已设置基于密码的ssh),创建Jenkins用户以执行所有任务。
还要为Slave设置标签。当启动新的Slave时,该Slave将附加到此标签。设置标签的好处是可以有多个Slave运行,一个是Linux,一个是Windows——为了告诉哪个Slave连接,我们必须设置标签并启用标签。
只需给出图像名称,并给出将用于启动Slave节点的Docker Hub中的图像的正确名称。
这是一个关键部分,我们必须告诉Jenkins将是主目录。我已将/home/jenkins设置为镜像中的主目录。
在使用部分中选择此选项,因为我们已经为Slave设置了标签,我希望该作业仅在特定的Slave上运行。
由于我在镜像中启用了SSH,因此从此镜像启动的任何容器都将启用SSH。Jenkins将使用SSH连接到Slave,并为SSH提供凭据。
我已经提供了凭证,但你只需点击添加,然后在此处提供凭证→用户名和密码。
我的从节点用户名为'jenkins',密码也为'jenkins',我已将这些凭据设置在我的容器镜像中。
如果你是第一次进行ssh登录→则会出现主机密钥检查,我们必须在其中键入yes或no。
作为程序,Jenkins无法打开键盘并键入。为此,我们应该使用基于密钥的身份验证。由于我们现在没有这个,因此只需选择非验证策略。
拉取策略是→每次出现新作业时,Jenkins都会转到Docker Hub并下载Docker映像。
在提供所有详细信息后,保存配置。
#现在让我们创建作业。
进入Jenkins仪表板→单击“新项目”->并提供详细信息。
我们正在使用Freestyle。
我在GitHub repo中有Java源代码。
我们正在从主分支构建代码。
现在添加构建步骤。
我希望代码由Maven构建。因此从选项中选择调用顶级Maven目标。
并编写干净的程序包→内部运行的命令→mvn clean package(如前面的手动方法所示)
构建后,我们将在target/中拥有**.jar**文件,因为我已经在手动方法中向你展示了路径。
添加另一个构建步骤,这次选择->执行Shell
使用java -jar命令测试应用程序。
在将来启动的从节点上使用我们已经设置的标签将作业与从节点标记。
在相应的作业中转到“常规”部分并选择此选项。
现在,一切都已配置好,只需运行作业。
这是我们的工作。
单击作业名称,然后单击立即构建
与此同时,我已经打开了我的实例,并使用watch -n 1 docker ps -a命令以实时显示Docker容器的启动。
一旦构建开始,就会启动一个容器,即我们的动态从节点。
检查作业的控制台输出,清楚地告诉它正在远程构建docker从节点。
构建成功,还创建了jar文件,并按照指示运行java -jar target / *.jar命令,测试成功。
构建完成。
一旦构建和测试完成,你可以看到 Docker 容器自动被删除,这就是动态 Slave 的工作原理。
感谢阅读!我们下次再见。
GitHub 仓库:https://github.com/Sayantan2k24/jenkins-docker-slave-maven-app.git
Docker Hub 仓库:https://hub.docker.com/r/sayantan2k21/simple-jenkins-maven-app
评论(0)