容器化部署实战:Docker 与 Kubernetes 从入门到生产

发布时间:2026/6/7 5:50:15

容器化部署实战:Docker 与 Kubernetes 从入门到生产 容器化部署实战Docker 与 Kubernetes 从入门到生产第一次接触 Docker 是 2014 年那时候容器概念刚刚火起来。最初我以为这只是又一个炒作的技术噱头没想到几年后它彻底改变了软件的开发、测试和部署方式。从物理机到虚拟机再到容器化每一次技术演进都在追求更高效的 Resource 利用率。我的金毛 Bug 喜欢追着地上的影子跑容器技术某种程度上也是在追逐一个影子让软件像光一样无处不在又随心所欲地运行。本文不讲废话直接从 Docker 基础、Kubernetes 核心概念、生产级部署实践、运维监控四个维度聊聊容器化部署。一、Docker 基础与核心概念Docker 是一个开源的容器化平台让开发者可以将应用及其依赖打包到一个轻量级、可移植的容器中。1.1 镜像与容器的关系Docker 的核心概念是镜像Image和容器Container。镜像是一个只读的模板定义了应用运行所需的一切操作系统、依赖包、代码、配置等。容器是镜像的运行实例可以被创建、启动、停止、删除。类比面向对象编程镜像就像类容器就像对象。类是静态的定义对象是动态的运行实例。# 示例Node.js 应用 Dockerfile FROM node:20-alpine WORKDIR /app COPY package*.json ./ RUN npm ci --onlyproduction COPY . . EXPOSE 3000 USER node CMD [node, server.js]这个 Dockerfile 定义了一个 Node.js 应用的镜像构建过程。每一行都创建一个新的镜像层最终形成一个完整的应用镜像。1.2 多阶段构建优化镜像体积镜像体积直接影响镜像的构建速度、拉取速度和运行效率。使用多阶段构建可以显著减小最终镜像的体积。# 多阶段构建示例 # 阶段1构建 FROM node:20 AS builder WORKDIR /app COPY package*.json ./ RUN npm ci COPY . . RUN npm run build # 阶段2运行 FROM node:20-alpine AS runner WORKDIR /app ENV NODE_ENVproduction # 只复制构建产物和运行时依赖 COPY --frombuilder /app/dist ./dist COPY --frombuilder /app/node_modules ./node_modules EXPOSE 3000 USER node CMD [node, dist/server.js]多阶段构建的原理是最终镜像只包含第二个 FROM 之后的指令第一个阶段的产物通过--from指令选择性复制。这种方式可以将一个 1GB 的 Node.js 镜像优化到 150MB 左右。1.3 Docker 网络与存储Docker 提供了多种网络模式bridge默认、host、overlay、none。对于大多数应用场景默认的 bridge 网络模式已经够用。# 创建自定义网络 docker network create my-network # 启动容器并加入网络 docker run -d --name app --network my-network app:latest docker run -d --name db --network my-network mongo:latest # 此时 app 容器可以通过主机名 db 访问 mongoDocker 的数据持久化通过 Volume 实现。容器内的文件系统是临时性的容器删除后数据丢失。对于需要持久化的数据必须使用 Volume# 创建命名卷 docker volume create my-data # 使用卷启动容器 docker run -d -v my-data:/app/data app:latest # 或者使用 bind mount docker run -d -v /host/path:/container/path app:latest二、Kubernetes 核心概念与架构Kubernetes简称 K8s是一个开源的容器编排平台用于自动化容器化应用的部署、扩缩容和管理。2.1 核心对象模型Kubernetes 的核心是各种资源对象。理解这些对象是掌握 Kubernetes 的基础。Pod是 Kubernetes 最小的调度单元。一个 Pod 可以包含一个或多个容器它们共享网络和存储。最常见的是单容器 Pod。apiVersion: v1 kind: Pod metadata: name: nginx-pod labels: app: nginx spec: containers: - name: nginx image: nginx:1.25 ports: - containerPort: 80 resources: limits: memory: 128Mi cpu: 500m requests: memory: 64Mi cpu: 250mDeployment管理 Pod 的部署提供滚动更新和回滚能力apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment spec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.25 ports: - containerPort: 80Service为一组 Pod 提供稳定的访问入口屏蔽了 Pod 的 IP 变化apiVersion: v1 kind: Service metadata: name: nginx-service spec: selector: app: nginx ports: - port: 80 targetPort: 80 type: ClusterIPflowchart LR subgraph Kubernetes Cluster subgraph Node 1 A1[Pod: nginx-1] end subgraph Node 2 A2[Pod: nginx-2] end subgraph Node 3 A3[Pod: nginx-3] end S[Service] end S -- A1 S -- A2 S -- A3 E[External Traffic] -- S如上图所示Service 作为 Pod 的统一入口自动做负载均衡。2.2 调度机制与资源管理Kubernetes 的调度器根据多种因素决定 Pod 应该调度到哪个节点资源请求量、亲和性/反亲和性规则、污点和容忍、Taint/Toleration 等。合理设置资源的 requests 和 limits 是保证集群稳定运行的关键requests容器需要的最小资源调度器据此选择合适的节点。limits容器可以使用的最大资源防止资源被单个容器耗尽。resources: requests: memory: 256Mi cpu: 250m limits: memory: 512Mi cpu: 500m如果节点资源不足Pod 可能会被驱逐或无法调度。这就是所谓的 OOMKilled内存不足被杀或 ThrottlingCPU 受限。2.3 配置管理与密钥管理应用配置应该与镜像解耦通过 ConfigMap 和 Secret 管理。ConfigMap 存储非敏感配置apiVersion: v1 kind: ConfigMap metadata: name: app-config data: DATABASE_HOST: db-service LOG_LEVEL: infoSecret 与 ConfigMap 类似但用于存储敏感数据。生产环境中Secret 应该配合外部密钥管理系统如 Vault、AWS Secrets Manager使用避免将敏感信息直接写入 Kubernetes。三、生产级部署实践从开发环境到生产环境需要考虑的问题完全不同。生产环境的容器化部署有其特殊的挑战。3.1 健康检查与就绪探针容器启动后不一定立即就绪可能还在做初始化或等待依赖就绪。健康检查机制确保只有真正可用的容器才接收流量。spec: containers: - name: app livenessProbe: httpGet: path: /healthz port: 8080 initialDelaySeconds: 10 periodSeconds: 10 failureThreshold: 3 readinessProbe: httpGet: path: /ready port: 8080 initialDelaySeconds: 5 periodSeconds: 5 failureThreshold: 3livenessProbe探测应用是否存活。如果探测失败Kubernetes 会重启容器。readinessProbe探测应用是否就绪。如果探测失败Pod 会被从 Service 的 Endpoint 中移除不再接收流量。3.2 滚动更新与回滚Deployment 的滚动更新机制确保在更新过程中服务不中断。Kubernetes 会逐步替换旧版本 Pod 为新版本 Pod。# 更新镜像 kubectl set image deployment/app-deployment appapp:v2 # 查看滚动更新状态 kubectl rollout status deployment/app-deployment # 回滚到上一个版本 kubectl rollout undo deployment/app-deployment # 回滚到指定版本 kubectl rollout undo deployment/app-deployment --to-revision2滚动更新策略的关键参数spec: strategy: type: RollingUpdate rollingUpdate: maxSurge: 1 # 最多可以超出期望的 Pod 数 maxUnavailable: 0 # 更新过程中最多不可用的 Pod 数3.3 资源配额与限额管理在多租户或共享集群环境中资源配额管理至关重要。LimitRange 限制单个容器的资源使用ResourceQuota 限制命名空间的总资源使用。apiVersion: v1 kind: LimitRange metadata: name: default-limit spec: limits: - max: memory: 1Gi cpu: 1 default: memory: 256Mi cpu: 200m defaultRequest: memory: 128Mi cpu: 100m type: Container四、运维监控与日志容器化环境下的监控和日志收集与传统的虚拟机环境有所不同需要适应动态的容器生命周期。4.1 监控体系搭建Kubernetes 监控通常采用 Prometheus Grafana 的组合。Prometheus 负责指标采集和存储Grafana 负责可视化展示。核心监控指标包括资源指标CPU、内存、网络、磁盘使用率应用指标请求延迟、错误率、吞吐量Kubernetes 指标Pod 状态、调度延迟、资源配额使用率# Prometheus 监控规则示例 apiVersion: monitoring.coreos.com/v1 kind: PrometheusRule metadata: name: app-alerts spec: groups: - name: app rules: - alert: HighErrorRate expr: | rate(http_requests_total{status~5..}[5m]) 0.05 for: 5m labels: severity: critical annotations: summary: High error rate detected description: Error rate is {{ $value | humanizePercentage }}4.2 日志收集方案容器化环境下的日志收集通常采用 EFKElasticsearch Fluentd Kibana或 Loki Promtail Grafana 的组合。flowchart LR subgraph Kubernetes Cluster P1[Pod] P2[Pod] P3[Pod] end P1 -- FP[Fluentd/Promtail] P2 -- FP P3 -- FP FP -- S[(Storage)] S -- V[Visualization]每个节点的 Fluentd/Promtail 守护进程负责收集该节点上所有容器的日志发送到后端存储系统。这种架构避免了每个 Pod 都需要部署日志 Agent 的开销。五、总结容器化部署已经从可选项变成了必选项。Docker 提供了容器化的基础设施Kubernetes 提供了容器编排的能力两者结合构成了现代云原生应用的标准部署方式。学习曲线确实存在但一旦掌握就能体会到容器化带来的巨大便利环境一致性、快速弹性扩缩容、CI/CD 集成、微服务架构支持。对于初次接触的开发者我的建议是先用 Docker 跑通一个简单的应用理解镜像和容器的基本概念然后用 Docker Compose 编排多个服务体验服务编排的感觉最后再上 Kubernetes理解 Pod、Deployment、Service 的关系。不要想着一口吃成胖子。技术选型时要考虑团队的运维能力和业务需求。小团队、简单场景用 Docker Compose 足够了中大型团队、需要弹性扩缩容的场景才需要上 Kubernetes。记住不是所有问题都需要用 Kubernetes 解决。

相关新闻