Skip to content

DevOps 从零到生产级掌握 ​

DevOps 不是“会用 Docker 命令”或“会点 Jenkins 发布按钮”。商业项目真正需要的是:代码能稳定构建,制品能追踪,配置能隔离,发布能回滚,服务能观测,故障能定位,权限和密钥不乱放。

一句话建立主线:

DevOps 是把开发、测试、构建、制品、部署、运行、监控、告警、回滚、复盘连接成闭环,让软件可以稳定、可重复、可审计地交付到生产环境。

学习目标 ​

学完这一页,你要能做到:

  1. 说清楚代码从提交到用户访问的全过程。
  2. 区分源码、构建产物、镜像、容器、Pod、服务入口。
  3. 解释 Docker 镜像分层、容器隔离、端口映射、数据卷和网络。
  4. 解释 Nginx 反向代理、负载均衡、限流、HTTPS 和静态资源缓存。
  5. 解释 Jenkins Pipeline 如何拉代码、测试、打包、构建镜像、部署和回滚。
  6. 解释 Kubernetes 中 Pod、Deployment、ReplicaSet、Service、Ingress、ConfigMap、Secret、Probe、Volume 的关系。
  7. 能写最小 Dockerfile、docker-compose、Jenkinsfile、K8s Deployment/Service YAML。
  8. 能排查“服务访问不了、发布失败、Pod 起不来、接口变慢、磁盘打满、配置不生效、健康检查失败”。
  9. 能把 DevOps 用到订单、支付、采集、搜索、网关、后台管理等商业系统。

如果要按“零基础能学会、面试能讲清、生产能排查”的标准验收,请配合阅读 DevOps 从零到精通验收清单。本页负责串主线,验收清单负责把 Docker、Nginx、Jenkins、Kubernetes、发布回滚和排障拆成可检查的学习目标。

全链路流程 ​

mermaid
flowchart TD
    A["开发提交代码"] --> B["Git 仓库"]
    B --> C["CI 触发流水线"]
    C --> D["编译和单元测试"]
    D --> E["打包产物<br/>jar 或 dist"]
    E --> F["构建 Docker 镜像"]
    F --> G["推送镜像仓库"]
    G --> H["部署到 Kubernetes"]
    H --> I["Pod 启动和健康检查"]
    I --> J["Service 提供集群内访问"]
    J --> K["Ingress 或 Nginx 暴露入口"]
    K --> L["用户访问服务"]
    L --> M["日志、指标、链路追踪"]
    M --> N["告警、回滚、复盘"]

这条链路里,任何一层出问题,表现都可能是“访问不了”。所以排查不能只盯应用日志,要先确定请求走到了哪一层。

第一层:从源码到构建产物 ​

源码不能直接发布到生产。生产运行的应该是可重复构建出来的产物,例如:

项目类型构建命令产物
Spring Bootmvn clean packageapp.jar
Vue/VitePressnpm run builddist 静态文件
Go 服务go build二进制文件
Python 服务构建镜像或打包依赖镜像或 wheel

为什么不能手动复制代码到服务器:

  1. 服务器环境不可控,同一份代码在不同机器表现可能不同。
  2. 依赖版本可能漂移。
  3. 无法审计这次发布来自哪个提交。
  4. 出问题时不知道该回滚到哪个版本。

最小构建脚本:

bash
#!/usr/bin/env bash
set -e

