📘 第23课:日志管理

生产部署

📝 容器日志管理

容器日志是排障的第一手资料。但如果不加管理,日志会快速占满磁盘,分散在各个容器中也难以检索。

🔍 Docker日志驱动

驱动说明适用场景
json-file默认,JSON格式本地文件开发/小规模
local优化的本地存储,自动轮转推荐替代json-file
syslog发送到syslog守护进程已有syslog基础设施
journald发送到systemd journalCentOS/RHEL系统
fluentd发送到Fluentd集中日志收集
awslogs发送到CloudWatchAWS环境
gcplogs发送到GCP LoggingGCP环境
none不收集日志高性能/安全场景

⚙️ 日志配置

# daemon.json全局配置 ✅
{
  "log-driver": "local",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3",
    "compress": "true"
  }
}

# 单容器配置 ✅
docker run -d --log-driver local \
  --log-opt max-size=10m --log-opt max-file=3 \
  nginx

# Compose配置 ✅
services:
  app:
    logging:
      driver: local
      options:
        max-size: "10m"
        max-file: "3"

🏗️ ELK/EFK日志集中方案

# EFK (Elasticsearch + Fluentd + Kibana) ✅
services:
  elasticsearch:
    image: elasticsearch:8.12.0
    environment:
      - discovery.type=single-node
      - xpack.security.enabled=false
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    volumes:
      - es-data:/usr/share/elasticsearch/data
    ports:
      - "9200:9200"

  fluentd:
    image: fluent/fluentd:v1.16
    volumes:
      - ./fluent.conf:/fluentd/etc/fluent.conf
    ports:
      - "24224:24224"

  kibana:
    image: kibana:8.12.0
    environment:
      - ELASTICSEARCH_HOSTS=http://elasticsearch:9200
    ports:
      - "5601:5601"

volumes:
  es-data:

📋 日志最佳实践

# 1. 应用输出到stdout/stderr ✅
# Docker自动捕获stdout/stderr作为日志
console.log("Server started on port 3000")

# 2. 使用JSON格式日志 ✅
{"level":"info","msg":"Request processed","path":"/api/users","duration_ms":45,"status":200}

# 3. 不要在容器内写日志文件
# ❌ RUN echo "log" >> /var/log/app.log
# ✅ RUN echo "log"  # 输出到stdout

# 4. 设置日志轮转防止磁盘满 ✅
logging:
  driver: local
  options:
    max-size: "10m"
    max-file: "5"

❓ 常见问题

