容器技术

依据 E:\wanho\二阶段\笔记\容器技术介绍.md 提炼重构 · 覆盖:容器发展史 / 容器概念与生态 / Docker 架构与版本 / 环境搭建 / 镜像管理 / 容器管理
用法:考前冲刺读 🎯 与 💡;实操查表用 🛠️ 与 📊;踩坑排错看 ⚠️。


🎯 核心考点概览

  1. 容器是操作系统级虚拟化:共享 Host OS 内核,把应用连同依赖库、配置、环境变量打包成隔离运行环境;底层两大基石是 Namespace 做隔离、Cgroups 做资源限制,一句话记「NS 划墙、CG 限额」。
  2. 发展主线:chroot(1979) → FreeBSD Jails / Solaris Zones → NS+Cgroups 入内核 → LXC(2008) → Docker(2013) 靠镜像分层 + Dockerfile + 镜像仓库出圈 → OCI 标准(2015) → runc/containerd 分层运行时 → Kubernetes 编排时代(2015 发布,2017 入 CNCF,1.24 移除 dockershim,containerd 成默认运行时)。
  3. Docker 是 C/S 架构:Client(只发指令不干活)经 Socket/HTTP 与 Docker Host 上的 daemon 通信,daemon 调度 containerd→runc 创建容器,Registry(Docker Hub / Harbor)负责镜像集中存放与分发。
  4. 镜像、容器、仓库的关系是必考点:镜像是只读模板(分层存储、可共享层),容器=镜像+一层可读写层的运行实例,容器删除则读写层数据丢失;Registry > Repository > Image > Tag 四级寻址,tag 不写默认 latest。
  5. 全生命周期命令链要能默写:pull / run(-d、-it、–rm、–restart) / ls / exec / attach / stop / kill / rm / prune / logs / stats,以及两组镜像搬迁对照——save↔load(保元数据分层)、export↔import(拍平当新镜像),四者不可交叉。

📚 核心概念解析

2.1 术语速查表

术语一句话定义必记点
容器 ContainerOS 级虚拟化,应用+依赖打包成的隔离运行环境共享内核;本质是受 NS/CG 管控的宿主机进程
NamespaceLinux 内核隔离机制(PID/Network/Mount/IPC/User…)决定「看得见什么」;2002‑2008 陆续入内核
CgroupsControl Groups,2007 入内核(Google 工程师开发)决定「用得了多少」:CPU/内存/IO/网络带宽限额
镜像 Image只读模板:应用+依赖库+配置打包分层存储、层可共享;不能直接运行
容器 vs 镜像容器是镜像的运行实例镜像上叠一层可读写层=容器;删容器即弃写层
Registry / 仓库集中存放、分发镜像的服务Docker Hub、Quay.io 公开;Docker Registry/Harbor 私有
Repository / Tag同类镜像的分类与版本指针一个镜像可多 tag,实际只占一份空间
Docker Enginedaemon + CLI 的合集,通常说的「Docker」管理工具角色,对内对接 runtime
runcOCI 标准底层运行时,真正创建容器libcontainer 改名而来(2016),Docker 默认 runtime
containerd高级运行时:管镜像与容器生命周期2016 从 Docker 拆出;上接 docker/K8s,下调 runc
OCI开放容器基金会(2015)两大规范:runtime spec + image format spec,保证互操作
CRIK8s 定义的容器运行时接口(2017‑2018)cri‑containerd 让 containerd 适配,K8s 不再绑死 Docker
LXC2008 第一个 Linux 用户态容器工具痛点:无镜像机制、配置复杂 → 催生 Docker
dockershimK8s 里的 Docker 适配层1.24 起移除,containerd 成默认
安全容器Kata(轻量 VM+独立内核)/ gVisor(用户态内核)强隔离方向;另有 crun、nerdctl、Podman、Wasm‑OCI
容器 OS专为跑容器定制的 OSCoreOS、atomic、ubuntu core;体积小启动快
编排引擎容器集群的调度/自愈/服务发现/滚动更新docker swarm、kubernetes(Borg 论文是思想源头)、mesos+marathon
服务发现动态环境里让 client 找到容器服务etcd、consul、zookeeper

