容器技术的应用
容器技术
依据
E:\wanho\二阶段\笔记\容器技术介绍.md提炼重构 · 覆盖:容器发展史 / 容器概念与生态 / Docker 架构与版本 / 环境搭建 / 镜像管理 / 容器管理
用法:考前冲刺读 🎯 与 💡;实操查表用 🛠️ 与 📊;踩坑排错看 ⚠️。
🎯 核心考点概览
- 容器是操作系统级虚拟化:共享 Host OS 内核,把应用连同依赖库、配置、环境变量打包成隔离运行环境;底层两大基石是 Namespace 做隔离、Cgroups 做资源限制,一句话记「NS 划墙、CG 限额」。
- 发展主线: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 成默认运行时)。
- Docker 是 C/S 架构:Client(只发指令不干活)经 Socket/HTTP 与 Docker Host 上的 daemon 通信,daemon 调度 containerd→runc 创建容器,Registry(Docker Hub / Harbor)负责镜像集中存放与分发。
- 镜像、容器、仓库的关系是必考点:镜像是只读模板(分层存储、可共享层),容器=镜像+一层可读写层的运行实例,容器删除则读写层数据丢失;Registry > Repository > Image > Tag 四级寻址,tag 不写默认
latest。 - 全生命周期命令链要能默写:pull / run(-d、-it、–rm、–restart) / ls / exec / attach / stop / kill / rm / prune / logs / stats,以及两组镜像搬迁对照——save↔load(保元数据分层)、export↔import(拍平当新镜像),四者不可交叉。
📚 核心概念解析
2.1 术语速查表
| 术语 | 一句话定义 | 必记点 |
|---|---|---|
| 容器 Container | OS 级虚拟化,应用+依赖打包成的隔离运行环境 | 共享内核;本质是受 NS/CG 管控的宿主机进程 |
| Namespace | Linux 内核隔离机制(PID/Network/Mount/IPC/User…) | 决定「看得见什么」;2002‑2008 陆续入内核 |
| Cgroups | Control Groups,2007 入内核(Google 工程师开发) | 决定「用得了多少」:CPU/内存/IO/网络带宽限额 |
| 镜像 Image | 只读模板:应用+依赖库+配置打包 | 分层存储、层可共享;不能直接运行 |
| 容器 vs 镜像 | 容器是镜像的运行实例 | 镜像上叠一层可读写层=容器;删容器即弃写层 |
| Registry / 仓库 | 集中存放、分发镜像的服务 | Docker Hub、Quay.io 公开;Docker Registry/Harbor 私有 |
| Repository / Tag | 同类镜像的分类与版本指针 | 一个镜像可多 tag,实际只占一份空间 |
| Docker Engine | daemon + CLI 的合集,通常说的「Docker」 | 管理工具角色,对内对接 runtime |
| runc | OCI 标准底层运行时,真正创建容器 | libcontainer 改名而来(2016),Docker 默认 runtime |
| containerd | 高级运行时:管镜像与容器生命周期 | 2016 从 Docker 拆出;上接 docker/K8s,下调 runc |
| OCI | 开放容器基金会(2015) | 两大规范:runtime spec + image format spec,保证互操作 |
| CRI | K8s 定义的容器运行时接口(2017‑2018) | cri‑containerd 让 containerd 适配,K8s 不再绑死 Docker |
| LXC | 2008 第一个 Linux 用户态容器工具 | 痛点:无镜像机制、配置复杂 → 催生 Docker |
| dockershim | K8s 里的 Docker 适配层 | 1.24 起移除,containerd 成默认 |
| 安全容器 | Kata(轻量 VM+独立内核)/ gVisor(用户态内核) | 强隔离方向;另有 crun、nerdctl、Podman、Wasm‑OCI |
| 容器 OS | 专为跑容器定制的 OS | CoreOS、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 / load | docker container export / import |
|---|---|---|
| 打包对象 | 镜像 | 容器(不管是否在运行) |
| 元数据/历史 | 完整保留 | 全部丢失,仅保存当时状态 |
| 分层结构 | 保留各层 | 拍平为新镜像 |
| 导入配对 | docker image load | docker image import(可加 -c 注入 Dockerfile 指令) |
| 交叉使用 | ❌ export 的 tar 用 load 会报错(见 ⚠️‑16) | ❌ |
2.5 attach vs exec(进入容器)
| 项 | attach | exec |
|---|---|---|
| 视图 | 关联容器原有 STDIN/OUT/ERR | 在运行容器里新开一条命令通道 |
| 多终端 | 所有窗口同步镜像,一处阻塞全体卡住 | 各终端互不影响 |
| 后台无 stdin 容器 | 只能看输出,不响应 Ctrl+C/Ctrl+Z | 正常 -it bash |
| 结论 | 应急看日志 | 推荐的交互方式 |
2.6 启停删一组动作对比
| 命令 | 动作语义 | 信号/细节 |
|---|---|---|
| stop | 优雅停止 | 先发 SIGTERM,默认等 10 秒(-t)不退再 SIGKILL |
| kill | 暴力停止 | 直接发信号,默认 KILL(-s 可换) |
| restart | stop+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 容器生态三层结构
- 核心技术:容器规范(OCI) / runtime(lxc、runc、rkt) / 管理工具(lxd、docker engine、rkt cli) / 定义工具(docker image、Dockerfile、ACI) / Registry / 容器 OS
- 平台技术:编排引擎(swarm、k8s、mesos) / 管理平台(Rancher、OpenShift、Kubesphere;EKS、AKS、ACK;Portainer、Docker Desktop、Lens) / 容器 PaaS(Deis、Flynn、Dokku)
- 支持技术:网络(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/EE | YY.MM.Patch | 17.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 发展史极简时间轴(原文表格)
| 时间 | 里程碑事件 | 核心价值 |
|---|---|---|
| 1979 | Unix chroot | 文件系统隔离原型 |
| 1998 | FreeBSD Jails | 完整 OS 级隔离雏形 |
| 2007 | Linux Cgroups 合入内核 | 资源限制基石 |
| 2008 | LXC 项目诞生 | 第一个 Linux 容器工具 |
| 2013 | Docker 发布 | 镜像+Dockerfile,容器大众化 |
| 2015 | OCI 成立;K8s 1.0 | 标准化 + 集群编排时代开启 |
| 2016 | runc、containerd | 分层容器运行时架构 |
| 2017 | K8s 移交 CNCF | K8s 成为编排事实标准 |
| 2022 | K8s 彻底移除 dockershim | containerd 成为 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):
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 一次做完)
- Client 发指令:用户执行
docker run nginx,请求经 Socket 交给 Docker daemon。 - daemon 查本地镜像:本地没有 nginx → 访问 Registry 下载,存入本机 Images。
- daemon 建容器并运行:读镜像、分配网络/存储资源,创建并启动 Container。
展开为笔记的「后台运行标准七步」:
- 检查本地镜像,不存在则从公有仓库下载;
- 用镜像创建容器并启动;
- 分配文件系统:只读镜像层之上叠一层可读写层;
- 从宿主网桥(docker0)桥接一个虚拟接口(veth)进容器;
- 从网桥地址池配一个 IP 给容器(如 172.17.0.2/16);
- 执行用户指定的应用程序;
- 应用退出后容器自动终止。
4.3 入门实验流程(两个容器)
- hello-world
docker run hello-world:本地无镜像 → 自动 pull → 创建容器 → 打印问候 → 自动退出。
- httpd web 服务
docker run -d -p 80:80 httpd:拉 httpd 镜像(内置 Apache);-d后台守护态;-p 80:80把容器 80 映射到宿主 80;ip -br a取宿主 IP(ens33);- 浏览器/curl 访问
http://<宿主IP>→It works!。
4.4 装机部署流程(CentOS 7 · allinone)
- 环境准备
- 挂载 ISO →
/dvd,fstab 固化(先cp /etc/fstab备份); - 默认 repo 移入
bak/,建dvd.repo本地源; yum clean all && yum makecache;- firewalld 开启并置 trusted zone(NAT 依赖它,不能 stop);
- 添加
docker-ce.repo(华为镜像)。
- 挂载 ISO →
- 安装:
yum install -y docker-ce→systemctl enable docker.service --now。 - 加速:写
/etc/docker/daemon.json(insecure-registries + registry-mirrors)→systemctl restart docker。 - 验证:
docker --version→docker run hello-world。 - 业务:
docker run -d -p 80:80 httpd→ip -br a→curl <宿主IP>。
4.5 C/S 分离部署流程
- server:装
docker-ce→ 改docker.service的 ExecStart 追加-H tcp://0.0.0.0:2375→daemon-reload+enable --now→lsof -i :2375确认 LISTEN。 - client:只装
docker-ce-cli→docker -H <serverIP> run/images。 - 数据归属: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 两条镜像搬迁路线(选路流程)
- 要连分层、tag、构建历史一起搬(镜像分发、离线环境)→
docker save -o x.tar→ 目标机docker load -i x.tar。 - 要固化某容器当前现场(装完软件的状态)→
docker container export -o x.tar→docker image import x.tar name:tag(拍平、丢元数据,当全新镜像)。 - 交叉必错:export 产物不能
load;save 产物不必import(会丢 tag 语义)。
4.9 发展史主线(因果链背诵版)
- 隔离思想:chroot(1979) → Jails(1998) → Zones(2000);
- 内核能力:PID(2002)/Net(2003)/IPC+Mount(2004‑06) NS → Cgroups(2007) → User NS(2008);
- NS+CG 合体 → LXC(2008),但缺镜像机制难分发;
- Docker(2013) 用镜像分层+Dockerfile+Hub 补齐分发;2014 弃 LXC 自研 libcontainer;
- OCI(2015) 定镜像/运行时两规范 → libcontainer 改名 runc(2016),containerd(2016) 接管生命周期;
- K8s(2015) 源自 Borg,2017 入 CNCF 成编排事实标准(Swarm 边缘化);
- CRI(2017‑18) → K8s 1.24 移除 dockershim,containerd 成集群默认;Docker 退居开发工具;
- 新方向:安全容器(Kata/gVisor)、Podman/Buildah、Wasm‑OCI。
⚠️ 易错点与避坑指南
| # | 坑 | 症状(笔记原文) | 根因与解法 |
|---|---|---|---|
| 1 | 关防火墙 | 容器端口映射/上网异常 | firewalld 的 NAT 被 docker 依赖:只调 zone(trusted),别 disable;systemctl enable firewalld --now |
| 2 | ISO 未关联 | 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 refused | docker search 等仍直连官方站点、不吃 mirror → 用 daemon.json 加速器/私有 Harbor 拉镜像;查 tag 改走 Hub API 或网页 |
| 4 | 改完 daemon.json 没生效 | 镜像还是拉不动 | 该文件仅启动时读取:systemctl restart docker |
| 5 | HTTP 私有仓库被拒 | 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 段) |
| 9 | tag 与镜像的删除关系 | 删了 myos 镜像还在 | 多 tag 时 image rm 只解标签;解掉最后一个标签才删层;按 ID 删则连所有 tag 一起清 |
| 10 | prune 误以为清光 | prune -a 后 httpd/hello-world 仍在 | 有容器(含 Exited 的 keen_kare)引用的镜像不算“无用”;docker ps -a 先确认,再删容器后 prune |
| 11 | rm 运行中容器失败 | 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) |
| 13 | attach 卡死/串台 | 多窗口同步显示、Ctrl+C/Ctrl+Z 无反应、只能 stop 控制 | attach 适合回看输出;日常交互一律 docker container exec -it ... bash(官方最推荐) |
| 14 | push 失败/密码裸奔 | 推送 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 拉不可变内容 |
| 16 | export 产物 load 失败 | open /var/lib/docker/tmp/docker-import-.../bin/json: no such file or directory | export tar 无镜像元数据,必须配 docker image import;save↔load、export↔import 两对各自配对,不交叉 |
| 17 | 以为 exec 能进停止容器 | exec 报 container not running | exec 仅对 running 容器有效;停止容器先 start,或用 docker run 新实例 |
| 18 | 2375 明文端口 | (补充,笔记未列) | -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)未收录,架构图以文字图重建。
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐
所有评论(0)