Docker从0到1:入门指南
目录
- 什么是Docker
- Docker的核心概念
- 容器(Container)
- 镜像(Image)
- 镜像层(Image Layers)
- Dockerfile
- 仓库(Repository)
- 数据卷(Volume)
- 网络(Network)
- Docker架构
- Docker安装
- Docker基本命令
- 实际应用场景
- Docker生态系统
- 最佳实践
- 常见问题
什么是Docker
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux或Windows操作系统的机器上。Docker容器完全使用沙箱机制,相互之间不会有任何接口。
Docker的优势:
- 轻量级: 容器共享操作系统内核,比虚拟机更轻量
- 可移植性: 在任何支持Docker的环境中运行
- 隔离性: 应用程序及其依赖项在容器内隔离运行
- 可扩展性: 容易水平扩展和管理
- 版本控制与组件复用: 类似于Git的镜像管理
Docker的核心概念
Docker生态系统包含几个相互关联的核心概念,它们共同构成了Docker的完整工作流程:
容器(Container)
容器是Docker的核心概念,它是一个标准化的软件单元,包含了应用程序及其所有依赖项,确保应用程序在任何环境中都能以相同的方式运行。
特点:
- 轻量级和可移植
- 与主机系统隔离
- 可以快速启动和停止
- 可以限制资源使用(CPU、内存等)
- 容器是镜像的运行实例,可以被创建、启动、停止、删除和暂停
镜像(Image)
Docker镜像是一个只读模板,用于创建Docker容器。镜像包含了运行应用程序所需的所有内容——代码、运行时、库、环境变量和配置文件。
特点:
- 分层结构,便于共享和重用
- 不可变性,一旦创建不能修改
- 可以通过Dockerfile构建
- 可以从Docker Hub等仓库获取
- 一个镜像可以创建多个容器实例
镜像层(Image Layers)
Docker镜像由多个只读层组成,每层代表Dockerfile中的一条指令:
- 每一层都建立在前一层的基础上
- 当镜像被修改时,只有变化的层会被重新构建
- 多个镜像可以共享相同的底层,节省存储空间
- 当容器启动时,会在最顶层添加一个可写层(容器层)
Dockerfile
Dockerfile是一个文本文件,包含了构建Docker镜像所需的所有命令。Docker可以通过读取Dockerfile中的指令自动构建镜像。
常用指令:
FROM
: 指定基础镜像RUN
: 执行命令COPY
/ADD
: 复制文件ENV
: 设置环境变量EXPOSE
: 声明容器监听的端口VOLUME
: 创建挂载点WORKDIR
: 设置工作目录USER
: 指定运行容器时的用户CMD
/ENTRYPOINT
: 指定容器启动时运行的命令
仓库(Repository)
Docker仓库用于存储和分发Docker镜像。Docker Hub是最流行的公共仓库,企业通常也会建立私有仓库。
类型:
- 公共仓库(如Docker Hub, GitHub Container Registry)
- 私有仓库(如Harbor, Nexus, AWS ECR, Azure Container Registry)
数据卷(Volume)
数据卷是Docker提供的一种持久化和共享数据的机制,用于解决容器中数据持久化的问题。
为什么需要数据卷?
Docker容器本身遵循"无状态"的设计理念,当容器被删除时,其中的所有数据也会丢失。这带来两个核心问题:
- 数据持久化问题:容器重启或删除后,容器内的数据会丢失
- 数据共享问题:容器之间或容器与主机之间需要共享数据
数据卷的核心特性:
- 持久化存储:数据卷完全独立于容器的生命周期,即使容器被删除,数据卷及其数据仍然存在
- 直接访问高效:数据卷绕过容器的写时复制(Copy-on-Write)层,性能更高
- 跨容器共享:多个容器可以挂载相同的数据卷,实现数据共享
- 主机独立:数据卷由Docker管理,不受特定主机文件系统路径的限制
- 支持多种驱动:本地存储、NFS、云存储等多种后端存储选项
- 更易于备份和迁移:数据卷可以被备份、恢复和迁移到其他Docker主机
数据卷与绑定挂载的区别:
特性 | 数据卷 | 绑定挂载 |
---|---|---|
存储位置 | 由Docker管理(/var/lib/docker/volumes/) | 由用户指定主机上的任意路径 |
迁移性 | 更好,不依赖主机目录结构 | 依赖主机特定路径 |
内容初始化 | 新卷会复制容器指定路径中的内容 | 覆盖容器中的目录,不复制内容 |
权限管理 | 可由容器内进程修改 | 依赖主机文件系统权限 |
适用场景 | 存储Docker应用数据 | 与主机系统共享配置文件或源代码 |
数据卷的使用场景:
- 数据库容器:存储数据库文件,确保容器重启后数据不丢失
- 内容管理系统:存储上传的媒体文件和文档
- 配置文件:存储可能需要动态修改的应用配置
- 日志文件:集中存储和管理容器的日志输出
- 共享数据:在微服务架构中不同服务间共享资源
数据卷的基本操作:
# 创建数据卷
docker volume create my_volume# 查看所有数据卷
docker volume ls# 查看数据卷详情
docker volume inspect my_volume# 删除数据卷
docker volume rm my_volume# 删除所有未使用的数据卷
docker volume prune# 启动容器并挂载数据卷
docker run -v my_volume:/data nginx# 使用只读模式挂载
docker run -v my_volume:/data:ro nginx
数据卷使用实例:
PostgreSQL数据库使用数据卷:
# 创建数据卷
docker volume create pgdata# 运行PostgreSQL容器并挂载数据卷
docker run -d \--name postgres \-e POSTGRES_PASSWORD=mysecretpassword \-v pgdata:/var/lib/postgresql/data \postgres:13
当容器删除后,您的数据仍然保存在pgdata
数据卷中,可以被新容器挂载使用。
网络(Network)
Docker网络允许容器相互通信:
- 桥接网络(Bridge): 默认网络,适合单主机容器通信
- 主机网络(Host): 共享主机网络栈
- 覆盖网络(Overlay): 适合跨主机容器通信
- Macvlan: 为容器分配MAC地址
- 空网络(None): 禁用所有网络
Docker架构
Docker使用客户端-服务器(C/S)架构模式,Docker客户端与Docker守护进程通信,后者负责构建、运行和分发Docker容器。
组件:
- Docker客户端(Client): 通过命令行或其他工具与Docker守护进程交互
- Docker守护进程(Daemon): 监听Docker API请求并管理Docker对象
- Docker镜像(Images): 用于创建容器的只读模板
- Docker容器(Containers): 镜像的可运行实例
- Docker注册表(Registry): 存储Docker镜像的地方
Docker安装
根据不同操作系统,Docker的安装方式也不同:
Linux (Ubuntu为例)
# 更新apt包索引
sudo apt-get update# 安装必要的包
sudo apt-get install apt-transport-https ca-certificates curl software-properties-common lrzsz -y# 指定使用阿里云镜像
sudo curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -# 设置稳定版仓库
sudo add-apt-repository "deb [arch=amd64] https://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"# 更新apt包索引
sudo apt-get update# 安装最新版本的Docker CE
sudo apt-get install docker-ce -y
Docker基本命令
镜像管理
# 列出本地镜像
docker images# 拉取镜像
docker pull [镜像名]:[标签]# 构建镜像
docker build -t [镜像名]:[标签] [Dockerfile路径]# 删除镜像
docker rmi [镜像ID]
容器管理
# 创建并启动容器
docker run [选项] [镜像名] [命令]# 列出运行中的容器
docker ps# 列出所有容器
docker ps -a# 启动/停止/重启容器
docker start/stop/restart [容器ID]# 进入容器
docker exec -it [容器ID] bash# 删除容器
docker rm [容器ID]
数据管理
# 创建数据卷
docker volume create [数据卷名]# 挂载数据卷
docker run -v [数据卷名]:[容器内路径] [镜像名]# 挂载主机目录
docker run -v [主机路径]:[容器内路径] [镜像名]
网络管理
# 创建网络
docker network create [网络名]# 将容器连接到网络
docker network connect [网络名] [容器ID]# 查看网络
docker network ls
实际应用场景
- 开发环境标准化: 确保所有开发人员使用相同的环境
- 持续集成/持续部署: 自动化构建、测试和部署流程
- 微服务架构: 每个服务独立部署在容器中
- 应用隔离: 在同一主机上运行多个应用而不互相干扰
- 快速扩展: 轻松创建多个相同配置的应用实例
Docker生态系统
Docker Compose
用于定义和运行多容器Docker应用程序的工具。使用YAML文件配置应用程序的服务,然后使用单个命令创建和启动所有服务。
Docker Swarm
Docker的原生集群管理工具,将多个Docker主机转变为单个虚拟Docker主机。
Kubernetes
开源容器编排平台,提供容器部署、扩展和管理的自动化。
最佳实践
- 使用官方镜像作为基础: 减少安全风险和兼容性问题
- 精简镜像大小: 使用多阶段构建和Alpine基础镜像
- 不在容器中存储数据: 使用卷或绑定挂载来持久化数据
- 指定镜像版本: 使用特定版本标签而不是
latest
- 限制容器资源: 设置内存和CPU限制
- 使用非root用户: 减少潜在的安全风险
- 定期更新基础镜像: 修复安全漏洞
常见问题
容器和虚拟机的区别?
- 容器共享主机的操作系统内核,更轻量级
- 虚拟机包含完整的操作系统,资源消耗更大
- 容器启动更快,通常在秒级
- 虚拟机提供更强的隔离性
容器停止后数据会丢失吗?
默认情况下,容器停止后数据仍然存在,但容器被删除后数据会丢失。要持久化数据,应使用Docker卷或绑定挂载。
如何在Docker中设置环境变量?
可以在Dockerfile中使用ENV指令,或在运行容器时使用-e
或--env
标志。
Docker的网络模式有哪些?
- bridge: 默认网络模式,创建虚拟网桥
- host: 直接使用主机网络
- none: 无网络
- overlay: 用于Docker Swarm服务之间的通信
- macvlan: 允许容器拥有MAC地址,看起来像物理网络上的设备