❓ 日志太多导致磁盘满了怎么办?立即清理:truncate -s 0 /var/lib/docker/containers/*/*-json.log。然后配置日志轮转:daemon.json中设置max-sizemax-file。推荐使用local驱动替代默认的json-file
❓ 如何查看已删除容器的日志?容器删除后日志也删除了。这就是为什么需要集中日志收集——所有日志实时发送到EFK/Loki等系统,即使容器删除日志仍在。

🏆 本课成就

📚 深度补充:日志管理进阶要点

【运维与部署阶段】生产环境注意事项

要点说明最佳实践
资源规划根据业务负载合理分配CPU/内存先压测再上线,设置requests和limits
监控告警设置关键指标阈值和告警规则Prometheus + AlertManager,5分钟P99延迟告警
备份策略定期备份关键数据和配置自动化备份脚本 + 异地存储 + 定期恢复演练
灰度发布新版本逐步放量降低风险金丝雀发布5%→20%→50%→100%
回滚预案部署前确认回滚方案和步骤保留前一版本镜像,数据库迁移向前兼容
文档更新配置变更必须同步更新文档GitOps管理配置,变更即文档
安全基线遵循CIS Docker Benchmark非root运行、只读FS、最小能力
日志规范结构化日志,统一格式JSON格式日志,包含traceId

常见误区与避坑指南

  1. 过度配置:不是所有服务都需要高可用,根据实际需求选择架构复杂度,避免过度工程
  2. 忽略日志:日志是排障的关键,确保日志格式统一、级别合理、采集完整
  3. 资源超卖:容器资源限制不是摆设,超卖会导致性能下降甚至OOM Kill
  4. 安全忽视:默认配置不等于安全配置,生产环境必须加固(非root、只读FS、最小能力)
  5. 监控缺失:没有监控等于盲飞,至少要有基础的健康检查和资源监控
  6. 手动运维:能自动化的绝不手动,手动操作容易出错且不可追溯
  7. 忽略网络策略:默认所有容器互通不安全,应按最小权限原则配置网络

进阶阅读与参考

Docker命令速查卡

# 容器生命周期
docker create/start/stop/restart/rm/pause/unpause
docker logs/top/stats/inspect/exec diff

# 镜像构建
docker build/pull/push/tag/rmi/images/history
docker save/load/import/manifest

# 网络与存储
docker network create/ls/inspect/connect/disconnect/rm/prune
docker volume create/ls/inspect/rm/prune

# Docker Compose
docker compose up/down/ps/logs/build/exec
docker compose config/stop/start/scale/top/cp

# 系统维护
docker system df/prune/info
docker builder prune
docker container/prune/image prune

# K8s常用命令
kubectl get/describe/logs/exec/apply/delete
kubectl rollout status/undo/history
kubectl scale/autoscale/set

本阶段知识脉络

运维与部署阶段知识体系: 核心概念实操演练最佳实践故障排查 每一课都遵循:概念讲解 → 命令实操 → 代码示例 → 常见问题 → 练习巩固 确保学完即能上手,理论实践并重。

生产环境检查清单

类别检查项命令/方法
安全性容器非root运行docker exec <c> whoami
只读文件系统docker run --read-only
最小能力集docker inspect --format '{{.HostConfig.CapAdd}}'
可靠性健康检查配置docker inspect --format '{{.State.Health}}'
重启策略docker inspect --format '{{.HostConfig.RestartPolicy}}'
资源限制docker stats --no-stream
可观测性日志收集日志驱动+集中式平台
指标监控Prometheus+cAdvisor
链路追踪Jaeger/Zipkin
备份数据卷备份定期tar备份到远程存储
配置版本化GitOps管理所有配置

SRE关键指标(SLI/SLO)

指标定义典型SLO
可用性成功请求/总请求99.9%
延迟请求处理时间P99<200ms
错误率5xx响应比例<0.1%
吞吐量QPS/TPS根据业务设定
MTTR平均恢复时间<15分钟
MTBF平均故障间隔根据业务设定

实战案例:故障排查流程

# Step 1: 检查容器状态
docker ps -a                          # 查看所有容器
docker inspect <container>            # 查看详细配置

# Step 2: 查看日志
docker logs --tail 100 <container>    # 最近100行日志
docker logs --since 1h <container>    # 最近1小时

# Step 3: 进入容器排查
docker exec -it <container> sh        # 进入容器shell

# Step 4: 检查资源
docker stats --no-stream              # 资源使用概览
docker system df                      # 磁盘使用

# Step 5: 网络排查
docker network ls                     # 网络列表
docker exec <c> ping <target>        # 网络连通性
docker exec <c> nslookup <svc>       # DNS解析

# Step 6: 检查健康状态
docker inspect --format '{{.State.Health}}' <c>
docker inspect --format '{{.State.ExitCode}}' <c>
docker inspect --format '{{.State.OOMKilled}}' <c>

Dockerfile模板:多语言通用

# 通用最佳实践模板
FROM alpine:3.19 AS builder
# ... 构建步骤 ...

FROM alpine:3.19
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
WORKDIR /app
COPY --from=builder /app/output .
USER appuser
HEALTHCHECK --interval=30s --timeout=3s --retries=3 \
  CMD wget -qO- http://localhost:8080/health || exit 1
EXPOSE 8080
CMD ["./app"]

Docker Compose健康检查模板

services:
  app:
    build: .
    healthcheck:
      test: ["CMD", "wget", "-qO-", "http://localhost:8080/health"]
      interval: 30s
      timeout: 5s
      retries: 3
      start_period: 30s
    restart: unless-stopped
    deploy:
      resources:
        limits:
          cpus: '1'
          memory: 512M

性能调优要点

调优方向具体措施预期效果
镜像构建多阶段构建+缓存优化构建时间减少50%+
容器启动小镜像+健康检查优化启动时间减少30%+
网络性能host模式或优化bridge延迟降低20%+
存储性能Volume替代bind mountIO性能提升10-30%
内存使用限制+请求合理配置避免OOM和资源浪费
CPU调度cpuset绑定+shares权重关键服务优先调度