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给映射起来