欢迎光临
我们一直在努力

Jenkins集成Ansible自动化配置管理:3种方案打通CI与IaC全流程

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是双手(执行、落地)。
  • 三种集成方案从**简单Shell企业Tower API**,按需选择。
  • Ansible的**幂等性**保证了无论执行多少次,服务器状态始终一致。
  • 结合**动态Inventory滚动更新**,可实现零停机部署。
  • 将Jenkins的可视化编排能力与Ansible的无代理批量管理能力结合,你的自动化运维体系将迈入代码即配置、部署即流水线的新阶段!

    在这里插入图片描述

    🌺The End🌺点点关注,收藏不迷路🌺

    ⬆ ⬆ 顶部 ⬆ ⬆

    赞(0)
    未经允许不得转载:171主机测评 » Jenkins集成Ansible自动化配置管理:3种方案打通CI与IaC全流程
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址