云计算实验笔记(二):PaaS 与容器化 ------ 从 Docker 命令到 Kubernetes 全景图
关键词:云计算、PaaS、容器、Docker、镜像、Volume、Network、Bridge、Host、UDB、Kubernetes
本文是云计算系列的第二篇。如果说第一篇讲的是 怎么虚拟出一台机器 ,这一篇讲的就是 怎么虚拟出一个进程------容器化。通过 Docker 把镜像、容器、卷、网络四大支柱一个一个吃透,最后把这些概念逐一映射到 AWS ECS / EKS、Azure AKS、GCP GKE 等主流 PaaS 平台。
目录
- [一、为什么需要容器:从 VM 到容器的范式跃迁](#一、为什么需要容器:从 VM 到容器的范式跃迁)
- [二、Docker 是什么 & 安装](#二、Docker 是什么 & 安装)
- 三、镜像(Image)
- 四、容器(Container)
- 五、数据卷(Volume)
- 六、网络(Network)
- 七、综合实战:三个真实场景
- 八、安全注意事项
- [九、VM vs 容器对比](#九、VM vs 容器对比)
- [十、Docker 概念 ↔ 主流云 PaaS 映射表](#十、Docker 概念 ↔ 主流云 PaaS 映射表)
- 十一、总结与下一步
一、为什么需要容器:从 VM 到容器的范式跃迁
虚拟机的一切都很好------隔离强、兼容老软件、可以跑任意操作系统。但它有三个绕不开的痛点:
- 启动慢:开机就是几十秒到几分钟,因为要走完一遍 BIOS → bootloader → kernel → init → userspace。
- 资源重:每台 VM 自带完整 OS,1G+ 内存起步。
- 打包大:一个 OVA 文件动辄几个 GB,分发和部署成本高。
容器化把这些痛点一一解决:
核心思想 :不再虚拟"硬件",而是 直接在宿主内核上隔离一组进程,让它们误以为自己跑在独占的机器里。
这一切靠的是 Linux 内核两个老特性:
- Namespace:把 PID、网络、挂载、UTS、IPC、User 六种资源切分成独立视图,进程"看不见"其他容器。
- Cgroups:限制每组进程能用的 CPU、内存、I/O,确保不会互相抢资源。
容器 = Namespace 隔离 + Cgroups 限额 + 联合文件系统打包。Docker 就是把这套底层 API 包装成了一个对开发者友好的工具链。
二、Docker 是什么 & 安装
2.1 Docker 的定位
Docker 是一个 容器平台 ,把应用 + 依赖 + 配置打包成 镜像(Image) ,并在任何装了 Docker 的机器上以 容器(Container) 的形式运行。
它解决的本质问题是:"It works on my machine"------开发环境和生产环境的不一致。
典型用途:
- 本地开发 / 测试环境一键拉起。
- 数据库、消息中间件、缓存的隔离运行。
- 微服务架构的部署单元。
- CI/CD 流水线里的标准执行环境。
2.2 在 Debian 上安装 Docker Engine
建议在 Lab 1 创建的 Debian VM 里安装。VM 使用 NAT 网络保证能下载镜像。
官方推荐使用 apt 仓库安装:
bash
# 1. 卸载旧版(如果有)
sudo apt remove docker docker-engine docker.io containerd runc
# 2. 安装依赖 + 添加 GPG key
sudo apt update
sudo apt install -y ca-certificates curl gnupg
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg | \
sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
# 3. 添加 Docker 仓库
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
https://download.docker.com/linux/debian $(. /etc/os-release && echo $VERSION_CODENAME) stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# 4. 安装
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
2.3 验证
bash
sudo systemctl status docker # 看是 active (running)
sudo systemctl start docker # 没起来就启动
sudo docker run hello-world # 跑一个最小镜像验证
💡 小技巧 :把当前用户加到
docker组,免去每次写sudo:
bashsudo usermod -aG docker $USER # 重新登录后生效但要注意:
docker组等同于 root 权限(因为可以挂载宿主根目录的容器),生产环境慎用。
三、镜像(Image)
镜像 = 只读模板。它是一组分层(layer)的只读文件系统快照 + 元数据,描述了"启动一个容器需要什么"。
3.1 基本命令
| 命令 | 作用 |
|---|---|
docker images |
列出本地镜像 |
docker search <name> |
在 Docker Hub 上搜索镜像 |
docker pull <name>[:tag] |
拉取镜像,默认 tag 是 latest |
docker inspect <image> |
查看镜像详细元数据(JSON) |
docker save -o xx.tar <image> |
把镜像导出成 tar |
docker load -i xx.tar |
从 tar 导入镜像 |
docker rmi <image> |
删除镜像 |
docker tag <image> <new_tag> |
给镜像打新标签(常用于推送私有仓库) |
docker history <image> |
查看镜像的层(每一条 = 一个 Dockerfile 指令) |
3.2 分层文件系统:Docker 性能的灵魂
一个镜像 ≠ 一个大文件,而是一叠 只读 layer。例如:
[Layer 4] my-app ── 来自 COPY ./app /app
[Layer 3] pip deps── 来自 RUN pip install -r requirements.txt
[Layer 2] python ── 来自 FROM python:3.11
[Layer 1] debian ── python 镜像底层依赖
好处:
- 共享层:10 个 Python 镜像共享同一个 Debian base,硬盘只占一份。
- 增量传输:只有发生变化的 layer 需要重新 pull / push。
- 缓存构建 :
docker build时未变的层直接命中缓存。
这就是为什么 Docker 拉镜像比下载一台 OVA 快几个量级。
3.3 镜像 vs 容器的本质区别
镜像是只读的类(class),容器是可读写的实例(instance)。
容器启动时,Docker 在镜像最上面盖一层 可读写层(container layer),所有运行时改动都写在这一层。删除容器,这一层就丢了,但镜像保持不变。
3.4 进阶:搭建本地 Docker Registry
实验题目要求:"在 VM1 上跑一个本地 registry,从 VM2 拉取镜像"。这模拟的是企业内网私有仓库。
为什么需要私有仓库?
- 公司内网不能访问 Docker Hub。
- 镜像太大,公网拉慢。
- 包含敏感代码或商业秘密。
- 离线部署场景(飞机上、保密机房)。
步骤 (两台 VM 必须在 同一个 NAT Network 里):
VM1(IP 假设为 10.0.1.4):
bash
# 启动一个 registry 容器,监听 5000 端口
docker run -d -p 5000:5000 --name registry registry:2
# 把要分发的镜像打 tag 指向本地仓库
docker tag hello-world 10.0.1.4:5000/hello-world
# 推送
docker push 10.0.1.4:5000/hello-world
VM2:
bash
# 由于是 HTTP(无 TLS),需要先告诉 daemon 这是 insecure registry
sudo nano /etc/docker/daemon.json
json
{
"insecure-registries": ["10.0.1.4:5000"]
}
bash
sudo systemctl restart docker
# 拉取
docker pull 10.0.1.4:5000/hello-world
生产环境当然要配 TLS 证书 + 基础认证,但实验验证完概念已经足够。
四、容器(Container)
4.1 生命周期速查
created ──run──> running ──stop──> stopped ──rm──> 销毁
│ │
│ └──start──> running
└──pause──> paused
4.2 基本命令
| 命令 | 作用 |
|---|---|
docker ps |
列出 运行中 的容器 |
docker ps -a |
列出 所有 容器(含已停止) |
docker run [OPTS] <image> [CMD] |
创建并启动容器 |
docker start <c> / stop <c> / restart <c> |
启停 |
docker rm <c> |
删除(必须先 stop,或加 -f) |
docker rename <old> <new> |
改名 |
docker exec -it <c> <cmd> |
进入容器执行命令 |
docker logs --tail 20 <c> |
查看最近 20 行日志 |
docker stats |
实时资源占用 |
docker inspect <c> |
详细元数据 |
4.3 关键参数
| 参数 | 含义 |
|---|---|
-d |
detached,后台跑 |
-it |
交互式 + 分配伪 TTY,常配合 shell |
--name <name> |
命名,否则 Docker 起一个有趣的随机名 |
-p <host>:<container> |
端口映射 |
-v <vol>:<path> |
挂载卷 |
-e KEY=VAL |
设置环境变量 |
--rm |
容器退出后自动删除(ephemeral 临时容器) |
--network <net> |
指定网络 |
--restart unless-stopped |
重启策略 |
4.4 实战一:hello-world ------ 理解 ephemeral 容器
bash
docker run hello-world
docker ps # 看不到
docker ps -a # 看到,状态是 Exited (0)
docker rm <id>
Q:什么是 ephemeral container?
跑完即走、不留下任何运行时痕迹的容器。常用于一次性任务(构建、迁移、批处理脚本)。
加 --rm 让它跑完自动删除:
bash
docker run --rm hello-world
docker ps -a # 这次连记录都不留
4.5 实战二:docker/welcome-to-docker ------ 理解端口映射
直接跑:
bash
docker run docker/welcome-to-docker
浏览器打开 http://localhost:访问失败。为什么?
容器内部 Nginx 监听 80 端口,但 容器有自己的网络命名空间,宿主机访问不到。需要做端口映射:
bash
docker rm <id>
docker run -p 8080:80 docker/welcome-to-docker
┌──────────── VM (宿主) ────────────┐
│ │
│ 浏览器 ──:8080──> Docker daemon │
│ │ │
│ │ DNAT │
│ ▼ │
│ ┌─── Container ────┐ │
│ │ Nginx :80 │ │
│ └──────────────────┘ │
└───────────────────────────────────┘
打开 http://localhost:8080 就能看到欢迎页。
4.6 实战二的延伸操作(题目要求)
bash
# 1. 删除旧容器
docker rm -f <id>
# 2. 后台跑
docker run -d -p 8080:80 docker/welcome-to-docker
docker ps
# 3. 停
docker stop <id>
# 4. 重启
docker start <id>
# 5. 改名
docker rename <id> welcome
# 6. 用新名 inspect
docker inspect welcome
# 7. 看 20 条日志
docker logs --tail 20 welcome
# 8. 看资源占用
docker stats welcome
# 9. 清理
docker rm -f welcome
4.7 实战三:alpine ------ 理解容器的"无状态"
Alpine 是只有 5 MB 的极简 Linux,开发者最爱用作 base。
bash
docker run -it --name alpine_1 alpine
Q1:你以什么身份登录? → root(Docker 默认)
Q2:你在哪? → 容器内的根文件系统(/),跟宿主完全无关。
在容器内:
sh
echo "alpine says hello" > /file.txt
exit
容器停止了(因为前台进程 sh 退出了)。重启 + 进入:
bash
docker start alpine_1
docker exec -it alpine_1 sh
ls /file.txt # 还在!
关键点 :容器停止 ≠ 数据丢失。只要不 rm,可读写层就还在。
但是:
bash
docker rm alpine_1
docker run -it --name alpine_2 alpine
ls /file.txt # No such file or directory
新容器是从镜像重新生成的,那一层可读写层已经随着 alpine_1 一起被销毁了。
Q:修改容器会改变原镜像吗? → 不会。镜像永远只读,所有修改都在容器的可读写层。这就是 Docker 的"不可变基础设施"哲学。
4.8 综合练习题答案
bash
# 1. 后台跑 welcome_1234
docker run -d -p 1234:80 --name welcome_1234 docker/welcome-to-docker
# 2. 浏览器访问 http://localhost:1234 验证
# 3. 停
docker stop welcome_1234
# 4. 跑 welcome_5678
docker run -d -p 5678:80 --name welcome_5678 docker/welcome-to-docker
# 5. 验证 http://localhost:5678
# 6. 停
docker stop welcome_5678
# 7. 改名
docker rename welcome_1234 welcome_1
docker rename welcome_5678 welcome_2
# 8. 一条命令批量启动
docker start welcome_1 welcome_2
# 9. 一条命令批量删除(先 stop 或 force)
docker rm -f welcome_1 welcome_2
# 10. 验证
docker ps -a
五、数据卷(Volume)
容器是无状态的,但数据库、上传文件、日志这些 必须持久化。Docker 给出三种存储方案:
| 类型 | 命令 | 特点 |
|---|---|---|
| Volume(卷) | -v vol_name:/path 或 --mount type=volume,... |
Docker 管理,最推荐 |
| Bind Mount | -v /host/path:/container/path |
直接挂宿主目录 |
| tmpfs | --tmpfs /path |
内存里,重启即丢 |
5.1 命名卷(Named Volume)
bash
docker volume create volume_1
docker volume ls
docker volume inspect volume_1
inspect 输出中的 Mountpoint 是宿主上的实际存储位置,典型路径 /var/lib/docker/volumes/volume_1/_data。
挂载并使用:
bash
docker run -it --name alpine_1 -v volume_1:/volume_data alpine
# 进入容器
echo "written from the container" > /volume_data/file_1.txt
exit
在 VM 宿主 上:
bash
sudo ls /var/lib/docker/volumes/volume_1/_data
# file_1.txt 在那里
sudo bash -c 'echo "written from the virtual machine" > /var/lib/docker/volumes/volume_1/_data/file_2.txt'
重启容器:
bash
docker start -ai alpine_1
ls /volume_data # file_1.txt, file_2.txt 都在
删容器,新容器挂同卷:
bash
docker rm -f alpine_1
docker run -it --name alpine_2 -v volume_1:/volume_data alpine
ls /volume_data # 数据还在
结论:卷的生命周期独立于容器,删容器不删卷。多个容器可以同时挂同一个卷,实现数据共享。
5.2 匿名卷(Anonymous Volume)
bash
docker run -it --name alpine_3 -v /volume_data alpine
未给卷名,Docker 自动用一个 64 位十六进制 hash 作为卷名:
bash
docker volume ls
# DRIVER VOLUME NAME
# local a3f8e91b2c4d6...
Q:匿名卷和命名卷的本质区别是什么?
- 持久性:都是持久的,删容器不删卷。
- 可发现性:匿名卷的名字是 hash,不利于运维。
- 共享性:你很难再把它挂到另一个容器(除非你记住那串 hash)。
5.3 临时容器 + 匿名卷
bash
docker run --rm -it -v /volume_data alpine
# 退出后
docker volume ls
Q:临时容器退出后,匿名卷会被自动清理吗?
普通
--rm不会 自动清理匿名卷。需要加-v:
bashdocker rm -v <c> # 删容器时清理匿名卷 docker run --rm -v ... # 不冲突,--rm 退出时连同匿名卷一起清理
5.4 卷的真实使用场景
- 数据库容器 :
docker run -v db_data:/var/lib/mysql mysql让 MySQL 重启后数据还在。 - 多容器共享 :Nginx 容器和 PHP-FPM 容器挂同一个
/var/www。 - 跨主机迁移 :备份
/var/lib/docker/volumes/<name>即可。 - 配置注入 :把宿主上的
.env文件 bind mount 进容器。
六、网络(Network)
6.1 三种默认网络
bash
docker network ls
NETWORK ID NAME DRIVER SCOPE
xxxxxxxxxxxx bridge bridge local ← 默认
xxxxxxxxxxxx host host local
xxxxxxxxxxxx none null local
Q:不指定网络时,默认是? → bridge(默认 docker0 桥)。
6.2 none 网络:完全隔离
bash
docker run -it --network none alpine
容器内 ip a 只看到 loopback lo,没有任何对外接口。
- VM ping 容器?❌
- 容器 ping VM?❌
- 容器上网?❌
适用场景:
- 跑高度敏感的离线计算(密钥派生、加解密)。
- 验证应用不依赖网络。
6.3 bridge 网络(默认)
bash
docker run -it --network bridge alpine
ip a
# eth0: 172.17.0.2/16
┌────────── VM 宿主 ──────────┐
│ │
internet ─── enp0s3 │ docker0 桥 172.17.0.1/16 │
│ │ │
│ ├── c1 172.17.0.2 │
│ └── c2 172.17.0.3 │
└──────────────────────────────┘
| 测试 | 结果 |
|---|---|
| VM ping 容器(172.17.0.2) | ✅ |
| 容器 ping VM(172.17.0.1) | ✅ |
| 容器 ping internet | ✅(通过 iptables MASQUERADE) |
| 容器之间通过 IP 互通 | ✅ |
| 容器之间通过名字互通 | ❌ 默认 bridge 不带 DNS 解析 |
动态接入/断开:
bash
docker network disconnect bridge <c>
docker network connect bridge <c>
6.4 host 网络:极致性能 × 极致风险
bash
docker run -it --network host alpine
ip a
# 看到的接口和宿主一模一样!
容器 直接共享宿主网络栈,不再需要端口映射。
bash
docker run --network host docker/welcome-to-docker
# 直接访问 http://<VM_IP> 就能看到 welcome 页面,不再加 :8080
| 测试 | 结果 |
|---|---|
| 容器对外服务 | 直接占用宿主端口(80 就是 80) |
| 容器间隔离 | 极弱,两个 host 网络容器可能争端口 |
| 安全性 | 差,容器能 sniff 宿主全部流量 |
Q:从安全角度看,host 网络合适吗?
不合适。除非你确切知道自己在做什么(比如做网络性能测试、跑 NTP / DHCP 服务器需要直接拿到原始包),否则不要用。
⚠️ Docker Desktop :在 macOS / Windows 上 host 网络 行为不同,因为 Docker Desktop 其实跑在一个 Linux 轻量虚拟机里。
6.5 用户自定义桥(User-Defined Bridge, UDB)
这是 生产环境最推荐 的网络。它和默认 bridge 看起来一样,但有一个杀手级特性:自动 DNS 解析。
bash
# 创建一个 /16 网段的 UDB
docker network create --subnet 172.100.0.0/16 my_bridge_1
# 两个容器都接到这个网络
docker run -dit --name web1 --network my_bridge_1 alpine sleep infinity
docker run -dit --name web2 --network my_bridge_1 alpine sleep infinity
# 在 web1 里直接用名字 ping web2!
docker exec -it web1 sh
# / # ping web2
# PING web2 (172.100.0.3): 56 data bytes
# 64 bytes from 172.100.0.3: seq=0 ttl=64 time=0.073 ms
这就是微服务架构的基础:服务 A 不需要知道服务 B 的 IP,只需要知道服务名。Kubernetes 的 Service DNS 就是这个思想的放大版。
6.6 UDB 之间的隔离
bash
docker network create --subnet 172.200.0.0/16 my_bridge_2
docker run -dit --name web3 --network my_bridge_2 alpine sleep infinity
docker exec -it web1 ping web3
# 失败:跨网络不可达,且没有 DNS 解析
要让 web1 同时能访问 my_bridge_1 和 my_bridge_2:
bash
docker network connect my_bridge_2 web1
docker exec -it web1 ping web3 # 现在通了
一个容器可以同时接多个网络,这就是把微服务拆成"前端网"、"后端网"、"数据库网"的实现机制。
6.7 网络模式连通性总表
| 网络 | 容器↔Internet | 容器↔宿主 | 容器↔容器 | 名字解析(DNS) | 隔离性 |
|---|---|---|---|---|---|
none |
❌ | ❌ | ❌ | --- | 最强 |
bridge |
✅ | ✅ | ✅(同 bridge) | ❌ | 中 |
host |
✅ | 共享 | 共享 | --- | 最弱 |
| UDB | ✅ | ✅ | ✅(同 UDB) | ✅ | 中(可配置) |
七、综合实战:三个真实场景
场景 1:WordPress 全栈(卷 + UDB)
bash
docker network create --subnet 172.30.0.0/16 wp_net
docker volume create wp_db
docker volume create wp_content
docker run -d --name wp_mysql --network wp_net \
-v wp_db:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=rootpw \
-e MYSQL_DATABASE=wp \
-e MYSQL_USER=wp \
-e MYSQL_PASSWORD=wppw \
mysql:8
docker run -d --name wp_app --network wp_net \
-p 8080:80 \
-v wp_content:/var/www/html \
-e WORDPRESS_DB_HOST=wp_mysql \
-e WORDPRESS_DB_USER=wp \
-e WORDPRESS_DB_PASSWORD=wppw \
-e WORDPRESS_DB_NAME=wp \
wordpress
- 浏览器
http://localhost:8080即开即用。 - 删除容器,数据仍在卷里,重新跑同样的命令就恢复。
- WordPress 用主机名
wp_mysql连数据库,不需要 IP------这就是 UDB DNS 的威力。
场景 2:CI 构建用的临时 Python 容器
bash
docker run --rm -v $(pwd):/workspace -w /workspace python:3.11 \
bash -c "pip install -r requirements.txt && pytest"
- bind mount 把当前目录映射进去。
--rm跑完就清。- 这是 GitHub Actions、GitLab CI、Jenkins 容器化 runner 的最常见模式。
场景 3:双层网络隔离(前端公网 + 后端私网)
bash
docker network create frontend
docker network create --internal backend # --internal 即"不能出网"
docker run -d --name api --network backend my-api
docker network connect frontend api # api 跨接两个网络
docker run -d --name web --network frontend -p 80:80 my-web
docker run -d --name db --network backend postgres
web只在frontend,不能直连db。db只在backend,完全不能上网。api横跨两个网络,扮演 BFF / 网关角色。- 这是云上"公有子网 + 私有子网"在 Docker 里的复刻。
八、安全注意事项
容器虽然轻量,但 共享宿主内核 这件事意味着隔离比 VM 弱。容易踩的坑:
| 坑 | 推荐做法 |
|---|---|
| 默认以 root 跑 | Dockerfile 里 USER 1000,或 docker run --user 1000:1000 |
| 暴露不必要的端口 | 只 -p 真正需要的端口;用 UDB 隔离内部服务 |
直接 mount /、/var/run/docker.sock |
等同于把容器 root 升级为宿主 root |
| 跑未审计的公网镜像 | 选官方镜像,扫描漏洞(Trivy、Snyk) |
| 没有资源限制 | --memory=512m --cpus=1.0 防止 OOM 拖垮宿主 |
用 host 网络 |
仅在性能极敏感且可信场景使用 |
资源限制示例:
bash
docker run -d --memory=100m --cpus=0.5 --pids-limit=100 nginx
监控:
bash
docker stats # 实时查看 CPU/内存/网络
九、VM vs 容器对比
| 维度 | 虚拟机 | 容器 |
|---|---|---|
| 虚拟层级 | 硬件 | 操作系统 |
| 内含 OS | 完整 Guest OS | 共享宿主内核 |
| 启动 | 数十秒~分钟 | 毫秒级 |
| 镜像大小 | GB 级 | MB 级 |
| 资源开销 | 重 | 轻 |
| 隔离强度 | 强(硬件级) | 中(命名空间) |
| 安全边界 | 高 | 较低 |
| 典型用途 | 多 OS 共存、合规、传统应用 | 微服务、CI/CD、云原生 |
实际生产 = 两者组合:VM 提供基础设施级隔离(一个客户一个 VM),容器在 VM 内部提供应用级密度(一个 VM 跑 N 个微服务)。这正是 EKS、AKS、GKE 的底层架构。
十、Docker 概念 ↔ 主流云 PaaS 映射表
| Docker 概念 | AWS | Azure | GCP | 说明 |
|---|---|---|---|---|
| Container | ECS Task / EKS Pod | AKS Pod / Container Instance | GKE Pod / Cloud Run Container | 运行中的应用实例 |
| Image | ECR Image | ACR Image | Artifact Registry Image | 打包好的应用工件 |
| Registry | Amazon ECR | Azure Container Registry | Artifact Registry | 镜像分发仓库 |
| Volume | EBS / EFS / Persistent Volume | Managed Disk / Azure Files | Persistent Disk / Filestore | 持久化存储 |
| Network | VPC | VNet | VPC | 虚拟通信层 |
| Port Binding | ALB / NLB + Security Group | NSG + Load Balancer | Firewall + Load Balancer | 服务暴露 |
| User-Defined Bridge | Private Subnet | Private Subnet | Private VPC | 容器内部专用网络 |
| Host Network | Host networking mode | Host networking | Host networking | 共享宿主网络栈 |
| Docker Runtime | containerd (ECS/EKS) | containerd (AKS) | containerd (GKE) | 真正跑容器的引擎 |
| Docker Compose | ECS Compose / K8s manifest | AKS manifest | K8s manifest | 多容器编排 |
| Local Registry | 私有 ECR | 私有 ACR | 私有 Artifact Registry | 内部镜像仓库 |
| Ephemeral Container | AWS Batch / Fargate Task | Container Instance | Cloud Run Job | 一次性任务 |
十一、总结与下一步
这一篇我们走完了容器化的完整版图:
- 容器 = Namespace + Cgroups + 联合文件系统,本质是隔离的进程,不是虚拟的机器。
- 镜像分层 是 Docker 高效分发和构建缓存的核心。
- 容器无状态 ,所有持久化要通过 Volume。
- 网络模式 决定隔离度:
none<UDB<bridge<host,UDB 是生产首选(带 DNS)。 - 多容器协作 靠 UDB + Volume + 端口映射,进一步往上就是 Docker Compose → Kubernetes。
- Docker 概念在云上完全对应,掌握本地 Docker 就掌握了 EKS / AKS / GKE 的一半。
下一步学习路径建议:
- Dockerfile 进阶 :多阶段构建、
.dockerignore、镜像瘦身。 - docker-compose:单文件描述整套服务,从命令式跨越到声明式。
- Kubernetes:当一台 VM 已经跑不下所有容器时的"容器调度操作系统"。
- Helm / Kustomize:管理 K8s YAML 模板。
- Service Mesh(Istio / Linkerd):在更高层管理服务间流量与安全。
- Serverless 容器:AWS Fargate、Cloud Run、Azure Container Apps,连"机器"都不用看见了。
回头看 Lab 1 和 Lab 2,你会发现这两篇笔记串起来正好走了 IaaS → PaaS 的完整跃迁:
物理机 ──虚拟化──> VM (IaaS) ──容器化──> Container (PaaS) ──编排──> K8s ──抽象──> Serverless
每一层都是对下一层资源的进一步抽象,云计算的全部演进,本质上就是不断把"基础设施"对用户隐藏得更彻底。
如果这篇笔记对你有帮助,欢迎点赞、收藏、转发 🙌