大家好,我是秋意零。
😈 CSDN作者主页
👿 简介
容器解决了应用打包的这个根本难题
当然还要其它应用场景,这里只是说明一个举例。
紧跟上面的例子:
容器解决了应用打包的这个根本难题
专业名词:
容器本身没有太大价值,有价值的是“容器编排” (相当于是说,技术本身没有价值,价值在于解决实际问题)
这里简单提一嘴: Kubernetes 可以看作是操作系统,而容器就是应用程序进程
可能觉得 Cgroups 和 Namespace 这两个概念很抽象,我们一起动手实践一下,就很容易理解这两项技术了。
我们使用 docker run
运行一个镜像容器,-it
参数是分配一个文本输入/输出环境,TTY
[root@master01 ~]# docker run -it busybox /bin/sh
/ # ps
PID USER TIME COMMAND
1 root 0:00 /bin/sh
7 root 0:00 ps
可以看到,我们第一个进程号是 PID=1
,并且运行的是 /bin/sh
命令,还有一个就是我们刚才执行的 ps
命令可以看到,我们已经被 Docker 隔离在一个跟宿主机完全不同的环境当中。
宿主机上我们执行 ps 命令可以看到,宿主机上有个进程,这个进程是我们运行容器时所使用的命令,也代表了我们容器也是一个进程表现出来的,所以 容器的本质是一个进程
。
[root@master01 ~]# ps -aux | grep "/bin/sh"
...
root 97285 0.3 0.2 933264 21796 pts/0 Sl+ 11:33 0:00 docker run -it busybox /bin/sh
...
为了表现这个容器是进程我们做一个实验
docker run -it busybox /bin/sh
这样一条命令ps -aux | grep "/bin/sh"
找到这里的 docker run -it busybox /bin/sh
进程,执行 kill -9 97285
(这里通过 ps 命令可以看到我的容器 PID 是97285)杀掉这个进程,如图可以看到 docker run -it busybox /bin/sh
进程退出了,说明了 容器的本质是一个进程
。/bin/sh
程序时,操作系统都会给它分配一个进程编号,比如 PID=1000。 进程编号具有唯一标识,就像员工的工号,所以我们可以看作 /bin/sh 是公司里的第 1000 名员工,而 1 号员工就是老板,管理全局的人。/bin/sh
程序运行在一个容器中。这时,Docker 就会在这个 1000 号员工入职时给他一个“障眼法”,让他永远看不到前面的其他 999 个员工,更看不到老板。这样,他就会以为自己第 1 号员工。这种机制,其实就是对被隔离应用的进程空间做了手脚,也就是使用了 Linxu 中的 Namespace 技术。
这种 Namespace 使用方式,其实是 Linux 创建新进程的一个可选参数,比如:
# 创建一个新的进程,并且返回它的进程号 pid
int pid = clone(main_function, stack_size, SIGCHLD, NULL);
而当我们用 clone() 系统调用创建一个新进程时,就可以在参数中指定 CLONE_NEWPID 参数(新PID),比如:
int pid = clone(main_function, stack_size, CLONE_NEWPID | SIGCHLD, NULL);
这时,新创建的这个进程将会“看到”一个全新的进程空间,在这个进程空间里,它的 PID 是 1。之所以说“看到”,是因为这只是一个“障眼法”,在宿主机真实的进程空间里,这个进程的 PID 还是真实的数值,比如 100。
这,就是 Linux 容器最基本的实现原理了
Docker 容器这个听起来玄而又玄的概念,实际上是在创建容器进程时,指定了这个进程所需要启用的一组 Namespace 参数。这样,容器就只能“看”到当前 Namespace 所限定的资源、文件、设备、状态,或者配置。而对于宿主机以及其他不相关的程序,它就完全看不到了。
所以说,容器,其实是一种特殊的进程而已。
相信大家学容器时都看过这个虚拟机和容器的对比图。
相信你此刻已经会心一笑:容器隔离不过都是“障眼法”罢了。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。