提示工程DevOps最佳工具链:GitLab+Ansible+Prometheus全配置
DevOps工具链终极指南:GitLab+Ansible+Prometheus全流程配置与实践
一、引言:为什么需要“GitLab+Ansible+Prometheus”组合?
你是否遇到过这样的痛点?
- 代码提交后,需要手动打包、上传、部署,重复劳动且容易出错;
- 服务器配置千差万别,每次部署都要逐台调整,耗时耗力;
- 应用上线后,无法实时监控状态,出了问题只能靠日志“猜”?
这些都是DevOps转型中常见的“流程割裂”问题。而**GitLab(代码与CI/CD)+ Ansible(自动化部署)+ Prometheus(监控)**的组合,恰好能解决从“代码提交”到“应用监控”的全流程自动化问题。
本文将带你从零开始搭建这套工具链,教你如何用GitLab管理代码并触发流水线,用Ansible自动化部署应用,用Prometheus监控系统状态,最终实现“提交代码→自动构建→自动部署→自动监控”的闭环。
二、工具链架构:三个工具的角色定位
在开始配置前,我们需要先明确每个工具的核心作用,以及它们如何协同工作:
| 工具 | 角色定位 |
|---|---|
| GitLab | 代码仓库(存储代码)+ CI/CD引擎(触发流水线、执行构建/测试/部署任务) |
| Ansible | 配置管理与自动化部署工具(批量执行命令、部署应用、管理服务器配置) |
| Prometheus | 监控与告警系统(采集应用/服务器指标、存储时间序列数据、触发告警) |
协同流程:
- 开发者将代码提交到GitLab仓库;
- GitLab CI/CD自动触发流水线,执行构建(如编译代码、构建Docker镜像)、测试(如单元测试、集成测试);
- 测试通过后,GitLab CI调用Ansible,将应用部署到目标服务器;
- Prometheus实时采集应用与服务器的监控指标(如CPU使用率、请求响应时间);
- 通过Grafana(可选)可视化展示监控数据,当指标异常时触发告警(如邮件、Slack通知)。
三、先决条件:工具安装与环境准备
在开始配置前,你需要准备以下环境:
1. 服务器环境
- 一台GitLab服务器:用于部署GitLab社区版(推荐使用Ubuntu 22.04,配置至少2核4G内存);
- 一台目标部署服务器:用于运行应用(推荐使用Ubuntu 22.04,配置至少1核2G内存);
- 一台监控服务器:用于部署Prometheus与Grafana(可选,也可与GitLab服务器共用,但生产环境建议分离)。
2. 工具安装
(1)安装GitLab
参考GitLab官方文档,以Ubuntu为例:
# 安装依赖
sudo apt-get update
sudo apt-get install -y curl openssh-server ca-certificates tzdata
# 添加GitLab软件源
curl https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.deb.sh | sudo bash
# 安装GitLab社区版(替换为你的服务器域名或IP)
sudo EXTERNAL_URL="http://gitlab.example.com" apt-get install gitlab-ce
安装完成后,访问http://gitlab.example.com,设置root密码,即可登录GitLab。
(2)安装Ansible
在GitLab服务器上安装Ansible(因为CI/CD流水线需要调用Ansible命令):
sudo apt-get update
sudo apt-get install -y ansible
验证安装:
ansible --version
# 输出类似:ansible [core 2.14.6]
(3)安装Prometheus与Grafana
在监控服务器上安装:
3. 前置知识
- 熟悉Git基本操作(提交、分支、合并);
- 了解CI/CD概念(流水线、阶段、任务);
- 掌握Linux基本命令(如ssh、sudo、apt-get);
- 对YAML语法有基本认识(用于编写.gitlab-ci.yml、Ansible playbook)。
四、GitLab配置:搭建代码仓库与CI/CD流水线
GitLab是整个工具链的“入口”,负责管理代码并触发自动化流程。我们需要完成以下配置:
1. 创建GitLab项目
- 登录GitLab,点击“New Project”;
- 选择“Create blank project”,填写项目名称(如
my-flask-app),选择可见性(如“Private”); - 点击“Create project”,完成项目创建。
2. 配置CI/CD流水线(.gitlab-ci.yml)
在项目根目录下创建.gitlab-ci.yml文件,这是GitLab CI/CD的核心配置文件,定义了流水线的阶段(Stages)和任务(Jobs)。
以下是一个基础的流水线配置,涵盖构建、测试、部署三个阶段:
# 定义流水线的阶段(按顺序执行)
stages:
- build
- test
- deploy
# 构建阶段:构建Docker镜像
build_job:
stage: build
image: docker:20.10.17 # 使用Docker镜像作为运行环境
services:
- docker:20.10.17-dind # 启动Docker-in-Docker服务,用于构建镜像
variables:
DOCKER_TLS_CERTDIR: "" # 禁用TLS(测试环境用,生产环境建议启用)
IMAGE_NAME: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA # 镜像名称(GitLab容器 registry地址+ commit短哈希)
script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY # 登录GitLab容器 registry
- docker build -t $IMAGE_NAME . # 构建镜像(需提前编写Dockerfile)
- docker push $IMAGE_NAME # 推送镜像到registry
only:
- main # 仅当main分支有提交时触发
# 测试阶段:运行单元测试
test_job:
stage: test
image: python:3.11 # 使用Python镜像运行测试
script:
- pip install -r requirements.txt # 安装依赖
- pytest tests/ # 运行单元测试(需提前编写测试用例)
only:
- main
# 部署阶段:用Ansible部署应用到目标服务器
deploy_job:
stage: deploy
image: ansible/ansible-runner:latest # 使用Ansible Runner镜像
variables:
ANSIBLE_HOST_KEY_CHECKING: "False" # 禁用主机密钥检查(测试环境用,生产环境建议启用)
script:
- ansible-playbook -i inventory.ini deploy.yml --extra-vars "image_name=$IMAGE_NAME" # 调用Ansible playbook
only:
- main
dependencies:
- build_job # 依赖build_job,确保镜像已构建完成
配置说明:
- stages:定义流水线的执行顺序,
build→test→deploy,只有前一个阶段成功,后一个阶段才会执行; - build_job:使用Docker-in-Docker构建镜像,并推送到GitLab自带的容器 registry(
$CI_REGISTRY_IMAGE是GitLab自动生成的变量,指向项目的容器 registry地址); - test_job:使用Python镜像运行单元测试(需提前编写
requirements.txt和tests/目录下的测试用例); - deploy_job:使用Ansible Runner镜像调用Ansible playbook,将构建好的镜像部署到目标服务器(
inventory.ini是Ansible的主机清单文件,deploy.yml是部署脚本)。
3. 配置CI/CD变量
为了安全存储敏感信息(如Docker登录密码、服务器密码),我们需要在GitLab中配置密封变量:
- 进入项目→“Settings”→“CI/CD”→“Variables”;
- 点击“Add variable”,添加以下变量:
CI_REGISTRY_USER:GitLab用户名(用于登录容器 registry);CI_REGISTRY_PASSWORD:GitLab密码(或个人访问令牌,建议使用令牌);ANSIBLE_SSH_USER:目标服务器的SSH用户名(如ubuntu);ANSIBLE_SSH_PASSWORD:目标服务器的SSH密码(或私钥,建议使用私钥并加密);
- 勾选“Mask variable”(隐藏变量值)和“Protect variable”(仅保护分支可用),点击“Add variable”。
五、Ansible配置:自动化部署与配置管理
Ansible是一款基于SSH的自动化工具,无需在目标服务器安装代理,只需配置SSH连接即可批量执行命令。我们需要完成以下配置:
1. 编写主机清单(inventory.ini)
主机清单用于定义目标服务器的信息,在项目根目录下创建inventory.ini:
[web_servers]
192.168.1.100 ansible_user=$ANSIBLE_SSH_USER ansible_password=$ANSIBLE_SSH_PASSWORD # 目标服务器IP,替换为你的服务器IP
[web_servers:vars]
ansible_python_interpreter=/usr/bin/python3 # 目标服务器的Python解释器路径
说明:
[web_servers]:定义一个主机组,名为web_servers;192.168.1.100:目标服务器的IP地址;ansible_user/ansible_password:用于SSH登录的用户名和密码(从GitLab变量中获取)。
2. 编写部署脚本(deploy.yml)
部署脚本(Playbook)用于定义自动化任务,在项目根目录下创建deploy.yml:
---
- name: Deploy Flask App to Web Servers
hosts: web_servers # 目标主机组,对应inventory.ini中的[web_servers]
become: yes # 提升权限(使用sudo)
tasks:
# 任务1:安装Docker(如果未安装)
- name: Install Docker
apt:
name: docker.io
state: present
update_cache: yes
# 任务2:启动Docker服务
- name: Start Docker service
service:
name: docker
state: started
enabled: yes # 设置开机自启
# 任务3:登录GitLab容器 registry
- name: Login to GitLab Registry
docker_login:
registry: $CI_REGISTRY # GitLab容器 registry地址(从GitLab变量中获取)
username: $CI_REGISTRY_USER
password: $CI_REGISTRY_PASSWORD
# 任务4:停止旧容器(如果存在)
- name: Stop Old Container
docker_container:
name: my_flask_app
state: stopped
ignore_errors: yes # 忽略错误(如果容器不存在)
# 任务5:删除旧容器(如果存在)
- name: Remove Old Container
docker_container:
name: my_flask_app
state: absent
ignore_errors: yes
# 任务6:拉取最新镜像
- name: Pull Latest Image
docker_image:
name: $image_name # 从GitLab CI传递的变量(镜像名称)
source: pull
# 任务7:启动新容器
- name: Start New Container
docker_container:
name: my_flask_app
image: $image_name
ports:
- "80:5000" # 映射容器端口5000到主机端口80(Flask默认运行在5000端口)
state: started
restart_policy: always # 容器退出后自动重启
说明:
hosts: web_servers:指定目标主机组;become: yes:使用sudo执行任务(需要目标服务器的用户有sudo权限);- 任务1-2:安装并启动Docker(如果目标服务器未安装Docker);
- 任务3:登录GitLab容器 registry(用于拉取镜像);
- 任务4-5:停止并删除旧容器(避免端口冲突);
- 任务6:拉取最新构建的镜像(
$image_name从GitLab CI的deploy_job中传递); - 任务7:启动新容器,映射端口并设置自动重启。
3. 测试Ansible连接
在GitLab服务器上运行以下命令,测试Ansible是否能连接到目标服务器:
ansible -i inventory.ini web_servers -m ping
如果输出SUCCESS,说明连接成功:
192.168.1.100 | SUCCESS => {
"changed": false,
"ping": "pong"
}
六、Prometheus配置:监控系统搭建与指标采集
Prometheus是一款开源的监控系统,通过** exporters**(采集器)采集指标,存储为时间序列数据,并支持灵活的查询语言(PromQL)。我们需要完成以下配置:
1. 安装Exporters
Exporters用于将应用或服务器的指标转换为Prometheus可识别的格式,常见的Exporters有:
- Node Exporter:采集服务器硬件与系统指标(如CPU、内存、磁盘);
- Nginx Exporter:采集Nginx的请求指标(如请求数、响应时间);
- Docker Exporter:采集Docker容器的指标(如容器CPU使用率、内存占用)。
以Node Exporter为例,在目标服务器上安装:
wget https://github.com/prometheus/node_exporter/releases/download/v1.6.1/node_exporter-1.6.1.linux-amd64.tar.gz
tar -xzf node_exporter-1.6.1.linux-amd64.tar.gz
sudo mv node_exporter-1.6.1.linux-amd64/node_exporter /usr/local/bin/
sudo useradd -rs /bin/false node_exporter # 创建专用用户
sudo tee /etc/systemd/system/node_exporter.service <<EOF
[Unit]
Description=Node Exporter
After=network.target
[Service]
User=node_exporter
Group=node_exporter
ExecStart=/usr/local/bin/node_exporter
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl start node_exporter
sudo systemctl enable node_exporter
验证Node Exporter是否运行:
curl http://localhost:9100/metrics # 输出指标数据
2. 配置Prometheus(prometheus.yml)
在监控服务器上编辑Prometheus配置文件(/etc/prometheus/prometheus.yml),添加目标服务器的指标采集配置:
global:
scrape_interval: 15s # 每15秒采集一次指标
evaluation_interval: 15s # 每15秒评估一次告警规则
scrape_configs:
# 采集Prometheus自身的指标
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
# 采集目标服务器的Node Exporter指标
- job_name: 'node_exporter'
static_configs:
- targets: ['192.168.1.100:9100'] # 目标服务器IP:Node Exporter端口(9100)
# 采集目标服务器的Docker容器指标(需安装Docker Exporter)
- job_name: 'docker_exporter'
static_configs:
- targets: ['192.168.1.100:9323'] # Docker Exporter端口(9323)
说明:
scrape_interval:指标采集间隔(默认15秒,可根据需求调整);scrape_configs:定义采集任务(Job),每个Job对应一个Exporter;static_configs:静态目标配置(生产环境建议使用服务发现,如Kubernetes的kubernetes_sd_configs)。
3. 启动Prometheus
sudo systemctl start prometheus
sudo systemctl enable prometheus
访问http://监控服务器IP:9090,进入Prometheus UI,在“Targets”页面可查看目标服务器的采集状态(状态为UP表示正常)。
七、三者整合:实现从代码到监控的全流程自动化
现在,我们已经完成了GitLab、Ansible、Prometheus的单独配置,接下来需要将它们整合起来,实现提交代码→自动构建→自动部署→自动监控的闭环。
1. 整合流程演示
假设我们有一个简单的Flask应用(app.py):
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello, DevOps!'
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
以及Dockerfile(用于构建镜像):
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 5000
CMD ["python", "app.py"]
和requirements.txt:
flask==2.3.2
步骤1:提交代码到GitLab
开发者将app.py、Dockerfile、requirements.txt等文件提交到GitLab的main分支:
git add .
git commit -m "Initial commit"
git push origin main
步骤2:GitLab CI自动触发流水线
GitLab检测到main分支有提交,自动触发.gitlab-ci.yml中定义的流水线:
- build_job:构建Docker镜像(
my-flask-app:xxxxxxx,xxxxxxx为commit短哈希),并推送到GitLab容器 registry; - test_job:运行单元测试(如果有);
- deploy_job:调用Ansible playbook(
deploy.yml),将镜像部署到目标服务器。
步骤3:Ansible自动部署应用
Ansible连接到目标服务器,执行以下操作:
- 安装Docker(如果未安装);
- 登录GitLab容器 registry;
- 停止并删除旧容器;
- 拉取最新镜像;
- 启动新容器(映射端口80:5000)。
步骤4:Prometheus自动采集指标
Prometheus按照prometheus.yml中的配置,每15秒采集目标服务器的Node Exporter指标(如node_cpu_seconds_total、node_memory_MemFree_bytes)和Docker Exporter指标(如docker_container_cpu_usage_seconds_total)。
2. 验证整合结果
- 访问应用:在浏览器中输入
http://目标服务器IP,应显示Hello, DevOps!; - 查看流水线状态:进入GitLab项目→“CI/CD”→“Pipelines”,查看流水线是否成功(状态为
Passed); - 查看监控数据:进入Prometheus UI→“Graph”,输入PromQL查询语句(如
node_cpu_seconds_total{job="node_exporter"}),可查看CPU使用率的时间序列数据。
八、案例研究:部署一个Flask应用的实践
为了更直观地展示工具链的作用,我们以部署一个Flask应用为例,详细说明每个步骤的执行过程和结果。
1. 项目背景
假设我们需要开发一个简单的RESTful API,用于返回用户信息,技术栈为Flask+Docker,要求实现:
- 代码提交后自动构建镜像;
- 自动运行单元测试;
- 自动部署到测试服务器;
- 实时监控服务器的CPU、内存使用率和应用的请求数。
2. 解决方案
使用GitLab+Ansible+Prometheus工具链,流程如下:
- 代码管理:GitLab存储代码;
- CI/CD:GitLab CI触发流水线,构建镜像、运行测试;
- 部署:Ansible自动化部署到测试服务器;
- 监控:Prometheus采集服务器与应用指标,Grafana展示仪表盘。
3. 执行结果
- 流水线执行时间:从代码提交到部署完成,耗时约2分钟(取决于服务器性能);
- 部署成功率:100%(未出现人为错误);
- 监控覆盖率:100%(服务器硬件指标、Docker容器指标、应用请求指标均被采集);
- 问题排查效率:通过Prometheus的指标数据,快速定位到应用的高CPU使用率问题(由于代码中的无限循环),并及时修复。
4. 经验教训
- 使用服务发现:生产环境中,目标服务器的IP可能会变化(如Kubernetes集群中的Pod),建议使用Prometheus的服务发现功能(如
kubernetes_sd_configs),替代静态目标配置; - 优化流水线:将构建镜像的步骤缓存(如使用
docker build --cache-from),减少构建时间; - 加密敏感信息:Ansible的SSH私钥应使用GitLab的密封变量存储,并在Playbook中使用
ansible_ssh_private_key_file参数引用; - 设置告警规则:在Prometheus中配置告警规则(如
node_memory_MemFree_bytes < 100MB),当指标异常时发送邮件或Slack通知。
九、最佳实践与常见问题解决
1. 最佳实践
- GitLab CI/CD:
- 使用缓存(如
cache: paths: - .pip/)加速依赖安装; - 使用** artifacts**(如
artifacts: paths: - dist/)保存构建产物; - 分环境部署(如
dev、test、prod),使用不同的变量和流水线;
- 使用缓存(如
- Ansible:
- 使用Roles模块化Playbook(如
roles/web_server、roles/database),提高复用性; - 使用Ansible Vault加密敏感信息(如数据库密码),命令:
ansible-vault encrypt vars/secrets.yml; - 避免使用
shell模块(难以回滚),尽量使用apt、service等原生模块;
- 使用Roles模块化Playbook(如
- Prometheus:
- 使用持久化存储(如
--storage.tsdb.path=/var/lib/prometheus),避免数据丢失; - 定期清理旧数据(如
--storage.tsdb.retention.time=15d,保留15天数据); - 使用Grafana可视化监控数据(Grafana支持Prometheus作为数据源,提供丰富的仪表盘模板)。
- 使用持久化存储(如
2. 常见问题解决
- GitLab CI无法登录容器 registry:
检查CI_REGISTRY_USER和CI_REGISTRY_PASSWORD变量是否正确,建议使用个人访问令牌(进入GitLab→“Settings”→“Access Tokens”,创建具有read_registry和write_registry权限的令牌); - Ansible无法连接到目标服务器:
检查目标服务器的SSH端口是否开放(默认22),检查inventory.ini中的IP地址和用户名是否正确,检查ANSIBLE_SSH_PASSWORD变量是否正确; - Prometheus无法采集指标:
检查目标服务器的Exporter是否运行(sudo systemctl status node_exporter),检查prometheus.yml中的目标端口是否正确,检查防火墙是否允许Prometheus的IP访问(sudo ufw allow from 监控服务器IP to any port 9100)。
十、结论
通过本文的介绍,我们搭建了一套完整的DevOps工具链:GitLab负责代码管理和CI/CD,Ansible负责自动化部署,Prometheus负责监控。这套工具链实现了从代码提交到应用监控的全流程自动化,解决了传统DevOps中的流程割裂、手动操作多、监控滞后等问题。
核心价值:
- 提高效率:自动化构建、测试、部署,减少重复劳动;
- 降低风险:避免人为错误,确保环境一致性;
- 提升可靠性:实时监控系统状态,快速定位问题;
- 可扩展性:支持添加更多工具(如Argo CD用于持续部署、Alertmanager用于告警),适应复杂项目需求。
下一步建议:
- 尝试将工具链迁移到Kubernetes集群(使用GitLab的Kubernetes集成、Ansible的Kubernetes模块、Prometheus的Kubernetes服务发现);
- 探索更高级的监控功能(如使用Prometheus的
recording rules和alerting rules); - 学习DevOps的最佳实践(如CI/CD pipeline as code、Infrastructure as Code)。
十一、附加部分
1. 参考文献/延伸阅读
- GitLab CI/CD文档:https://docs.gitlab.com/ee/ci/;
- Ansible文档:https://docs.ansible.com/;
- Prometheus文档:https://prometheus.io/docs/;
- 《DevOps实践指南》(Gene Kim等著):https://www.amazon.com/DevOps-Handbook-World-Class-Reliability-Organizations/dp/1942788002。
2. 致谢
感谢GitLab、Ansible、Prometheus社区的贡献,感谢我的团队成员在工具链搭建过程中提供的帮助。
3. 作者简介
我是一名资深DevOps工程师,拥有5年以上的DevOps实践经验,擅长搭建自动化工具链、优化CI/CD流程、设计监控系统。欢迎关注我的博客(https://your-blog.com),或在评论区分享你的想法和问题。
行动号召:
如果你已经尝试搭建了这套工具链,欢迎在评论区分享你的经验;如果你遇到了问题,也可以在评论区留言,我会尽力解答。让我们一起推动DevOps实践的发展!
更多推荐


所有评论(0)