学海无涯,志当存远。燃心砺志,奋进不辍。
愿诸君得此鸡汤,如沐春风,事业有成。
若觉此言甚善,烦请赐赞一枚,共励学途,同铸辉煌!
Docker容器是轻量级、可移植的软件单元,基于Docker镜像创建。它在隔离的进程空间中运行应用程序,包含代码、运行时环境、系统工具和依赖库。容器共享主机操作系统内核,启动快、资源占用低。
✅ 微服务部署:独立部署/扩展单个服务
✅ 持续集成/交付 (CI/CD):标准化构建、测试环境
✅ 开发环境统一:解决“在我机器上能运行”问题
✅ 云原生应用:Kubernetes等平台的基础单元
✅ 快速搭建复杂环境(如数据库、中间件集群)
Docker采用客户端-服务端 (C/S) 架构:
Docker Client:用户命令行工具 (docker
)
Docker Daemon (服务端):管理容器、镜像、网络等核心服务
Registry:镜像仓库(如Docker Hub)
Containers & Images:容器运行实例及其静态模板
组件 | 作用 |
---|---|
Docker Daemon | 常驻后台进程,管理容器生命周期、镜像存储、网络等 |
Docker Client | 用户与Daemon交互的接口(CLI或API) |
Images | 只读模板,包含应用和运行环境(分层存储) |
Containers | 镜像的运行实例(可读写的容器层) |
Registry | 镜像仓库(公共如Docker Hub,私有如Harbor) |
Dockerfile | 定义镜像构建步骤的脚本文件 |
修改镜像源为国内仓库(加速下载):
// 编辑 /etc/docker/daemon.json
{
"registry-mirrors": ["https://<镜像加速器地址>"]
// 示例:阿里云 "https://xxxx.mirror.aliyuncs.com"
}
sudo systemctl restart docker # 重启生效
docker ps # 查看运行中的容器
docker ps -a # 查看所有容器(含已停止)
docker stats # 实时监控容器资源占用
top -p $(pgrep dockerd) # 查看Docker Daemon进程资源使用
特性 | 虚拟化 (VM) | 容器化 (Docker) |
---|---|---|
隔离级别 | 硬件级虚拟化 (Hypervisor) | 进程级隔离 (cgroups/namespaces) |
Guest OS | 每个VM需独立OS内核 | 共享主机OS内核 |
启动速度 | 慢(分钟级) | 快(秒级) |
资源占用 | 高(内存、CPU冗余) | 低(按需分配) |
镜像大小 | GB级 | MB级 |
Docker Swarm是Docker官方提供的轻量级容器编排工具,用于管理多主机Docker集群。支持:
集群节点管理(Manager/Worker)
服务部署、滚动更新
负载均衡与服务发现
故障恢复(自动重启容器)
分层存储 (Layer):
镜像由多层只读文件系统叠加而成(每层对应Dockerfile的一条指令)。
联合挂载 (UnionFS):
启动容器时,在镜像层之上添加一个可写层(容器层),所有修改在此层进行。
写时复制 (Copy-on-Write):
当修改文件时,从镜像层复制到容器层进行修改,保证底层只读性。
编写 Dockerfile:
FROM ubuntu:20.04 # 基础镜像
RUN apt update && apt install -y python3 # 安装依赖
COPY app.py /app # 复制代码
CMD ["python3", "/app/app.py"] # 启动命令
构建镜像:
docker build -t my-app:1.0 . # 当前目录构建,标签为my-app:1.0
运行容器:
docker run -d --name my-container my-app:1.0
解析Dockerfile:逐行读取指令
初始化构建环境:创建临时构建上下文
执行指令序列:
FROM
:拉取基础镜像(如未本地存在)
RUN
/COPY
/ADD
:创建新镜像层执行操作
ENV
/WORKDIR
:设置元数据
缓存机制:检查指令是否匹配缓存(若相同指令且上下文未变则复用层)
生成最终镜像:合并所有层并添加镜像配置(CMD/ENTRYPOINT等)
docker push <镜像名>:<标签>
# 示例:
docker push my-registry.com/app:v1.0
需先通过
docker login
认证仓库权限
只读模板:包含应用程序代码、依赖库、环境变量和配置文件
分层结构:由多个只读层(Layer)叠加组成
静态定义:提供容器运行所需的基础文件系统快照
docker pull <镜像名>:<标签> # 默认从Docker Hub拉取
docker pull registry.private.com/app:v2 # 从私有仓库拉取
标签省略时默认使用
:latest
基础镜像:Dockerfile中 FROM
指定的初始层
最小化OS:通常为精简版操作系统(如 alpine
、ubuntu
)
不依赖父镜像:其Dockerfile以 FROM scratch
开头(空镜像)
层级堆叠:每个Dockerfile指令(RUN/COPY等)生成新的只读层
联合挂载:启动容器时所有层按顺序挂载为单一文件系统视图
唯一ID:每层有独立的哈希标识(内容变更则ID改变)
存储效率:相同层可被多个镜像/容器共享
快速构建:仅重建变更层(利用缓存机制)
减小体积:基础层(如OS)只需存储一次
版本追踪:层哈希值天然支持镜像版本控制
写时复制机制:当容器需要修改文件时:
定位文件所在镜像层
复制该文件到容器可写层
所有修改作用于副本(原始镜像层保持不变)
关键特性:保证镜像层不可变性,提升资源利用率
位于镜像层之上:容器启动时创建的空白读写层
生命周期:
所有文件修改存储于此层(增删改)
容器删除时该层销毁(数据不持久化)
临时性:需通过卷(Volume)或绑定挂载实现数据持久化
docker commit [选项] <容器ID> <新镜像名>:<标签>
# 示例:
docker commit -m "Added config" c3ab8e my-app:v2
选项:
-m
:提交信息(类似Git commit)
-a
:指定作者
1.运行基础容器:
docker run -it ubuntu:20.04 /bin/bash
2.在容器内修改:
apt update && apt install -y python3
echo "print('Hello')" > app.py
3.退出容器并提交:
docker commit <容器ID> my-python-app:v1
4.验证新镜像:
docker run my-python-app:v1 python3 app.py
⚠️ 注意:生产环境推荐使用可复现的Dockerfile而非
commit
Docker引擎是核心运行时组件,采用C/S架构:
Docker Daemon:常驻后台进程,管理容器生命周期、镜像、网络等
Docker Client:用户交互接口(CLI/REST API)
containerd:容器运行时(管理容器执行、镜像分发)
runc:底层容器运行时(遵循OCI标准创建容器)
docker exec -it <容器ID或名称> <命令> # 示例:进入容器的bash终端 docker exec -it nginx-container /bin/bash
-i
:保持标准输入打开,-t
:分配伪终端
docker ps # 仅显示运行中的容器 docker ps -a # 显示所有容器(包括已停止的)
Created:docker create
创建容器(文件系统初始化)
Running:docker start/run
启动进程
Paused:docker pause
暂停进程(CPU/内存冻结)
Stopped:docker stop
发送SIGTERM优雅终止
Restarted:docker restart
重新启动
Destroyed:docker rm
删除容器及存储层
键值对元数据:附加到镜像/容器/网络等对象
作用:
分类管理(如env=prod
, team=devops
)
自动化策略(配合监控/日志工具过滤)
设置方式:
Dockerfile
LABEL version="1.0" maintainer="[email protected]"
docker create
命令作用创建容器但不立即启动:
docker create --name temp-container nginx:alpine
预分配文件系统(初始化可写层)
配置网络/卷等参数
需手动执行 docker start
启动
docker exec <容器ID> ls /app # 查看特定目录 docker diff <容器ID> # 查看文件系统变更(A添加/D删除/C修改) # 或进入容器交互终端: docker exec -it <容器ID> /bin/sh
# 主机 → 容器 docker cp /host/file.txt <容器ID>:/container/path/ # 容器 → 主机 docker cp <容器ID>:/container/logs/ /host/backup/
docker run -d --name nginx-server \ -p 8080:80 \ # 指定端口映射(主机8080→容器80) -v $(pwd)/html:/usr/share/nginx/html \ # 挂载本地html目录 nginx:latest
随机端口映射:使用
-P
代替-p 8080:80
(自动绑定主机随机端口到容器80)
指令 | 用途 |
---|---|
FROM |
指定基础镜像 |
RUN |
执行命令并创建新层 |
COPY /ADD |
复制文件到镜像 |
CMD |
容器启动默认命令 |
ENTRYPOINT |
容器入口点(可执行文件) |
ENV |
设置环境变量 |
WORKDIR |
设置工作目录 |
EXPOSE |
声明监听端口 |
VOLUME |
定义匿名卷 |
FROM
:必须为首条指令,指定构建起点(如ubuntu:22.04
)
RUN
:在镜像层执行命令(如RUN apt install -y python3
)
COPY
:复制主机文件到镜像(不支持URL解压)
ADD
:类似COPY,但支持URL和自动解压tar包
CMD
:容器启动时执行的默认命令(可被docker run
覆盖)
ENTRYPOINT
:容器的主进程(与CMD配合使用)
ENV
:设置持久化环境变量(如ENV APP_HOME=/app
)
WORKDIR
:设置后续指令的工作路径(类似cd
)
读取Dockerfile:解析指令序列
初始化构建上下文:发送当前目录文件到Daemon
逐层构建:
检查指令缓存(未命中则执行)
RUN
/COPY
等指令生成新镜像层
生成最终镜像:添加元数据(CMD/ENV等)并输出镜像ID
COPY
vs ADD
特性 | COPY |
ADD |
---|---|---|
复制本地文件 | ✅ | ✅ |
URL下载 | ❌ | ✅(自动下载到镜像) |
自动解压 | ❌ | ✅(支持tar/gzip/bzip2/xz) |
最佳实践 | 推荐用于普通文件复制 | 仅需自动解压或远程下载时使用 |
常驻进程:dockerd
监听UNIX套接字(/var/run/docker.sock
)
核心功能:
镜像管理(构建/拉取/存储)
容器生命周期管理(create/start/stop)
网络驱动(bridge/host/none等)
存储驱动(overlay2、aufs等管理分层)
依赖组件:将容器操作委托给containerd
和runc
维度 | Docker容器 | 传统虚拟机 |
---|---|---|
虚拟化目标 | 进程级隔离 | 硬件级虚拟化 |
Guest OS | 共享主机内核 | 独立OS内核(每VM一份) |
启动速度 | 秒级 | 分钟级 |
资源开销 | 低(无Hypervisor层) | 高(需预留资源) |
隔离性 | 较弱(内核共享) | 强(完全隔离) |
特性 | Docker | LXC (原生Linux容器) |
---|---|---|
核心能力 | 基于LXC改进 | 直接使用cgroups/namespaces |
镜像格式 | 分层镜像(UnionFS) | 完整文件系统模板 |
可移植性 | 强(跨环境一致) | 弱(依赖主机环境) |
生态系统 | 丰富(Hub/K8s集成) | 较简单 |
部署单元 | 单进程模型(推荐) | 可运行完整系统 |
默认路径:
Linux:/var/lib/docker/image/<存储驱动>/
Windows:C:\ProgramData\docker\windowsfilter\
关键目录:
overlay2/
:镜像分层文件(使用overlay2驱动时)
imagedb/
:镜像元数据数据库
查看命令:
docker info | grep "Docker Root Dir"
原因:
镜像架构与宿主机不匹配(如ARM镜像运行在x86主机)
Dockerfile中ENTRYPOINT/CMD指向不存在的二进制文件
启动脚本格式错误(如Windows换行符在Linux容器运行)
解决步骤:
检查镜像架构:docker inspect --format='{{.Architecture}}' <镜像>
显式指定平台:docker run --platform linux/amd64 ...
验证启动命令:docker run --entrypoint sh <镜像>
进入容器检查
转换脚本格式:dos2unix startup.sh
使用 分离快捷键:
# 在容器交互终端中按顺序按下 Ctrl + P 然后 Ctrl + Q
直接输入
exit
或Ctrl+D
会终止容器进程
docker image prune # 删除悬空镜像(无标签)
docker image prune -a # 删除所有未被容器使用的镜像
docker system prune # 清理镜像/容器/网络/构建缓存(加-f强制)
docker inspect --format='{{range .Config.Env}}{{println .}}{{end}}' <镜像名>
# 或运行容器时打印:
docker run <镜像> env
不会立即丢失:
停止的容器文件系统仍存在(通过docker ps -a
可见)
数据存储在容器可写层,直到容器被删除(docker rm
)
持久化建议:
重要数据使用-v
挂载卷(Volume)或绑定目录
数据库等有状态服务必须使用持久化存储
docker stop $(docker ps -q) # 获取所有运行容器ID并停止
docker container prune # 交互式删除所有停止的容器
docker rm $(docker ps -a -q -f status=exited) # 批量删除已退出容器
Docker官方的公共镜像仓库:
存储海量官方/社区镜像(如nginx, mysql等)
提供镜像托管、自动构建、漏洞扫描服务
支持免费账户创建私有仓库(1个私有库)
访问地址:https://hub.docker.com
利用Linux内核特性实现隔离:
隔离类型 | 技术实现 |
---|---|
进程隔离 | PID Namespace |
网络隔离 | Network Namespace |
文件系统 | Mount Namespace |
用户权限 | User Namespace |
资源限制 | cgroups (CPU/内存/IO) |
逻辑概念:同一镜像的不同版本集合(如ubuntu
仓库包含20.04/22.04等)
命名规范:[registry_host]/[namespace]/repository_name:tag
示例:docker.io/library/nginx:latest
服务实体:存储和分发镜像的服务器程序
类型:
公有Registry:Docker Hub, Quay.io
私有Registry:Harbor, Docker Registry
核心功能:处理docker push/pull
请求
VMware开源的企业级私有镜像仓库:
核心功能:镜像存储、RBAC权限控制、漏洞扫描
扩展特性:镜像复制、Web UI管理、审计日志
适用场景:企业CI/CD流水线、合规安全要求高的环境
多租户支持:项目级权限管理
漏洞扫描:集成Clair/Trivy
镜像签名:Notary组件保障完整性
跨仓库复制:多数据中心同步
GC机制:自动清理过期镜像
LDAP/AD集成:统一身份认证
组件 | 功能 |
---|---|
Core | API/UI服务 |
Registry | 镜像存储(Docker Registry) |
Job Service | 镜像复制/扫描任务调度 |
Portal | Web管理界面 |
Database | 元数据存储(PostgreSQL) |
Redis | 缓存会话/任务队列 |
docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]
# 示例:
docker tag nginx:latest my-registry.com/project/nginx:v1.0
导出镜像:
docker save -o image.tar image_name:tag # 保存为tar文件
导入镜像:
docker load -i image.tar # 从tar文件加载
export/import
vs save/load
区别命令 | 对象 | 保留信息 | 用途 |
---|---|---|---|
docker export |
容器 | 仅文件系统(无元数据) | 迁移容器当前状态 |
docker import |
容器→镜像 | 生成新镜像(丢失历史层) | |
docker save |
镜像 | 完整镜像(含所有层和元数据) | 备份/迁移完整镜像 |
docker load |
镜像 | 恢复完整镜像结构 |
macOS/Windows:
使用Docker Desktop
(底层创建Linux虚拟机)
macOS:HyperKit虚拟化
Windows:Hyper-V/WSL2
关键限制:
只能运行与虚拟机内核兼容的Linux容器
docker port
映射报错解决错误原因:
容器未暴露端口或映射配置错误
解决步骤:
检查容器是否监听端口:docker exec <容器> netstat -tuln
运行容器时显式映射端口:docker run -p 8080:80 ...
若使用-P
随机映射,确认Dockerfile有EXPOSE 80
可行但违反最佳实践:
可通过Supervisor/Systemd管理多进程
生产环境不推荐:
违背单一职责原则
日志收集困难
故障隔离性差
资源限制不精确
应拆分为多个容器通过网络通信
使用--cpu-shares
设置相对权重(默认1024):
docker run -d --cpu-shares 512 app1 # 获得50%的CPU时间
docker run -d --cpu-shares 1024 app2 # 获得100%基准权重
docker run -d --memory 500m app # 硬限制500MB内存
docker run -d --memory-reservation 300m app # 软限制300MB
限制容器磁盘空间:
docker run -it --storage-opt size=10G ubuntu # 限制10G
需底层文件系统支持:
Devicemapper:直接配置dm.basesize
Btrfs/ZFS:原生支持配额
原因:私有仓库未正确配置
解决:
检查仓库地址格式:http(s)://host:port
对于非HTTPS仓库,在/etc/docker/daemon.json
添加:
{ "insecure-registries": ["my-registry:5000"] }
重启Docker:systemctl restart docker
主配置文件:/etc/docker/daemon.json
修改步骤:
编辑配置文件
重载配置:systemctl reload docker
或重启:systemctl restart docker
关键配置项:
{
"registry-mirrors": ["https://mirror.ccs.tencentyun.com"],
"data-root": "/data/docker",
"log-driver": "json-file"
}
停止Docker:systemctl stop docker
迁移数据:rsync -av /var/lib/docker/ /new/path
修改配置:
// /etc/docker/daemon.json { "data-root": "/new/path" }
重启:systemctl start docker
核心机制:
将多个目录(层)挂载到单一虚拟文件系统
写时复制(CoW):
修改文件时从只读层复制到可写层
驱劢实现:
Overlay2(推荐)、AUFS、DeviceMapper
类型 | 适合度 | 示例 | 原因 |
---|---|---|---|
无状态 | ★★★★★ | Web服务、API网关 | 易扩展、无持久化数据依赖 |
有状态 | ★★★☆☆ | 数据库、消息队列 | 需持久化存储+稳定网络标识 |
最佳实践: |
有状态服务需配合持久卷和StatefulSet(K8s)
运行容器时添加 --rm
参数:
docker run -it --rm ubuntu bash # 容器退出后自动删除
临时容器层数据丢失:默认容器层(可写层)在容器删除后销毁
持久化方案:
挂载卷(Volume):-v my_volume:/data
绑定主机目录:-v /host/path:/container/path
共享数据容器:通过 --volumes-from
复用
编写Dockerfile:
FROM openjdk:11-jre
COPY target/app.jar /app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "/app.jar"]
构建镜像:(后面有个点,.
是 Linux/Unix 系统中表示“当前目录”的符号:从当前目录作为构建上下文,读取 Dockerfile
并构建镜像)
docker build -t java-app:v1 .
运行容器:
docker run -d -p 8080:8080 --name my-java-app java-app:v1
验证:curl http://localhost:8080/health
定义容器默认启动命令:
CMD ["executable", "arg1", "arg2"] # exec格式(推荐)
CMD command arg1 arg2 # shell格式
可被覆盖:docker run <镜像> <新命令>
与ENTRYPOINT协作:
ENTRYPOINT
定义固定可执行文件
CMD
提供默认参数
多容器应用编排工具:
通过YAML文件定义服务/网络/卷
一键启动/停止整个应用栈
支持服务依赖、环境变量、扩缩容
典型文件:docker-compose.yml
Linux安装:
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
修改默认网络配置:
# 停止Docker
systemctl stop docker
# 修改配置文件 /etc/docker/daemon.json
{
"bip": "192.168.100.1/24" # 设置网桥IP段
}
重启Docker:systemctl start docker
# 创建自定义网络
docker network create \
--driver=bridge \
--subnet=10.10.0.0/16 \
--gateway=10.10.0.1 \
my-network
# 指定容器使用该网络
docker run --network=my-network nginx
修改配置(不推荐暴露端口):
# /etc/docker/daemon.json
{
"hosts": ["tcp://0.0.0.0:2375", "unix:///var/run/docker.sock"]
}
重启Docker:systemctl restart docker
生产环境必须使用TLS加密(端口2376)
方式 | 命令示例 | 特点 |
---|---|---|
绑定挂载 | -v /host/path:/container/path |
主机目录直接映射(可读写) |
卷挂载 | -v my_volume:/container/path |
Docker管理生命周期(推荐) |
临时文件系统 | --tmpfs /container/path |
内存存储(重启丢失) |
配置镜像加速器:
// /etc/docker/daemon.json
{
"registry-mirrors": [
"https://registry.docker-cn.com",
"https://hub-mirror.c.163.com"
]
}
重启Docker:systemctl restart docker
运行时注入:
docker run --add-host db:192.168.1.100 nginx
修改容器内部文件:
docker exec -it my-container sh -c "echo '192.168.1.100 db' >> /etc/hosts"
启动Registry容器时指定端口:
docker run -d -p 5000:5000 --name registry registry:2
客户端拉取镜像:
docker pull myhost:5000/myimage:tag
断开旧网络:
docker network disconnect bridge my-container
连接新网络:
docker network connect my-custom-net my-container
docker logs my-container # 查看历史日志 docker logs -f my-container # 实时追踪日志 docker logs --tail 100 my-container # 查看最后100行
进入容器安装:
docker exec -it my-container sh
# Alpine: apk add curl
# Ubuntu: apt update && apt install curl
构建新镜像:
dockerfile
FROM original-image
RUN apt update && apt install -y curl # 添加缺失工具
操作 | 命令 |
---|---|
主机→容器拷贝 | docker cp file.txt my-container:/path |
容器→主机拷贝 | docker cp my-container:/log.txt ./ |
目录挂载 | -v /host/path:/container/path |
version: '3.8'
services:
web:
image: nginx:alpine
ports:
- "80:80"
volumes:
- ./html:/usr/share/nginx/html
db:
image: postgres:13
environment:
POSTGRES_PASSWORD: example
volumes:
data: # 声明命名卷
Docker Hub网页搜索
API查询:
curl "https://registry.hub.docker.com/v2/repositories/library/nginx/tags/" | jq
命令行工具:
docker search nginx --limit 10 # 查看可用版本
指令 | 是否可覆盖 | 典型用途 |
---|---|---|
CMD |
✅ (run命令覆盖) | 定义默认参数 |
ENTRYPOINT |
❌ (需--entrypoint覆盖) | 定义容器主程序 |
组合使用: |
dockerfile
ENTRYPOINT ["java", "-jar"]
CMD ["/app.jar"] # 可被覆盖:docker run my-app /other.jar
模式 | 命令参数 | 特点 |
---|---|---|
bridge | --net=bridge (默认) |
容器通过网桥连接 |
host | --net=host |
共享主机网络栈 |
none | --net=none |
无网络接口 |
container | --net=container:ID |
共享其他容器网络 |
安装中文字体:dockerfile
RUN apt update && apt install -y fonts-wqy-zenhei
设置环境变量:dockerfile
ENV LANG C.UTF-8
启动容器时指定:
docker run -e LANG=C.UTF-8 my-image
定位失败指令:查看日志中最后执行的步骤
进入中间层调试:
docker run -it <失败前镜像ID> sh # 手动执行命令
分阶段构建:复杂操作拆分为多个RUN
清理缓存重建:docker build --no-cache .
示例:
RUN apt install
失败可尝试先apt update
学海无涯,志当存远。燃心砺志,奋进不辍。
愿诸君得此鸡汤,如沐春风,事业有成。
若觉此言甚善,烦请赐赞一枚,共励学途,同铸辉煌!