2.2 容器 vs 虚拟机(原文表格)

特性容器虚拟机
启动速度秒级分钟级
性能接近原生较弱
内存代价很小较多
硬盘使用一般为 MB一般为 GB
运行密度单机支持上千个容器一般几十个
隔离性安全隔离完全隔离
迁移性优秀一般

原理层差异:容器不需要 Hypervisor 指令级模拟或 JIT,指令直接在核心 CPU 上跑;省去整个 Guest OS(几十 GB),只带应用依赖(几十 MB)。

2.3 集装箱 ↔ 容器特性对照(Docker 的设计隐喻)

维度集装箱容器
打包对象几乎任何货物任何软件及其依赖
硬件依赖标准形状接口,全程免开箱免修改跑在物理机/虚机/公有云/私有云
隔离性香蕉不会被铁桶压烂资源、网络、库隔离,无依赖冲突
自动化自动装卸移动run/start/stop 标准化操作
高效性各交通工具间快速搬运轻量,快速启动与迁移
职责分工货主管装什么,承运主管运开发管写代码,运维管基础环境

对应两句口号——开发:Build Once, Run Anywhere;运维:Configure Once, Run Anything。

2.4 save/load vs export/import(高频易混)

对比项docker image save / loaddocker container export / import
打包对象镜像容器(不管是否在运行)
元数据/历史完整保留全部丢失,仅保存当时状态
分层结构保留各层拍平为新镜像
导入配对docker image loaddocker image import(可加 -c 注入 Dockerfile 指令)
交叉使用❌ export 的 tar 用 load 会报错(见 ⚠️‑16)❌

2.5 attach vs exec(进入容器)

项attachexec
视图关联容器原有 STDIN/OUT/ERR在运行容器里新开一条命令通道
多终端所有窗口同步镜像,一处阻塞全体卡住各终端互不影响
后台无 stdin 容器只能看输出,不响应 Ctrl+C/Ctrl+Z正常 -it bash
结论应急看日志推荐的交互方式

2.6 启停删一组动作对比

命令动作语义信号/细节
stop优雅停止先发 SIGTERM,默认等 10 秒(-t)不退再 SIGKILL
kill暴力停止直接发信号,默认 KILL(-s 可换)
restartstop+start状态为 exited 则等价直接 start
pause/unpause冻结/恢复容器内全部进程容器仍 Up,状态标 (Paused)
rm删除默认不能删运行中容器;-f 用 SIGKILL 强删
prune批量清理container prune 清所有已停止;image prune 默认清无 tag 悬空镜像,-a 清所有未被容器引用的

2.7 运行时分工链(现代 Docker/K8s)

docker CLI → dockerd → containerd → runc(OCI) → 容器进程(Namespace+Cgroups)
K8s → CRI → cri-containerd → containerd → runc

其他 OCI 兼容件:nerdctl(containerd 的 docker 风格 CLI)、crun(C 实现轻量 runc)、Podman+Buildah(无守护进程,红帽)。

2.8 容器生态三层结构

  1. 核心技术:容器规范(OCI) / runtime(lxc、runc、rkt) / 管理工具(lxd、docker engine、rkt cli) / 定义工具(docker image、Dockerfile、ACI) / Registry / 容器 OS
  2. 平台技术:编排引擎(swarm、k8s、mesos) / 管理平台(Rancher、OpenShift、Kubesphere;EKS、AKS、ACK;Portainer、Docker Desktop、Lens) / 容器 PaaS(Deis、Flynn、Dokku)
  3. 支持技术:网络(flannel、weave、calico、docker network) / 服务发现(etcd、consul、zookeeper) / 监控(docker stats、sysdig、cAdvisor/Heapster、Weave Scope) / 数据管理(Flocker) / 日志(docker logs、logspout) / 安全(OpenSCAP)

2.9 Docker 版本三阶段

阶段格式关键点
2013‑2017.02 语义化 1.x主.次.补丁0.1 基于 LXC;1.0 生产可用+Hub;1.12 内置 Swarm/healthcheck;1.13 末版重排 CLI
2017.03‑2022.06 日历版 CE/EEYY.MM.Patch17.03 首版 runc 落地;17.05 多阶段构建;18.09 全面 containerd;20.10 经典稳定(cgroup v2、rootless);22.06 终点、Compose V1 废弃
2023.02 至今 回归语义化23.x+23.0 BuildKit 默认;24.0/25.0 生产推荐;29.x 清理老旧接口

