1. 引言
1.1 为什么学习 Docker
1.1.1 Docker 的优势
- 环境一致:在不同环境中(开发、测试、生产)保持一致的运行环境。
- 快速部署:容器启动速度快,适合微服务架构。
- 资源隔离:容器之间相互隔离,避免资源冲突(举例:容器1报错,内存溢出,不会影响容器2的运行)。
- 可扩展性:轻松扩展应用实例,适应高并发场景。
1.1.2 Docker 应用场景
- 开发环境一致性:使用 Dockerfile 定义项目环境,团队成员和 CI/CD 流程可以快速复现相同的运行环境。
- 持续集成与交付:在 CI/CD 工具(如 Jenkins、GitHub Actions)中集成 Docker,实现一键构建、测试和部署。
- 微服务架构支持:使用 Docker Compose 或 Kubernetes 编排容器,快速启动和管理微服务集群。
- 资源优化与高效部署:在一台服务器上运行多个容器,或在云环境中快速启动容器以应对流量高峰。
1.2 本文目标
- 适合人群:初学者、开发者、运维人员
- 学习目标:掌握 Docker 的核心概念、安装与基本操作
2. Docker 是什么?
Docker 是一个开源的容器化平台,允许开发者将应用程序及其依赖打包成一个可移植的容器。容器可以在任何安装了 Docker 的环境中运行,确保应用的一致性和可移植性。
2.1 容器化技术简介
容器化技术是一种轻量级的虚拟化技术,用于将应用程序及其依赖项打包到一个独立的运行环境中,称为“容器”。容器化技术的核心思想是通过隔离应用程序的运行环境,确保其在任何支持容器化技术的环境中都能一致运行。
2.1.1 容器化技术的定义
- 容器化:将应用程序及其依赖项(代码、配置文件、库、环境变量等)打包到一个独立的、可移植的单元中,这个单元称为“容器”。
- 容器:容器是一个运行中的镜像实例,它共享宿主机的内核,但与其他容器隔离。容器是轻量级的,启动速度快,资源占用少。
2.1.2 容器化与虚拟机的对比
特性 | 容器化 | 虚拟机 |
---|---|---|
隔离性 | 进程隔离,共享宿主机内核 | 完全隔离,每个虚拟机都有独立的内核 |
启动速度 | 快(秒级) | 慢(分钟级) |
资源占用 | 轻量级(MB 级) | 重量级(GB 级) |
性能开销 | 低 | 高 |
适用场景 | 微服务、开发测试、云原生应用 | 高企业级应用、多租户环境 |
2.2 Docker 的架构
2.2.1 Docker 客户端(Docker Client)
Docker 客户端是用户与 Docker 交互的工具。它发送命令到 Docker 服务器(Docker Daemon),并接收服务器的响应。客户端可以是命令行工具(CLI)或其他支持 Docker API 的工具。
-
功能:
- 提供命令行界面(CLI),用于执行 Docker 命令。
- 支持与其他工具集成,如 Docker Compose 和 Docker Machine。
- 可以通过 API 与其他应用程序交互。
-
使用场景:
- 开发者通过客户端构建、运行和管理容器。
- 客户端可以连接到本地或远程的 Docker 服务器。
-
示例命令:
# 查看 Docker 版本信息 docker version# 列出所有运行中的容器 docker ps# 运行一个容器 docker run hello-world
2.2.2 Docker 服务器(Docker Daemon)
Docker 服务器(也称为 Docker 守护进程)是 Docker 的后台服务,负责管理 Docker 对象(如镜像、容器、网络和卷)。它接收来自客户端的请求,并执行相应的操作。
-
功能:
- 管理 Docker 对象(镜像、容器、网络、卷等)。
- 提供 REST API,允许客户端与服务器通信。
- 处理客户端的请求,如创建、启动、停止和删除容器。
-
组件:
- Docker Daemon:主守护进程,负责管理 Docker 对象。
- Docker API:提供与 Docker 守护进程通信的接口。
- Docker Registry:存储和分发 Docker 镜像的仓库。
-
工作流程:
- 客户端发送请求到 Docker 守护进程。
- 守护进程处理请求,并执行相应的操作。
- 守护进程将结果返回给客户端。
-
示例:
- 守护进程监听默认的 Unix 套接字(
/var/run/docker.sock
)。 - 可以配置守护进程监听 TCP 端口,以支持远程客户端连接。
- 守护进程监听默认的 Unix 套接字(
2.3 Docker 的核心理念
2.3.1 镜像(image)
- 定义:Docker 镜像是一个只读模板,包含了运行应用程序所需的所有内容,包括代码、依赖项、库、配置文件等。
- 特点:
- 镜像是不可变的,一旦创建就不能修改。
- 镜像可以被分层,每一层代表一个变更。
- 镜像可以存储在本地或远程仓库中。
- 用途:
- 用于创建容器。
- 可以在不同环境中分发和共享。
- 示例:
# 拉取一个镜像 docker pull nginx# 查看本地镜像 docker images
2.3.2 容器(container)
- 定义:容器是镜像的运行实例。它是一个隔离的、轻量级的运行环境。
- 特点:
- 容器是动态的,可以启动、停止、删除。
- 容器共享宿主机的内核,因此启动速度快、资源占用少。
- 容器之间是隔离的,不会互相干扰。
- 生命周期:
- 创建(创建容器时,镜像会被加载并分配一个可写层)。
- 运行(容器启动并执行指定的命令)。
- 停止(容器停止运行,但数据仍然保留)。
- 删除(容器被彻底删除)。
- 示例:
# 创建并运行一个容器 docker run -d --name my-nginx nginx# 查看运行中的容器 docker ps# 停止容器 docker stop my-nginx# 删除容器 docker rm my-nginx
2.3.3 仓库(repository)
- 定义:仓库是一个存储和分发 Docker 镜像的地方。
- 类型:
- 公共仓库:如 Docker Hub,任何人都可以访问。
- 私有仓库:如企业内部搭建的仓库,只有授权用户可以访问。
- 用途:
- 存储和共享镜像。
- 管理镜像的版本和标签。
- 示例:
# 推送镜像到仓库 docker push my-nginx:latest# 从仓库拉取镜像 docker pull my-nginx:latest
2.3.4 镜像、容器和仓库的关系
Docker 镜像、容器和仓库的关系可以类比为菜谱、做好的菜和菜谱书:
- 镜像:菜谱(包含了做菜的步骤和材料清单)。
- 容器:做好的菜(按照菜谱做出来的实际菜品)。
- 仓库:菜谱书(收集了各种菜谱的地方)。
3. Docker 安装
3.1 在 Ubuntu 上安装 Docker
# 更新包索引
sudo apt-get update# 安装依赖包
sudo apt-get install apt-transport-https ca-certificates curl software-properties-common# 添加 Docker 的官方 GPG 密钥
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -# 添加 Docker 的 APT 仓库
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"# 更新包索引
sudo apt-get update# 安装 Docker CE
sudo apt-get install docker-ce# 验证 Docker 是否安装成功
sudo docker run hello-world
3.2 在 Windows 和 macOS 上安装 Docker
- 下载并安装 Docker Desktop。
3.3 在 CentOS 上安装 Docker
- 可参考博主的另外一篇文章 CentOS 7 64 安装 Docker。
4. Docker 基本命令
可参考另外一篇文章:Docker 基础命令 - 以 Nginx 实战总结
4.1 常用基础命令
# 查看所有运行中的容器
docker ps# 查看所有容器(包括停止的)
docker ps -a# 查看所有镜像
docker images# 拉取镜像
docker pull <镜像名称># 运行容器
docker run -d -p 8080:80 --name my_container nginx# 进入容器
docker exec -it <容器名称或ID> /bin/bash# 停止容器
docker stop <容器名称或ID># 删除容器
docker rm <容器名称或ID># 删除镜像
docker rmi <镜像ID>
4.2 查看容器日志与进入容器
# 查看容器日志
docker logs <容器名称或ID># 进入容器内部
docker exec -it <容器名称或ID> /bin/bash
5. Docker 网络
Docker 网络是 Docker 提供的一种机制,用于管理容器之间的通信。它通过虚拟网络实现容器之间的连接、隔离和数据传输。Docker 网络的核心目标是确保容器之间能够高效、安全地通信,同时保持隔离性。
5.1 Docker 网络类型
5.1.1 Bridge 网络(桥接网络)
- 定义与特点:这是 Docker 的默认网络类型。Docker 在宿主机上创建一个虚拟网桥(如
docker0
),将容器连接到这个网桥上。每个容器都有一个独立的 IP 地址,并且可以通过这个 IP 地址在同一网络内进行通信。 - 工作原理:当创建一个容器时,Docker 会为容器分配一个 IP 地址,并将容器连接到宿主机上的虚拟网桥。容器之间可以通过这个网桥进行通信,就像在同一个局域网内一样。
- 应用场景:适用于大多数简单的应用场景,特别是在单个宿主机上运行多个容器时。例如,开发环境中运行的多个微服务容器可以使用 Bridge 网络进行通信。
5.1.2 Host 网络
- 定义与特点:使用 Host 网络类型的容器直接使用宿主机的网络栈,不会创建独立的网络命名空间。这意味着容器将与宿主机共享 IP 地址和端口,并且可以直接访问宿主机上的网络资源。
- 工作原理:容器直接使用宿主机的网络接口和 IP 地址,与宿主机在网络层面上完全融合。容器内的应用程序可以直接监听宿主机的端口,并且可以与宿主机上的其他进程进行通信。
- 应用场景:当需要容器与宿主机上的其他进程进行高性能通信时,或者容器需要直接访问宿主机上的网络设备时,可以使用 Host 网络。例如,一些网络性能敏感的应用或者需要直接访问硬件设备的容器可以选择 Host 网络。
5.1.3. None 网络
- 定义与特点:None 网络类型表示容器没有任何网络配置。容器将完全隔离于网络,不能与其他容器或外部系统进行通信。
- 工作原理:创建容器时,不进行任何网络配置,容器内没有网络接口和 IP 地址。这种网络类型通常用于需要完全隔离网络环境的场景。
- 应用场景:在某些安全要求较高的场景中,或者需要对容器的网络进行特殊定制时,可以先使用 None 网络类型创建容器,然后再通过其他方式为容器配置网络。例如,在进行安全测试时,可以使用 None 网络类型创建容器,以确保容器与外部网络完全隔离。
5.2 自定义网络
Docker 自定义网络允许用户根据具体需求创建和管理网络环境
# 创建自定义网络
docker network create my_network# 查看网络
docker network ls# 查看网络详细信息
docker network inspect my_network
5.3 桥接模式的容器互联
根据上面创建的my_network网络,进行容器互联
# 运行容器并连接到自定义网络
docker run -d --name container1 --network my_network nginx# 运行另一个容器并连接到同一个网络
docker run -d --name container2 --network my_network nginx
6 Docker 数据卷
Docker 数据卷是一种用于持久化数据的机制,它允许数据独立于容器的生命周期存在。数据卷可以被一个或多个容器共享,并且可以在容器重启或删除后仍然保留数据。
6.1 数据卷的特点
-
数据持久化:
- 数据卷中的数据独立于容器的生命周期,即使容器被删除,数据仍然保留。
- 适用于需要长期保存的数据,如数据库文件、配置文件等。
-
与容器解耦:
- 数据卷可以独立于容器进行管理和操作,不会随着容器的删除而丢失。
- 数据卷可以在不同的容器之间共享,便于数据的共享和迁移。
-
数据共享:
- 多个容器可以同时挂载同一个数据卷,实现数据的共享。
- 适用于需要多个容器访问相同数据的场景,如 Web 服务器和日志分析工具共享日志文件。
-
数据备份与恢复:
- 数据卷中的数据可以轻松备份和恢复,便于数据的管理和维护。
- 可以通过简单的文件系统操作对数据卷进行备份和恢复。
6.2 数据卷的使用场景
-
数据库持久化:
- 在容器中运行数据库时,使用数据卷可以确保数据库文件在容器重启或删除后仍然保留。
- 例如,MySQL 容器可以将数据库文件存储在数据卷中。
-
文件共享:
- 多个容器需要共享文件时,可以将文件存储在数据卷中,所有容器都可以访问这些文件。
- 例如,Web 服务器和日志分析工具可以共享日志文件。
-
配置文件管理:
- 将配置文件存储在数据卷中,便于在不同环境中快速切换配置。
- 例如,开发、测试和生产环境可以使用不同的配置文件。
-
数据备份与恢复:
- 定期备份数据卷中的数据,确保数据的安全性。
- 在需要时,可以快速恢复数据到容器中。
6.3 数据卷的操作
-
创建数据卷:
使用docker volume create
命令创建一个数据卷:docker volume create myvolume
-
将数据卷挂载到容器:
在创建容器时,使用-v
或--mount
选项将数据卷挂载到容器的指定目录:docker run -d --name mycontainer -v myvolume:/data myimage
-v myvolume:/data
:将数据卷myvolume
挂载到容器的/data
目录。
-
查看数据卷:
使用docker volume ls
命令查看所有数据卷:docker volume ls
-
查看数据卷的详细信息:
使用docker volume inspect
命令查看数据卷的详细信息:docker volume inspect myvolume
-
删除数据卷:
使用docker volume rm
命令删除数据卷:docker volume rm myvolume
7. Dockerfile
7.1 基本概念
Dockerfile 是一个文本文件,用于定义如何构建 Docker 镜像。它包含了一系列指令,这些指令告诉 Docker 如何一步步创建镜像。Dockerfile 是自动化构建镜像的核心工具,确保镜像的构建过程可重复、可维护。
7.2 Dockerfile 的作用
- 自动化构建:通过 Dockerfile,可以自动化镜像的构建过程,避免手动操作的繁琐和错误。
- 可维护性:Dockerfile 是一个脚本文件,可以存储在版本控制系统中,便于团队协作和历史追溯。
- 一致性:确保在不同环境中构建的镜像具有一致性,避免“在我的机器上可以运行”的问题。
- 可移植性:Dockerfile 可以在任何支持 Docker 的环境中运行,确保镜像的可移植性。
7.3 Dockerfile 的基本结构
Dockerfile 通常包含以下几个部分:
- 基础镜像:指定构建新镜像的基础镜像。
- 维护者信息:可选,用于标识镜像的维护者。
- 安装依赖:安装运行应用程序所需的依赖项。
- 复制文件:将应用程序代码或配置文件复制到镜像中。
- 环境变量:设置环境变量,用于配置应用程序。
- 暴露端口:指定容器运行时需要暴露的端口。
- 默认命令:指定容器启动时运行的默认命令。
7.4 Dockerfile 的常用指令
-
FROM:
- 指定基础镜像。
- 语法:
FROM <image>[:<tag>]
- 示例:
FROM ubuntu:20.04
-
RUN:
- 在镜像中执行命令。
- 语法:
RUN <command>
或RUN ["executable", "param1", "param2"]
- 示例:
RUN apt-get update && apt-get install -y nginx
-
COPY:
- 将本地文件或目录复制到镜像中。
- 语法:
COPY <src> <dest>
- 示例:
COPY . /app
-
ADD:
- 类似于 COPY,但支持远程 URL 和自动解压。
- 语法:
ADD <src> <dest>
- 示例:
ADD https://example.com/file.tar.gz /app
-
ENV:
- 设置环境变量。
- 语法:
ENV <key> <value>
或ENV <key>=<value> ...
- 示例:
ENV APP_HOME /app
-
EXPOSE:
- 指定容器运行时需要暴露的端口。
- 语法:
EXPOSE <port> [<port>...]
- 示例:
EXPOSE 80 443
-
CMD:
- 指定容器启动时运行的默认命令。
- 语法:
CMD ["executable", "param1", "param2"]
或CMD command param1 param2
- 示例:
CMD ["python", "app.py"]
-
ENTRYPOINT:
- 指定容器启动时运行的入口点。
- 语法:
ENTRYPOINT ["executable", "param1", "param2"]
或ENTRYPOINT command param1 param2
- 示例:
ENTRYPOINT ["nginx", "-g", "daemon off;"]
-
VOLUME:
- 创建一个挂载点,用于存储持久化数据。
- 语法:
VOLUME ["<mount>", ...]
- 示例:
VOLUME ["/data"]
-
WORKDIR:
- 设置工作目录。
- 语法:
WORKDIR <path>
- 示例:
WORKDIR /app
-
LABEL:
- 为镜像添加元数据。
- 语法:
LABEL <key>=<value> <key>=<value> ...
- 示例:
LABEL version="1.0" maintainer="example@example.com"
8. Docker Compose
可参考另外一篇文章:Docker Compose 基础知识
8.1 基本概念
Docker Compose 是一个用于定义和管理多容器 Docker 应用程序的工具。它通过一个 YAML 文件(docker-compose.yml
)来配置应用程序的服务、网络和卷,简化了复杂应用程序的部署和管理。
8.2 安装 Docker Compose
# 下载 Docker Compose
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose# 赋予执行权限
sudo chmod +x /usr/local/bin/docker-compose# 验证安装
docker-compose --version
8.3 使用 Docker Compose
- 创建
docker-compose.yml
文件:
version: '3'services:web:image: nginx:latestports:- "8080:80"volumes:- ./html:/usr/share/nginx/htmldb:image: postgres:latestenvironment:POSTGRES_PASSWORD: example
- 启动服务:
docker-compose up -d
- 停止服务:
docker-compose down
9. Docker 私有仓库
9.1 基本概念
Docker 私有仓库是一个用于存储和管理 Docker 镜像的内部平台。与公共仓库(如 Docker Hub)不同,私有仓库提供了更高级别的安全性和定制化选项,适用于企业内部或敏感项目的镜像管理
9.2 Nexus 镜像仓库搭建与配置
- 安装 Nexus:
# 下载 Nexus
wget https://sonatype.com/download/nexus# 安装 Nexus
sudo apt-get install nexus# 启动 Nexus
sudo systemctl start nexus
- 配置 Nexus:
- 访问 Nexus 管理界面:http://localhost:8081
- 创建 Docker 私有仓库
- 使用 Nexus:
# 登录 Nexus
docker login nexus.example.com# 推送镜像
docker push nexus.example.com/myapp# 拉取镜像
docker pull nexus.example.com/myapp
10. 总结
Docker 是一个强大的工具,可以简化应用的部署和管理。
- 安装和配置 Docker
- 使用基本的 Docker 命令
- 使用 Docker Compose 管理多容器应用
- 理解 Docker 的网络和数据管理
- 构建和推送镜像