1、Docker事实
1)容器技术的兴起源于Pass技术的普及
2)Docker公司发布的Docker项目具有里程碑式的意义
3)Docker项目通过容器镜像解决了应用打包这个根本性难题
4)容器本身没有价值,有价值的是容器编排
2、容器到底是怎么回事?
容器其实是一种沙盒技术,沙盒就是能够像集装箱一样,把应用装起来的技术,这样应用与应用之间就因为有了边界而不至于互相干扰,而被装进集装箱的应用也可以被方便地搬来搬去
那这个边界是如何实现的呢?
程序运行起来后计算机执行环境的总和,就是进程。
容器技术的核心功能就是通过约束和修改进程的动态表现,从而为其创造出一个边界,Cgroup技术是用来制造约束的主要手段,而namespace是用来修改进程视图的主要方法
docker run -it busybox /bin/sh //-it 告诉Docker启动容器后需要分配一个文本输入/输出环境 //启动一个容器,在容器里执行/bin/sh,并且分配一个命令行终端跟这个容器交互
每当在宿主机上运行一个/bin/sh程序,操作系统都会给它分配一个进程编号,如PID=100,这个编号是进程的唯一标识。而现在通过Docker把/bin/sh程序运行在一个容器中,Docker会让这些进程只能看到重新计算过的进程编号,比如PID=1,可实际上它们在宿主机的操作系统中,还是原来的第100号进程。这种技术就是Linux里面的Namespace机制
Namespace只是Linux创建新进程的一个可选参数,在Linux系统中创建线程的系统调用时clone()
int pid = clone(main_function, stack_size, SIGCHLD, NULL);//创建一个新的进程并且返回它的进程号pid
当用clone()系统调用创建一个新的进程时,就可以在参数中指定CLONE_NEWPID参数
int pid = clone(main_function, stack_size, CLONE_NEWPID | SIGCHLD, NULL);//创建一个新的进程并且返回它的进程号pid
这时新创建的进程就会看到一个全新的进程空间,在这个进程空间里,它的PID是1。之所以说看到,因为这其实只是一个障眼法,在宿主机真实的进程空间里,这个进程的PID还是真实的数值100
还可以多次执行上面的clone() 调用,这样就会创建多个PID NameSpace,而每个Namespace里的应用进程,都会认为自己是当前容器里的第1号进程,它们既看不到宿主机里真正的进程空间,也看不到其他PID Namespace里面的具体情况
Docker实际上是在创建容器进程时,指定了这个进程所需要启用的一组Namespace参数,这样容器就只能看到当前Namespace所限定的资源、文件、设备、状态。而对于宿主机以及其他不相干的程序,就完全看不见了
namespace | 引入的相关内核版本 | 被隔离的全局系统资源 | 在容器语境下的隔离效果 |
---|---|---|---|
Mount namespaces | Linux 2.4.19 | 文件系统挂接点 | 每个容器能看到不同的文件系统层次结构 |
UTS namespaces | Linux 2.6.19 | nodename 和 domainname | 每个容器可以有自己的 hostname 和 domainame |
IPC namespaces | Linux 2.6.19 | 特定的进程间通信资源,包括System V IPC 和 POSIX message queues | 每个容器有其自己的 System V IPC 和 POSIX 消息队列文件系统,因此,只有在同一个 IPC namespace 的进程之间才能互相通信 |
PID namespaces | Linux 2.6.24 | 进程 ID 数字空间 (process ID number space) | 每个 PID namespace 中的进程可以有其独立的 PID; 每个容器可以有其 PID 为 1 的root 进程;也使得容器可以在不同的 host 之间迁移,因为 namespace 中的进程 ID 和 host 无关了。这也使得容器中的每个进程有两个PID:容器中的 PID 和 host 上的 PID。 |
Network namespaces | 始于Linux 2.6.24 完成于 Linux 2.6.29 | 网络相关的系统资源 | 每个容器用有其独立的网络设备,IP 地址,IP 路由表,/proc/net 目录,端口号等等。这也使得一个 host 上多个容器内的同一个应用都绑定到各自容器的 80 端口上。 |
User namespaces | 始于 Linux 2.6.23 完成于 Linux 3.8) | 用户和组 ID 空间 | 在 user namespace 中的进程的用户和组 ID 可以和在 host 上不同; 每个 container 可以有不同的 user 和 group id;一个 host 上的非特权用户可以成为 user namespace 中的特权用户; |