2.10 发展史极简时间轴(原文表格)

时间里程碑事件核心价值
1979Unix chroot文件系统隔离原型
1998FreeBSD Jails完整 OS 级隔离雏形
2007Linux Cgroups 合入内核资源限制基石
2008LXC 项目诞生第一个 Linux 容器工具
2013Docker 发布镜像+Dockerfile,容器大众化
2015OCI 成立;K8s 1.0标准化 + 集群编排时代开启
2016runc、containerd分层容器运行时架构
2017K8s 移交 CNCFK8s 成为编排事实标准
2022K8s 彻底移除 dockershimcontainerd 成为 K8s 默认运行时
2023 至今Wasm 容器、安全容器轻量、强隔离新方向

时间轴未列但会考:2000 Solaris Zones;2002 PID NS / 2003 Net NS / 2004‑2006 IPC+Mount NS;2008 User NS(容器内 root≠宿主机 root);2010 Warden;2014 libcontainer 替换 LXC、Google Borg 论文;2019 K8s 1.24 起移除 dockershim(笔记两处分别写 2019/1.24 与时间轴 2022,正文「1.24 正式移除」为准)。


🛠️ 关键命令与配置

环境基准:CentOS 7 最小化安装 · runtime=runc · 管理工具=Docker Engine · 主机提示符 [root@docker ~]#。
笔记中的回显仅收录判题所需的错误行与关键行,均保留原样。

3.1 环境准备(本地 yum 源)

# 1) 挂载 ISO 到 /dvd,并写入开机自动挂载(改 fstab 前先备份)
mkdir /dvd
cp /etc/fstab /etc/fstab.bak
echo '/dev/sr0 /dvd iso9660 defaults 0 0'>> /etc/fstab
mount /dvd
ls /dvd

# 若报“找不到媒体”,是虚拟机没关联 ISO:
# mount: /dev/sr0 写保护,将以只读方式挂载
# mount: 在 /dev/sr0 上找不到媒体

