(三)学习、实践、理解 CI/CD 与 DevOps:声明式 API,Docker Compose 容器编排

系列文章:

(一)学习、实践、理解 CI/CD 与 DevOps:起步

(二)学习、实践、理解 CI/CD 与 DevOps:容器化

云原生的代表技术包括容器、服务网格、微服务、不可变基础设施和声明式 API

Docker Compose 的技术理念,以及配置文件 docker-compose.yml 则是声明式 API 的一个重要实践。

声明式API

声明式 API(Declarative API)是一种定义系统期望状态的接口设计范式,用户只需描述「要什么」,而非「怎么做」,系统通过持续调和自动将实际状态收敛到期望状态。

它是云原生自动化和弹性的核心机制。

与之对应的是命令式 API,用户需明确每一步操作。以下是最典型与常见的命令式 API和声明式 API 的类型对比,按领域分类整理:

领域 命令式 API(Imperative) 声明式 API(Declarative)
云原生/K8s kubectl run、create、delete(需手动执行每一步) kubectl apply -f yaml(定义状态,系统自动调和)
数据库 手写遍历、连接、过滤等逻辑(如Java代码处理数据) SQL 查询语句(如SELECT * FROM users WHERE age > 18
前端开发 jQuery 操作 DOM(如$('.btn').click(...) Vue/React 模板语法(如<button @click="handle">
基础设施 Ansible 脚本、Shell 脚本(一步步执行命令) Terraform HCL、Kubernetes YAML(描述期望状态)
自动化运维 手动执行扩容命令(如kubectl scale --replicas=5 Deployment 文件中声明replicas: 5,控制器自动维持

在 Docker 容器服务中,docker rundocker execdocker build 等均为命令式 API,而 Docker Compose 则以声明式 API 的方式,通过定义 docker-compose.yml 文件,描述容器服务的期望状态,系统自动将实际状态收敛到期望状态。

阶段五:docker-compose 容器编排

在阶段四中,使用命令式API docker builddocker rundocker stop docker rm docker rmi 等指令操作容器,存在多个显著缺陷:

  1. 手动操作多、易出错:每一步(如构建镜像、启动容器、更新服务、容器卸载、镜像清理)都需手动执行命令,容易遗漏或出错。
  2. 部署流程不可复现:没有统一描述文件,部署依赖人工记忆和脚本(或操作手册),团队协作困难,不利于长期维护。
  3. 容器依赖管理困难:容器实例间的依赖顺序需人工维护配置,如先启动 MySQL,然后启动 Nacos、Redis,再启动鉴权微服务、核心微服务等。
  4. 无版本管理:手动执行 shell 指令无法记录到 git 仓库,无法追踪和管理版本。
  5. 可移植性:在不同的环境中,如本地、测试、生产等,需手动调整配置,如端口、环境变量等,增加了部署的难度。

上述问题,Docker Compose 声明式 API 可以有效解决:

  1. 配置即代码:在 docker-compose.yml 声明期望状态,与源码一起提交到 git 仓库,支持版本管理。
  2. 容器编排:通过单一 YAML 文件定义多个服务、网络、卷等资源,并借助 depends_on 字段声明服务间的依赖顺序。
  3. 开箱即用:项目配置由 docker-compose.yml 文件定义,用户仅需执行 docker compose up -ddocker-compose down 等少量项目无关的命令式指令,可一键启动整个多容器应用栈,可移植性高。

此外,还有环境一致一键生命周期管理的特点。


引入 Docker Compose,进入阶段五:

  1. 在个人电脑上使用 IDE 如 VsCode、WebStorm 开发、调试
  2. 本地开发环境,查看开发效果 npm run dev
  3. 制作 Dockerfile,并编辑 docker-compose.yml
  4. 执行 docker build 生成容器镜像
  5. 将生成的镜像推送到 DockerHub 等镜像仓库
  6. 在云服务器上(具备公网 IP)拉取项目
  7. 执行 docker-compose up -d 启动容器实例

如果不使用镜像仓库,也可以在云服务器上直接构建镜像,略过步骤4和步骤5,步骤7执行 docker-compose up -d --build

其他 Docker Compose 指令:

  • docker-compose down:停止并删除容器实例
  • docker-compose logs:查看容器实例日志
  • docker-compose ps:查看容器实例状态

本项目 docker-compose.yml,除了项目核心:Nginx 静态资源代理,还增加了 Nginx负载均衡、可观测性套件服务如 grafana、prometheus、loki 等,共计 8 个容器实例。

试想如果使用 docker run 来执行,不仅需要执行多条指令,还需要考虑网络、端口、环境变量、挂载卷、依赖关系等,会是什么样的体验?繁琐是一方面,出差错是更难接受的。

yaml 复制代码
networks:
  tiny-sparrow-network:
    external: false
services:
  # 软负载
  nginx-gateway:
    image: nginx:alpine3.20-perl
    container_name: nginx-gateway
    ports:
      - "80:80"
    networks:
      - tiny-sparrow-network
    volumes:
      # 设置目录挂载
      - ./nginx.conf:/etc/nginx/conf.d/default.conf

  # VitePress 静态网站
  vitepress-website:
    image: xxl1997/xiaolin-docs:0.0.1
    build: ./
    container_name: vitepress-website
    volumes:
      - ./volumes/website/logs:/var/log/nginx
    networks:
      - tiny-sparrow-network
    environment:
      # 设置中国时区
      TZ: Asia/Shanghai


  # Grafana
  # 默认端口3000
  grafana-website:
    image: grafana/grafana:11.3.2-ubuntu
    container_name: grafana-website
    networks:
      - tiny-sparrow-network
    ports:
      - "9000:3000"
    volumes:
      - ./volumes/grafana/grafana.ini:/etc/grafana/grafana.ini:ro
      - ./volumes/grafana/provisioning/etc/datasources:/etc/grafana/provisioning/datasources:ro
      - ./volumes/grafana/provisioning/etc/dashboards:/etc/grafana/provisioning/dashboards:ro
      - ./volumes/grafana/provisioning/var/dashboards:/var/lib/grafana/dashboards:ro
    environment:
      # 中国时区、匿名登陆
      TZ: Asia/Shanghai
      GF_AUTH_ANONYMOUS_ENABLED: true
      GF_AUTH_ANONYMOUS_ORG_ROLE: Admin
      GF_USERS_ALLOW_SIGN_UP: false

  # Prometheus
  prometheus-website:
    image: prom/prometheus:v2.53.3
    container_name: prometheus-website
    volumes:
      # 设置目录挂载
      - ./volumes/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
    environment:
      TZ: Asia/Shanghai
    networks:
      - tiny-sparrow-network
    command:
      - "--config.file=/etc/prometheus/prometheus.yml" # prometheus配置文件
      - "--storage.tsdb.path=/prometheus" # prometheus数据存储路径

  # 启动node-exporter
  # 该模式仅支持在 Linux 中运行
  # 容器内端口9100
  node-exporter-website:
    image: prom/node-exporter:v1.8.2
    container_name: node-exporter-website
    environment:
      TZ: Asia/Shanghai
    # host宿主机模式
    network_mode: host
    # 容器与宿主机共享进程号
    pid: host
    # https://github.com/prometheus/node_exporter
    volumes:
      - '/:/host:ro,rslave'
    command:
      - '--path.rootfs=/host'

  # nginx-prometheus-exporter
  nginx-exporter-website:
    image: nginx/nginx-prometheus-exporter:1.4
    container_name: nginx-exporter-website
    # 默认端口:9113
    environment:
      TZ: Asia/Shanghai
    networks:
      - tiny-sparrow-network
    # 需要与抓取的 Nginx 服务在同一网络,且信息一致
    command: "--nginx.scrape-uri=http://vitepress-website:8081/stub_status" # 配置 Prometheus 抓取 Nginx 状态的 URI

  promtail-website:
    image: grafana/promtail:3.4
    container_name: promtail-website
    volumes:
      # 设置目录挂载
      - ./volumes/promtail/promtail.yaml:/etc/promtail/promtail.yaml:ro
      - ./volumes/website/logs:/var/log
    environment:
      TZ: Asia/Shanghai
    networks:
      - tiny-sparrow-network
    command:
      - "--config.file=/etc/promtail/promtail.yaml" # promtail配置文件
    depends_on:
      - loki-website

  # Loki
  # 默认端口3100
  loki-website:
    image: grafana/loki:3.4
    container_name: loki-website
    ports:
      - "3100:3100"
    volumes:
      - ./volumes/loki/loki-local-config.yaml:/etc/loki/local-config.yaml:ro
    environment:
      TZ: Asia/Shanghai
    networks:
      - tiny-sparrow-network
    command:
      - "--config.file=/etc/loki/local-config.yaml"

总结

如果你有过在 GitHub 中搜查项目的经验,Docker Compose 已经成为开箱即用的最佳实践。

Docker Compose 作为声明式容器编排工具,其价值与项目复杂度呈现正相关关系。

大前端场景 中,由于通常仅需管理少量容器(如前端应用、Nginx 等),手动执行 docker run 等命令即可满足基本需求,Docker Compose 的优势可能不够显著。

然而,当面对微服务集群时,Docker Compose 的价值即刻凸显。

本文将在后期引入 SpringCloud 微服务场景。

关注微信公众号,获取运维资讯

如果此篇文章对你有所帮助,感谢你的点赞收藏,也欢迎在评论区友好交流。

微信搜索关注公众号:持续运维

参考

  1. Docker Compose,docs.docker.com/compose/
  2. Docker Compose 命令,docs.docker.com/compose/ref...
相关推荐
茗创科技3 分钟前
Nature Neuroscience | 如何在大规模自动化MRI分析中规避伪影陷阱?
运维·自动化
爱喝水的鱼丶1 小时前
SAP-ABAP: Open SQL集合函数COUNT(统计行数)、SUM(数值求和)、AVG(平均值)、MAX/MIN(极值)深度指南
运维·数据库·sql·sap·报表·abap·程序
AI 嗯啦2 小时前
linux的用户操作(详细介绍)
linux·运维·服务器
东东今天敲代码了吗2 小时前
Ubuntu20.04 离线安装 FFmpeg 静态编译包
linux·运维·服务器·ubuntu·ffmpeg
LH_R2 小时前
OneTerm 开源堡垒机 | 历时三个月重构大更新
运维·后端·安全
敢敢のwings3 小时前
Latent Action在具身智能中的使用
运维·chrome
mylove_北极甜虾3 小时前
OpenWebUI通过pipeline对接dify的workflow
运维·容器·dify·openwebui
Lemon程序馆3 小时前
Arthas | Java 线上问题快速定位神器
java·运维·后端
tjjingpan4 小时前
HCIP-Datacom Core Technology V1.0_6 IS-IS原理和配置
linux·运维·服务器