Docker 详细教程 – wiki词典

Docker 详细教程

Docker 是一个开源的应用容器引擎,它允许开发者将应用程序及其所有依赖项打包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。容器采用沙箱机制,相互之间不会有任何接口,并且性能开销极低。

本教程将详细介绍 Docker 的核心概念、安装、基本操作、Dockerfile 以及多容器应用管理等内容,帮助您从入门到实践。

第一部分:Docker 基础

1. 什么是 Docker?

Docker 是一种容器化技术,它将应用程序源代码与在任何环境中运行该代码所需的操作系统库和依赖项相结合,打包成标准化的、可执行的组件——容器。借助 Docker,您可以将容器当做轻巧、模块化的虚拟机来使用,实现对容器的高效创建、部署及复制,并在不同环境之间迁移它们。

2. 为什么使用 Docker?

  • 环境一致性:Docker 解决了“在我机器上能跑”的问题,确保应用程序在开发、测试、生产环境中的运行一致性。
  • 资源高效:容器直接共享主机内核,无需虚拟化整个操作系统,从而节省内存和 CPU 资源。
  • 快速部署:容器可以秒级启动,支持自动化扩缩容。
  • 隔离性:每个容器拥有独立的文件系统、网络和进程空间,与其他容器隔离。
  • 简化管理:Docker 提供了丰富的工具和平台,用于管理容器、服务和集群,使应用程序的部署、扩展和运维变得简单。

3. Docker 核心概念

  • 镜像 (Image):镜像是一个只读模板,定义了容器的运行环境,包括应用程序代码、库、工具、依赖项和运行应用程序所需的其他文件。镜像通过分层存储(Layer)优化空间和构建速度。
  • 容器 (Container):容器是 Docker 镜像的可运行实例,封装了应用程序及其环境,为应用程序提供了一个隔离的运行环境。容器可以被创建、启动、停止、删除、暂停等。
  • 仓库 (Repository):仓库是集中存放 Docker 镜像的地方,类似 Git 的远程仓库。Docker Hub 是官方提供的公共镜像仓库,用户可以在其中搜索、拉取和分享镜像。
  • Dockerfile:Dockerfile 是一个文本文件,包含了一系列指令,用于描述如何自动构建 Docker 镜像。

4. Docker 与虚拟机的区别

虚拟机 (VM) 虚拟化的是服务器硬件,它可以在一个操作系统中运行另一个完整的操作系统。而容器虚拟化的是服务器的操作系统,Docker 是容器的操作系统(或运行时)。

  • 资源占用:虚拟机独占一部分内存和硬盘空间,运行完整操作系统,资源占用多。容器是进程级别的,直接运行在宿主机的操作系统上,资源占用少。
  • 启动速度:虚拟机启动需要几分钟,而容器启动通常是秒级的。
  • 隔离级别:虚拟机提供硬件级别的隔离,容器提供进程级别的隔离。

第二部分:Docker 安装

Docker Engine 是一个客户端-服务器应用程序,负责构建、运行和管理容器。它由一个守护进程(Docker Daemon)和一个命令行界面(CLI)组成。Docker 官方提供了在 Linux、Windows 和 macOS 上的安装指南。

1. Linux 上安装 Docker (以 Ubuntu/CentOS 为例)

Ubuntu:

“`bash

更新 apt 包索引

sudo apt update

安装 Docker 依赖包

sudo apt install ca-certificates curl gnupg

添加 Docker 官方 GPG 密钥

sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg –dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

添加 Docker 仓库到 Apt 源

echo \
“deb [arch=”$(dpkg –print-architecture)” signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
“$(. /etc/os-release && echo “$VERSION_CODENAME”)” stable” | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

再次更新 apt 包索引

sudo apt update

安装 Docker Engine、CLI 和 Containerd

sudo apt install docker-ce docker-ce-cli containerd.io

启动 Docker 服务

sudo systemctl start docker

设置 Docker 开机自启动

sudo systemctl enable docker
“`

CentOS:

