Skip to content
大纲

Docker

Docker 是一种轻量级的容器化技术,能够将应用程序及其依赖打包到一个容器中,确保在不同环境中都可以一致运行。本文将从 Docker 的安装、基本命令、镜像管理、容器使用和实际应用部署几个方面,详细讲解如何使用 Docker。

1. Docker 的安装

1.1 安装前的准备

Docker 支持多种操作系统,主要包括 Linux(Ubuntu、CentOS 等)、Windows 和 macOS。在安装之前,请确保你的系统满足以下要求:

  • 64 位操作系统。
  • 支持虚拟化(Windows 和 macOS 会使用虚拟机运行 Docker)。

1.2 安装步骤

在 Linux 上安装(以 Ubuntu 为例)

  1. 更新系统:
    bash
    sudo apt-get update
    sudo apt-get upgrade
  2. 安装必要依赖:
    bash
    sudo apt-get install -y apt-transport-https ca-certificates curl software-properties-common
  3. 添加 Docker 官方 GPG 密钥和源:
    bash
    curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
    echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
  4. 安装 Docker:
    bash
    sudo apt-get update
    sudo apt-get install -y docker-ce docker-ce-cli containerd.io
  5. 验证 Docker 是否安装成功:
    bash
    docker --version

在 Windows 和 macOS 上安装

  1. 访问 Docker Desktop 下载适合系统的安装包。
  2. 安装 Docker Desktop,启用 Hyper-V 或 WSL 2(Windows 上需要)。
  3. 安装完成后,启动 Docker Desktop 并验证:
    bash
    docker --version

1.3 设置 Docker 镜像源

Docker 默认使用官方的镜像仓库 Docker Hub,但国内网络环境可能无法访问。

推荐使用阿里云镜像加速器,速度更快。

使用阿里云的镜像加速器时,仅支持阿里云用户使用具备公网访问能力的阿里云产品进行镜像加速,且仅限于特定范围内的容器镜像。推荐使用制品中心提供的官方支持的容器基础镜像。

在 Linux 上配置

可以通过修改 daemon 配置文件 /etc/docker/daemon.json 来使用加速器

bash
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://xxx.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

在 macOS 上配置

在 macOS 上,可以使用 Docker Desktop 的设置界面来配置加速器。

在任务栏点击 Docker Desktop 应用图标 -> Settings,在左侧导航菜单选择 Docker Engine,在右侧输入栏编辑 json 文件。 在原有内容后面添加 registry-mirrors 配置项,如下:

json
{
	"builder": {
    "gc": {
      "defaultKeepStorage": "20GB",
      "enabled": true
    }
  },
  "experimental": false,
  "registry-mirrors": ["https://xxx.mirror.aliyuncs.com"]
}

2. Docker 的基本使用

2.1 核心概念

  • 镜像(Image):Docker 镜像是一个轻量级的、独立的、可执行的软件包,包含代码、运行时、库和配置文件。
  • 容器(Container):容器是镜像的运行实例,可以启动、停止、删除、复制等,具有轻量、隔离的特点。
  • Dockerfile:用于定义 Docker 镜像的构建规则。
  • Docker Hub:官方的镜像仓库,提供大量可用的镜像。
  • Docker Compose:用于定义和运行多个容器的编排工具。

2.2 常用命令

镜像相关

  1. 搜索镜像:
    bash
    docker search <镜像名>
  2. 拉取镜像:
    bash
    docker pull <镜像名称[:标签]>
    示例:拉取最新版的 Nginx 镜像:
    bash
    docker pull nginx:latest
  3. 查看本地镜像:
    bash
    docker images
  4. 删除镜像:
    bash
    docker rmi <镜像ID>

容器相关

  1. 启动容器(以 Nginx 为例):
    bash
    docker run -d --name my-nginx -p 8080:80 nginx
    • -d:后台运行。
    • --name:指定容器名称。
    • -p:映射端口。
  2. 查看运行中的容器:
    bash
    docker ps
    
    # 查看已停止的容器:
    docker ps -a
  3. 停止容器:
    bash
    docker stop <容器ID或名>
  4. 删除容器:
    bash
    docker rm <容器ID或名>
  5. 进入容器:
    bash
    docker exec -it <容器ID或名> bash
  6. 查看容器日志:
    bash
    docker logs <容器ID或名>

