[Kubernetes]深入解析Pod
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容器(Infra容器占用极少的资源,它的镜像时用汇编语言编写的,永远处于“暂停”状态的容器)。在Pod中,Infra容器永远都是第一个被创建的容器,而其他用户定义的容器,则通过join Network Namespace的方式,与Infra容器关联在一起,如下图所示,对于同一个Pod里面的所有用户容器,它们的进出流量都是通过Infra容器完成的。
在Infra容器Hold住Network Namespace后,用户容器就可以加入到Infra容器的Network Namespace中。对于Pod里容器A和容器B来说
- 它们可以直接使用localhost进行通信
- 它们看到的网络设备跟infra容器看到的完全一样
- 一个Pod只有一个IP地址(即这个Pod的Network Namespace对应的IP地址)。其他所有网络资源,都是一个Pod一份,并且被该Pod中的所有容器共享
- Pod的生命周期只跟Infra容器一致,而与容器A和容器B无关
Pod中重要字段含义和用法
Pod是Kubernetes的最小编排单位,这个设计落实到API对象上,容器(Container)就成了Pod属性里的一个普通的字段,那么哪些属性属于Pod对象,又有哪些属性属于Container对象?
Pod扮演的是传统部署环境里虚拟机的角色,这样的设计是为了使用户从传统环境(虚拟机环境)向Kubernetes(容器环境)的迁移更加平滑。那也可以把Pod看成传统环境里的“机器”,把容器看作是运行再这个“机器”里的“用户进程“
凡是调度、网络、存储以及安全相关的属性,基本上都是Pod级别的, 它们描述的是“机器”这个整体,而不是里面运行的“程序”
NodeSelector:一个供用户将Pod与Node进行绑定的字段
apiVersion: v1
kind: Pod
……
spec:
nodeSelector:
disktype: ssd ##这个pod只能运行再携带了“disktype:ssd”标签的节点上,否则调度失败
NodeName:
一旦Pod这个字段被赋值,Kubernetes项目就会认为这个Pod已经经过了调度,调度的结果就是复制节点的名字。这个字段一般由调度器负责设置
HostAliases:定义了Pod的hosts文件里的内容
在Kubernetes项目中,如果要设置hosts文件里的内容,一定要通过下面这种方法,否则如果直接修改了hosts文件的话,在Pod被删除重建以后,kubelet会自动覆盖掉被修改的内容
apiVersion: v1
kind: Pod
……
spec:
hostAliases:
- ip: "10.1.2.3"
hostnames:
- "foo.remote"
- "bar.remote"
……
凡是跟容器的Linux Namespace相关的属性,也一定是Pod级别的
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
shareProcessNamespace: true #共享PID Namespace
containers:
……
凡是Pod中的容器要共享宿主机的Namespace也一定是Podc级别的定义
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
hostNetwork: true #共享宿主机Network Namespace
hostIPC: true #共享宿主机IPC Namespace
hostPID: true #共享宿主机PID Namespace
containers:
……
Pod的生命周期
- Pending:Pod的YAML文件已经提交给了Kubernetes,API对象已经被创建并保存在Etcd当中,但是这个Pod里有些容器因为某种原因而不能被顺利创建,比如调度不成功
- Running:Pod已经调度成功,跟一个具体的节点绑定,它包含的容器都已经创建成功,并且至少有一个正在运行中
- Succeeded: Pod里所有容器都正常运行完毕,并且已经退出了,一次性任务最常见
- Failed:Pod里至少有一个容器以不正常的状态(非0的返回码)退出
- Unknown:Pod状态不能持续地被kubelet汇报给kub-apiserver,很可能是Master和Kubelet之间通信出了问题
[Kubernetes]深入解析Pod的更多相关文章
- Kubernetes — 深入解析Pod对象:基本概念(二)
作为 Kubernetes 项目里最核心的编排对象,Pod 携带的信息非常丰富.其中,资源定义(比如 CPU.内存等),以及调度相关的字段.在本篇,我们就先从一种特殊的 Volume 开始,来帮助你更 ...
- [Kubernetes]深入解析Pod对象
k8s集群搭建是比较容易的,但是我们为什么要搭建,里面涉及到的内容,我们为什么需要? 这篇文章就尝试来讲讲,我们为什么需要一个Pod,对Pod对象来一个深入解析. 我们为什么需要Pod 我们先来谈一个 ...
- Kubernetes — 深入解析Pod对象:基本概念(一)
在上一篇文章中,我详细介绍了 Pod 这个 Kubernetes 项目中最重要的概念. 现在,你已经非常清楚:Pod,而不是容器,才是 Kubernetes 项目中的最小编排单位.将这个设计落实到 A ...
- kubernetes调度之pod优先级和资源抢占
系列目录 Pod可以拥有优先级.优先意味着相对于其它pod某个pod更为重要.如果重要的pod不能被调度,则kubernetes调度器会优先于(驱离)低优先级的pod来让处于pending状态的高优先 ...
- 14. 深入解析Pod对象(一)
14. 深入解析Pod对象(一) """ 通过前面的讲解,大家应该都知道: Pod,而不是容器,它是 Kubernetes 项目中的最小编排单位.将这个设计落实到 API ...
- 15. 深入解析Pod对象(二):使用进阶
15. 深入解析Pod对象(二):使用进阶 15.1 Projected Volume,投射数据卷 备注:Projected Volume 是 Kubernetes v1.11 之后的新特性 在 Ku ...
- kubernetes集群pod使用tc进行网络资源限额
kubernetes集群pod使用tc进行网络资源限额 Docker容器可以实现CPU,内存,磁盘的IO限额,但是没有实现网络IO的限额.主要原因是在实际使用中,构建的网络环境是往超级复杂的大型网络. ...
- Kubernetes对象之Pod
系列目录 Pod是Kubernetes调度的最小单元.一个Pod可以包含一个或多个容器,因此它可以被看作是内部容器的逻辑宿主机.Pod的设计理念是为了支持多个容器在一个Pod中共享网络和文件系统 因此 ...
- 傲视Kubernetes(三):Kubernetes中的Pod
从本文开始,将正式开始Kubernetes的核心内容学习.首先要了解的是Pod,总共大约分为六篇左右,本篇是第一篇,相信学完之后,我们会对Pod有一个整体的理解. 本文内容: 1.什么是Pod 2.P ...
随机推荐
- SPOJ1716 GSS3(线段树)
题意 Sol 会了GSS1,GSS3就比较无脑了 直接加个单点修改即可,然后update一下 /* */ #include<cstdio> #include<cstring> ...
- Android 8.0 NotificationChannel 采坑实例
Android O 上Notification的新特性: 通知通道功能 1. 简介: 通知通道功能使开发者管理自己应用的通知成为一个组或者一个通道,用户可以通过通知通道完成设置通知,如:阻止所有通知, ...
- uvm_pkg——老板,打包带走
Thus spake the master programmer: “After three day without programming, life becomes meaningless.” 编 ...
- FZU 1977 Pandora adventure (插头DP,常规)
题意:有一个n*m矩阵,其中有些格子必走,有些格子不可走,其他格子是可走也可不走,问有多少条哈密顿回路? 思路: 本来是一道很简单的题,代码写多了连白痴bug都查不出了,竟然用i>=ex& ...
- vijos 1034 家族(水题日常)
描述 若某个家族人员过于庞大,要判断两个是否是亲戚,确实还很不容易,现在给出某个亲戚关系图,求任意给出的两个人是否具有亲戚关系. 规定:x和y是亲戚,y和z是亲戚,那么x和z也是亲戚.如果x,y是亲戚 ...
- python一周速成学习笔记
目录 一:语法元素 1.注释,变量,空格的使用 2.输入函数,输出函数 3.分支语句,循环语句 4.保留字in,同步赋值 5.import与def以及turtle库 6.eval函数与repr函数 二 ...
- Android(java)学习笔记145:Handler消息机制的原理和实现
联合学习 Android 异步消息处理机制 让你深入理解 Looper.Handler.Message三者关系 1. 首先我们通过一个实例案例来引出一个异常: (1)布局文件activity_m ...
- k sum(lintcode)
没通过的代码: class Solution { public: /* * @param A: An integer array * @param k: A positive integer (k & ...
- jquery操作滚动条滚动到指定元素位置 scrollTop
$('.brand_t a').bind('click',function(){ if($(this).attr('title1')){ var toChar = $(this).attr('titl ...
- ios之UITabelViewCell的自定义(代码实现)
在用到UITableVIew的时候,经常会自定义每行的Cell 在IOS控件UITableView详解中的下面代码修改部分代码就可以实现自定义的Cell了 [cpp] view plaincopy - ...