Docker简介:容器化技术发展、Docker架构、Docker与虚拟机对比

大家好,我是这次课程的主讲。咱们直接开聊Docker。说实话,这几年我面试过不少自称会用Docker的工程师,结果一问三不知的情况并不少见。很多人只是会敲几个命令而已。今天这第一课,咱们就把地基打牢。

容器化技术:从物理机到“集装箱”

先说说容器化技术是怎么来的。你想想看,早期的部署方式是什么样?直接在一台物理机上装操作系统,然后部署应用。这叫传统部署。

  • 物理机时代:一台机器一个应用。资源利用率低得可怜。我早期做项目时,一台8核机器就跑了1个Tomcat,CPU使用率常年不到5%。
  • 虚拟机时代:通过Hypervisor虚拟出多个操作系统。每个虚拟机里部署应用。隔离性不错,但每个虚拟机都包含完整的操作系统,占用大量磁盘和内存。
  • 容器时代:共享宿主机内核。进程级别的隔离。启动就是毫秒级。说白了,容器就是一个带着自己运行环境的标准“箱子”。

核心变化:容器化技术的本质是“把应用及其依赖打包成一个标准单元”,实现“一次构建,随处运行”。这和造船用标准集装箱是一个道理。

为什么要用Docker?我个人的体会是,它解决了两个最头疼的问题:“环境不一致”和“交付效率低”。以前开发和运维经常因为“我机器上能跑啊”这句话吵架。Docker直接终结了这个话题。

提示:Docker只是容器化技术的一种实现。还有其他选择比如containerd、CRI-O。但Docker是目前最流行的,生态最完善。

Docker架构:Client-Server模式

Docker的架构并不复杂。它采用的是标准的客户端-服务器(C/S)架构。搞清楚这个,后面学什么命令都有底气。

主要的组件就这么几个:

  • Docker Client:我们敲命令的终端。它把命令发给守护进程。
  • Docker Daemon:后台服务进程。它负责创建、管理、运行容器和镜像。
  • Docker Registry:镜像仓库。类似于代码的GitHub。我们常用的就是Docker Hub。
  • Images(镜像):容器的模板。只读的。
  • Containers(容器):镜像的运行实例。有读写层。

我曾经遇到过一个案例,同事在CI/CD流水线里反复卡在构建阶段,排查了半天发现是Docker Client和Daemon的版本不一致,API通信失败了。嗯,这里要注意版本兼容性。

# 查看Docker版本,确认Client和Server版本
docker version

警告:Docker Daemon如果宕机,所有运行中的容器也会停掉!在线上环境一定要配置daemon的自启动和健康检查。

下面这张图展示了Docker的核心组件和它们之间的交互关系。我建议大家多看几遍。

Docker架构组件关系图 Docker Client Docker Daemon Docker Registry Images (镜像) Containers (容器) 说明 Client 通过 REST API 向 Daemon 发送指令。 Daemon 负责拉取 Registry 中的镜像,并管理容器。 容器是镜像的运行实例,镜像存储在Registry中。

Docker vs 虚拟机:核心差异

很多人喜欢拿Docker和VM对比。这其实不太对,因为它们的出发点完全不同。但为了帮助理解,我列个表对比一下核心差异。你看完就明白了。

特性 虚拟机 (VM) 容器 (Docker)
启动时间 分钟级(需要引导操作系统) 毫秒级
磁盘占用 GB级(包含完整OS) MB级(共享宿主机内核)
性能 有损耗(Hypervisor层) 接近原生
隔离级别 硬件级别(强隔离) 进程级别(轻量隔离)
系统支持 每个VM可以运行不同OS(Windows/Linux) 所有容器必须与宿主机共享相同内核(例如Linux容器不能在Windows内核上直接跑)
资源密度 一台物理机通常运行几个到几十个VM 一台宿主机可运行成百上千个容器

我自己做线上业务时,有一台16核32G的服务器,跑8个4核8G的VM就快扛不住了。但如果换成Docker,同样的机器我轻松跑了30多个容器,CPU和内存的利用率直接翻倍。这就是差距。

一句话总结:虚拟机虚拟的是硬件,容器虚拟的是操作系统。所以容器更轻、更快、更省资源。但如果你需要运行不同内核的应用,比如在Linux上跑Windows程序,那还是得用VM。

为什么要用Docker做批量质控环境?说白了,就是因为它能快速生成大量互相隔离的测试环境。我之前做微服务测试,需要同时启动10个服务实例做压力测试。用虚拟机得等半小时创建,用Docker,一条命令全部搞定。

避坑指南:我踩过的坑

讲完架构和对比,我分享几个实际中容易翻车的地方:

  • 容器内时间同步问题:默认情况下容器使用UTC时间。我曾因日志时间混乱排查了半天。记得挂载/etc/localtime。
  • 文件句柄限制:大量容器同时打开文件时,容易达到系统的fs.file-max限制。一定要提前调整宿主机内核参数。
  • 网络性能损失:桥接网络模式比宿主机网络模式多一层NAT转换。高性能场景建议使用--network=host。

好了,关于Docker是什么、怎么来、以及和VM的区别,就聊到这儿。这些东西是后面所有操作的基础,理解它们比你背一堆命令重要得多。