Pod是Kubernetes项目的原子调度单位
为什么需要Pod?
容器是未来云计算系统中的进程,容器镜像就是这个系统里的".exe"安装包,那Kubernetes就是操作系统。
在一个真正的操作系统里,进程不是独自运行的,而是以进程组的方式组织在一起。对操作系统来说,进程组更方便管理,比如Linux只要将信号SIGKILL信号发送给一个进程组,那么该进程组中的所有进程都会收到这个信号而终止运行。
可以通过下面这个命令查看进程组,进程后面括号里的数字就是它的进程组ID(process group ID)
$ pstree -g
这里有一个叫rsyslogd的程序,它负责的是Linux操作系统里的日志处理,由三个进程组成:一个imklog模块,一个imuxsock模块,一个rsyslogd自己的main函数主进程。这三个进程一定要运行在同一台机器上,否则它们之间基于Socket的通信和文件交换都会出现问题。
那现在如果把rsyslogd这个应用容器化,受限于容器的“单进程模型”(不是指容器里只能运行一个进程,而是指容器没有管理多个进程的能力),这三个模块必须被分别制作成是哪个不同的容器。在这个三个容器运行的时候,它们的设置的内存配额都是1GB。
假设现在kubernetes集群上有两个节点,node1上有3GB内存可用,node2上有2.5GB内存可用。这是假设用Docker Swarm来运行这个程序,为了让这个是三个容器都运行在同一台机器上,就必须在另外两个容器上设置一个affinity=main(与main容器有亲密性)的约束(即它们两个必须与main容器运行在同一台机器上)。然后顺序执行:“docker run main”,"docker run imkloh","docker run imuxsock",创建这三个容器,这三个容器会进入Swarm的待调度队列。然后main容器和imklog容器都出队并被调度到node2上,那当imuxsock出队时,Swarm就懵了,node2仅有0.5GB了,并不足以运行imuxsock容器。
上面就是一个典型的成组调度(gang scheduling)没有被妥善处理的例子
但是在Kubernetes中,Pod是原子调度单位,这就意味着Kubernetes的项目调度器是统一按照Pod而非容器的资源需求进行计算的。
所以像imklog、imuxsock和main函数这是三个容器将组成一个Pod,这样kubernetes项目在调度时,自然就会选择内存等于3GB的node1节点进行绑定。
像容器这样的紧密协作,可以称为“超亲密关系”,这些具有超亲密关系的容器的典型特征包括但不限于:互相之间会发生直接的文件交换,使用localhost或者Socket文件进行本地通信、会发生非常频繁的远程调用,需要共享某些Linux Namespace。
但是也不是所有有关系的容器都属于同一个pod,例如php应用容器和MySQL虽然会发生关系,但是没有必要也不应该部署在同一台机器上,它们更适合做出两个pod。
Pod实现原理
Pod只是一个逻辑概念,Kubernetes真正处理的还是宿主机操作系统上Linux容器的Namespace和Cgroups,而并不存在一个所谓的Pod边界或隔离环境
Pod其实是一组共享了某些资源的容器,Pod里的所有容器,共享的是同一个Network Namespace,并且可以声明共享同一个Volume
在Kubernetes项目里,Pod的实现需要使用一个中间容器,这个容器叫做Infra容器。在Pod中,Infra容器永远都是第一个被创建的容器,而其他用户定义的容器,则通过join Network Namespace的方式,与Infra容器关联在一起,如下图所示
原文地址:https://www.cnblogs.com/yuxiaoba/p/9694821.html