使用 jenkins 进行持续部署
Posted
技术标签:
【中文标题】使用 jenkins 进行持续部署【英文标题】:continuous deployment with jenkins 【发布时间】:2012-12-08 05:18:30 【问题描述】:我想用 jenkins 部署到测试环境和生产环境。为此,我需要连接到所需环境的服务器,例如 ssh/scp。
我想知道最好的方法是什么。
我找到了一些插件来执行此操作,例如 Jenkins-Deploy-Plug-in 或 Jenkins Publish over SSH 插件。第一个有很多问题,部署到生产环境中并不值得信赖,第二个您需要更改全局配置,每次部署都是手动工作。
任何想法如何解决这个问题?也许有一些脚本或插件?
我目前唯一的想法是:使用 jenkins 连接到服务器(可能使用 SSH 插件)并在那里执行连接到所需环境的脚本。但这是两个联系。这真的有必要吗?我希望有一个更直接的方法。
感谢任何提示。
【问题讨论】:
这里有点晚了,但这确实是ARA tools 的目的。将 Jenkins 与 BuildMaster 或 XLDeploy 等工具集成,然后让该工具将其部署到生产环境。 【参考方案1】:我建议以下程序:
一个单一的 shell 脚本(存储在 jenkins 服务器的某个地方)可以完成所有工作。 基本上,该脚本执行构建工件的 scp,然后连接到服务器 (ssh) 并执行所有必要的部署任务(设置维护页面、备份当前应用程序、部署新应用程序......)。
在jenkins服务器上,至少有2个job:
第一个只是简单地进行构建(使用 maven 或任何其他构建脚本) 第二个作业执行部署:因此该作业仅运行 shell 脚本。 (我建议为每个目标环境执行一项部署作业:测试、生产……)它不需要任何“特殊”的詹金斯插件来实现这种“一键部署”。 它只要求 jenkins 用户对目标服务器具有 ssh 访问权限。
编辑
这是一个示例 shell 脚本来说明我的帖子
#This script will copy the last artifact build by the job "MyApp" to test.myserver.com
#and remotely execute the deployment script.
#copy the war to the server
#(the job "MyApp" is using maven, that's why the war can be found at this location)
scp -i <HOME_DIR>/.ssh/id_dsa $HUDSON_HOME/jobs/MyApp_Build/workspace/myapp/target/myapp.war deployeruser@test.myserver.com:/tmp/
#connect to the server and execute the deployment script
ssh -i <HOME_DIR>/.ssh/id_dsa deployeruser@test.myserver.com
#The following is just an example of what a deployment script can be.
#of course you must adapt it to your needs and environment
"cd <TOMCAT_DIR>;
#first copy the current war to a backup directory (additionaly, I have a cron task deleting old undeployed apps)
cp -rf myapp-apps/myapp* undeployed/myapp-apps/;
#execute a script (stored on the server) to properly stop the app
sh bin/myapp.sh stop;
#delete current app
rm -rf myapp-apps/myapp;
rm -rf myapp-apps/myapp.war;
#copy the uploaded war in tomcat app directory
cp /tmp/myapp.war myapp-apps/;
#execute a script (stored on the server) to start the app
sh bin/myapp.sh start"
【讨论】:
1.您的意思是将脚本存储在与詹金斯相同的服务器上吗?不知道詹金斯也可以存储脚本。 2. 我想到了一个参数化的工作,它将依赖于参数部署到测试环境或生产环境。您是否有理由为每个目标环境推荐一份工作? 每个目标一个作业,因为它是“一键测试”和“一键生产”。使用参数化作业可能需要更多点击? (不知道参数化作业的确切含义) 我把脚本放在 /home/jenkins/deploy-script/deploy-myapp-test.sh ,我只是用 jenkins 作业调用这个脚本。我不使用 jenkins 来存储脚本:我将它手动放在这个位置。 除了目标服务器之外,“部署到测试”和“部署到产品”这两个作业是相同的(从我目前的角度来看)。所以我认为使用参数化作业将目标服务器 url 作为参数传递可能是一种选择。但这对我来说是新的,还没有尝试过。谢谢你的协助。我希望我明天能写出一个工作脚本,这对我来说也是新的。也许您喜欢分享您的“deploy-myapp-test.sh”脚本作为示例。 谢谢,总是很高兴看到一个例子。即使我必须适应很多事情。就像为 ssh 连接配置服务器一样,因为服务器实际上需要密码身份验证,从存储库获取 .war 和其他详细信息。【参考方案2】:使用 SSH 会损害您环境的安全性 并且很难排除故障。
最好在远程机器上安装一个Jenkins-Slave 并通过在 Slave 上执行 Job 来运行测试。
Slave被Server监控,省去了很多麻烦 管理连接。
您可以在成功构建结束时触发远程作业 并将该构建的工件传递给它。 (也可以让第一个作业将工件存储在共享驱动器上 并将这些工件的位置传递给下一个作业)。
看这里:
詹金斯 - Distributed builds 詹金斯 - Parameterized Trigger Plugin 詹金斯 - Copy Artifact Plugin【讨论】:
我想部署到生产环境。如果我理解正确,那么我的生产服务器上需要一个 Jenkins-Slave 吗?那不是一个好主意。由于测试服务器应该是生产服务器的副本,因此将其部署到与生产服务器不同并配置不同(例如在其上安装 jenkins-slave)是没有意义的。 好点。另一方面,能够在生产服务器上强制进行远程安装也“不太酷”,除非您可以严格监控这些部署(即:仅在您想要的时候发生,发布到您想要的版本,并就成功或失败给出良好的反馈)。 我同意 Gonen 的观点。 prod 服务器上必须存在某种客户端才能允许部署。仅仅因为 SSH 通常是内置的,并不比 Jenkins slave 更有效。我担心的是 Jenkins prod slave 是否可以被锁定到 prod 部署工作。如果另一个 Jenkins 工作可以出现并在没有适当许可的情况下劫持它,这可能是一个问题。我还没有深入了解 Jenkins,但考虑到我目前看到的安全选项,它看起来并不好。 @juanitogan,Jenkins 可以被锁定到只有选定用户可以创建/修改/删除/运行作业的级别,我认为从属(代理)到主控之间的连接是安全,它规定很难劫持奴隶,并且您可以将其管理限制为选定的用户。考虑到您从 Jenkins 那里获得的对在其上运行的每个操作的良好反馈,它应该更容易控制(因此:更安全)。 @Gonen,是的,但是如何阻止可以在开发机器上创建/修改/删除/运行作业的开发人员暂时借用生产从属设备以规避 QA 并将某些东西投入生产?据我所知,如果您对一个奴隶拥有权利,那么您对所有奴隶都拥有权利。【参考方案3】:理想情况下,您应该使用 Fabric 或 Capistrano 之类的东西进行部署,并从 Jenkins 调用这些脚本。我也将 Capistrano 广泛用于 Ruby On Rails 和非 Ruby 应用程序。我看到的最大优势是:
在部署时出现错误时回滚部署的内置智能。 它提供的钩子用于运行一组脚本,例如数据库迁移、服务重启等。 在需要时手动回滚。【讨论】:
以上是关于使用 jenkins 进行持续部署的主要内容,如果未能解决你的问题,请参考以下文章