git rev-parse --short HEAD
mvn clean test package
ls -lh target/*.jar

set -e 的作用是前一步失败后立即停止。如果不停止,测试失败也继续发布,生产风险会非常高。

第二层:Docker 镜像和容器 ​

镜像是只读模板,容器是镜像运行起来后的进程环境。

mermaid
flowchart TD
    A["Dockerfile"] --> B["docker build"]
    B --> C["镜像 image"]
    C --> D["docker run"]
    D --> E["容器 container"]

镜像为什么有分层 ​

Dockerfile 每条关键指令通常形成一层。相同层可以复用缓存,减少构建时间和传输体积。

dockerfile
FROM eclipse-temurin:8-jre
WORKDIR /app
COPY target/app.jar /app/app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "/app/app.jar"]

这里用 JDK8 运行时是因为很多企业项目仍以 JDK8 为主。学习 DevOps 时不要只看最新版本,生产中常见的是 JDK8、JDK11、JDK17 混用。

容器不等于虚拟机 ​

容器本质上仍是宿主机上的进程,只是通过 namespace 做隔离,通过 cgroup 做资源限制,通过镜像层提供文件系统。

概念解决什么问题不理解会怎样
namespace隔离进程、网络、挂载点误以为容器是完整虚拟机
cgroup限制 CPU、内存容器 OOM 不知道为什么
image layer复用文件系统层镜像越打越大
volume持久化数据容器删了数据也没了
bridge network容器间通信服务连不上依赖

最小运行 Demo ​

bash
docker build -t order-api:1.0.0 .
docker run -d --name order-api -p 8080:8080 \
  -e SPRING_PROFILES_ACTIVE=prod \
  order-api:1.0.0
docker logs -f order-api
curl http://127.0.0.1:8080/actuator/health

常见坑:

现象常见原因排查命令
容器启动后马上退出入口命令错误、应用启动失败docker logs 容器名
本机访问不到端口没有 -p 映射docker ps
配置没生效环境变量名或 profile 错docker inspect
容器内连不上外部 DB网络、防火墙、地址写 localhostdocker exec 进入容器测试
磁盘越来越大日志无限写、镜像没清理docker system df

第三层:Docker Compose ​

Compose 适合本地开发、测试环境或单机部署,把多个容器组合起来。

mermaid
flowchart TD
    A["Compose项目"] --> B["order-api"]
    A --> C["mysql"]
    A --> D["redis"]
    B --> E["服务名DNS访问mysql和redis"]
    C --> F["Secret提供初始化密码"]
    C --> G["Named Volume保存数据"]
    C --> H["Healthcheck表达启动状态"]

完整配置不应使用明文root密码,也不应默认把MySQL、Redis端口暴露到所有宿主机接口。请完成 Compose商业栈Demo 与 MySQL容器化Demo。depends_on 和健康检查只改善初始顺序,生产代码仍要有连接超时、退避重试和连接池恢复。

第四层:Nginx 入口层 ​

Nginx 常见职责:

  1. 反向代理:把外部请求转发给后端服务。
  2. 负载均衡:多个后端实例分摊流量。
  3. 静态资源:直接返回前端文件、图片、下载文件。
  4. HTTPS 终止:处理 TLS 证书。
  5. 限流:保护后端不被突发流量打垮。
  6. 缓存:缓存低频变化内容。
mermaid
flowchart TD
    A["用户请求"] --> B["Nginx"]
    B --> C{"路径判断"}
    C -- "/api" --> D["后端服务集群"]
    C -- "/static" --> E["静态资源目录"]
    C -- "HTTPS" --> F["证书和 TLS"]

最小反向代理:

nginx
upstream order_api {
    server 10.0.0.11:8080;
    server 10.0.0.12:8080;
}

server {
    listen 80;
    server_name example.com;

    location /api/ {
        proxy_pass http://order_api/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

如果不设置 X-Forwarded-For,后端看到的可能只有 Nginx IP,审计、风控、限流都会受影响。

Nginx 排查顺序 ​

现象排查点
404location 是否匹配、静态目录是否存在
502后端服务不可达、端口不通、upstream 错
504后端超时、网关超时太短、服务太慢
客户端真实 IP 丢失请求头没有透传
上传大文件失败client_max_body_size 太小
接口被打爆没有限流、没有连接数限制

第五层:Jenkins Pipeline ​

Jenkins 不只是“点按钮发布”,核心是把发布过程变成可审计的流水线。

mermaid
flowchart TD
    A["拉代码"] --> B["编译"]
    B --> C["测试"]
    C --> D["构建镜像"]
    D --> E["推送镜像"]
    E --> F["部署"]
    F --> G["健康检查"]
    G --> H{"是否成功"}
    H -- "成功" --> I["通知"]
    H -- "失败" --> J["回滚或停止发布"]

最小 Jenkinsfile:

groovy
pipeline {
  agent any

  environment {
    APP_NAME = 'order-api'
    REGISTRY = 'registry.example.com/backend'
    IMAGE_TAG = "${env.BUILD_NUMBER}"
  }

  stages {
    stage('Checkout') {
      steps {
        checkout scm
      }
    }

    stage('Test and Package') {
      steps {
        sh 'mvn clean test package'
      }
    }

    stage('Build Image') {
      steps {
        sh 'docker build -t $REGISTRY/$APP_NAME:$IMAGE_TAG .'
      }
    }

    stage('Push Image') {
      steps {
        sh 'docker push $REGISTRY/$APP_NAME:$IMAGE_TAG'
      }
    }

    stage('Deploy') {
      steps {
        sh 'kubectl set image deployment/order-api order-api=$REGISTRY/$APP_NAME:$IMAGE_TAG'
        sh 'kubectl rollout status deployment/order-api --timeout=120s'
      }
    }
  }
}

生产注意:

  1. 凭据必须放 Jenkins Credentials,不要写在 Jenkinsfile。
  2. 镜像标签不要只用 latest,要用版本号、构建号或 Git commit。
  3. 发布后必须做健康检查。
  4. 失败要能停止或回滚。
  5. 流水线日志不能打印密码、token、私钥。

第六层:Kubernetes 核心对象 ​

K8s 用来管理容器集群。它解决的是:多实例、自动拉起、滚动更新、服务发现、配置管理、扩缩容和故障恢复。

mermaid
flowchart TD
    A["Deployment"] --> B["ReplicaSet"]
    B --> C["Pod 1"]
    B --> D["Pod 2"]
    B --> E["Pod 3"]
    F["Service"] --> C
    F --> D
    F --> E
    G["Ingress"] --> F
    H["ConfigMap 和 Secret"] --> C
对象作用初学者要记住
Pod最小调度单位容器运行在 Pod 里
Deployment管理副本和发布一般不要直接手写裸 Pod
ReplicaSet维持副本数通常由 Deployment 管
Service稳定访问入口Pod IP 会变,Service 名稳定
Ingress集群外入口通常配合 Nginx Ingress
ConfigMap普通配置不放密码
Secret敏感配置仍要结合权限和加密
Probe健康检查决定是否接流量或重启
Volume持久化数据Pod 重建后数据不丢

最小部署:

yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: order-api
spec:
  replicas: 3
  selector:
    matchLabels:
      app: order-api
  template:
    metadata:
      labels:
        app: order-api
    spec:
      containers:
        - name: order-api
          image: registry.example.com/backend/order-api:1.0.0
          ports:
            - containerPort: 8080
          env:
            - name: SPRING_PROFILES_ACTIVE
              value: prod
          readinessProbe:
            httpGet:
              path: /actuator/health/readiness
              port: 8080
            initialDelaySeconds: 20
            periodSeconds: 5
          livenessProbe:
            httpGet:
              path: /actuator/health/liveness
              port: 8080
            initialDelaySeconds: 60
            periodSeconds: 10
---
apiVersion: v1
kind: Service
metadata:
  name: order-api
spec:
  selector:
    app: order-api
  ports:
    - port: 80
      targetPort: 8080

为什么要 readiness 和 liveness 分开:

探针表示什么失败后果
readiness是否准备好接流量Service 暂时不转发给它
liveness进程是否活着K8s 重启容器

如果把慢启动服务的 liveness 配太激进,应用还没启动完就被反复杀掉,会进入 CrashLoopBackOff。

第七层:灰度发布和回滚 ​

生产发布不能只追求“快”,还要能控制风险。

mermaid
flowchart TD
    A["新版本镜像"] --> B["少量实例或少量流量"]
    B --> C["观察错误率和延迟"]
    C --> D{"指标正常"}
    D -- "是" --> E["扩大流量"]
    D -- "否" --> F["回滚旧版本"]

K8s 回滚命令:

bash
kubectl rollout history deployment/order-api
kubectl rollout undo deployment/order-api
kubectl rollout status deployment/order-api

回滚依赖一个前提:旧镜像还在,配置兼容,数据库变更可回退或向前兼容。很多事故不是代码不能回滚,而是数据库表结构已经不可逆。

第八层:可观测性 ​

线上系统至少要有三类证据:

类型回答的问题例子
日志某次请求具体发生了什么异常堆栈、业务参数、traceId
指标系统整体是否健康QPS、P99、错误率、CPU、内存
链路追踪请求经过哪些服务网关 -> 订单 -> 库存 -> 支付
mermaid
flowchart TD
    A["用户请求"] --> B["网关生成 traceId"]
    B --> C["订单服务"]
    C --> D["库存服务"]
    C --> E["支付服务"]
    C --> F["写日志和指标"]
    F --> G["日志平台和监控系统"]

没有可观测性会怎样:

  1. 用户说慢,但不知道哪个接口慢。
  2. 接口报错,但没有请求上下文。
  3. 发布后错误率升高,但没有自动告警。
  4. 多服务调用失败,只能靠猜。

商业项目场景 ​

订单系统发布 ​

订单系统通常涉及订单、库存、支付、MQ 和数据库。发布时要重点关注:

  1. 数据库变更要先兼容旧代码。
  2. 消息格式要兼容旧消费者。
  3. 支付回调接口不能随意中断。
  4. 发布后观察错误率、支付成功率、订单状态卡住数量。
  5. 回滚时不能让订单状态机出现逆向流转。

医疗数据采集平台 ​

采集平台通常有设备接入、数据清洗、异步入库、文件归档和查询服务。DevOps 重点:

  1. 采集网关要滚动发布,避免大量设备同时断连。
  2. 原始报文和清洗结果要有日志和归档。
  3. 消息队列堆积要告警。
  4. 数据库连接池、磁盘、对象存储要监控。
  5. 配置变更要可审计,避免采集规则误改。

生产排查总流程 ​

mermaid
flowchart TD
    A["线上故障"] --> B{"用户表现"}
    B -- "访问不了" --> C["查 DNS、Nginx、Ingress、Service"]
    B -- "接口报错" --> D["查应用日志和依赖状态"]
    B -- "接口变慢" --> E["查 P99、线程池、DB、Redis、MQ"]
    B -- "发布失败" --> F["查流水线、镜像、权限、K8s 事件"]
    B -- "Pod 起不来" --> G["查 describe、logs、探针、资源"]
    C --> H["确认请求到达哪一层"]
    D --> I["根据 traceId 找完整链路"]
    E --> J["定位瓶颈层而不是盲目扩容"]
    F --> K["停止发布或回滚"]

常用命令:

bash
kubectl get pod -n prod
kubectl describe pod order-api-xxx -n prod
kubectl logs order-api-xxx -n prod --tail=200
kubectl get events -n prod --sort-by=.metadata.creationTimestamp
kubectl rollout status deployment/order-api -n prod
kubectl top pod -n prod

面试标准回答 ​

DevOps 是什么 ​

text
DevOps 是把开发、测试、构建、部署、运行、监控和反馈连接起来的工程实践。它的目标不是单纯自动发布,而是让软件交付可重复、可追踪、可回滚、可观测,减少环境差异和人工操作风险。

Docker 和虚拟机有什么区别 ​

text
虚拟机虚拟完整操作系统,隔离强但启动慢、资源重;Docker 容器共享宿主机内核,通过 namespace 和 cgroup 隔离进程、网络和资源,启动快、镜像轻,适合应用交付和弹性部署。但容器不是完整虚拟机,数据持久化、网络和资源限制需要单独设计。

Kubernetes 为什么需要 Service ​

text
Pod 是动态的,重建后 IP 会变化。Service 提供稳定的访问入口,通过标签选择一组 Pod,并把流量转发到健康 Pod。没有 Service,调用方需要感知 Pod IP 变化,服务发现和负载均衡都会很困难。

发布失败怎么处理 ​

text
先停止继续放量,确认失败发生在构建、镜像推送、部署、启动、健康检查还是流量入口。再看流水线日志、镜像标签、K8s events、Pod logs 和探针状态。若已经影响生产,优先回滚到上一稳定版本,同时保留现场证据再分析根因。

关联知识点 ​

知识点继续学习
DevOps 总览运维工具
从零到精通验收DevOps 从零到精通验收清单
商业场景训练营DevOps 商业场景训练营
Docker 入门Docker 入门路线
Docker第一次运行CLI、hello-world、run、端口、日志、可写层与Volume实验
Docker安装与权限组件、仓库签名、systemd、rootless和升级
Docker daemon配置配置来源、data-root、日志、网络、代理、安全变更与回滚
Docker命令体系对象、生命周期、诊断与安全清理
Docker底层原理namespace、cgroup、OverlayFS与生命周期
DockerfileDockerfile构建原理、JDK 8/17与生产镜像
Docker Compose项目模型、生命周期、依赖健康与商业编排
Spring Boot容器化JDK 8/17、资源预算、探针和优雅停机
MySQL容器化初始化、Volume、内存、备份恢复和升级
Redis容器化ACL、RDB/AOF、内存预算、备份与高可用边界
Nginx容器化启动链、配置挂载、反向代理、TLS、优雅重载与排障
Docker生产排障按状态、网络、资源、存储和事故取证的Runbook
Docker容器信息容器状态、inspect、资源与日志
Docker网络原理namespace、veth、bridge、DNS、SNAT与端口发布
Docker存储原理可写层、Volume、Bind、权限、备份与恢复
NginxNginx 总览
Nginx事件模型Master、Worker、epoll、状态机、连接容量与平滑reload
Nginx配置匹配listen、server_name、location、rewrite、静态文件与proxy_pass全过程
Nginx 负载均衡算法、健康判断、重试幂等、连接复用、动态节点与故障排查
Nginx限流rate、burst、delay、并发、真实IP、多实例和商业策略
Nginx日志排障Request ID、分段耗时、499/502/504、轮转和生产取证
Nginx代理缓存Key、TTL、stale、缓存锁、多实例与一致性
Jenkins PipelineCPS、Agent、并发、凭据、制品、审批与可靠发布
Jenkins执行架构Controller、Agent、Queue、Executor、Workspace与制品生命周期
Jenkins Shared Library加载、信任、版本、API、测试与多项目升级治理
Jenkins商业发布不可变制品、数据库兼容、灰度、指标闸门、多对象回滚与前滚
K8s 从零入口对象心智模型、第一个应用、执行链路、故障实验与完整学习路线
K8s 架构API请求、控制循环、调度、CRI/CNI/CSI与Pod创建全过程
K8s 工作负载Deployment滚动更新、优雅终止、StatefulSet、DaemonSet与批任务
K8s 网络Pod网络、Service、EndpointSlice、DNS、kube-proxy与NetworkPolicy
K8s IngressIngressClass、Controller、Host/Path、TLS与4xx/5xx排障
K8s 配置与密钥ConfigMap/Secret注入、投射更新、加密、权限与零停机轮换
K8s 存储PV/PVC、StorageClass、CSI供应挂载、扩容、快照与恢复
K8s 探针kubelet执行、Startup门控、Readiness流量与Liveness重启全过程
K8s HelmChart、Values、模板渲染、Release、Hook、CRD与生产发布
K8s 可观测性日志、指标、Trace、Event、资源口径与生产排障证据链
K8s 面试题面试题

本章小结 ​

DevOps 的核心不是堆工具,而是把软件交付变成闭环:源码可构建,产物可追踪,镜像可复现,配置可隔离,发布可回滚,服务可观测,故障可定位。小白学习时要先把“代码怎么变成线上服务”这条链路走通,再逐个深入 Docker、Nginx、Jenkins 和 Kubernetes。