k8s组件详解之为什么需要pod
pod详解1. 容器的本质隔离(namespace)**简述:**指定该进程需要启动的一组Namespace,容器只能看到当前Namespace限定的资源、文件、设备等,而宿主机以及其他进程透明了。**举例:**如PID namespace(隔离进程号,只能看到本身及子进程),mount namespace(挂载点信息),network Namespace(隔离网络设备及配置)。**存在的问题:*
pod详解
1. 容器的本质
-
隔离(namespace)
简述: 指定该进程需要启动的一组Namespace,容器只能看到当前Namespace限定的资源、文件、设备等,而宿主机以及其他进程透明了。
举例: 如PID namespace(隔离进程号,只能看到本身及子进程),mount namespace(挂载点信息),network Namespace(隔离网络设备及配置)。
存在的问题: 隔离不彻底,在容器中做操作linux内核相关的操作,会对宿主机及其他容器造成影响,如settimeofday修改时钟。所以容器里面能做什么,不能做什么,需要慎重。
-
限制(cgroup)
简述: 除了容器视图的隔离,容器本身占用的资源也应该被限制,否则一个容器把所有宿主机资源占用了,则势必影响到其他容器。
举例: cpu、内存、磁盘、网络宽带等。
存在的问题: 在容器中使用free、top等命令时发现其返回的数据是宿主机的,这在某些场景下是致命的,如我们在使用很多组件的时候,为了满足并发的诉求,通常会使用线程池,而线程池的线程数创建通常是基于系统的cpu创建的,而宿主机的cpu数据往往是容器的几十甚至上百倍,这样该线程池的创建往往不合理,导致出现严重的性能问题。
-
切换进程的根目录(rootfs)
简述: 容器即使开启了mount namespace,但mount namespace修改的容器进程对文件系统挂载点的认知,但原本在宿主机已经存在的挂载点,容器也会继承下来,所以要修改这部分的进程视图,则需要重新挂载宿主机的目录,即重新挂载它的整个根目录"/",
**举例:**docker优先使用privot_root,不支持的情况下使用chroot.
**存在的问题:**rootfs只是一个操作系统包含的文件、配置和目录,不包括内核,而内核指的是操作系统的内核,这意味着应用程序需要配置内核参数、加载额外的内存模块或与内核直接交互。都是与宿主机的直接操作。
2. 为什么需要pod
众所周知,k8s的最小调度单位是pod,在大家都已经熟悉的容器概念下,为什么要抽象一个pod的组件呢来增加认知的成本呢,某种程度上可以认为k8s的流行主要是其解决了生产运维里面各组件、应用之间的关系,这些关系其系统在设计之初就已经对关系模型做了各种抽象。比如web应用于数据库之间的访问关系,负载均衡器与后端服务之间的关系,应用组与机器节点资源的关系。以下常见的几个问题,在未使用k8s的pod进行抽象的情况下,是难以处理的。
-
成组调度问题: 假设现在有两个节点node-1,node-2,node-1剩余3.5G可用内存,node-2剩余2.5G内存,有三个容器应用(A,B,C)有亲密关系,每个应用都需要1G内存,需要成组的部署在一个节点,如果使用docker swarm来运行,可以在B、C两个容器上设置affinity=A的约束,那Swarm调度时,在node-1节点无问题,在node-2节点调度时,A、B启动后,C因内存不够拉不起来。而因为affinity的约束,C又必须在node-2节点启动。
-
对等关系问题: 如果希望多个容器之间共享一个networkspace、并且可以共享一个volumn。在容器层面可以理解为多个容器共享另外一个容器的网络和volumn,通过–net --volumes-from可以实现,但这样会存在容器先后启动顺序的问题,意味着被共享的容器必须要先启动,这样容器之间的对等关系就变成了拓扑关系了。
而pod的抽象本质上就是处理容器的各类关系,成组调度问题的解决在pod中很简单,在pod中可以存在多个容器container,而资源的限制是以pod为单位进行限制。对等关系问题的解决,pod中解决比较巧妙,通过一个中间容器Infra容器,这个容器在pod中永远是第一个被创建,其他容器通过关联Infra容器的方式进行创建。所以在同一个pod中的容器,可以共享网络跟存储。
3. pod的本质
pod在实际中扮演的传统基础设施里面的虚拟机角色,容器则是虚拟机里运行程序。一个pod中可以运行多个容器,如有顺序关系的应用通过init container方式。这样对容器进行编排,也是从传统应用转微服务架构的过渡方式。
更多推荐
所有评论(0)