一、为什么 IDC 运维要掌握 Docker

传统 IDC 机房部署应用,最常遇到的问题就是"环境不一致":开发环境能跑,生产环境就报错;换一台服务器,依赖版本对不上,服务起不来。Docker 通过容器镜像把应用连同运行环境一起打包,从根本上解决了这个问题。对 IDC 运维来说,Docker 带来的直接收益有三点:一是部署效率大幅提升,一条命令即可拉起完整服务;二是资源利用率更高,单台物理机可以跑几十个容器,比虚拟机更省资源;三是环境隔离,不同业务互不干扰,故障爆炸半径更小。

二、安装 Docker 与基础配置

生产环境建议使用官方源安装 Docker Engine,不要用系统自带的旧版本。以 CentOS 7 为例:

# 卸载旧版本
yum remove -y docker docker-client docker-common docker-engine

# 安装依赖
yum install -y yum-utils device-mapper-persistent-data lvm2

# 配置阿里云镜像源
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

# 安装 Docker Engine
yum install -y docker-ce docker-ce-cli containerd.io

# 启动并设置开机自启
systemctl enable --now docker

安装完成后,配置镜像加速器(国内服务器必配,否则拉取镜像极慢):编辑 /etc/docker/daemon.json

{
  "registry-mirrors": ["https://docker.mirrors.ustc.edu.cn"],
  "data-root": "/data/docker",
  "log-driver": "json-file",
  "log-opts": {"max-size": "50m", "max-file": "3"}
}

注意两点:data-root 建议放到独立数据盘,避免镜像和容器写满系统盘;log-opts 限制日志大小,防止容器日志无限增长撑爆磁盘——这是 IDC 生产环境最常见的磁盘事故之一。

三、常用命令速查

日常运维最常用的命令就这几条,务必烂熟于心:

docker ps                    # 查看运行中的容器
docker ps -a                 # 查看所有容器(含已退出)
docker images                # 查看本地镜像
docker pull nginx:1.24       # 拉取镜像
docker run -d --name web -p 80:80 nginx:1.24   # 运行容器
docker exec -it web bash     # 进入容器
docker logs -f --tail 200 web  # 查看容器日志
docker inspect web           # 查看容器详细信息
docker stop/start/restart web # 启停容器
docker rm -f web             # 强制删除容器
docker system df             # 查看磁盘占用
docker system prune -a       # 清理无用镜像和容器(谨慎使用)

排障时最常用的是 docker logsdocker inspect:前者看应用日志,后者看挂载、网络、环境变量等配置是否生效。

四、生产环境部署实战:Nginx + PHP-FPM + MySQL

以一个典型 Web 业务为例,用 docker-compose 编排三件套。先创建 docker-compose.yml

version: "3.8"
services:
  nginx:
    image: nginx:1.24
    container_name: web-nginx
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./www:/usr/share/nginx/html
      - ./nginx/conf.d:/etc/nginx/conf.d
      - ./nginx/ssl:/etc/nginx/ssl
    depends_on:
      - php
    restart: always
    networks:
      - webnet

  php:
    image: php:7.4-fpm
    container_name: web-php
    volumes:
      - ./www:/usr/share/nginx/html
      - ./php/php.ini:/usr/local/etc/php/conf.d/custom.ini
    restart: always
    networks:
      - webnet

  mysql:
    image: mysql:5.7
    container_name: web-mysql
    environment:
      MYSQL_ROOT_PASSWORD: "ChangeMe123!"
      MYSQL_DATABASE: webdb
    volumes:
      - ./mysql-data:/var/lib/mysql
    restart: always
    networks:
      - webnet

networks:
  webnet:
    driver: bridge

启动命令:

docker-compose up -d          # 后台启动
docker-compose ps             # 查看状态
docker-compose logs -f        # 跟踪日志
docker-compose down           # 停止并删除容器

这里有几个生产要点:restart: always 保证服务器重启后容器自动拉起;数据目录挂载到宿主机,容器删了数据不丢;容器间用自定义网络通信,避免用 --link 这种旧方式。

五、容器数据持久化与备份

容器是"一次性"的,删掉重建是常态,所以数据必须持久化。三种方式:bind mount(挂载宿主机目录,如上面示例)、volume(Docker 管理的卷)、tmpfs(内存盘,仅临时数据)。数据库这类有状态服务,务必用 bind mount 或 volume,并定期备份:

# 备份 MySQL 容器中的数据
docker exec web-mysql mysqldump -uroot -pChangeMe123! webdb > /backup/webdb_$(date +%F).sql

# 备份挂载目录
rsync -avz --delete /data/docker/volumes/ /backup/volumes/

六、镜像构建与私有仓库

业务应用应通过 Dockerfile 构建镜像,实现"一次构建、到处运行"。同时建议搭建 Harbor 私有仓库,镜像不走公网,既安全又快:

# 示例 Dockerfile
FROM centos:7
RUN yum install -y httpd && yum clean all
COPY index.html /var/www/html/
EXPOSE 80
CMD ["/usr/sbin/httpd", "-DFOREGROUND"]
# 构建并推送
docker build -t harbor.7ehl.com/web/app:v1.0 .
docker login harbor.7ehl.com
docker push harbor.7ehl.com/web/app:v1.0

镜像打 tag 时务必带版本号,不要全部用 latest,否则回滚时无法定位版本。

七、常见故障排查

1. 端口冲突:容器起不来提示 bind: address already in use,用 ss -lntp | grep 80 找占用进程,或换映射端口。

2. 磁盘被镜像占满:频繁构建会产生大量悬空镜像,用 docker system df 查看,配合 docker image prune 清理。

3. 容器内时间不对:宿主机没同步时间导致容器时区错误,挂载 /etc/localtime:/etc/localtime:ro 解决。

4. 容器内 DNS 解析失败:检查宿主机 /etc/resolv.conf,或给容器指定 --dns 8.8.8.8

八、安全加固建议

生产容器不能裸奔:第一,不要用 root 跑应用进程,Dockerfile 里用 USER 指定普通用户;第二,限制资源占用,run 时加 --memory 512m --cpus 1 防止单容器拖垮整机;第三,非必要不映射特权端口以外的端口,管理接口只绑内网 IP;第四,定期 docker pull 更新基础镜像,及时修复已知 CVE;第五,开启 Docker 的审计日志,配合 Fail2ban 防护 SSH。

九、总结

Docker 是 IDC 运维的必修课。掌握镜像构建、容器编排、数据持久化和故障排查这四板斧,就能把绝大多数应用标准化地跑起来。下一篇文章可以进一步深入 Kubernetes 集群运维,但先把 Docker 基础打牢,生产环境才不会翻车。