Jenkins集成Ansible自动化配置管理:3种方案打通CI与IaC全流程
-
-
- 📈 Jenkins + Ansible 协作流程图
- 一、核心原理:Jenkins 和 Ansible 为何是绝配?
- 二、第一步:Jenkins 节点安装 Ansible 环境
- 三、第二步:配置 Ansible Inventory 主机清单
- 四、第三步:编写 Ansible Playbook 部署逻辑
- 五、第四步:三种集成方案实战对比
-
- 方案一:Shell 直接调用(最简单,推荐新手)
- 方案二:Ansible Plugin 插件调用(功能完整,推荐生产环境)
- 方案三:Ansible Tower / AWX API 远程调用(企业级,适合大型集群)
- 六、进阶技巧:动态 Inventory 与滚动更新
-
- 1. 使用动态 Inventory(如AWS EC2、阿里云ECS)
- 2. 滚动更新配置
- 📚 常见问题排查清单
- 📊 三种方案对比总结
- 💎 总结
-
|
🌺The Begin🌺点点关注,收藏不迷路🌺 ⬇ ⬇ 底部 ⬇ ⬇ |
在现代DevOps体系中,Jenkins 负责"编排与触发“,Ansible 负责”执行与落地"。二者结合,可以实现从代码提交到服务器配置变更的全自动闭环——应用编译完成后,Ansible自动将二进制分发到50台服务器,并更新配置文件、重启服务。
📈 Jenkins + Ansible 协作流程图
先通过一张图理清Jenkins如何调用Ansible完成自动化配置:
#mermaid-svg-QnhfDCERVif0tj8X{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-QnhfDCERVif0tj8X .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-QnhfDCERVif0tj8X .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-QnhfDCERVif0tj8X .error-icon{fill:#552222;}#mermaid-svg-QnhfDCERVif0tj8X .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-QnhfDCERVif0tj8X .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-QnhfDCERVif0tj8X .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-QnhfDCERVif0tj8X .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-QnhfDCERVif0tj8X .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-QnhfDCERVif0tj8X .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-QnhfDCERVif0tj8X .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-QnhfDCERVif0tj8X .marker{fill:#333333;stroke:#333333;}#mermaid-svg-QnhfDCERVif0tj8X .marker.cross{stroke:#333333;}#mermaid-svg-QnhfDCERVif0tj8X svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-QnhfDCERVif0tj8X p{margin:0;}#mermaid-svg-QnhfDCERVif0tj8X .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-QnhfDCERVif0tj8X .cluster-label text{fill:#333;}#mermaid-svg-QnhfDCERVif0tj8X .cluster-label span{color:#333;}#mermaid-svg-QnhfDCERVif0tj8X .cluster-label span p{background-color:transparent;}#mermaid-svg-QnhfDCERVif0tj8X .label text,#mermaid-svg-QnhfDCERVif0tj8X span{fill:#333;color:#333;}#mermaid-svg-QnhfDCERVif0tj8X .node rect,#mermaid-svg-QnhfDCERVif0tj8X .node circle,#mermaid-svg-QnhfDCERVif0tj8X .node ellipse,#mermaid-svg-QnhfDCERVif0tj8X .node polygon,#mermaid-svg-QnhfDCERVif0tj8X .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-QnhfDCERVif0tj8X .rough-node .label text,#mermaid-svg-QnhfDCERVif0tj8X .node .label text,#mermaid-svg-QnhfDCERVif0tj8X .image-shape .label,#mermaid-svg-QnhfDCERVif0tj8X .icon-shape .label{text-anchor:middle;}#mermaid-svg-QnhfDCERVif0tj8X .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-QnhfDCERVif0tj8X .rough-node .label,#mermaid-svg-QnhfDCERVif0tj8X .node .label,#mermaid-svg-QnhfDCERVif0tj8X .image-shape .label,#mermaid-svg-QnhfDCERVif0tj8X .icon-shape .label{text-align:center;}#mermaid-svg-QnhfDCERVif0tj8X .node.clickable{cursor:pointer;}#mermaid-svg-QnhfDCERVif0tj8X .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-QnhfDCERVif0tj8X .arrowheadPath{fill:#333333;}#mermaid-svg-QnhfDCERVif0tj8X .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-QnhfDCERVif0tj8X .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-QnhfDCERVif0tj8X .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-QnhfDCERVif0tj8X .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-QnhfDCERVif0tj8X .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-QnhfDCERVif0tj8X .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-QnhfDCERVif0tj8X .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-QnhfDCERVif0tj8X .cluster text{fill:#333;}#mermaid-svg-QnhfDCERVif0tj8X .cluster span{color:#333;}#mermaid-svg-QnhfDCERVif0tj8X div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-QnhfDCERVif0tj8X .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-QnhfDCERVif0tj8X rect.text{fill:none;stroke-width:0;}#mermaid-svg-QnhfDCERVif0tj8X .icon-shape,#mermaid-svg-QnhfDCERVif0tj8X .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-QnhfDCERVif0tj8X .icon-shape p,#mermaid-svg-QnhfDCERVif0tj8X .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-QnhfDCERVif0tj8X .icon-shape .label rect,#mermaid-svg-QnhfDCERVif0tj8X .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-QnhfDCERVif0tj8X .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-QnhfDCERVif0tj8X .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-QnhfDCERVif0tj8X :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
方案1
方案2
方案3
💻 开发者提交代码
⚙️ Jenkins 触发流水线
📦 Stage 1: 编译打包
📦 Stage 2: 单元测试
📦 Stage 3: 构建镜像
🚀 Stage 4: 调用 Ansible
调用方式
Shell直接执行ansible-playbook
Ansible Plugin插件调用
Ansible Tower API远程触发
📄 Ansible 执行 Playbook
🗄️ 目标服务器1: 部署应用
🗄️ 目标服务器2: 更新配置
🗄️ 目标服务器3: 重启服务
✅ 配置管理完成
📊 结果回传 Jenkins
一、核心原理:Jenkins 和 Ansible 为何是绝配?
在集成之前,必须理解二者的分工边界:
| Jenkins | 代码拉取、编译构建、触发部署、可视化编排 | 无代理服务器的批量命令执行 |
| Ansible | SSH免代理批量管理、幂等配置下发、服务编排 | 代码编译、持续集成触发 |
黄金组合逻辑: Jenkins的Pipeline流程走到"部署"环节时,将**控制权移交给Ansible**。Ansible通过SSH连接到目标服务器,完成应用部署、配置文件更新、服务重启。完成后将结果返回给Jenkins,由Jenkins统一展示成功或失败。
二、第一步:Jenkins 节点安装 Ansible 环境
无论使用哪种方案,Jenkins所在的服务器(或Agent节点)必须安装Ansible。
安装命令(Ubuntu/Debian):
sudo apt update
sudo apt install -y ansible sshpass
ansible –version # 验证安装
安装命令(CentOS/RHEL):
sudo yum install -y epel-release
sudo yum install -y ansible sshpass
ansible –version
关键检查清单:
- 确认Jenkins用户(通常是 jenkins)能执行 ansible 命令。
- 确认Jenkins用户拥有SSH私钥,并能免密登录目标服务器:# 切换到jenkins用户测试
sudo su – jenkins
ssh target-server-ip 'echo "Connection OK"'
三、第二步:配置 Ansible Inventory 主机清单
Ansible需要知道管理哪些服务器。在Jenkins工作目录下创建主机清单文件。
Inventory 文件示例(/var/lib/jenkins/ansible/hosts):
[webservers]
web01 ansible_host=192.168.1.101 ansible_user=deploy
web02 ansible_host=192.168.1.102 ansible_user=deploy
[dbservers]
db01 ansible_host=192.168.1.201 ansible_user=deploy
[production:children]
webservers
dbservers
[all:vars]
ansible_ssh_private_key_file=/var/lib/jenkins/.ssh/id_rsa
ansible_python_interpreter=/usr/bin/python3
安全提示:
- SSH私钥文件权限必须是 600。
- 不要将Inventory文件提交到代码仓库,应放在Jenkins服务器的固定路径。
四、第三步:编写 Ansible Playbook 部署逻辑
Playbook是Ansible的核心,定义了对目标服务器要执行的配置步骤。
Playbook 示例(deploy-app.yml):
—
– name: 部署应用并更新配置
hosts: webservers
become: yes
vars:
app_version: "{{ lookup('env', 'APP_VERSION') | default('latest', true) }}"
deploy_path: /opt/myapp
tasks:
– name: 创建应用目录
file:
path: "{{ deploy_path }}"
state: directory
mode: '0755'
– name: 拷贝构建产物到目标服务器
copy:
src: "{{ workspace }}/target/myapp.jar"
dest: "{{ deploy_path }}/myapp-{{ app_version }}.jar"
mode: '0644'
– name: 更新应用配置文件
template:
src: "{{ workspace }}/config/application.yml.j2"
dest: "{{ deploy_path }}/config/application.yml"
notify: 重启应用服务
– name: 创建软链接指向新版本
file:
src: "{{ deploy_path }}/myapp-{{ app_version }}.jar"
dest: "{{ deploy_path }}/myapp.jar"
state: link
handlers:
– name: 重启应用服务
systemd:
name: myapp
state: restarted
daemon_reload: yes
Playbook 关键点解析:
- hosts: webservers:指定目标服务器组。
- become: yes:以root权限执行(对应Jenkins与Ansible分工图中的特权操作)。
- {{ workspace }}:由Jenkins传递的变量,指向当前构建的路径。
五、第四步:三种集成方案实战对比
方案一:Shell 直接调用(最简单,推荐新手)
直接在Jenkins Pipeline的 sh 步骤中执行 ansible-playbook 命令。
Jenkins Pipeline 配置:
pipeline {
agent any
environment {
ANSIBLE_HOST_KEY_CHECKING = 'False' // 禁用首次连接确认
ANSIBLE_INVENTORY = '/var/lib/jenkins/ansible/hosts'
}
stages {
stage('Compile') {
steps {
sh 'mvn clean package -DskipTests'
}
}
stage('Deploy with Ansible') {
steps {
sh '''
ansible-playbook \\
-i $ANSIBLE_INVENTORY \\
-e workspace=$WORKSPACE \\
-e app_version=${BUILD_NUMBER} \\
deploy-app.yml
'''
}
}
}
}
优点: 零额外插件,调试方便,直接在控制台看输出。 缺点: 输出日志混杂,无法利用Ansible插件的高级可视化功能。
方案二:Ansible Plugin 插件调用(功能完整,推荐生产环境)
安装官方 Ansible Plugin,可以在Jenkins UI中直接触发Playbook,并获得彩色输出。
1. 安装插件 进入 Manage Jenkins → Plugins → Available plugins,搜索并安装:
- Ansible 插件。
2. 全局工具配置 进入 Manage Jenkins → Tools → Ansible installations:
- Name:Ansible-2.15
- Path to ansible executables directory:/usr/bin(或自定义安装路径)
- 勾选 Install automatically(可选,让Jenkins自动下载Ansible)。
3. Pipeline 调用语法
pipeline {
agent any
stages {
stage('Run Ansible Playbook') {
steps {
ansiblePlaybook(
playbook: 'deploy-app.yml',
inventory: '/var/lib/jenkins/ansible/hosts',
extras: '-e workspace=$WORKSPACE -e app_version=${BUILD_NUMBER}',
colorized: true // 开启彩色日志输出
)
}
}
}
}
输出效果: 控制台日志中,每个Ansible任务会显示为 ok/changed/failed 的彩色状态,一目了然。
方案三:Ansible Tower / AWX API 远程调用(企业级,适合大型集群)
如果使用 Ansible Tower(商业版)或 AWX(开源版),Jenkins只需调用REST API,无需安装Ansible。
Pipeline 配置:
pipeline {
agent any
environment {
TOWER_HOST = 'https://tower.mycompany.com'
TOWER_TOKEN = credentials('ansible-tower-token') // 引用凭证插件
}
stages {
stage('Trigger Ansible Job') {
steps {
sh '''
curl -k -X POST \\
-H "Authorization: Bearer $TOWER_TOKEN" \\
-H "Content-Type: application/json" \\
-d '{"extra_vars": {"app_version":"'${BUILD_NUMBER}'"}}' \\
$TOWER_HOST/api/v2/job_templates/15/launch/
'''
}
}
stage('Wait for Job Completion') {
steps {
script {
// 轮询等待Tower任务完成
timeout(time: 5, unit: 'MINUTES') {
waitUntil {
def result = sh(
script: "curl -k -H 'Authorization: Bearer $TOWER_TOKEN' $TOWER_HOST/api/v2/jobs/16/ | jq -r .status",
returnStdout: true
).trim()
echo "Ansible Tower Job Status: ${result}"
result == 'successful'
}
}
}
}
}
}
}
适用场景:
- 管理数百台服务器的集群环境。
- 需要RBAC权限控制(谁可以部署生产环境)。
- 需要审计日志和调度管理。
六、进阶技巧:动态 Inventory 与滚动更新
1. 使用动态 Inventory(如AWS EC2、阿里云ECS)
Ansible支持从云平台动态获取服务器列表,无需手动维护主机清单。
示例(AWS EC2动态清单脚本):
ansible-playbook -i ec2.py deploy-app.yml
在Jenkins中只需安装 boto3 库并配置好AWS CLI即可。
2. 滚动更新配置
对于无状态Web集群,应使用 serial 关键字分批更新,确保服务不中断。
– name: 滚动更新Web集群
hosts: webservers
serial: 2 # 每次只更新2台
max_fail_percentage: 30 # 失败超过30%则停止
tasks:
– name: 将服务器从负载均衡移除
# … 调用LB API
– name: 更新应用
# … 部署任务
– name: 重新加入负载均衡
# … 健康检查通过后加回
Jenkins中的集成: 只需将上述Playbook路径传入,Ansible会自动处理分批逻辑。
📚 常见问题排查清单
| ansible: command not found | Jenkins用户PATH中无Ansible | 在Pipeline中添加 export PATH=$PATH:/usr/bin |
| Host key verification failed | 首次连接SSH未确认指纹 | 设置 ANSIBLE_HOST_KEY_CHECKING=False |
| Permission denied (publickey) | SSH私钥权限或路径错误 | 确认私钥600权限且Jenkins用户可读 |
| Playbook执行成功但服务未更新 | notify 未触发Handler | 检查模板文件是否真正发生了变更 |
| missing required library: jmespath | 缺少JSON查询库 | pip install jmespath |
📊 三种方案对比总结
| Shell直接调用 | ⭐ | ⭐⭐ | 小 | 学习测试、简单项目 |
| Ansible Plugin | ⭐⭐ | ⭐⭐⭐⭐ | 中 | 生产环境常规部署 |
| Tower API调用 | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | 大 | 企业级集群、多团队协作 |
💎 总结
通过本文,你已掌握Jenkins与Ansible集成的核心要点:
将Jenkins的可视化编排能力与Ansible的无代理批量管理能力结合,你的自动化运维体系将迈入代码即配置、部署即流水线的新阶段!

|
🌺The End🌺点点关注,收藏不迷路🌺 ⬆ ⬆ 顶部 ⬆ ⬆ |






