从零上手 Docker,容器技术完整入门指南
Docker 容器技术实战
第1章 容器生态系统
1.1 容器技术概述
容器技术是继大数据、云计算之后的核心技术方向,核心价值是实现应用的一次构建,随处运行。传统应用部署面临环境差异、依赖复杂、迁移成本高等问题,容器通过标准化的打包机制,将应用及其依赖统一封装,实现了跨环境的一致运行。
从技术趋势来看,Docker是容器技术的事实标准,其生态体系仍在快速完善,掌握容器技术是职业能力提升的核心路径。
1.2 容器生态全景
容器是典型的平台级技术,生态体系覆盖核心技术、平台技术、支持技术三大层级,学习前先建立全局认知,可避免知识点碎片化。
1.2.1 容器核心技术
核心技术是容器运行的基础,支撑容器在主机上的完整生命周期。
| 技术分类 | 说明 | 主流实现 |
|---|---|---|
| 容器规范 | 定义容器标准,保证不同厂商容器的可移植性与互操作性 | OCI(开放容器倡议)发布的运行时规范、镜像格式规范 |
| 容器运行时(Runtime) | 真正运行容器的组件,与操作系统内核协作提供运行环境 | runc(Docker默认,符合OCI规范)、lxc、rkt |
| 容器管理工具 | 对接运行时,向用户提供操作接口 | Docker Engine、lxd、rkt cli |
| 容器定义工具 | 定义容器的内容与属性,支持保存、共享与重建 | Docker镜像、Dockerfile、ACI(rkt镜像格式) |
| 镜像仓库(Registry) | 统一存储、分发容器镜像的仓库 | Docker Hub、Quay.io、Harbor、私有Registry |
| 容器操作系统 | 专为容器定制的轻量化操作系统,体积小、启动快、运行效率高 | CoreOS、Atomic、Ubuntu Core |
补充说明:OCI(Open Container Initiative)由Docker、Google、红帽等厂商联合成立,目的是制定开放的容器标准,避免生态碎片化。
1.2.2 容器平台技术
平台技术支撑容器在分布式集群环境中运行,面向微服务架构的部署与管理。
-
容器编排引擎
:负责容器集群的管理、调度、服务发现、自动扩缩容等,主流实现:
- Docker Swarm:Docker官方自研编排工具,轻量易用
- Kubernetes(K8s):Google主导的开源编排引擎,是当前业界事实标准
- Mesos+Marathon:通用集群资源调度平台,兼顾容器与非容器负载
-
容器管理平台:封装编排引擎底层细节,提供应用目录、一键部署等更易用的功能,代表:Rancher、ContainerShip。
-
容器化PaaS:面向应用开发的平台,屏蔽底层基础设施,代表:Deis、Flynn、Dokku。
1.2.3 容器支持技术
支撑容器基础设施的周边技术体系。
| 技术分类 | 作用 | 主流方案 |
|---|---|---|
| 容器网络 | 管理容器间、容器与外部的连通性与隔离性 | Docker原生网络、Flannel、Weave、Calico |
| 服务发现 | 动态维护微服务的地址信息,解决容器IP动态变化的问题 | etcd、Consul、ZooKeeper |
| 监控方案 | 采集容器状态、资源使用率等监控数据 | docker stats、cAdvisor、Sysdig |
| 数据管理 | 实现容器持久化数据的迁移与管理 | Flocker |
| 日志管理 | 收集、转发、存储容器日志 | docker logs、Logspout |
| 安全扫描 | 检测容器镜像的漏洞与风险 | OpenSCAP、Docker Scout |
第2章 容器架构与核心原理
2.1 容器的本质:What/Why/How
2.1.1 什么是容器
容器是一种轻量级、可移植、自包含的软件打包技术,应用及其依赖被打包在容器中,可在几乎任何环境以一致的方式运行。
容器与虚拟机是经常被对比的两种虚拟化技术,核心差异如下:
| 对比维度 | 容器 | 虚拟机 |
|---|---|---|
| 启动速度 | 秒级甚至毫秒级 | 数秒至数十秒 |
| 内核使用 | 共享宿主机内核 | 独立完整内核 |
| 实现原理 | 基于Linux内核Namespace+Cgroup等技术,进程级隔离 | 基于Hypervisor虚拟化,系统级隔离 |
| 资源消耗 | 极小,仅额外消耗进程级开销 | 较高,需要完整操作系统资源 |
| 运行密度 | 单台主机可启动上千个容器 | 单台主机通常几十个虚拟机 |
| 镜像大小 | MB级 | GB级 |
| 适用场景 | DevOps、微服务、持续集成 | 硬件资源划分、强隔离需求 |
2.1.2 为什么需要容器
容器核心解决的是应用可移植性问题。 当前软件开发面临「多服务组件+多部署环境」的双重复杂度:应用包含MQ、缓存、数据库等多种服务,同时需要部署在虚拟机、私有云、公有云等不同环境,形成了N×M的配置矩阵,开发与运维成本极高。
Docker借鉴了物流行业「集装箱」的思想:将应用及其依赖统一打包成标准“容器”,容器在整个生命周期中密封,跨环境无需开箱,直接运行,彻底解决了环境差异带来的部署问题。
2.1.3 容器的核心特性
对应集装箱的设计思想,Docker的核心特性如下:
- 标准化打包:任何软件及其依赖都可打包成容器镜像
- 环境一致性:容器无需修改即可运行在虚拟机、物理机、公有云、私有云
- 资源隔离:容器间资源、网络、依赖完全隔离,互不影响
- 自动化操作:提供标准化的启动、停止、删除接口,适配自动化运维
- 轻量高效:秒级启动,迁移快速,资源开销极低
- 职责解耦:开发聚焦业务代码,运维聚焦基础环境
2.2 Docker架构详解
Docker采用客户端-服务器(C/S)架构,核心组件包括客户端、守护进程、镜像、仓库、容器五部分。
2.2.1 核心组件
- Docker客户端(Client) 用户与Docker交互的入口,以命令行(CLI)为主要形式。客户端将用户命令通过REST API发送给守护进程执行。 常用命令包括
docker run、docker build、docker pull等,也支持通过-H参数连接远程守护进程。 - Docker守护进程(Daemon) 后台运行的dockerd服务,负责监听API请求、管理Docker对象(镜像、容器、网络、卷等),也可与其他守护进程通信实现集群管理。
- Docker镜像(Image) 只读的容器模板,包含创建容器的指令与文件系统。镜像基于分层结构构建,可基于基础镜像扩展新镜像。
- 镜像仓库(Registry) 集中存储和分发镜像的服务。分为公共仓库(如Docker Hub)和私有仓库(如Harbor、自建Registry)。
- Docker容器(Container) 镜像的运行实例,是可读写的运行环境。可通过API或CLI创建、启动、停止、删除容器。
2.2.2 内部实现机制
Docker守护进程内部通过不同驱动实现核心能力:
- Graph driver:管理镜像分层文件系统
- Network driver:创建与管理容器网络
- Exec driver:执行容器内命令,限制资源使用
- Libcontainer:独立的容器管理库,底层对接内核Namespace与Cgroup
2.3 Docker组件协作流程
以docker run httpd为例,组件协作流程如下:
- 客户端执行
docker run命令,向守护进程发送请求 - 守护进程检查本地是否存在httpd镜像,不存在则从Registry下载
- 镜像下载完成后保存到本地存储
- 守护进程基于镜像创建容器,分配资源、启动进程
- 将执行结果返回给客户端
可通过
docker images查看本地镜像,docker ps查看运行中的容器,验证上述流程。
第3章 Docker镜像
3.1 镜像原理与分层结构
镜像是容器的基础,本质是分层的只读文件系统。
3.1.1 最小镜像:hello-world
hello-world是Docker官方提供的最简镜像,仅十几KB,用于验证Docker环境。 其Dockerfile仅3条指令:
FROM scratch
COPY hello /
CMD ["/hello"]
FROM scratch:从空文件系统开始构建,是最基础的根镜像COPY hello /:将可执行文件hello复制到镜像根目录CMD ["/hello"]:容器启动时执行hello程序
3.1.2 基础镜像(Base Image)
基础镜像指提供基础操作系统环境的镜像,如CentOS、Ubuntu、Debian等。 核心原理:容器共享宿主机的Linux内核,镜像仅需要提供用户态的rootfs文件系统,因此体积远小于完整操作系统。
- 例如CentOS 7镜像仅200MB左右,而完整安装的CentOS系统需要数GB
- 容器内的内核版本与宿主机完全一致,无法单独升级内核
注意:如果应用对内核版本有严格要求,不适合使用容器部署,建议使用虚拟机。
3.1.3 分层结构与Copy-on-Write
Docker镜像采用分层堆叠结构,每安装一个软件就增加一层镜像层,所有镜像层都是只读的。 容器启动时,会在镜像层顶部添加一层可写的容器层:
- 新增文件:直接写入容器层
- 修改文件:先从镜像层复制到容器层,修改后保存在容器层(写时复制Copy-on-Write)
- 删除文件:在容器层创建whiteout文件遮挡下层文件
- 读取文件:从上到下逐层查找,返回最先找到的文件
核心优势:镜像层可被多个容器共享,大幅节省磁盘与内存空间;同时镜像构建可复用缓存,提升构建效率。
3.2 构建镜像的两种方式
3.2.1 docker commit(不推荐)
通过提交运行中容器的修改生成新镜像,分为三步:运行容器→修改容器→提交为镜像。
示例:在ubuntu镜像中安装vim并生成新镜像
# 1. 运行交互容器
docker run -it ubuntu
# 2. 容器内安装vim
apt-get update && apt-get install -y vim
# 3. 新开终端,提交容器为新镜像
docker commit <容器ID/名称> ubuntu-with-vim
缺点:手工构建效率低、可重复性差、无法审计镜像内容,存在安全隐患,仅用于临时调试。
3.2.2 Dockerfile构建(推荐)
Dockerfile是记录镜像构建步骤的文本文件,每条指令对应一个镜像层,可重复、可审计,是构建镜像的标准方式。
基础构建命令:
docker build -t <镜像名:标签> <构建上下文路径>
-t:指定镜像名称与标签- 构建上下文:打包发送给守护进程的目录,Dockerfile中的COPY/ADD指令只能引用上下文中的文件
- 默认查找上下文目录下名为
Dockerfile的文件,可通过-f指定自定义路径
3.3 Dockerfile指令详解
3.3.1 核心指令说明
| 指令 | 作用 | 说明 |
|---|---|---|
FROM | 指定基础镜像 | 必须是第一条指令 |
MAINTAINER | 声明镜像作者 | 可选,现已推荐使用LABEL |
COPY | 复制构建上下文中的文件到镜像 | 仅复制,不解压归档文件 |
ADD | 复制文件到镜像 | 源为归档文件时自动解压,支持远程URL |
ENV | 设置环境变量 | 后续指令可引用 |
EXPOSE | 声明容器监听端口 | 仅做声明,不自动映射端口 |
VOLUME | 声明数据卷挂载点 | 容器启动时自动创建managed volume |
WORKDIR | 设置工作目录 | 为后续指令指定默认路径,不存在则自动创建 |
RUN | 构建时执行命令 | 创建新的镜像层,用于安装软件 |
CMD | 容器启动默认命令 | 可被docker run后的参数覆盖,仅最后一条生效 |
ENTRYPOINT | 容器启动入口命令 | 一定会执行,docker run参数会作为参数传入 |
3.3.2 RUN/CMD/ENTRYPOINT对比
三个指令都可执行命令,核心区别如下:
- RUN:构建镜像时执行,用于安装软件、配置环境,生成镜像层
- CMD:容器启动时默认执行,可被命令行参数覆盖
- ENTRYPOINT:容器启动时必定执行,命令行参数会作为追加参数传入
最佳实践:服务类镜像优先使用Exec格式的ENTRYPOINT,搭配CMD提供默认参数;工具类镜像可使用CMD设置默认命令。
3.3.3 Shell格式与Exec格式
- Shell格式:
RUN apt-get install vim,底层调用/bin/sh -c执行命令,支持环境变量解析 - Exec格式:
RUN ["apt-get", "install", "-y", "vim"],直接执行程序,不启动shell,环境变量不会被解析
3.3.4 构建缓存特性
Docker构建时会缓存已有的镜像层,指令未变化时直接复用缓存,大幅提升构建速度。
- 某一层指令修改后,其上方所有层缓存有效,下方所有层缓存失效
- 可通过
--no-cache参数强制禁用缓存
3.4 镜像命名与分发
3.4.1 镜像命名规范
完整镜像名称格式:
[仓库地址/命名空间/]仓库名:标签
- 标签(Tag):用于标识版本,默认值为
latest,不代表“最新稳定版”,仅表示未指定标签时的默认值 - Docker Hub官方镜像可省略仓库地址,例如
httpd:latest
3.4.2 标签最佳实践
采用语义化版本方案,例如镜像myimage发布v1.9.1时,同时打标签:1.9.1、1.9、1、latest。 版本更新时,移动对应大版本、次版本的标签,用户可灵活选择精度。
3.4.3 公共镜像仓库使用
-
Docker Hub:全球最大公共镜像仓库,注册账号后可上传自有镜像
# 登录 docker login # 重命名镜像,匹配账号格式 docker tag httpd:latest <用户名>/httpd:v1 # 上传镜像 docker push <用户名>/httpd:v1 -
国内镜像加速器:解决Docker Hub访问慢的问题,阿里云、华为云均提供免费加速服务 配置方式(以阿里云为例):
mkdir -p /etc/docker tee /etc/docker/daemon.json <<-'EOF' { "registry-mirrors": ["https://<加速器地址>.mirror.aliyuncs.com"] } EOF systemctl daemon-reload systemctl restart docker可通过
docker info查看Registry Mirrors字段验证配置。
3.5 私有镜像仓库搭建
3.5.1 官方Registry(轻量版)
Docker官方提供的开源镜像仓库,单容器即可启动。
# 启动Registry容器,挂载数据目录到宿主机
docker run -d -p 5000:5000 -v /myregistry:/var/lib/registry registry:2
# 重命名镜像
docker tag httpd:latest localhost:5000/httpd:v1
# 上传镜像
docker push localhost:5000/httpd:v1
# 验证仓库
curl http://localhost:5000/v2/_catalog
官方Registry功能简单,适合小型场景;企业级场景推荐使用Harbor。
3.5.2 Harbor企业级仓库
Harbor是VMware开源的企业级镜像仓库,提供Web UI、权限管理、审计日志、安全扫描等功能。
安装步骤:
-
下载离线安装包(推荐v2.9.1稳定版)并解压
-
复制文件到安装目录,修改
harbor.yml配置:
hostname:设置为服务器IP或域名- 注释掉https配置(内网可暂用HTTP)
- 设置管理员密码
-
执行
./prepare生成配置,再执行./install.sh安装启动 -
配置Docker信任该仓库:
{ "insecure-registries": ["192.168.108.30"] } -
登录并上传/下载镜像
docker login 192.168.108.30 docker tag nginx:latest 192.168.108.30/cloud/nginx:latest docker push 192.168.108.30/cloud/nginx:latest
3.6 镜像本地导入导出
| 命令 | 作用 | 特点 |
|---|---|---|
docker save | 将镜像保存为tar包 | 保留完整镜像历史与元数据,可跨主机迁移镜像 |
docker load | 从tar包导入镜像 | 对应save命令导出的文件 |
docker export | 将容器文件系统导出为tar包 | 仅保存容器当前状态,丢失历史与元数据,体积更小 |
docker import | 导入容器tar包为镜像 | 对应export命令导出的文件 |
示例:
# 保存镜像
docker save httpd hello-world -o images.tar
# 导入镜像
docker load -i images.tar
本章小结
- 镜像是分层只读文件系统,基于Copy-on-Write机制实现高效共享
- Dockerfile是构建镜像的标准方式,核心指令需区分RUN/CMD/ENTRYPOINT的差异
- 镜像可通过公共仓库、私有仓库分发,也可通过save/load做本地迁移
- 企业级场景推荐使用Harbor搭建私有镜像仓库
第4章 Docker容器
4.1 容器生命周期操作
4.1.1 启动容器
docker run = docker create + docker start,是创建并启动容器的核心命令。
常用参数:
-d:后台守护模式运行-it:交互模式,分配终端并打开标准输入--name:指定容器名称-p:端口映射-v:数据卷挂载-e:设置环境变量--restart:重启策略,可选no/always/on-failure:N
重启策略说明:
--restart=always表示容器退出时自动重启(手动stop除外);on-failure:3表示异常退出时最多重启3次。
4.1.2 进入容器
两种常用方式:
-
docker attach
:附加到容器启动命令的终端,不启动新进程
- 退出快捷键:
Ctrl+P然后Ctrl+Q,直接Ctrl+C会终止容器
- 退出快捷键:
-
docker exec
:在运行容器中启动新进程,是最常用方式
docker exec -it <容器ID/名称> bash
4.1.3 状态管理命令
| 命令 | 作用 |
|---|---|
docker ps / docker ps -a | 查看运行中/所有容器 |
docker start/stop/restart | 启动/停止/重启容器 |
docker pause/unpause | 暂停/恢复容器,暂停时不占用CPU |
docker kill | 强制停止容器(发送SIGKILL) |
docker rm | 删除容器,-f强制删除运行中容器 |
docker rename | 重命名容器 |
批量操作示例:
# 删除所有已退出的容器
docker rm -f $(docker ps -aq -f status=exited)
# 强制删除所有容器(谨慎使用)
docker rm -f $(docker ps -aq)
4.1.4 容器状态机
容器完整生命周期状态流转: Created→Running→Paused→Running/Exited→Running/Deleted
- docker create创建的容器处于Created状态
- 正常执行完启动命令或stop/kill后进入Exited状态
- pause命令暂停后进入Paused状态
4.2 容器资源限制
Docker通过Linux内核的Cgroup机制限制容器资源,核心包括CPU、内存、磁盘IO三大类。
4.2.1 内存限制
-m / --memory:设置物理内存使用限额,如200M、2G--memory-swap:设置内存+swap总限额
常用配置说明:
-m 200M --memory-swap=300M:物理内存200M,可用swap 100M- 仅设置
-m时,swap默认等于内存大小,即总限额为内存的2倍 --memory-swap=-1:swap不受限制,可用宿主机全部swap空间
4.2.2 CPU限制
通过--cpu-shares设置CPU时间片权重,默认值1024。
- 权重是相对值,仅在CPU资源紧张时生效
- 例如两个容器权重分别为1024和512,CPU满载时获得的时间片比例为2:1
- 单个容器运行时,即使权重很低也可占用全部CPU资源
4.3 容器底层实现原理
容器的两大核心技术:Namespace实现资源隔离,Cgroup实现资源限制。
4.3.1 Namespace(命名空间)
让容器认为自己拥有独立的全局资源,共6种:
- Mount Namespace:隔离文件系统挂载点,容器有独立的根目录
- UTS Namespace:隔离主机名,容器可设置独立hostname
- IPC Namespace:隔离进程间通信,容器内共享内存、信号量独立
- PID Namespace:隔离进程ID,容器内有独立的PID 1进程
- Network Namespace:隔离网络栈,容器有独立的网卡、IP、路由表
- User Namespace:隔离用户,容器内用户不映射到宿主机
4.3.2 Cgroup(控制组)
Linux内核提供的进程资源管控机制,Docker使用的核心子系统:
cpu:CPU调度权重memory:内存使用限额blkio:块设备IO限制cpuset:绑定CPU核心devices:设备访问权限控制
可在/sys/fs/cgroup/目录下查看每个容器对应的Cgroup配置。
本章小结
- 容器生命周期操作是日常运维的基础,需熟练掌握run、exec、ps、rm等核心命令
- 资源限制通过Cgroup实现,生产环境必须配置内存与CPU限额,避免容器抢占宿主机资源
- Namespace实现了容器的六大隔离维度,是容器轻量隔离的核心原理
第5章 Docker网络
5.1 四大原生网络模式
Docker安装后默认创建bridge、host、none三种网络,加上container模式共四类。
| 网络模式 | 驱动 | 说明 | 适用场景 |
|---|---|---|---|
| bridge | bridge | 默认模式,容器挂在docker0网桥上,通过NAT访问外网 | 大多数单主机场景 |
| host | host | 共享宿主机网络命名空间,网络配置与宿主机完全一致 | 高网络性能需求场景 |
| none | null | 无网络,仅回环接口 | 高安全、无需联网的容器 |
| container | - | 共享另一个容器的网络栈 | 容器间通过loopback高效通信、网络监控 |
5.1.1 none网络
容器只有lo回环接口,完全无法联网,用于对安全性要求极高的离线场景,如密码生成容器。
5.1.2 host网络
容器共享宿主机的网络栈,性能接近原生,但端口会与宿主机冲突,适合网络传输密集型应用。
5.1.3 bridge网络(默认)
Docker创建名为docker0的Linux网桥,容器通过veth pair连接到网桥上,是最常用的模式。
- 网桥默认网段:
172.17.0.0/16,网关为docker0的IP172.17.0.1 - 容器自动从网段分配IP,通过宿主机的NAT规则访问外网
- 不同网桥之间默认被iptables隔离,无法直接通信
5.2 自定义bridge网络
5.2.1 创建自定义网络
# 创建默认网段的bridge网络
docker network create --driver bridge my_net
# 指定网段与网关
docker network create --driver bridge --subnet 172.22.16.0/24 --gateway 172.22.16.1 my_net2
5.2.2 指定容器IP
只有用户指定子网的网络支持静态IP:
docker run -it --network=my_net2 --ip 172.22.16.8 busybox
5.2.3 网络连接管理
# 将已有容器加入指定网络
docker network connect my_net2 <容器名>
# 断开容器网络
docker network disconnect my_net2 <容器名>
一个容器可同时加入多个网络,实现不同网络域的连通。
5.3 容器间通信
5.3.1 IP通信
同一网络中的容器可直接通过IP通信,是最基础的方式。
5.3.2 Docker DNS服务
自定义bridge网络支持内置DNS,容器可直接通过容器名通信。
# 启动两个容器,指定名称
docker run -itd --network=my_net2 --name bbox1 busybox
docker run -itd --network=my_net2 --name bbox2 busybox
# bbox2中ping bbox1
docker exec -it bbox2 ping bbox1
注意:默认bridge网络不支持DNS解析,必须使用自定义网络。
5.3.3 Joined容器
多个容器共享同一个网络栈,通过127.0.0.1互相访问,适合紧密耦合的服务。
# 启动web容器
docker run -d --name web1 httpd
# busybox共享web1的网络
docker run -it --network=container:web1 busybox
两个容器网卡、IP、端口完全一致,可直接通过回环地址访问对方服务。
5.4 外部访问与端口映射
容器访问外网默认通过宿主机NAT实现;外部访问容器需要端口映射。
5.4.1 端口映射语法
# 指定宿主机端口:容器端口
docker run -d -p 8080:80 httpd
# 宿主机随机分配端口
docker run -d -p 80 httpd
可通过docker ps或docker port <容器名>查看映射关系。
5.4.2 实现原理
宿主机上的docker-proxy进程监听映射端口,将流量转发到对应容器的端口;同时iptables配置MASQUERADE规则实现容器出站NAT。
本章小结
- bridge是默认网络模式,生产环境推荐创建自定义bridge网络,启用DNS服务
- 容器间通信三种方式:IP、DNS、Joined容器,各有适用场景
- 端口映射是外部访问容器服务的核心方式,底层通过docker-proxy与iptables实现
第6章 Docker存储
6.1 存储驱动与分层文件系统
Docker通过存储驱动(Storage Driver)实现镜像分层结构,CentOS Stream 8默认使用overlay2驱动,底层文件系统为xfs。 镜像与容器层数据默认存储在/var/lib/docker/目录下。
最佳实践:优先使用发行版默认的存储驱动,经过最充分的兼容性测试。
分层文件系统适合无状态应用:应用本身作为镜像的一部分,容器销毁时数据随之清除,无需持久化。
6.2 数据卷(Data Volume)
数据卷是宿主机文件系统中的目录/文件,直接挂载到容器中,用于持久化数据,生命周期独立于容器。
分为两类:
6.2.1 Bind Mount(绑定挂载)
将宿主机上指定的目录/文件挂载到容器中。
# 挂载目录
docker run -d -p 80:80 -v /root/htdocs:/usr/local/apache2/htdocs httpd
# 只读挂载
docker run -d -p 80:80 -v /root/htdocs:/usr/local/apache2/htdocs:ro httpd
- 优点:直观灵活,可直接在宿主机操作数据
- 缺点:依赖宿主机特定路径,移植性差
6.2.2 Docker Managed Volume(托管卷)
Docker在/var/lib/docker/volumes/下自动创建管理的卷,只需指定容器内挂载点。
docker run -d -p 80:80 -v /usr/local/apache2/htdocs httpd
- 优点:移植性强,无需关心宿主机路径
- 缺点:访问数据需要通过容器或进入卷目录
6.2.3 两类卷对比
| 对比项 | Bind Mount | Docker Managed Volume |
|---|---|---|
| 卷位置 | 宿主机任意路径 | /var/lib/docker/volumes/下 |
| 对已有目录影响 | 隐藏原有内容,替换为宿主机数据 | 将容器内原有数据复制到卷中 |
| 单文件支持 | 支持 | 不支持,仅支持目录 |
| 权限控制 | 支持只读/读写 | 仅读写 |
| 移植性 | 弱,绑定宿主机路径 | 强,与宿主机解耦 |
6.3 数据共享方案
6.3.1 宿主机与容器共享
-
Bind Mount直接挂载共享目录
-
Managed Volume可通过
docker cp在宿主机与容器间拷贝文件
# 宿主机文件拷贝到容器 docker cp /root/index.html <容器名>:/usr/local/apache2/htdocs
6.3.2 多容器共享数据
-
共享Bind Mount:多个容器挂载同一个宿主机目录
-
数据卷容器(Volume Container)
:专门提供数据卷的容器,其他容器通过
--volumes-from挂载
# 创建数据卷容器 docker create --name vc_data -v /root/htdocs:/usr/local/apache2/htdocs busybox # 业务容器挂载数据卷容器 docker run -d --name web1 --volumes-from vc_data httpd -
Data-packed Volume Container:将数据打包到镜像中,自包含数据,移植性极强,适合静态配置、静态文件场景。
6.4 数据卷生命周期管理
-
备份:直接备份宿主机上的卷目录即可
-
恢复:将备份数据拷贝回卷目录
-
迁移:停止旧容器,启动新容器挂载同一卷
-
删除
:
- Bind Mount不会随容器删除,需手动清理
- Managed Volume:
docker rm -v删除容器时同时删除卷;孤儿卷可通过docker volume prune清理
注意:生产环境数据库等有状态服务必须使用数据卷持久化数据,避免容器删除导致数据丢失。
本章小结
- 容器存储分为分层文件系统和数据卷,无状态应用用前者,持久化数据用后者
- 数据卷分Bind Mount和Managed Volume,按需选择;生产环境推荐Managed Volume配合数据卷容器
- 数据卷生命周期独立于容器,删除容器时注意重要数据备份
第7章 容器监控
7.1 Docker原生监控命令
| 命令 | 作用 |
|---|---|
docker ps | 查看容器运行状态、端口、名称等基础信息 |
docker top <容器> | 查看容器内运行的进程,支持ps命令参数 |
docker stats | 实时查看容器CPU、内存、网络IO、磁盘IO使用率 |
docker stats默认实时刷新,支持--no-stream只输出一次结果,支持自定义输出格式。
7.2 cAdvisor监控工具
Google开源的容器监控数据采集工具,可采集容器资源使用数据,并提供Web界面查看。
部署命令:
docker run \
--volume=/:/rootfs:ro \
--volume=/var/run:/var/run:rw \
--volume=/sys:/sys:ro \
--volume=/var/lib/docker/:/var/lib/docker:ro \
--publish=8080:8080 \
--detach=true \
--name=cadvisor \
google/cadvisor:latest
访问http://<宿主机IP>:8080即可查看监控界面。
- 优点:数据全面,可导出对接第三方监控系统
- 缺点:仅支持单主机,可视化能力弱,通常作为数据采集器配合Grafana等使用
本章小结
- 日常排查优先使用docker原生命令,轻量高效
- cAdvisor适合作为监控数据采集组件,生产环境通常配合Prometheus+Grafana构建完整监控体系
第8章 容器日志
8.1 docker logs命令
Docker将容器标准输出(STDOUT)与标准错误(STDERR)作为日志收集,通过docker logs查看。
常用参数:
-f:持续跟踪日志,类似tail -f--tail N:查看最后N行-t:显示时间戳
示例:
# 查看最近10行日志并持续跟踪
docker logs -f --tail 10 <容器名>
8.2 日志管理最佳实践
- 应用日志输出到标准输出/标准错误,不要写入文件,由Docker统一管理
- 生产环境部署集中式日志方案,通过日志驱动将日志转发到ELK等日志平台
- 单个容器日志文件过大时,可配置日志轮转策略
本章小结
- docker logs是排查容器问题的核心工具,需熟练掌握常用参数
- 生产环境遵循日志标准化原则,输出到控制台,配合集中式日志系统管理
第9章 Docker Compose多容器编排
9.1 Compose概述
Docker Compose是定义和运行多容器应用的工具,通过YAML文件定义一组关联的容器服务,实现一键启停、批量管理。
两个核心概念:
- 服务(Service):一个应用组件对应的容器集群
- 项目(Project):一组关联服务组成的完整业务单元
Compose V2已用Go语言重写,集成在Docker CLI中,通过docker compose命令调用。
9.2 Compose模板文件
默认文件名为docker-compose.yml,核心结构:
services:
服务名:
image: 镜像名
restart: 重启策略
ports:
- "宿主机端口:容器端口"
volumes:
- 卷映射
environment:
- 环境变量=值
links:
- 关联服务名
常用命令:
# 后台启动所有服务
docker compose up -d
# 停止并删除所有容器、网络
docker compose down
# 查看服务状态
docker compose ps
# 查看服务日志
docker compose logs -f
9.3 实战:WordPress多容器部署
实现WordPress+MySQL的博客系统,一键启动。
- 创建项目目录,编写
docker-compose.yml
services:
blog:
image: wordpress:latest
restart: always
links:
- db
ports:
- "80:80"
environment:
- WORDPRESS_DB_HOST=db
- WORDPRESS_DB_USER=root
- WORDPRESS_DB_PASSWORD=huawei
- WORDPRESS_DB_NAME=wordpress
volumes:
- ./web:/var/www/html
db:
image: mysql:5.7
restart: always
environment:
- MYSQL_ROOT_PASSWORD=huawei
- MYSQL_DATABASE=wordpress
volumes:
- ./mysql:/var/lib/mysql
- 启动服务
docker compose up -d
- 访问
http://<宿主机IP>,完成WordPress初始化配置即可使用。
本章小结
- Compose是单主机多容器编排的首选工具,通过声明式配置简化多容器管理
- 模板文件遵循YAML语法,注意缩进与格式规范
- 适合开发测试环境、小型应用部署,大规模集群推荐使用Kubernetes
第10章 图形化管理工具
10.1 DockerUI
轻量级国产Docker管理工具,Web界面友好,适合Docker初学者。
部署命令:
docker run -d --name docker.ui --restart always \
-v /var/run/docker.sock:/var/run/docker.sock \
-p 8999:8999 joinsunsoft/docker.ui
- 访问地址:
http://<宿主机IP>:8999 - 默认账号密码:ginghan/123456
- 功能:容器、镜像、卷、网络管理,Swarm集群管理等
10.2 Portainer
主流的开源容器管理平台,分为社区版和商业版,社区版免费,功能全面。
部署步骤:
# 创建数据卷
docker volume create portainer_data
# 启动Portainer
docker run -d -p 8000:8000 -p 9443:9443 --name portainer --restart=always \
-v /var/run/docker.sock:/var/run/docker.sock \
-v portainer_data:/data \
portainer/portainer-ce:latest
- 访问地址:
https://<宿主机IP>:9443 - 首次访问创建管理员账号,连接本地Docker环境即可管理
本章小结
- 图形化工具降低了Docker操作门槛,适合管理多主机或非专业人员使用
- Portainer是当前主流选择,功能完善,社区活跃
综合实验
实验1:部署Ghost开源内容管理系统
Ghost是基于Node.js的开源CMS系统,适合博客、内容网站。
- 创建数据目录
mkdir -p /data/ghost
chmod -R 777 /data/ghost
- 启动Ghost容器
docker run -d \
--restart always \
--name ghost \
-p 2368:2368 \
-v /data/ghost:/var/lib/ghost/content \
-e NODE_ENV=development \
-e url=http://<宿主机IP>:2368 \
ghost
- 验证访问:浏览器打开
http://<宿主机IP>:2368/ghost,完成管理员注册即可使用。
实验2:构建自定义Java环境镜像
基于CentOS 8构建包含JDK 8、vim、网络工具的自定义镜像。
- 准备JDK安装包(从Oracle官网下载对应版本)与Dockerfile放在同一目录
- 编写Dockerfile
FROM centos:8.4.2105
MAINTAINER author <email@example.com>
ENV MYPATH /usr/local
WORKDIR $MYPATH
# 配置阿里云CentOS Vault源
RUN minorver=8.4.2105 \
&& sed -e "s|^mirrorlist=|#mirrorlist=|g" \
-e "s|^#baseurl=http://mirror.centos.org/\$contentdir/\$releasever|baseurl=https://mirrors.aliyun.com/centos-vault/$minorver|g" \
-i.bak /etc/yum.repos.d/CentOS-*.repo
# 安装基础工具
RUN yum -y install vim net-tools glibc.i686
# 安装JDK
RUN mkdir /usr/local/java
ADD jdk-8u461-linux-x64.tar.gz /usr/local/java/
# 配置环境变量
ENV JAVA_HOME /usr/local/java/jdk1.8.0_461
ENV JRE_HOME $JAVA_HOME/jre
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib:$CLASSPATH
ENV PATH $JAVA_HOME/bin:$PATH
EXPOSE 80
CMD ["/bin/bash"]
- 构建镜像并验证
docker build -t centos-java8:461 .
docker run -it centos-java8:461 java -version
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐

所有评论(0)