Docker是什么呢?
Docker是一个进程,这个进程把他所依赖的东西统统打包在一起,然后运行起来。在 The Twelve-Factor App中,docker的做法是好多原则的印证与实践。例如下面加粗的部分:
- 一份基准代码,多分部署
- 显示声明依赖、配置;
- 在环境中存储配置
- 把后端服务当做附加资源
- 严格分离构建和运行
- 以一个或多个无状态进程运行应用
- 通过端口绑定提供服务
- 通过进程模型进行扩展
- 快速启动和优雅终止可做大话健壮性
- 尽可能报纸开发、预发布、线上环境相同
- 把日志当做事件流
- 后台管理任务当做一次性进程运行
因此,我们在使用docker的时候,不要纠结于是否能进入docker内部看一下,因为docker就是一个进程,他的隔离性很好的为我们解决了环境问题,我们要从运行态的角度去看他。
Docker的实现
Docker使用namespace做隔离,cgroup做资源限制,我觉得理解了namespace就可以理解docker原理的6成,namespace的原理简单总结如下:
namespace
Namespace是什么?
Namespace是Linux用来隔离资源的手段,在同一个namespace中的进程可以感知彼此存在,但感知不到其他空间中的进程。这正是docker所提供给我们的:自己的hostname,自己的网络,PID为1,与其他docker隔离。
namespace的分派是伴随着进程创建的,Linux进程创建主要是clone函数。
Linux的namespace有如下5种,docker正是利用这几种namespace实现了docker的核心原理:
- Mount:CLONE_NEWUTS | CLONE_NEWPID | CLONE_NEWNS 可以在子进程里面mount自己的文件系统。因此,如果我们把自己需要的东西都拷贝到一个新的目录下,并以这个目录为蓝本来创建
- UTS:CLONE_NEWUTS,子进程可以设置自己的hostname
- IPC:CLONE_NEWUTS | CLONE_NEWIPC 隔离不同namespace之间的进程之间的内存、信号量、消息队列
- PID: CLONE_NEWUTS | CLONE_NEWPID,子进程的PID变成了1,PID为1的进程是init,地位非常特殊。他作为所有进程的父进程,有很多特权(比如:屏蔽信号等)
- Network :网桥、veth pair (一头连在网桥上,一头连在docker的network namespace中),IPVLAN驱动。这一块的东西比较多,后面再展开讨论
- User 可以把容器中的uid和真实系统的uid给映射起来