docker的前世今生

本人目前从事云原生运维和开发工作约有 3 年时间,一直没有做系统性的整理。偶然发现这个氛围如此良好的社区,故打算做一些系统性的总结以及个人的经验总结,和大家共同学习。共勉,希望坚持更新,每周一篇好文章。

docker的诞生和使用

docker是什么 ?它是怎么诞生的? 作用是什么 ?就以上问题作出简短回答
Docker一词来自英国口语,意为码头工人(Dock Worker),即从船上装卸货物的人。它不仅是一家公司的名字,同时也是是PaaS提供商dotCloud(2013年更名为docker)开源的一个基于LXC的高级容器引擎,是一种用容器轻松创建、部署和运行应用程序的工具。
在日常工作中,多数人说到docker其实主要指的是Docker引擎技术,其指的是运行和编排容器的基础设施工具。如果经常使用vmware,其可以理解为vmware的ESXi(vmware的核心管理程序),即docker是核心容器运行时。

docker技术的核心组成

Docker 的核心组件包括 Docker Engine、Docker镜像和Docker容器

  • Docker Engine是Docker的核心运行时引擎,负责创建和管理容器。它利用Linux内核的容器特性,实现了轻量级的隔离和资源管理,使得容器间相互独立,并能够高效地共享主机的资源。

  • Docker镜像是一个只读模板,包含了运行应用程序所需的所有文件和设置。镜像可以通过Dockerfile定义和构建,或从Docker Hub(私有仓库)等仓库中获取。镜像可以保存、共享和复制,以便在不同的环境中部署和运行应用程序。

  • Docker容器是基于Docker镜像创建的可执行实例。容器是轻量级的,可快速启动和停止,具有自己的文件系统、网络和进程空间。每个容器都是相互隔离的,可以独立运行,并且与宿主机和其他容器之间共享资源。

    从操作系统角度深入理解dokcer技术实现

    前面提到docker翻译过来是集装箱的意思,容器其实就是一种沙盒技术实现,沙盒就像集装箱一样,封装自己的应用,搬来搬去,达到开箱即用的目的。而应用与之前就需要进行隔离,不能够互相影响,其实现就是基于进程的良好的隔离。对于 Docker 等大多数 Linux 容器来说,Cgroups 技术是用来制造约束的主要手段,而 Namespace 技术则是用来修改进程视图的主要方法。
    根据实际容器运行演示和说明 Cgroups和 Namespaces 技术
    首先 docker run 一个容器 或者 通过 yaml自己发布一个pod。
    待容器运行或者pod 运行后,找到对应的 container id ;docker exec -it /bin/bash 或者 kubect exec -it pod name -n namesapce bash 进入容器。
    如下图,图一中进入容器的1号进程是一个自定义的脚本,这就说明容器的业务进程通过cgroups技术在宿主机实现了隔离,并且我们无法看到宿主机其他进程。而当我们在宿主机上执行docker top container id;见图二,便看到之前图一的一号进程id在宿主机上的进程id是完全不一样的。这种其实就是 Linux 里面的 Namespace 机制实现的,在宿主机上将重新计算的进程号显示出来。

docker的前世今生

docker的前世今生

在 Linux 系统中创建进程的系统调用是 clone()是
int pid = clone(main_function, stack_size, SIGCHLD, NULL);

用 clone() 系统调用创建一个新进程时,就可以在参数中指定 CLONE_NEWPID 参数 ;
int pid = clone(main_function, stack_size, CLONE_NEWPID | SIGCHLD, NULL);
因此新创建的这个进程将会“看到”一个全新的进程空间,在这个进程空间里,它的 PID 是 1。在宿主机真实的进程空间里,这个进程的 PID 还是真实的数值,比如 16890
多次执行上面的 clone() 调用,这样就会创建多个 PID Namespace,而每个 Namespace 里的应用进程,都会认为自己是当前容器里的第 1 号进程,它们既看不到宿主机里真正的进程空间,也看不到其他 PID Namespace 里的具体情况。
说说cgroup针对在实际应用在pod中的体现
如图所示,我们在声明pod中的资源限制其实最终体现在容器上的资源限制,
可以在宿主机上 目录 /sys/fs/cgroup/cpu/kubepods
cat cpu.cfs_quota_us
cat cpu.cfs_period_us
针对以上参数说明

from GPT

  • cpu.cfs_quota_us 命令用于查看 CPU 控制组中设置的 CPU 配额(quota)。该值表示在每个周期内,CPU 对应用程序可使用的时间量。单位是微秒(μs)。如果该值为 -1,则表示没有限制;如果该值为 0,则表示禁止使用 CPU。通常,正整数值表示限制了 CPU 使用时间的百分比。
  • cpu.cfs_period_us 命令用于查看 CPU 控制组中设置的 CPU 周期(period)。该值表示每个周期的长度,也就是时间片的大小。单位同样是微秒(μs)。CPU 配额与周期的比值决定了应用程序可以使用 CPU 的时间比例。例如,如果配额为 50000 μs,周期为 100000 μs,则应用程序最多可以使用 50% 的 CPU 时间。
    综合结果显示只使用了一半的CPU带宽。
    docker的前世今生

docker与虚拟机对比

提起虚拟机,大家都不陌生。针对容器技术,大家觉得是翻版的“虚拟机”,其实不然,实际有一些本质的区别。
docker的前世今生
左边名为Hypervisor 的软件是虚拟机最主要的部分。它通过硬件虚拟化功能,模拟出了运行一个操作系统需要的各种硬件,比如 CPU、内存、I/O 设备等等。然后,它在这些虚拟的硬件上安装了一个新的操作系统,可以是centos ubuntu等等。这样,用户的应用进程就可以运行在这个虚拟的机器中,它能看到的自然也只有 OS 的文件和目录,以及这个机器里的虚拟设备。这就是为什么虚拟机也能起到将不同的应用进程相互隔离的作用。但是实现相同的效果虚拟机消耗的资源比容器实现多的不是一点半点,而且在拉起进程所用的时间也是几十倍的差距。从右边就可以轻易理解容器化技术实现借助docker项目在进程启动的时候加上各种限制参数,达到类似虚拟机实现的效果。总结来说docker使用优点:成本低,轻量化、性能损耗低。
说完docker的优点,再说说其缺点,比如隔离不彻底。虽然进程隔离,可使用不通的镜像(系统)版本,但实际的内核确实共用的。这就对一些服务依赖内核特性的问题暴露出来,需要权衡使用那个内核版本用于生产环境。还有就是时间问题,如果出现宿主机时间同步变慢,同时也会影响容器的时间,然而虚拟机则不会有这影响。

自认为容器隔离技术还没讲明白,下期再补充。

本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 2

写的可能粗糙,如有错误欢迎指正

8个月前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!