“`bash

卸载旧版本 Docker

sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine

安装 yum-utils 包

sudo yum install -y yum-utils

添加 Docker 仓库

sudo yum-config-manager \
–add-repo \
https://download.docker.com/linux/centos/docker-ce.repo

安装 Docker Engine、CLI 和 Containerd

sudo yum install docker-ce docker-ce-cli containerd.io

启动 Docker 服务

sudo systemctl start docker

设置 Docker 开机自启动

sudo systemctl enable docker
“`

2. Windows 上安装 Docker

对于 Windows 10 专业版、企业版、教育版和部分家庭版,推荐安装 Docker Desktop for Windows。Docker Desktop 包含了 Docker Engine、Docker CLI 客户端、Docker Compose、Kubernetes 等,并提供对 Docker Hub 的访问。

访问 Docker 官方网站下载 Docker Desktop 安装包,双击运行并按照提示完成安装。

3. macOS 上安装 Docker

对于 macOS 用户,推荐安装 Docker Desktop for Mac

访问 Docker 官方网站下载 Docker Desktop 安装包,双击运行并按照提示完成安装。

4. 配置镜像加速器

由于网络原因,从 Docker Hub 拉取镜像可能会很慢。配置镜像加速器可以显著提高下载速度。

编辑 /etc/docker/daemon.json 文件 (如果文件不存在则创建),添加或修改 registry-mirrors 配置。

json
{
"registry-mirrors": [
"https://docker.mirrors.ustc.edu.cn",
"https://registry.docker-cn.com"
]
}

保存文件后,重启 Docker 服务:

bash
sudo systemctl restart docker

第三部分:Docker 基本命令

1. 服务管理

  • 启动 Docker 服务sudo systemctl start docker
  • 停止 Docker 服务sudo systemctl stop docker
  • 重启 Docker 服务sudo systemctl restart docker
  • 查看 Docker 服务状态sudo systemctl status docker
  • 设置开机自启动sudo systemctl enable docker
  • 查看 Docker 版本信息docker version
  • 查看 Docker 简要信息docker info

2. 镜像管理

  • 搜索镜像docker search <关键字>
    • 例如:docker search ubuntu
  • 拉取镜像docker pull <镜像名>[:<标签>]
    • 例如:docker pull ubuntu:20.04 (拉取 Ubuntu 20.04 版本的镜像)
    • 如果不指定标签,默认拉取 latest 版本。
  • 查看本地镜像docker imagesdocker image ls
  • 删除镜像docker rmi <镜像ID或镜像名>
    • 例如:docker rmi ubuntu:20.04
    • 强制删除:docker rmi -f <镜像ID或镜像名>
  • 导出镜像docker save -o <文件名>.tar <镜像名>[:<标签>]
    • 例如:docker save -o ubuntu.tar ubuntu:20.04
  • 导入镜像docker load -i <文件名>.tar
    • 例如:docker load -i ubuntu.tar

3. 容器管理

  • 创建并启动容器docker run [OPTIONS] <镜像名>[:<标签>] [COMMAND] [ARG...]
    • docker run 命令会根据镜像创建一个新的容器并启动它。
    • 常用选项:
      • -i:交互式操作。
      • -t:分配一个伪终端。通常与 -i 结合使用,即 -it
      • -d:后台运行容器。
      • -p <宿主机端口>:<容器端口>:端口映射。
      • --name <容器名>:为容器指定一个名称。
      • -v <宿主机路径>:<容器路径>:数据卷挂载。
    • 例如:docker run -it --name myubuntu ubuntu:20.04 /bin/bash (创建一个名为 myubuntu 的容器并进入其 bash 终端)
    • 例如:docker run -d -p 80:80 --name mynginx nginx (后台运行一个 Nginx 容器,并将宿主机的 80 端口映射到容器的 80 端口)
  • 列出运行中的容器docker ps
  • 列出所有容器 (包括已停止的)docker ps -a
  • 启动已停止的容器docker start <容器ID或容器名>
  • 停止运行中的容器docker stop <容器ID或容器名>
  • 重启容器docker restart <容器ID或容器名>
  • 删除容器docker rm <容器ID或容器名>
    • 强制删除运行中的容器:docker rm -f <容器ID或容器名>
  • 进入运行中的容器docker exec -it <容器ID或容器名> /bin/bash
    • docker attach <容器ID或容器名> 也可以进入容器,但退出时容器也会停止。
  • 查看容器日志docker logs <容器ID或容器名>
  • 暂停/恢复容器docker pause <容器ID或容器名> / docker unpause <容器ID或容器名>