3. Dockerfile 的使用

Dockerfile 是构建 Docker 镜像的核心工具。以下是一个简单的示例:

bash
# 使用官方基础镜像
FROM node:18

# 设置工作目录
WORKDIR /app

# 复制 package.json 并安装依赖
COPY package.json .
RUN npm install

# 复制应用代码
COPY . .

# 暴露端口
EXPOSE 3000

# 启动应用
CMD ["node", "server.js"]

构建镜像

使用 Dockerfile 构建镜像的命令:

bash
docker build -t my-node-app .

4. 使用 Docker 部署应用

4.1 部署单个服务

以 Nginx 为例,部署一个静态网站:

  1. 创建一个本地文件夹 html,并添加 index.html 文件。
  2. 启动 Nginx 容器,并挂载文件夹:
    bash
    docker run -d --name nginx-server -p 8080:80 -v $(pwd)/html:/usr/share/nginx/html nginx
    • -d:后台运行容器,并返回容器 ID。
    • --name nginx-server:指定容器名称。
    • -p 8080:80:将主机的 8080 端口映射到容器的 80 端口。
    • -v $(pwd)/html:/usr/share/nginx/html:将主机的 html 文件夹挂载到容器的 /usr/share/nginx/html 目录。
    • nginx:指定要运行的镜像名称。

访问 http://localhost:8080 即可看到网站页面。

4.2 使用 Docker Compose 部署多个服务

Docker Compose 是一个用于定义和运行多个 Docker 容器的应用程序工具。它使用 YAML 文件来描述应用程序的服务,然后使用一个命令来创建并启动多个容器。

示例:部署一个 WordPress 应用

创建 docker-compose.yml 文件:

yaml
version: '3.8'
services:
	db:
		image: mysql:5.7
		restart: always
		environment: 
			MYSQL_ROOT_PASSWORD: root
			MYSQL_DATABASE: wordpress
			MYSQL_USER: user
			MYSQL_PASSWORD: password
			TZ: Asia/Shanghai
	wordpress:
		image: wordpress:latest
		restart: always
		ports:
			- "8080:80"
		environment:
			WORDPRESS_DB_HOST: db
			WORDPRESS_DB_USER: user
			WORDPRESS_DB_PASSWORD: password
			WORDPRESS_DB_NAME: wordpress

启动服务:

bash
docker-compose up -d

访问 http://localhost:8080,即可看到 WordPress 应用。

5. Docker 数据持久化

5.1 为什么需要数据持久化?

Docker 容器中的数据默认存储在容器内的文件系统中,但容器本质上是短暂的(临时的)。如果容器被删除或重新创建,容器内的数据会随之丢失。因此,为了保证重要数据的长期保存和共享,我们需要实现数据的持久化。

5.2 实现数据持久化的方式

方式 1:使用 Bind Mount(绑定挂载)

绑定挂载是将主机的目录或文件直接挂载到容器中,使容器可以直接访问主机的数据。

  • 优点:
    1. 数据存储在主机上,可被其他进程直接访问。
    2. 无需 Docker 进行额外的数据管理。
  • 使用方法:
    bash
    docker run -d --name my-container -v /path/on/host:/path/in/container my-image
    • /path/on/host:主机上要挂载的目录或文件。
    • /path/in/container:容器内的目录或文件。
  • 示例: 将主机 /html 目录挂载到容器的 /usr/share/nginx/html 目录。
    bash
    docker run -d --name my-container -v /html:/usr/share/nginx/html nginx
    这样,主机 /html 目录中的内容会直接映射到 Nginx 的默认静态文件目录中。

方式 2:使用 Volume(卷)

Docker 卷是 Docker 提供的一种数据持久化机制,用于将数据存储在 Docker 管理的路径中。相比 Bind Mount,卷更适合 Docker 环境,尤其是容器间共享数据的场景。

  • 优点:
    1. 卷由 Docker 管理,独立于主机文件系统。
    2. 支持容器间的数据共享。
    3. 数据独立于容器生命周期,容器删除后数据仍然保留。
    4. 跨平台兼容性更好。
  • 使用方法: 创建一个名为 my-volume 的卷,挂载到容器的 /usr/share/nginx/html
    bash
    docker volume create my-volume
    docker run -d --name my-nginx -v my-volume:/usr/share/nginx/html nginx
    卷的数据存储路径在主机上可以通过以下命令查看:
    bash
    docker volume inspect my-volume
    
    # 查看卷列表
    docker volume ls

