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的更多相关文章

  1. Kubernetes — 深入解析Pod对象:基本概念(二)

    作为 Kubernetes 项目里最核心的编排对象,Pod 携带的信息非常丰富.其中,资源定义(比如 CPU.内存等),以及调度相关的字段.在本篇,我们就先从一种特殊的 Volume 开始,来帮助你更 ...

  2. [Kubernetes]深入解析Pod对象

    k8s集群搭建是比较容易的,但是我们为什么要搭建,里面涉及到的内容,我们为什么需要? 这篇文章就尝试来讲讲,我们为什么需要一个Pod,对Pod对象来一个深入解析. 我们为什么需要Pod 我们先来谈一个 ...

  3. Kubernetes — 深入解析Pod对象:基本概念(一)

    在上一篇文章中,我详细介绍了 Pod 这个 Kubernetes 项目中最重要的概念. 现在,你已经非常清楚:Pod,而不是容器,才是 Kubernetes 项目中的最小编排单位.将这个设计落实到 A ...

  4. kubernetes调度之pod优先级和资源抢占

    系列目录 Pod可以拥有优先级.优先意味着相对于其它pod某个pod更为重要.如果重要的pod不能被调度,则kubernetes调度器会优先于(驱离)低优先级的pod来让处于pending状态的高优先 ...

  5. 14. 深入解析Pod对象(一)

    14. 深入解析Pod对象(一) """ 通过前面的讲解,大家应该都知道: Pod,而不是容器,它是 Kubernetes 项目中的最小编排单位.将这个设计落实到 API ...

  6. 15. 深入解析Pod对象(二):使用进阶

    15. 深入解析Pod对象(二):使用进阶 15.1 Projected Volume,投射数据卷 备注:Projected Volume 是 Kubernetes v1.11 之后的新特性 在 Ku ...

  7. kubernetes集群pod使用tc进行网络资源限额

    kubernetes集群pod使用tc进行网络资源限额 Docker容器可以实现CPU,内存,磁盘的IO限额,但是没有实现网络IO的限额.主要原因是在实际使用中,构建的网络环境是往超级复杂的大型网络. ...

  8. Kubernetes对象之Pod

    系列目录 Pod是Kubernetes调度的最小单元.一个Pod可以包含一个或多个容器,因此它可以被看作是内部容器的逻辑宿主机.Pod的设计理念是为了支持多个容器在一个Pod中共享网络和文件系统 因此 ...

  9. 傲视Kubernetes(三):Kubernetes中的Pod

    从本文开始,将正式开始Kubernetes的核心内容学习.首先要了解的是Pod,总共大约分为六篇左右,本篇是第一篇,相信学完之后,我们会对Pod有一个整体的理解. 本文内容: 1.什么是Pod 2.P ...

随机推荐

  1. leetcode166 Fraction to Recurring Decimal

    思路: 模拟. 实现: class Solution { public: string fractionToDecimal(int numerator, int denominator) { long ...

  2. 保存 http request 的数据到数据库表

    开发需求:把 http request 对象的数据保存到数据库中 第一步:编写 RequestInfoService 类,保存方法名是 saveRequestInfo // 保存request信息 p ...

  3. Linux中yum、rpm、configure使用介绍

    安装程序命令介绍 安装包选择策略:能上外网:yum方式.绿色方式->不能上外网:rpm方式.configure方式 1.yum命令yum安装包时,会包所依赖的包也会安装到系统,将源换成163的源 ...

  4. COFF文件格式

    链接器 目录 一 COFF-Common Object File Format-通用对象文件格式... 3 COFF的文件格式与结构体... 4 文件头... 5 numberOfSections(区 ...

  5. PHP高端课程

    关于目后佐道IT教育 http://www.cnblogs.com/itpua/p/7710917.html 目后佐道IT教育的师资团队 http://www.cnblogs.com/itpua/p/ ...

  6. Google Colab的一些注意事项

    1.执行命令行前面加! 当我们使用python解释器时,我们需要不停地在命令行和IDE 之间切换,当我们需要使用命令行工具时.不过,Jupyter Notebook给了我们在notebook中运行sh ...

  7. dinner 后台 nodemon 部署 Koa (关闭everything 安装或排除node_modules) # mysql 没开192.168.x.x 需要设置一下 #Navicat Premium,mysql 数据库版本有要求:mysql-5.7.17.msi 对??的支持

    tip1:新建数据库 记得选 字符集和排序规则 utf8 -- UTF-8 Unicode utf8_general_ci 后台链接部分 1. 全局管理员安装 nodemon,后台热部署(右键 管理员 ...

  8. Gersgorin 圆盘

    将学习到什么 好多.   Gersgorin 圆盘定理   对任何 \(A \in M_n\),我们总可以记 \(A=D+B\),其中 \(D=\mathrm{diag}(a_{11},\cdots, ...

  9. 解决VS2013无法安装ArcObjects10.2的问题

    之前在网上看到的10.1在vs2012安装不上的问题,解决办法是改注册表HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\1 ...

  10. Bootstrap历练实例:大的按钮

    <!DOCTYPE html><html><head> <meta http-equiv="Content-Type" content=& ...