第四部分:Dockerfile 详解

Dockerfile 是一个文本文件,用于自动化构建 Docker 镜像。它包含了一系列指令,每条指令都对应着镜像的一层。

1. Dockerfile 作用

  • 自动化构建:通过编写 Dockerfile,可以自动化地构建出符合特定需求的镜像。
  • 版本控制:Dockerfile 可以像代码一样进行版本控制,方便追踪和回溯镜像的构建过程。
  • 环境再现:确保每次构建的镜像环境都是一致的。

2. 常用 Dockerfile 指令

  • FROM <基础镜像>[:<标签>]:指定基础镜像,所有 Dockerfile 都必须以 FROM 指令开始。
    • 例如:FROM ubuntu:20.04
  • RUN <命令>:在当前镜像层中执行命令,并提交结果。常用于安装软件包、创建目录等。
    • 例如:RUN apt-get update && apt-get install -y nginx
  • COPY <源路径> <目标路径>:将宿主机的文件或目录复制到镜像中。
    • 例如:COPY ./app /usr/src/app
  • ADD <源路径> <目标路径>:与 COPY 类似,但 ADD 支持解压压缩文件和处理 URL。
    • 例如:ADD http://example.com/latest.tar.gz /tmp/
  • WORKDIR <路径>:设置工作目录,后续的 RUN, CMD, ENTRYPOINT 等指令都会在该目录下执行。
    • 例如:WORKDIR /app
  • CMD ["可执行文件", "参数1", "参数2"]:容器启动时执行的默认命令。一个 Dockerfile 中只能有一个 CMD 指令,如果指定了多个,只有最后一个生效。
    • 例如:CMD ["nginx", "-g", "daemon off;"]
  • ENTRYPOINT ["可执行文件", "参数1", "参数2"]:容器启动时执行的命令,不会被 docker run 后面的命令覆盖,而是作为其参数。
    • 例如:ENTRYPOINT ["/usr/bin/nginx"]
  • EXPOSE <端口号>:声明容器运行时监听的端口。这只是一个声明,并不会实际发布端口,需要配合 docker run -p 使用。
    • 例如:EXPOSE 80
  • ENV <键>=<值>:设置环境变量。
    • 例如:ENV MY_VAR=my_value

3. 构建镜像示例

创建一个名为 Dockerfile 的文件:

“`dockerfile

使用官方的 Node.js 16 镜像作为基础

FROM node:16

设置工作目录

WORKDIR /app

将 package.json 和 package-lock.json 复制到工作目录

COPY package*.json ./

安装项目依赖

RUN npm install

将所有文件复制到工作目录

COPY . .

暴露端口

EXPOSE 3000

定义容器启动时执行的命令

CMD [“npm”, “start”]
“`

Dockerfile 所在的目录下执行构建命令:

bash
docker build -t my-node-app:1.0 .

  • -t my-node-app:1.0:为构建的镜像指定名称和标签。
  • .:表示 Dockerfile 所在的上下文路径为当前目录。

构建成功后,可以使用 docker images 查看新构建的镜像。

第五部分:Docker Compose

Docker Compose 是一个用于定义和运行多容器 Docker 应用程序的工具。通过 Compose,您可以使用 YAML 文件来配置应用程序所需的所有服务,然后使用一个命令就可以从配置中创建并启动所有服务。

1. 什么是 Docker Compose?

在实际应用中,一个完整的项目通常由多个服务组成,例如一个 Web 应用程序可能需要 Web 服务器、数据库、缓存等多个容器。手动管理这些容器会非常繁琐。Docker Compose 旨在解决这个问题,它允许您通过一个 docker-compose.yml 文件来定义和管理这些相互关联的容器,从而简化多容器应用的部署和管理。

2. 安装 Docker Compose

如果您安装的是 Docker Desktop (Windows/macOS),Docker Compose 通常已经内置。

对于 Linux 系统,可以通过以下方式安装:

“`bash

下载 Docker Compose 二进制文件

sudo curl -L “https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)” -o /usr/local/bin/docker-compose

赋予执行权限

sudo chmod +x /usr/local/bin/docker-compose

验证安装

docker-compose –version
“`

3. docker-compose.yml 文件结构

docker-compose.yml 文件是 Docker Compose 的核心,它使用 YAML 格式定义了应用程序的服务、网络和数据卷。

一个典型的 docker-compose.yml 文件包含以下顶级键:

  • version:指定 Compose 文件格式的版本。
  • services:定义应用程序中的各个服务(容器)。每个服务下可以配置 imagebuildportsvolumesenvironmentdepends_onnetworks 等。
  • networks:定义应用程序使用的网络。
  • volumes:定义应用程序使用的数据卷。

示例 docker-compose.yml 文件:

“`yaml
version: ‘3.8’ # Compose 文件格式版本

services:
web: # 定义一个名为 ‘web’ 的服务
build: . # 从当前目录的 Dockerfile 构建镜像
ports:
– “80:80” # 将宿主机的 80 端口映射到容器的 80 端口
volumes:
– .:/app # 将当前目录挂载到容器的 /app 目录
depends_on:
– db # 依赖于 ‘db’ 服务
environment:
– DATABASE_URL=postgresql://user:password@db:5432/mydatabase # 环境变量

db: # 定义一个名为 ‘db’ 的服务
image: postgres:13 # 使用 PostgreSQL 13 官方镜像
environment:
– POSTGRES_DB=mydatabase
– POSTGRES_USER=user
– POSTGRES_PASSWORD=password
volumes:
– db_data:/var/lib/postgresql/data # 将命名数据卷 ‘db_data’ 挂载到数据库数据目录

volumes:
db_data: # 定义一个命名数据卷
“`

4. Docker Compose 常用命令

  • 启动所有服务docker-compose up
    • 后台运行:docker-compose up -d
  • 停止所有服务docker-compose stop
  • 停止并移除所有服务、网络、数据卷docker-compose down
  • 构建或重新构建服务镜像docker-compose build
  • 查看服务状态docker-compose ps
  • 查看服务日志docker-compose logs
  • 在指定服务容器上执行命令docker-compose run <服务名> <命令>
  • 删除所有(停止状态的)服务容器docker-compose rm

第六部分:Docker 数据管理与网络

1. 数据管理 (数据持久化)

容器是临时的,容器删除后其内部的数据也会丢失。为了实现数据的持久化和共享,Docker 提供了两种主要的数据管理方式:数据卷 (Volumes) 和绑定挂载 (Bind Mounts)。

  • 数据卷 (Volumes)
    数据卷是 Docker 管理的宿主机文件系统中的特殊目录,独立于容器的生命周期。即使容器被删除,数据卷中的数据仍然会保留。数据卷是 Docker 中持久化数据的最佳方式,并且可以方便地在多个容器之间共享和重用。

    • 创建命名数据卷docker volume create <卷名>
      • 例如:docker volume create my_data
    • 挂载数据卷:在 docker run 命令中使用 -v <卷名>:<容器路径>--mount source=<卷名>,target=<容器路径>
      • 例如:docker run -d -v my_data:/app/data --name mycontainer myimage
    • 查看数据卷docker volume ls
    • 查看数据卷详情docker volume inspect <卷名>
    • 删除数据卷docker volume rm <卷名>
  • 绑定挂载 (Bind Mounts)
    绑定挂载允许您将宿主机上的任意目录或文件直接挂载到容器中。宿主机上的非 Docker 进程和容器可以同时使用挂载的文件系统。绑定挂载的生命周期与宿主机文件系统绑定,不被 Docker 管理。

    • 挂载绑定挂载:在 docker run 命令中使用 -v <宿主机路径>:<容器路径>--mount type=bind,source=<宿主机路径>,target=<容器路径>
      • 例如:docker run -d -v /path/on/host:/app/config --name mycontainer myimage

2. Docker 网络

