DevOps工具链终极指南:GitLab+Ansible+Prometheus全流程配置与实践

一、引言:为什么需要“GitLab+Ansible+Prometheus”组合?

你是否遇到过这样的痛点?

  • 代码提交后,需要手动打包、上传、部署,重复劳动且容易出错;
  • 服务器配置千差万别,每次部署都要逐台调整,耗时耗力;
  • 应用上线后,无法实时监控状态,出了问题只能靠日志“猜”?

这些都是DevOps转型中常见的“流程割裂”问题。而**GitLab(代码与CI/CD)+ Ansible(自动化部署)+ Prometheus(监控)**的组合,恰好能解决从“代码提交”到“应用监控”的全流程自动化问题。

本文将带你从零开始搭建这套工具链,教你如何用GitLab管理代码并触发流水线,用Ansible自动化部署应用,用Prometheus监控系统状态,最终实现“提交代码→自动构建→自动部署→自动监控”的闭环。

二、工具链架构:三个工具的角色定位

在开始配置前,我们需要先明确每个工具的核心作用,以及它们如何协同工作:

工具 角色定位
GitLab 代码仓库(存储代码)+ CI/CD引擎(触发流水线、执行构建/测试/部署任务)
Ansible 配置管理与自动化部署工具(批量执行命令、部署应用、管理服务器配置)
Prometheus 监控与告警系统(采集应用/服务器指标、存储时间序列数据、触发告警)

协同流程

  1. 开发者将代码提交到GitLab仓库;
  2. GitLab CI/CD自动触发流水线,执行构建(如编译代码、构建Docker镜像)、测试(如单元测试、集成测试);
  3. 测试通过后,GitLab CI调用Ansible,将应用部署到目标服务器;
  4. Prometheus实时采集应用与服务器的监控指标(如CPU使用率、请求响应时间);
  5. 通过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

监控服务器上安装:

  • 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:定义流水线的执行顺序,buildtestdeploy,只有前一个阶段成功,后一个阶段才会执行;
  • build_job:使用Docker-in-Docker构建镜像,并推送到GitLab自带的容器 registry($CI_REGISTRY_IMAGE是GitLab自动生成的变量,指向项目的容器 registry地址);
  • test_job:使用Python镜像运行单元测试(需提前编写requirements.txttests/目录下的测试用例);
  • 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.pyDockerfilerequirements.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:xxxxxxxxxxxxxx为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_totalnode_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/)保存构建产物;
    • 环境部署(如devtestprod),使用不同的变量和流水线;
  • Ansible
    • 使用Roles模块化Playbook(如roles/web_serverroles/database),提高复用性;
    • 使用Ansible Vault加密敏感信息(如数据库密码),命令:ansible-vault encrypt vars/secrets.yml
    • 避免使用shell模块(难以回滚),尽量使用aptservice等原生模块;
  • Prometheus
    • 使用持久化存储(如--storage.tsdb.path=/var/lib/prometheus),避免数据丢失;
    • 定期清理旧数据(如--storage.tsdb.retention.time=15d,保留15天数据);
    • 使用Grafana可视化监控数据(Grafana支持Prometheus作为数据源,提供丰富的仪表盘模板)。

2. 常见问题解决

  • GitLab CI无法登录容器 registry
    检查CI_REGISTRY_USERCI_REGISTRY_PASSWORD变量是否正确,建议使用个人访问令牌(进入GitLab→“Settings”→“Access Tokens”,创建具有read_registrywrite_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 rulesalerting rules);
  • 学习DevOps的最佳实践(如CI/CD pipeline as code、Infrastructure as Code)。

十一、附加部分

1. 参考文献/延伸阅读

2. 致谢

感谢GitLab、Ansible、Prometheus社区的贡献,感谢我的团队成员在工具链搭建过程中提供的帮助。

3. 作者简介

我是一名资深DevOps工程师,拥有5年以上的DevOps实践经验,擅长搭建自动化工具链、优化CI/CD流程、设计监控系统。欢迎关注我的博客(https://your-blog.com),或在评论区分享你的想法和问题。

行动号召
如果你已经尝试搭建了这套工具链,欢迎在评论区分享你的经验;如果你遇到了问题,也可以在评论区留言,我会尽力解答。让我们一起推动DevOps实践的发展!

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