方式 3:使用 tmpfs(临时文件系统)

tmpfs 是一种将数据存储在主机的内存中的方式,适合对性能要求高且不需要持久化的数据(如临时缓存)。

  • 优点:
    1. 存储在内存中,读写性能快。
    2. 数据随着容器停止而销毁,避免敏感数据留在磁盘上。
  • 使用方法: 启动容器时,使用 --tmpfs 参数来指定一个临时文件系统。例如:
    bash
    docker run -d --name my-container --tmpfs /path/in/container image-name
  • 示例: 将容器的 /usr/share/nginx/html 挂载为一个临时文件系统:
    bash
    docker run -d --name my-nginx --tmpfs /usr/share/nginx/html nginx

5.3 数据持久化的最佳实践

  1. 优先使用 Volume:
    • 如果数据仅由 Docker 管理,建议使用 Docker 卷,因为它更易于管理和迁移。
    • 适合需要容器间共享的数据场景。
  2. 使用 Bind Mount 访问主机数据:
    • 如果需要将主机上的目录(如日志文件)与容器共享,使用 Bind Mount 更加直接。
    • 注意权限问题,确保主机目录的读写权限与容器一致。
  3. 选择合适的存储驱动:
    • 根据使用的文件系统和存储需求,选择合适的 Docker 存储驱动(如 overlay2、aufs 等)。
  4. 备份数据:
    • 定期备份卷中的数据,尤其是生产环境中的重要数据。
    • 可以使用命令将卷数据导出:
      bash
      docker run --rm -v my-volume:/data -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /data
  5. 注意性能和存储需求:
    • 对性能要求高的数据(如缓存),可以使用 tmpfs。
    • 对重要数据,建议使用卷并结合外部存储方案(如 NFS、云存储)。

5.4 数据迁移与备份

  1. 将数据从卷导出 使用容器将卷中的数据导出为压缩包:
bash
docker run --rm -v my-volume:/data -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /data
  1. 将数据导入到新卷 将备份数据导入到一个新的卷中:
bash
docker run --rm -v my-new-volume:/data -v $(pwd):/backup ubuntu tar xvf /backup/backup.tar -C /data

5.5 持久化与容器编排(Docker Compose)

在 Docker Compose 中,可以通过 volumes 配置数据持久化。

示例:部署带持久化的 MySQL 服务

yaml
version: '3.8'
services:
  db:
		image: mysql:5.7
		environment:
			MYSQL_ROOT_PASSWORD: root
			MYSQL_DATABASE: my_db
		volumes:
			- db-data:/var/lib/mysql
volumes:
  db-data:

在上面配置中:

  • volumes 配置了一个名为 db-data 的持久化卷,挂载到 MySQL 容器的 /var/lib/mysql 目录。
  • 数据会持久化到 Docker 卷 db-data 中。
  • 即使容器被删除,数据依然保留。

6. Docker 的优势与注意事项

6.1 优势

  1. 轻量级:相比虚拟机,Docker 容器启动更快,占用资源更少。
  2. 一致性:开发环境与生产环境一致,避免“它在我机器上能运行”的问题。
  3. 易于扩展:支持水平扩展和微服务架构。
  4. 丰富的生态:Docker Hub 提供了大量开箱即用的镜像。

6.2 注意事项

  1. 安全性:避免使用不可信的镜像。
  2. 数据持久化:容器中的数据是临时的,需使用卷(Volume)进行持久化。
  3. 资源限制:为容器设置 CPU 和内存限制,避免资源耗尽。

7. 总结

Docker 是现代开发和部署的核心工具之一,其轻量级特性和丰富的生态系统使得它成为开发者和运维工程师的首选工具。通过本文,你已经学习了 Docker 的安装、基本命令、镜像构建和应用部署等关键内容,希望这能帮助你在实际项目中更高效地使用 Docker。