Docker 提供了多种网络模式,用于容器之间的通信以及容器与宿主机、外部网络的通信。

  • bridge 模式 (默认)
    Docker 默认的网络模式。此模式会为每个容器分配独立的网络命名空间和 IP 地址,并将一个主机上的 Docker 容器连接到一个虚拟网桥上。容器之间可以通过 IP 地址相互通信,外部网络通过端口映射访问容器。
  • host 模式
    容器与宿主机共享网络命名空间。容器直接使用宿主机的网络栈,没有独立的 IP 地址。容器内部的服务可以直接使用宿主机的 IP 地址和端口。
  • none 模式
    容器拥有自己的网络命名空间,但 Docker 不为其进行任何网络配置。容器没有网卡、IP、路由等信息,需要手动配置网络。
  • container 模式
    新创建的容器与一个已经存在的容器共享网络命名空间。新容器不会创建自己的网卡和 IP,而是与指定容器共享 IP、端口范围等。
  • 自定义网络
    除了默认的 bridge 网络,您可以创建自定义的桥接网络,以实现更好的隔离和控制。当您希望将相关的容器分组或需要控制哪些容器可以相互通信时,自定义网络特别有用。

    • 创建自定义网络docker network create <网络名>
      • 例如:docker network create my_app_network
    • 连接容器到网络:在 docker run 命令中使用 --network <网络名>
      • 例如:docker run -d --network my_app_network --name mycontainer myimage
    • 查看网络docker network ls
    • 查看网络详情docker network inspect <网络名>

第七部分:Docker 最佳实践

1. Dockerfile 优化

  • 使用最小化基础镜像:选择体积小、功能精简的基础镜像,如 Alpine Linux,可以显著减小镜像大小,提高下载速度和安全性。
  • 设定最小权限的 USER:避免在容器中以 root 用户运行应用程序,创建并使用非 root 用户。
  • 优化缓存顺序:将不常变化的指令放在 Dockerfile 的前面,利用 Docker 的分层缓存机制,加快镜像构建速度。
  • 使用 .dockerignore 文件:排除构建上下文中不需要的文件和目录,减少构建时间和镜像大小。
  • 避免安装不必要的包:只安装应用程序运行所需的依赖,减少镜像体积和潜在的安全漏洞。
  • 使用 COPY 而不是 ADDCOPY 功能更明确,只用于复制文件。ADD 具有解压和处理 URL 的功能,可能引入不必要的复杂性和安全风险。
  • 多阶段构建 (Multi-stage builds):将构建环境和运行时环境分离,只将最终的应用程序 artifact 复制到最终镜像中,从而大大减小最终镜像的体积。

2. 安全考虑

  • 使用特定的镜像版本:避免使用 latest 标签,而是使用带有明确版本号的镜像,确保环境的可重复性和稳定性,并便于追踪漏洞。
  • 扫描镜像漏洞:定期使用工具(如 Trivy, Clair)扫描镜像中的已知漏洞。
  • 不要在镜像中包含机密信息:敏感数据(如 API 密钥、密码)不应硬编码在 Dockerfile 或镜像中。应使用 Docker Secrets、环境变量或外部密钥管理工具(如 Hashicorp Vault)进行管理。
  • 运行时防护
    • 禁用特权模式:避免使用 --privileged 运行容器。
    • 设置只读文件系统:使用 --read-only 运行容器,限制容器对文件系统的写入能力。
    • 启用 Seccomp:限制容器可以进行的系统调用。
  • 网络隔离:使用自定义网络,并根据需要限制容器间的通信。

3. 日志管理

  • 查看容器日志:使用 docker logs <容器ID或容器名> 命令查看容器的标准输出和标准错误日志。
  • 限制日志大小:Docker 默认使用 json-file 日志驱动。为了防止日志文件无限增长占用磁盘空间,可以在 /etc/docker/daemon.json 中配置日志选项,例如 max-sizemax-file

    json
    {
    "log-driver": "json-file",
    "log-opts": {
    "max-size": "10m",
    "max-file": "3"
    }
    }

    保存后重启 Docker 服务。
    * 集中化日志管理:对于大规模部署,建议集成 ELK Stack (Elasticsearch, Logstash, Kibana) 或其他日志管理工具,实现日志的集中收集、存储、分析和可视化。

本教程涵盖了 Docker 的核心概念、安装、基本操作、Dockerfile、Docker Compose、数据管理、网络以及最佳实践。希望这些内容能帮助您更好地理解和使用 Docker。

滚动至顶部