容器和虚拟机很像,在很长一段时间里,我就是把容器当作一个小巧、容易配置的虚拟机来使用的。
实际上,虚拟机是在主机操作系统上又运行了一个操作系统,虚拟机中的应用是运行在虚拟机的操作系统中的。而容器中的应用是直接运行在主机操作系统中的,只是容器借助主机操作系统对每个容器进行资源隔离、性能约束等操作。
容器使用Linux的Namespace技术,将容器内外的资源隔离开来,容器里的进程仍然运行在主机的操作系统上,以进程隔离为例:
容器相当于一个隔离箱,容器内的进程只能与容器内的进程通信。同样的,容器还隔离了网络、用户、文件系统等信息,以致于在容器内做什么完全不会影响到主机,这就达到了容器封装的目的。
docker用Linux的另一个核心技术cgroups限制、统计某个容器资源使用量。
光隔离也不行,容器还需必要的通信,docker提供以下几种网络模式:
Libnetwork常见的网络模式 | 作用 | 业务场景 |
---|---|---|
null空网络模式 | 不提供任何容器网络 | 处理一些保密数据,出于安全考虑,需要一个隔离的网络环境执行一些纯计算任务 |
bridge桥接模式 | 使得容器和容器之间网络可以互通 | 容器需要实现网络通信或者提供网络服务 |
host主机网络模式 | 让容器内的程序可以使用到主机的网络 | 容器需要控制主机网络或者用主机网络提供服务 |
container网络模式 | 将两个容器放到同一网络空间中,可以直接通过localhost本地访问 | 两个容器之间需要直接通过localhost通信,一般用于网络接管或代理场景 |
默认情况,docker为bridge桥接模式,启动容器时可以将容器的某个端口映射到主机上,这相当于host主机网络模式。
docker的文件系统也比较有意思,当我们进入docker容器内部,来到根目录,看起来就好像是一个操作系统的根目录一样,但这只是假像,当我们操作docker内部的文件系统,只不过是主机上一个普通的目录/var/lib/docker/volumes/对应的卷/_data/
。
docker的文件系统还有一个有趣的地方是,它是分层的。镜像层只读,容器层可读写。如果多个容器都是由同一个公共镜像构建出来的,那么它只需存储一次这个公共镜像即可,这相比虚拟机可以节省很多存储空间。
https://github.com/worker24h/containerc实现了一个简单的容器,适合学习。