Docker容器化实战完全指南

· 阅读约需6分钟

前言

Docker作为容器化技术的代表,已经彻底改变了应用部署和开发的方式。本文将从基础概念到实战部署,系统性地介绍Docker的核心技术和最佳实践,帮助你快速掌握容器化技术。

本文基于Docker 20.10+版本,适用于CentOS 7/8、Ubuntu 18.04/20.04等主流发行版。


一、Docker基础概念

1.1 什么是容器化

容器化是将应用及其依赖打包到一个可移植的容器中,使其能够在任何环境中一致运行的技术。

容器 vs 虚拟机:特性容器虚拟机
启动速度秒级分钟级
资源占用MB级GB级
性能接近原生约有5-10%损耗
隔离性进程级隔离完全隔离

1.2 Docker核心组件

  • 镜像(Image):只读的模板,用于创建容器
  • 容器(Container):镜像的运行实例
  • 仓库(Registry):存储镜像的地方(Docker Hub)
  • Dockerfile:构建镜像的脚本文件
  • Docker Compose:多容器编排工具

二、Docker安装与配置

2.1 CentOS安装Docker

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

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

# 添加Docker源
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

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

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

2.2 Ubuntu安装Docker

# 更新包索引
apt update

# 安装依赖
apt install -y apt-transport-https ca-certificates curl gnupg-agent software-properties-common

# 添加GPG密钥
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -

# 添加Docker源
add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"

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

2.3 配置Docker镜像加速

# 创建配置目录
mkdir -p /etc/docker

# 配置镜像加速器(使用阿里云或网易云)
cat > /etc/docker/daemon.json << EOF
{
  "registry-mirrors": [
    "https://docker.mirrors.ustc.edu.cn",
    "https://hub-mirror.c.163.com"
  ],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m",
    "max-file": "3"
  }
}
EOF

# 重启Docker
systemctl daemon-reload
systemctl restart docker

# 验证配置
docker info

三、Docker常用命令

3.1 镜像操作

# 搜索镜像
docker search nginx

# 拉取镜像
docker pull nginx:latest
docker pull nginx:1.21

# 查看本地镜像
docker images

# 删除镜像
docker rmi nginx:latest

# 导出镜像
docker save -o nginx.tar nginx:latest

# 导入镜像
docker load -i nginx.tar

3.2 容器操作

# 运行容器
docker run -d --name nginx -p 80:80 nginx:latest

# 常用参数说明:
# -d: 后台运行
# --name: 指定容器名称
# -p: 端口映射 主机端口:容器端口
# -v: 数据卷挂载 主机路径:容器路径
# -e: 设置环境变量
# --restart=always: 开机自启

# 查看运行中的容器
docker ps

# 查看所有容器(包括停止的)
docker ps -a

# 停止容器
docker stop nginx

# 启动容器
docker start nginx

# 重启容器
docker restart nginx

# 删除容器
docker rm nginx
docker rm -f nginx  # 强制删除运行中的容器

# 进入容器
docker exec -it nginx /bin/bash

# 查看容器日志
docker logs nginx
docker logs -f --tail 100 nginx

# 查看容器资源使用
docker stats

3.3 数据卷操作

# 创建数据卷
docker volume create mysql_data

# 查看数据卷
docker volume ls

# 使用数据卷运行容器
docker run -d --name mysql -v mysql_data:/var/lib/mysql mysql:5.7

四、Dockerfile实战

4.1 Dockerfile基础指令

# 基础镜像
FROM nginx:1.21

# 维护者信息
MAINTAINER yourname <your@email.com>

# 设置工作目录
WORKDIR /usr/share/nginx/html

# 复制文件
COPY index.html .
COPY dist/ .

# 添加文件(支持自动解压)
ADD app.tar.gz /opt/

# 执行命令
RUN apt update && apt install -y curl

# 设置环境变量
ENV NODE_ENV production
ENV PORT 3000

# 暴露端口
EXPOSE 80 443

# 容器启动时执行的命令
CMD ["nginx", "-g", "daemon off;"]

# 入口点
ENTRYPOINT ["docker-entrypoint.sh"]

4.2 构建Node.js应用镜像

# 多阶段构建:第一阶段构建
FROM node:16-alpine AS builder

WORKDIR /app

# 先复制package.json,利用缓存
COPY package*.json ./
RUN npm install --production

# 复制源码
COPY . .
RUN npm run build

# 第二阶段:运行时镜像
FROM nginx:1.21-alpine

# 从构建阶段复制产物
COPY --from=builder /app/dist /usr/share/nginx/html

# 复制nginx配置
COPY nginx.conf /etc/nginx/conf.d/default.conf

EXPOSE 80

CMD ["nginx", "-g", "daemon off;"]

4.3 构建镜像命令

# 构建镜像
docker build -t myapp:v1 .

# 指定Dockerfile
docker build -f Dockerfile.prod -t myapp:v1 .

