第一章:Docker基础回顾
各位同学,咱们开始上课。这一章我打算带大家快速过一遍Docker的基础知识。你可能会想:「都学高可用容灾了,还讲基础?」嗯,我理解这个疑问。但说实话,我在生产环境里见过太多因为基础不牢导致的翻车事故。所以,咱们还是把地基打扎实了再往上盖楼。
1.1 Docker架构:到底谁在干活?
Docker的架构,说白了就是「客户端-服务端」模式。我刚开始接触时也觉得这概念很虚,直到有一次排查一个容器启动失败的问题,才真正理解了它的价值。
核心组件就三个:
- Docker客户端(Client):你敲命令的那个终端
- Docker守护进程(Daemon):真正干活的,在后台跑着
- Docker仓库(Registry):存镜像的地方,类似GitHub
你想想看,你执行 docker run 的时候,客户端把指令发给守护进程,守护进程去仓库拉镜像,然后创建容器。整个过程就像点外卖——你下单,餐厅做菜,骑手送餐。我在项目中遇到过有人误以为Docker是虚拟机,其实它只是进程级别的隔离,共享宿主机内核。这一点非常重要,后面讲容灾时会反复提到。
关键点:Docker是进程级虚拟化,不是硬件级虚拟化。容器共享宿主机内核,所以Windows宿主机不能直接跑Linux容器(除非用WSL2)。
1.2 三大核心组件:镜像、容器、仓库
镜像(Image)
镜像是一个只读的模板,包含了运行应用所需的一切:代码、运行时、系统工具、库、配置。我个人习惯把镜像想象成「类」——面向对象里的那个类。容器就是「实例」。镜像分层存储,每一层都是只读的。你拉取一个镜像时,只会下载本地没有的层,这就是为什么第二次拉取会快很多。
避坑指南:我曾经在CI/CD流水线里没注意镜像层缓存,每次构建都重新下载所有依赖,导致构建时间长达20分钟。后来改用多阶段构建,把依赖层单独缓存,时间降到了3分钟。记住:RUN apt-get update && apt-get install -y 这种命令要写在一行,否则每一行都会生成一个新层,镜像体积会膨胀。
容器(Container)
容器是镜像的运行实例。你可以启动、停止、删除、暂停它。每个容器都是隔离的,有自己的文件系统、网络、进程空间。嗯,这里要注意:容器停止后数据不会自动丢失,除非你加了 --rm 参数。我见过有人把数据库跑在容器里,容器一停数据全没了,因为没挂载持久化卷。
仓库(Registry)
仓库就是存镜像的地方。Docker Hub是官方的公共仓库,但企业一般用私有仓库,比如Harbor、AWS ECR。我记得有一次生产环境拉镜像特别慢,排查发现是从Docker Hub拉的,而Docker Hub在国内访问不稳定。后来改成用阿里云镜像加速器,问题就解决了。
| 组件 | 类比 | 关键特性 |
|---|---|---|
| 镜像 | 类(Class) | 只读、分层、可复用 |
| 容器 | 实例(Instance) | 可读写、隔离、生命周期短 |
| 仓库 | GitHub | 存储、分发、版本管理 |
1.3 常用命令与生命周期管理
命令这东西,背是背不完的。我建议你记住几个核心的,其他的查文档就行。下面是我日常用得最多的命令:
# 镜像操作
docker pull nginx:latest # 拉取镜像
docker images # 查看本地镜像
docker rmi nginx # 删除镜像
# 容器操作
docker run -d --name my-nginx -p 80:80 nginx # 运行容器
docker ps -a # 查看所有容器(包括已停止的)
docker stop my-nginx # 停止容器
docker start my-nginx # 启动已停止的容器
docker rm my-nginx # 删除容器
# 进入容器
docker exec -it my-nginx /bin/bash # 进入容器内部
# 日志与监控
docker logs -f my-nginx # 实时查看日志
docker stats # 查看资源使用情况
容器的生命周期有五个状态:Created、Running、Paused、Stopped、Deleted。你想想看,一个容器从创建到删除,其实就对应着应用的启动、运行、暂停、停止、销毁。我在做高可用设计时,经常用 docker restart always 策略,让容器崩溃后自动重启。但要注意,这只适用于无状态服务,有状态服务需要更复杂的处理。
警告:不要在生产环境用 docker run --rm 跑数据库容器!容器一停数据就没了。一定要用 -v 挂载持久化卷,或者用 --mount 绑定宿主机目录。
1.4 我的个人经验总结
做Docker基础回顾,我其实想强调三件事:
- 理解分层镜像:镜像层是只读的,容器层是可写的。你修改文件时,其实是把文件从镜像层复制到容器层再修改(写时复制)。这解释了为什么容器内修改文件不影响镜像。
- 网络模式要选对:默认是bridge模式,容器之间通过IP通信。生产环境我一般用自定义网络,因为自带DNS解析,可以用容器名通信。
- 资源限制不能省:不加
--memory和--cpus限制,一个容器可能把宿主机资源吃光。我在项目中遇到过Java应用内存泄漏,把整个宿主机搞挂了,所有容器都受影响。
好了,基础部分就到这里。下一章咱们开始聊Docker Compose和Swarm,那才是真正进入高可用的门槛。记住,基础不牢,地动山摇。这些概念你理解透了,后面的容灾设计才能听得明白。