# 2) 清场:默认 repo 移走,建本地 dvd.repo
mkdir /etc/yum.repos.d/bak
mv /etc/yum.repos.d/*repo /etc/yum.repos.d/bak
vim /etc/yum.repos.d/dvd.repo

/etc/yum.repos.d/dvd.repo:

[dvd]
name=local repo from dvd
baseurl=file:///dvd
gpgcheck=0
# 3) 重建元数据缓存
yum clean all
yum makecache

# 4) 防火墙:不能关闭!部分容器服务依赖 firewalld 的 NAT 功能
systemctl enable firewalld.service --now
firewall-cmd --set-default-zone=trusted

/etc/yum.repos.d/docker-ce.repo(华为云镜像):

cat > /etc/yum.repos.d/docker-ce.repo <<'EOF'
[docker-ce-stable]
name=Docker CE Stable - $basearch
baseurl=https://mirrors.huaweicloud.com/docker-ce/linux/centos/7/$basearch/stable
enabled=1
gpgcheck=0
EOF

3.2 安装与首次验证(allinone)

yum install -y docker-ce             # 安装 Docker Engine
systemctl enable docker.service --now # 开机自启并立即启动 daemon

# 配置镜像加速(docker.io 直连不通,必须走加速器/私有 Harbor)
mkdir -p /etc/docker
tee /etc/docker/daemon.json <<'EOF'
{
  "insecure-registries": ["hub.laoma.cloud"],
  "registry-mirrors": ["http://hub.laoma.cloud","https://docker.m.daocloud.io"]
}
EOF
systemctl restart docker             # daemon.json 改完必须重启才生效

# 验证
docker --version                     # 例:Docker version 26.1.3, build b72abbb
docker run hello-world               # 完整验证 Client→daemon→pull→建容器→回显 链路
docker run -d -p 80:80 httpd         # 起 web:-d 后台,-p 宿主机80→容器80
ip -br a                             # 宿主 IP;注意 docker0=172.17.0.1/16 网桥、veth 已生成
curl 10.1.8.130                      # <html><body><h1>It works!</h1></body></html>

3.3 C/S 分离部署

# ===== server 端 =====
dnf install -y docker-ce
vim /usr/lib/systemd/system/docker.service
# ExecStart 末尾追加 -H tcp://0.0.0.0:2375(监听 TCP API)
# ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock -H tcp://0.0.0.0:2375
systemctl daemon-reload
systemctl enable docker.service --now
lsof -i :2375                        # dockerd 应处于 LISTEN
# ===== client 端(只装命令行,不装 daemon)=====
dnf install -y docker-ce-cli
docker -H 10.1.8.130 run hello-world
docker -H 10.1.8.130 images

要点:镜像和容器都存在 server 端,client 只是操控面板。(补充,笔记未提:2375 无 TLS,等于把 Docker 控制权裸奔给整个网段,生产应换 2376+证书或套防火墙。)

3.4 镜像管理命令

# —— 查 ——
mandb; man -k docker                 # 本地手册库检索 docker 命令
docker search --filter stars=3 centos   # Docker Hub 搜索(直连不通会报错,见 ⚠️‑3)
docker search --limit 10 --no-trunc nginx

# Hub API 查某镜像全部 tag(Docker 本身没有这个命令,走 API/网页/第三方)
curl -s "https://registry.hub.docker.com/v2/repositories/library/nginx/tags/" | jq '.results[].name'    # 官方镜像加 library/
curl -s "https://registry.hub.docker.com/v2/repositories/bitnami/mysql/tags/" | jq '.results[].name'    # 非官方不加
pip install docker-search; docker-search tags nginx

# 私有 Harbor(课堂 hub.laoma.cloud)查 tag
curl -s "http://hub.laoma.cloud/api/v2.0/projects" | jq -r '.[].name'
curl -s "http://hub.laoma.cloud/api/v2.0/projects/library/repositories" | jq -r '.[].name'
curl -s "http://hub.laoma.cloud/api/v2.0/projects/library/repositories/nginx/artifacts" | jq -r '.[].tags[].name' | sort -V
curl -s -u student:Student123 "http://hub.laoma.cloud/api/v2.0/projects/library/repositories/nginx/artifacts" | jq -r '.[].tags[].name' | sort -V

# —— 取 ——
docker image pull centos:8                    # 语法:NAME[:TAG|@DIGEST];缺省 tag=latest
docker image pull registry.access.redhat.com/ubi8   # 直连指定 registry 拉取
# 命名格式:服务器地址:端口/分类/镜像名:tag;默认 Docker Hub 可省服务器前缀
# 下载存储位置:/var/lib/docker/<StorageDriver>(默认 overlay2);相同的层本机只存一份

# —— 看 ——
docker image ls                               # 别名 images/list;-a 含中间层镜像
docker image ls --format "{{.Repository}}:{{.Tag}}"   # Go 模板控制输出列
docker image inspect myos -f '{{.Architecture}}'      # amd64;另有 -f '{{.Os}}'
docker image history myos                     # 分层构建历史
docker image history myos --no-trunc          # 完整层 ID 与构建指令
docker info|grep 'Storage Driver'             # Storage Driver: overlay2

# —— 打标 ——
docker image tag centos:8 myos                # 语法:SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]
docker image tag centos:8 myos:v1             # 多 tag 指向同一 IMAGE ID,只占一份空间

# —— 删 ——
docker image rm myos                          # 多 tag 时只解绑 myos:latest 这一个标签
docker image rm myos:v1                       # 解绑最后一个标签时,才真正删除镜像层
docker image rm 958373fdd7e8                  # 按 ID 删除:连带所有 tag
docker image prune                            # 清悬空(无 tag)镜像
docker image prune -a <<< "y"                 # 清所有"没有容器引用"的镜像(含已退出容器引用的都不删)
# --filter until=<timestamp> 按时间过滤;-f 免确认

# —— 搬 ——
docker save httpd -o httpd.tar                # 单镜像存 tar
docker save httpd hello-world -o images.tar   # 多镜像存一个 tar
docker image load -i images.tar               # tar 导入(保留 tag/分层/历史)

# —— 传 ——
docker login                                  # 默认 docker.io,需账号;密码明文写进配置(见 ⚠️‑14)
docker image tag hello-world:latest mage16196/myhello   # 推送前必须改成 username/image:tag
docker image push mage16196/myhello

tag 命名最佳实践(版本 1.9.1 发布时打 1.9.1/1.9/1/latest 四个标签;1.9.2 发布时把 1.9、1 从旧版移动过来,latest 指向 2.0.0):

  1. myimage:1 恒指 1.x 分支最新;myimage:1.9 恒指 1.9.x 最新;latest 恒指绝对最新;锁版本才写 1.9.1。

3.5 容器管理命令

# —— 查 ——
docker container ls                           # 只看运行中(别名 ps)
docker container ls -a                        # 含已退出/暂停
docker container ls -f status=exited          # 按状态过滤
docker container ls -n 3 / -l / -q            # 最后 n 个 / 最新一个 / 只要 ID
docker container top be05a7c31635             # 容器内进程(PID 是宿主机视角)
docker container stats                        # 实时资源;-a 全部;--no-stream 取一次
docker container stats --format '{{.Container}}\t{{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}'
docker container inspect be05a7c31635 -f '{{.State.Pid}}'                          # 主进程 PID
docker container inspect be05a7c31635 -f '{{.NetworkSettings.Networks.bridge.IPAddress}}'   # 容器 IP(如 172.17.0.2)
docker logs 5bd4eb2e; docker logs -f 5bd4eb2e # 看日志 / 动态追日志

# —— 建与起 ——
docker container create centos:8              # 只创建不启动
docker container create -it --name myos -h myos centos:8   # -i 保 stdin,-t 伪终端,--name 命名,-h 主机名
docker container start 12ea7f1                # 按 ID 前缀启动
docker container start -ai myos               # 启动并接管终端(-a 附 stdout/-i 交互)

# —— run = create + start ——
docker container run centos:8 echo hello world    # 带 COMMAND 覆盖镜像默认命令;不带则用镜像 Cmd(centos:8 为 /bin/bash)
docker container run -it centos:8                 # 交互起;exit 后容器即 Exited(主进程退出容器就退)
docker run -d centos:8 sh -c 'while true;do echo sleep 5;sleep 5;done'   # 守护态后台
docker container run --name test --rm centos:8 echo hello world          # 一次性任务:跑完自动删容器
docker container run --name test2 -it --restart=always centos:8          # 退出也自动拉起;但手动 docker container stop 的不会重启

# —— 进入容器 ——
docker container attach 5bd4eb2e348b          # 关联原终端输出(多窗口同步;后台无 stdin 容器看得到打不进)
docker container exec -it 5bd4eb2e348b bash   # ★推荐:新开交互通道,不影响其他终端

# —— 停用 ——
docker container stop test2                   # SIGTERM→等 10s(-t 可调)→SIGKILL
docker container kill 817f24cc                # 直接 KILL(-s 换信号;Exited (137))
docker container restart be05a7c31635         # stop+start
docker container pause 5bd4eb2e348b           # 冻结全部进程(Up (Paused))
docker container unpause 5bd4eb2e348b         # 解冻

# —— 删 ——
docker container rm test1                     # 只能删非运行容器
docker container rm -f myos                   # 运行中强删(SIGKILL);-v 连带匿名卷
docker container prune -f                     # 批量清所有已停止容器

# —— 容器导出/导入 ——
docker container export be05a7c31635 -o myhttpd.tar    # 运行中也能导;只剩当时文件系统状态
docker image import myhttpd.tar myweb:v1               # 导入为新镜像;-c 可补 Dockerfile 指令

指定镜像/容器时:ID、名称、能唯一匹配的前缀均可(笔记「小技巧」)。
Windows 侧:Docker Desktop 跑在 WSL 或 Hyper‑V 两种架构之上;文档 docs.docker.com/desktop/setup/install/windows-install/。

3.6 历史彩蛋:chroot 救援(早期文件系统隔离的实战)

# root 破解密码流程(原文片段):把损坏系统挂载进来,再切根
/dev/centos/root /mnt/sysroot            # fstab 挂载条目
mount -o rw,remount /mnt/sysroot         # 由只读改可写
chroot /mnt/sysroot/                     # 切换根目录进入"旧系统"

📊 架构与流程梳理

4.1 Docker C/S 架构总览

   ┌──────────┐  docker build/pull/run/...  ┌─────────────────────────────────┐
   │  Client  │ ────────── Socket ────────► │        Docker Host              │
   │ (CLI 等) │ ◄────────────────────────── │  dockerd ─► containerd ─► runc  │
   └──────────┘        REST/Socket          │        ┌──────────────────┐     │
     只发指令·不干活                          │        │ Container × N    │     │
                                            │        │ (镜像RO层+读写层) │     │
                                            │  Images │  Containers      │     │
                                            └────┬───────────────────────┘─────┘
                                                 │ pull / push
                                            ┌────▼────────────────────────┐
                                            │ Registry(Docker Hub/Harbor)│
                                            └─────────────────────────────┘
  • Client:用户交互入口(docker build/pull/run),不直接创建容器。
  • Docker Host:常驻 daemon 处理一切请求(构建、拉取、创建、启停、销毁);内含只读 Images 与运行实例 Containers。
  • Registry:镜像仓库,公开(Docker Hub、Quay.io)/私有(Docker Registry、Harbor)两类;按 Repository 分类、Tag 区分版本。

4.2 docker run nginx 完整交互流程(daemon 视角七步,run 一次做完)

  1. Client 发指令:用户执行 docker run nginx,请求经 Socket 交给 Docker daemon。
  2. daemon 查本地镜像:本地没有 nginx → 访问 Registry 下载,存入本机 Images。
  3. daemon 建容器并运行:读镜像、分配网络/存储资源,创建并启动 Container。

展开为笔记的「后台运行标准七步」:

  1. 检查本地镜像,不存在则从公有仓库下载;
  2. 用镜像创建容器并启动;
  3. 分配文件系统:只读镜像层之上叠一层可读写层;
  4. 从宿主网桥(docker0)桥接一个虚拟接口(veth)进容器;
  5. 从网桥地址池配一个 IP 给容器(如 172.17.0.2/16);
  6. 执行用户指定的应用程序;
  7. 应用退出后容器自动终止。

4.3 入门实验流程(两个容器)

  1. hello-world
    1. docker run hello-world:本地无镜像 → 自动 pull → 创建容器 → 打印问候 → 自动退出。
  2. httpd web 服务
    1. docker run -d -p 80:80 httpd:拉 httpd 镜像(内置 Apache);
    2. -d 后台守护态;-p 80:80 把容器 80 映射到宿主 80;
    3. ip -br a 取宿主 IP(ens33);
    4. 浏览器/curl 访问 http://<宿主IP> → It works!。

4.4 装机部署流程(CentOS 7 · allinone)

  1. 环境准备
    1. 挂载 ISO → /dvd,fstab 固化(先 cp /etc/fstab 备份);
    2. 默认 repo 移入 bak/,建 dvd.repo 本地源;
    3. yum clean all && yum makecache;
    4. firewalld 开启并置 trusted zone(NAT 依赖它,不能 stop);
    5. 添加 docker-ce.repo(华为镜像)。
  2. 安装:yum install -y docker-ce → systemctl enable docker.service --now。
  3. 加速:写 /etc/docker/daemon.json(insecure-registries + registry-mirrors)→ systemctl restart docker。
  4. 验证:docker --version → docker run hello-world。
  5. 业务:docker run -d -p 80:80 httpd → ip -br a → curl <宿主IP>。

4.5 C/S 分离部署流程

  1. server:装 docker-ce → 改 docker.service 的 ExecStart 追加 -H tcp://0.0.0.0:2375 → daemon-reload + enable --now → lsof -i :2375 确认 LISTEN。
  2. client:只装 docker-ce-cli → docker -H <serverIP> run/images。
  3. 数据归属:image 和 container 全部存储在 server 端。

4.6 容器生命周期状态流

 create ──► (已创建未启动)
 run/start ─► running ──pause──► running(Paused) ──unpause──► running
 running ──stop(SIGTERM→KILL)──► exited ──start──► running
 running ──kill(SIGKILL)───────► exited(137)
 exited / running(-f) ──rm──► 删除
 run --rm:进程退出即自动删除;run 一次性命令:执行完毕容器自动终止

4.7 镜像分层与容器读写层(overlay2)

 容器视角(MergedDir)
 ┌───────────────────────────┐
 │ 容器可读写层 UpperDir      │ ← 容器内一切新写入;容器删除 → 写层数据默认丢失
 ├───────────────────────────┤
 │ 镜像层 N(只读 RO)        │ ← 多镜像/多容器共享同层,本机仅存一份
 │ …                         │
 │ 镜像层 1(基础层,只读)    │
 └───────────────────────────┘
 落盘:/var/lib/docker/overlay2/<id>/{merged,diff,work}(inspect 的 GraphDriver 可见)

4.8 两条镜像搬迁路线(选路流程)

  1. 要连分层、tag、构建历史一起搬(镜像分发、离线环境)→ docker save -o x.tar → 目标机 docker load -i x.tar。
  2. 要固化某容器当前现场(装完软件的状态)→ docker container export -o x.tar → docker image import x.tar name:tag(拍平、丢元数据,当全新镜像)。
  3. 交叉必错:export 产物不能 load;save 产物不必 import(会丢 tag 语义)。

4.9 发展史主线(因果链背诵版)

  1. 隔离思想:chroot(1979) → Jails(1998) → Zones(2000);
  2. 内核能力:PID(2002)/Net(2003)/IPC+Mount(2004‑06) NS → Cgroups(2007) → User NS(2008);
  3. NS+CG 合体 → LXC(2008),但缺镜像机制难分发;
  4. Docker(2013) 用镜像分层+Dockerfile+Hub 补齐分发;2014 弃 LXC 自研 libcontainer;
  5. OCI(2015) 定镜像/运行时两规范 → libcontainer 改名 runc(2016),containerd(2016) 接管生命周期;
  6. K8s(2015) 源自 Borg,2017 入 CNCF 成编排事实标准(Swarm 边缘化);
  7. CRI(2017‑18) → K8s 1.24 移除 dockershim,containerd 成集群默认;Docker 退居开发工具;
  8. 新方向:安全容器(Kata/gVisor)、Podman/Buildah、Wasm‑OCI。

⚠️ 易错点与避坑指南

#坑症状(笔记原文)根因与解法
1关防火墙容器端口映射/上网异常firewalld 的 NAT 被 docker 依赖:只调 zone(trusted),别 disable;systemctl enable firewalld --now
2ISO 未关联mount: 在 /dev/sr0 上找不到媒体虚拟机设置里勾选/重挂对应 ISO 文件,再 mount /dvd
3直连 Docker Hub 失败Error response from daemon: Get "https://index.docker.io/v1/search?q=centos&n=25": dial tcp 104.244.43.208:443: connect: connection refuseddocker search 等仍直连官方站点、不吃 mirror → 用 daemon.json 加速器/私有 Harbor 拉镜像;查 tag 改走 Hub API 或网页
4改完 daemon.json 没生效镜像还是拉不动该文件仅启动时读取:systemctl restart docker
5HTTP 私有仓库被拒pull Harbor 报 https 错明文仓库须写入 insecure-registries,与 registry-mirrors 并列配置
6默认 repo 没清yum 走外网超时安装 ISO 源前把 /etc/yum.repos.d/*repo 移入 bak,只留 dvd.repo+docker-ce.repo
7直接“运行镜像”/指望容器存数据docker image run 不存在;容器删了数据没了镜像只读,只能 run 实例化;持久数据走 volume/挂载(笔记:写层随容器删除而丢)
8删不掉被引用的镜像Error response from daemon: conflict: unable to remove repository reference "httpd" (must force) - container be05a7c31635 is using its referenced image ...已退出的容器也算引用:先 docker container rm 再 image rm;急用 -f(注意残留 <none> 镜像仍被用,见笔记 load 段)
9tag 与镜像的删除关系删了 myos 镜像还在多 tag 时 image rm 只解标签;解掉最后一个标签才删层;按 ID 删则连所有 tag 一起清
10prune 误以为清光prune -a 后 httpd/hello-world 仍在有容器(含 Exited 的 keen_kare)引用的镜像不算“无用”;docker ps -a 先确认,再删容器后 prune
11rm 运行中容器失败Error response from daemon: You cannot remove a running container ... Stop the container before attempting removal or force remove先 stop 或 rm -f(SIGKILL);带 -v 才连匿名卷一起删
12交互容器 exit 后“消失”run -it centos:8 一 exit 就 Exited容器生命周期=主进程生命周期:常驻服务用 -d+前台进程,或 --restart=always(手动 stop 的不会自动起,这是特性不是 bug)
13attach 卡死/串台多窗口同步显示、Ctrl+C/Ctrl+Z 无反应、只能 stop 控制attach 适合回看输出;日常交互一律 docker container exec -it ... bash(官方最推荐)
14push 失败/密码裸奔推送 404 / WARNING! Your password will be stored unencrypted in /root/.docker/config.json.① 先 docker tag 镜像 username/image:tag(默认推 docker.io 且需登录);② 配 credential helper;③ docker.io 当前不可直连,课内推私有 Harbor
15拉了个“默认版本”不写 tag 全拿 latest缺省补 :latest;生产锁版本号,或按 image@sha256:digest 拉不可变内容
16export 产物 load 失败open /var/lib/docker/tmp/docker-import-.../bin/json: no such file or directoryexport tar 无镜像元数据,必须配 docker image import;save↔load、export↔import 两对各自配对,不交叉
17以为 exec 能进停止容器exec 报 container not runningexec 仅对 running 容器有效;停止容器先 start,或用 docker run 新实例
182375 明文端口(补充,笔记未列)-H tcp://0.0.0.0:2375 无认证无加密,任何可达主机都能建特权容器=宿主 root;仅实验环境用,生产改 2376+TLS 或绑内网/防火墙

💡 记忆口诀 / 一句话总结

容器概念(发展史+本质)

「chroot 开门,Jails/Zones 立墙;NS 划墙、CG 限额;LXC 铺路没镜像,Docker 分层带箱上路;OCI 立规,runc/containerd 分工,K8s 成编,dockershim 让位。」
一句话:Namespace 管“看见什么”,Cgroups 管“用多少”,镜像管“带什么跑”。

容器 vs 虚拟机

「虚拟机虚拟的是硬件,容器虚拟的是操作系统;秒级起、MB 级身、共享内核、迁移如搬箱。」

Docker 架构

「Client 动嘴,daemon 跑腿,containerd 张罗,runc 接生,Registry 管仓库——Socket 一根线牵起 C/S。」

镜像与容器

「镜像只读不能跑,加层可写才成容器;写层随容器死,共享层赖镜像活;一个镜像多个 tag,删尽 tag 才删层。」

安装部署

「sr0 没媒体先挂盘;防火墙只调 zone 不关停,NAT 全凭它吃饭;加速器配好必 restart,改 json 不重启等于白改。」

镜像命令

「search 查、pull 取、ls 看、tag 贴、inspect 翻家底、history 查户口;save 打包给 load,push 先 login 再 username/image:tag。」

容器命令

「create 备料 run 上桌,-it 交互 -d 后台 --rm 一次性;exec 开门是新客,attach 照镜会串台;stop 先礼后兵,kill 直发 KILL(137);rm 不带 -f 动不了活容器,prune 只清没主的。」

save/export 之辨(必考)

「save 搬镜像保层带历史,load 认它;export 拍容器成一页白纸,import 认它——纸别塞进镜像的箱,load 必报 bin/json 不存在。」

版本与生态

「1.x 语义、17.03 起看日历、23.0 回归语义;Docker 管单机,K8s 管集群,Swarm 退居二线;Rancher/OpenShift 管 K8s,Portainer 管小局,云上 EKS/AKS/ACK 托管买现成。」


附注:本文全部命令、报错原文与表格数据取自笔记原文件;标「补充」的两条(2375 安全、digest 拉取口径延伸)为整理时加入,笔记未直接给出。原笔记中的课堂课件图片(内网 192.168.45.200)未收录,架构图以文字图重建。

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