# 无缓存构建
docker build --no-cache -t myapp:v1 .

# 推送镜像到仓库
docker tag myapp:v1 registry.example.com/myapp:v1
docker push registry.example.com/myapp:v1

五、Docker Compose多容器编排

5.1 安装Docker Compose

# 下载二进制文件
curl -L "https://github.com/docker/compose/releases/download/v2.20.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

# 添加执行权限
chmod +x /usr/local/bin/docker-compose

# 验证安装
docker-compose --version

5.2 WordPress完整部署示例

version: '3.8'

services:
  mysql:
    image: mysql:5.7
    container_name: mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: root123456
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wpuser
      MYSQL_PASSWORD: wp123456
    volumes:
      - mysql_data:/var/lib/mysql
    networks:
      - wp_network

  wordpress:
    image: wordpress:php7.4-apache
    container_name: wordpress
    restart: always
    ports:
      - "8080:80"
    environment:
      WORDPRESS_DB_HOST: mysql:3306
      WORDPRESS_DB_NAME: wordpress
      WORDPRESS_DB_USER: wpuser
      WORDPRESS_DB_PASSWORD: wp123456
    volumes:
      - wp_data:/var/www/html
    depends_on:
      - mysql
    networks:
      - wp_network

volumes:
  mysql_data:
  wp_data:

networks:
  wp_network:
    driver: bridge

5.3 Compose常用命令

# 启动服务
docker-compose up -d

# 查看服务状态
docker-compose ps

# 查看日志
docker-compose logs -f

# 停止服务
docker-compose stop

# 停止并删除容器
docker-compose down

# 重启服务
docker-compose restart

# 重新构建并启动
docker-compose up -d --build

六、实战:LNMP环境部署

docker-compose.yml

version: '3.8'

services:
  nginx:
    image: nginx:1.21
    container_name: lnmp_nginx
    restart: always
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx/conf.d:/etc/nginx/conf.d
      - ./nginx/ssl:/etc/nginx/ssl
      - ./www:/var/www/html
      - ./nginx/logs:/var/log/nginx
    networks:
      - lnmp_network

  php:
    image: php:7.4-fpm
    container_name: lnmp_php
    restart: always
    volumes:
      - ./www:/var/www/html
      - ./php/php.ini:/usr/local/etc/php/php.ini
    networks:
      - lnmp_network

  mysql:
    image: mysql:5.7
    container_name: lnmp_mysql
    restart: always
    ports:
      - "3306:3306"
    environment:
      MYSQL_ROOT_PASSWORD: root123456
    volumes:
      - ./mysql/data:/var/lib/mysql
      - ./mysql/conf:/etc/mysql/conf.d
    networks:
      - lnmp_network

  redis:
    image: redis:6-alpine
    container_name: lnmp_redis
    restart: always
    ports:
      - "6379:6379"
    command: redis-server --requirepass redis123456
    volumes:
      - ./redis/data:/data
    networks:
      - lnmp_network

networks:
  lnmp_network:
    driver: bridge

七、Docker安全最佳实践

7.1 容器安全配置

# 1. 不要以root用户运行容器
# 在Dockerfile中创建普通用户
RUN useradd -m appuser
USER appuser

# 2. 使用只读文件系统
docker run --read-only --tmpfs /tmp nginx

# 3. 限制容器资源
docker run -d --name nginx \
  --memory=512m \
  --cpus=1 \
  --pids-limit=100 \
  nginx

# 4. 禁用不需要的能力
docker run --cap-drop=ALL --cap-add=NET_BIND_SERVICE nginx

7.2 镜像安全扫描

# 使用Trivy扫描镜像漏洞
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
  aquasec/trivy image nginx:latest

八、常见问题与解决方案

8.1 容器时间同步

# 挂载宿主机时区
docker run -v /etc/localtime:/etc/localtime:ro nginx

# 或设置环境变量
docker run -e TZ=Asia/Shanghai nginx

8.2 清理Docker资源

# 清理停止的容器
docker container prune -f

# 清理未使用的镜像
docker image prune -a -f

# 清理未使用的数据卷
docker volume prune -f

# 清理所有未使用资源
docker system prune -a -f

8.3 容器内部无法访问外网

# 检查DNS配置
cat /etc/docker/daemon.json
{
  "dns": ["8.8.8.8", "114.114.114.114"]
}

总结

Docker容器化技术已经成为现代应用部署的标准。通过本文的学习,你应该能够:

  1. 熟练安装配置Docker环境
  2. 掌握常用命令进行镜像和容器管理
  3. 编写Dockerfile构建自定义镜像
  4. 使用Docker Compose编排多容器应用
  5. 遵循最佳实践确保容器安全

容器化不是终点,而是云原生旅程的起点。接下来你可以继续学习Kubernetes、Service Mesh等更高级的容器编排技术。


参考资料: