Skip to content

Docker 容器化部署

一、Docker 简介

1. 什么是 Docker?

Docker 是一个开源的容器化平台,它允许开发者将应用程序及其依赖打包成一个轻量级、可移植的容器,然后在任何环境中运行。Docker 容器是完全隔离的,它们共享主机的内核,但有自己的文件系统、网络和进程空间。

2. Docker 的优势

  • 轻量级:容器比虚拟机更轻,启动速度更快
  • 可移植性:容器可以在任何支持 Docker 的环境中运行
  • 一致性:容器确保应用在不同环境中运行一致
  • 隔离性:容器之间相互隔离,提高安全性
  • 可扩展性:易于水平扩展应用
  • 版本控制:可以对容器镜像进行版本管理
  • CI/CD 集成:与 CI/CD 流程无缝集成

3. Docker 的核心概念

  • 镜像(Image):只读的模板,包含运行应用所需的所有内容
  • 容器(Container):镜像的运行实例
  • 仓库(Repository):存储镜像的地方,如 Docker Hub
  • Dockerfile:定义如何构建镜像的文本文件
  • Docker Compose:用于定义和运行多容器应用的工具

二、Docker 安装

1. 在 Linux 上安装 Docker

bash
# 更新包管理器
sudo apt-get update

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

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

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

# 更新包管理器并安装 Docker
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io

# 验证安装
sudo docker run hello-world

2. 在 Windows 上安装 Docker

  • 下载 Docker Desktop for Windows 安装包
  • 运行安装程序,按照提示完成安装
  • 启动 Docker Desktop,等待 Docker 引擎启动
  • 验证安装:打开 PowerShell 并运行 docker run hello-world

3. 在 macOS 上安装 Docker

  • 下载 Docker Desktop for Mac 安装包
  • 运行安装程序,按照提示完成安装
  • 启动 Docker Desktop,等待 Docker 引擎启动
  • 验证安装:打开终端并运行 docker run hello-world

三、Docker 基本操作

1. 镜像操作

  • 拉取镜像docker pull image_name:tag
  • 列出镜像docker images
  • 删除镜像docker rmi image_name:tag
  • 构建镜像docker build -t image_name:tag .
  • 标记镜像docker tag image_name:tag new_image_name:new_tag
  • 推送镜像docker push image_name:tag

2. 容器操作

  • 运行容器docker run -d --name container_name image_name:tag
  • 列出容器docker ps(运行中)或 docker ps -a(所有)
  • 停止容器docker stop container_name
  • 启动容器docker start container_name
  • 重启容器docker restart container_name
  • 删除容器docker rm container_name
  • 进入容器docker exec -it container_name bash
  • 查看容器日志docker logs container_name
  • 查看容器状态docker inspect container_name

3. 网络操作

  • 创建网络docker network create network_name
  • 列出网络docker network ls
  • 删除网络docker network rm network_name
  • 连接容器到网络docker network connect network_name container_name
  • 断开容器与网络的连接docker network disconnect network_name container_name

4. 存储操作

  • 创建卷docker volume create volume_name
  • 列出卷docker volume ls
  • 删除卷docker volume rm volume_name
  • 查看卷详情docker volume inspect volume_name

四、Dockerfile

1. Dockerfile 基本结构

dockerfile
# 基础镜像
FROM ubuntu:20.04

# 维护者信息
MAINTAINER your_name <your_email>

# 环境变量
ENV DEBIAN_FRONTEND=noninteractive

# 安装依赖
RUN apt-get update && apt-get install -y \
    nginx \
    curl \
    && rm -rf /var/lib/apt/lists/*

# 复制文件
COPY . /app

# 工作目录
WORKDIR /app

# 暴露端口
EXPOSE 80

# 启动命令
CMD ["nginx", "-g", "daemon off;"]

2. Dockerfile 指令

  • FROM:指定基础镜像
  • MAINTAINER:指定维护者信息
  • RUN:在构建过程中执行命令
  • COPY:复制文件到镜像
  • ADD:复制文件到镜像,支持 URL 和 tar 解压
  • WORKDIR:设置工作目录
  • ENV:设置环境变量
  • EXPOSE:暴露端口
  • CMD:容器启动时执行的命令
  • ENTRYPOINT:容器启动时执行的命令(不可被覆盖)
  • VOLUME:创建卷
  • ARG:构建时的参数
  • ONBUILD:当镜像被用作基础镜像时执行的命令

3. 构建最佳实践

  • 使用官方基础镜像:确保安全性和稳定性
  • 最小化镜像大小:使用 Alpine 等轻量级基础镜像
  • 使用 .dockerignore 文件:排除不需要的文件
  • 分层构建:合理组织 Dockerfile,利用缓存
  • 减少 RUN 指令:合并多个命令,减少镜像层数
  • 使用非 root 用户:提高安全性
  • 清理缓存:在构建过程中清理 apt、npm 等缓存

五、Docker Compose

1. 什么是 Docker Compose?

Docker Compose 是一个用于定义和运行多容器 Docker 应用的工具。它使用 YAML 文件来配置应用的服务、网络和卷,然后通过一个命令来启动整个应用。

2. Docker Compose 配置示例

yaml
version: '3'
services:
  web:
    build: .
    ports:
      - "80:80"
    volumes:
      - ./app:/app
    depends_on:
      - db
  db:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: myapp
    volumes:
      - mysql_data:/var/lib/mysql
volumes:
  mysql_data:

3. Docker Compose 命令

  • 启动服务docker-compose up -d
  • 停止服务docker-compose down
  • 查看服务状态docker-compose ps
  • 查看服务日志docker-compose logs
  • 构建服务docker-compose build
  • 重启服务docker-compose restart
  • 进入容器docker-compose exec service_name bash

六、容器化部署实践

1. 前端应用容器化

Dockerfile 示例(Vue 应用)

dockerfile
# 构建阶段
FROM node:16-alpine as build
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build

# 运行阶段
FROM nginx:alpine
COPY --from=build /app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

Docker Compose 配置示例

yaml
version: '3'
services:
  frontend:
    build: .
    ports:
      - "80:80"
    restart: always

2. 后端应用容器化

Dockerfile 示例(Node.js 应用)

dockerfile
FROM node:16-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install --production
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]

Docker Compose 配置示例

yaml
version: '3'
services:
  backend:
    build: .
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=production
      - DATABASE_URL=mongodb://mongo:27017/myapp
    depends_on:
      - mongo
  mongo:
    image: mongo:4.4
    volumes:
      - mongo_data:/data/db
volumes:
  mongo_data:

3. 数据库容器化

Docker Compose 配置示例(PostgreSQL)

yaml
version: '3'
services:
  db:
    image: postgres:13
    environment:
      POSTGRES_USER: myuser
      POSTGRES_PASSWORD: mypassword
      POSTGRES_DB: myapp
    ports:
      - "5432:5432"
    volumes:
      - postgres_data:/var/lib/postgresql/data
volumes:
  postgres_data:

七、Docker 网络

1. 网络类型

  • 桥接网络(Bridge):默认网络类型,容器之间可以相互通信
  • 主机网络(Host):容器直接使用主机网络,性能更好
  • 覆盖网络(Overlay):用于跨主机通信,适用于 Docker Swarm
  • None:容器没有网络连接

2. 网络配置

  • 创建网络docker network create --driver bridge mynetwork
  • 运行容器时指定网络docker run --network mynetwork --name container_name image_name
  • 在 Docker Compose 中配置网络
    yaml
    networks:
      mynetwork:
        driver: bridge

八、Docker 存储

1. 存储类型

  • 卷(Volumes):由 Docker 管理的存储,适合持久化数据
  • 绑定挂载(Bind Mounts):将主机目录挂载到容器
  • tmpfs 挂载:存储在内存中,适合临时数据

2. 卷的使用

  • 创建卷docker volume create myvolume
  • 运行容器时使用卷docker run -v myvolume:/app/data image_name
  • 在 Docker Compose 中使用卷
    yaml
    volumes:
      - myvolume:/app/data

九、Docker 安全

1. 安全最佳实践

  • 使用官方镜像:避免使用未知来源的镜像
  • 最小化镜像:只包含必要的组件
  • 使用非 root 用户:在容器中使用非 root 用户
  • 定期更新镜像:及时更新基础镜像和依赖
  • 限制容器权限:使用 --cap-drop 减少容器权限
  • 网络隔离:使用自定义网络,限制容器间通信
  • 监控容器:监控容器的运行状态和网络活动
  • 扫描镜像:使用工具扫描镜像中的漏洞

2. 常见安全问题

  • 容器逃逸:容器突破隔离,访问主机资源
  • 镜像漏洞:基础镜像或依赖包中的安全漏洞
  • 权限提升:容器内的特权操作
  • 网络攻击:容器间网络通信被攻击
  • 数据泄露:敏感数据未加密存储

十、Docker 编排

1. Docker Swarm

Docker Swarm 是 Docker 内置的容器编排工具,用于管理多容器、多主机的集群。

  • 初始化 Swarmdocker swarm init
  • 添加节点docker swarm join --token token manager_ip:2377
  • 部署服务docker service create --name myservice --replicas 3 -p 80:80 nginx
  • 查看服务docker service ls
  • 扩展服务docker service scale myservice=5

2. Kubernetes

Kubernetes 是一个开源的容器编排平台,用于自动部署、扩展和管理容器化应用。

  • 部署应用:使用 Deployment 资源
  • 服务发现:使用 Service 资源
  • 负载均衡:使用 Ingress 资源
  • 存储管理:使用 PersistentVolume 资源

十一、监控与日志

1. 监控工具

  • Docker Stats:查看容器的资源使用情况
  • cAdvisor:收集容器的资源使用和性能指标
  • Prometheus:监控系统,用于收集和存储指标
  • Grafana:可视化监控数据

2. 日志管理

  • Docker Logs:查看容器日志
  • ELK Stack:Elasticsearch、Logstash、Kibana 的组合,用于日志收集和分析
  • Fluentd:开源的日志收集器

十二、最佳实践

1. 镜像最佳实践

  • 使用多阶段构建:减少镜像大小
  • 使用 Alpine 基础镜像:轻量级基础镜像
  • 合理使用缓存:优化构建速度
  • 定期清理镜像:删除不需要的镜像

2. 容器最佳实践

  • 限制资源使用:使用 --memory--cpus 限制容器资源
  • 设置健康检查:确保容器正常运行
  • 使用标签:为容器添加标签,便于管理
  • 避免在容器中存储数据:使用卷存储数据

3. 部署最佳实践

  • 使用 Docker Compose:管理多容器应用
  • 使用环境变量:配置应用参数
  • 实现 CI/CD:自动化构建和部署
  • 备份数据:定期备份卷中的数据
  • 测试容器:在部署前测试容器

十三、常见问题与解决方案

1. 容器启动失败

  • 原因:端口冲突、配置错误、依赖问题等
  • 解决方案:检查日志,修复配置,确保依赖服务正常运行

2. 镜像构建失败

  • 原因:依赖下载失败、Dockerfile 语法错误等
  • 解决方案:检查网络连接,修复 Dockerfile 语法

3. 容器性能问题

  • 原因:资源限制不足、应用优化不足等
  • 解决方案:增加资源限制,优化应用代码

4. 数据持久化问题

  • 原因:卷配置错误、权限问题等
  • 解决方案:检查卷配置,确保权限正确

5. 网络连接问题

  • 原因:网络配置错误、防火墙规则等
  • 解决方案:检查网络配置,确保防火墙允许必要的端口

十四、总结

Docker 容器化技术已经成为现代应用部署的标准实践,它提供了一种轻量级、可移植、一致的部署方式,大大简化了应用的开发、测试和部署流程。

通过掌握 Docker 的核心概念、基本操作、Dockerfile 编写、Docker Compose 配置以及容器化部署实践,你可以构建一个高效、可靠的容器化应用环境。同时,关注 Docker 的安全最佳实践、监控与日志管理,以及容器编排技术,可以进一步提升应用的可靠性和可扩展性。

作为一名开发人员或运维工程师,掌握 Docker 容器化技术将有助于你更高效地构建和部署应用,适应现代云原生架构的需求,从而在竞争激烈的技术领域中保持优势。

Released under the MIT License.