目录

文章目录

  • 目录
  • 为什么需要 Pod
    • 真实操作系统里的例子
    • 进程组概念
    • Pod = “进程组”
  • 为什么 Pod 必须是原子调度单位?
  • Pod要解决的问题
    • 共享网络
    • 共享存储

为什么需要 Pod

真实操作系统里的例子

如果说 Kubernetes 就是操作系统的话,那么我们不妨看一下真实的操作系统的例子。

​例如,一个程序叫做 Helloworld,这个 Helloworld 程序实际上是由一组进程组成的,需要注意一下,这里说的进程实际上等同于 Linux 中的线程。

因为 Linux 中的线程是轻量级进程,所以如果从 Linux 系统中去查看 Helloworld 中的 pstree,将会看到这个 Helloworld 实际上是由四个线程组成的,分别是 {api、main、log、compute}。也就是说,四个这样的线程共同协作,共享 Helloworld 程序的资源,组成了 Helloworld 程序的真实工作情况。

​这是操作系统里面进程组或者线程组中一个非常真实的例子,以上就是进程组的一个概念。

​在真实的操作系统里面,一个程序往往是根据进程组来进行管理的。Kubernetes 把它类比为一个操作系统,比如说 Linux。针对于容器我们可以类比为进程,就是前面的 Linux 线程。那么 Pod 又是什么呢?实际上 Pod 就是我们刚刚提到的进程组,也就是 Linux 里的线程组。

进程组概念

​还是前面那个例子:Helloworld 程序由四个进程组成,这些进程之间会共享一些资源和文件。那么现在有一个问题:假如说现在把 Helloworld 程序用容器跑起来,你会怎么去做?

​当然,最自然的一个解法就是,我现在就启动一个 Docker 容器,里面运行四个进程。可是这样会有一个问题,这种情况下容器里面 PID=1 的进程该是谁? 比如说,它应该是我的 main 进程,那么问题来了,谁又负责去管理剩余的 3 个进程呢?

​这个核心问题在于,容器的设计本身是一种“单进程”模型,不是说容器里只能起一个进程,由于容器的应用等于进程,所以只能去管理 PID=1 的这个进程,其他再起来的进程其实是一个托管状态。 所以说服务应用进程本身就具有“进程管理”的能力。

​比如说 Helloworld 的程序有 system 的能力,或者直接把容器里 PID=1 的进程直接改成 systemd,否则这个应用,或者是容器是没有办法去管理很多个进程的。因为 PID=1 进程是应用本身,如果现在把这个 PID=1 的进程给 kill 了,或者它自己运行过程中死掉了,那么剩下三个进程的资源就没有人回收了,这个是非常非常严重的一个问题。

​而反过来真的把这个应用本身改成了 systemd,或者在容器里面运行了一个 systemd,将会导致另外一个问题:使得管理容器,不再是管理应用本身了,而等于是管理 systemd,这里的问题就非常明显了。比如说我这个容器里面 run 的程序或者进程是 systemd,那么接下来,这个应用是不是退出了?是不是 fail 了?是不是出现异常失败了?实际上是没办法直接知道的,因为容器管理的是 systemd。这就是为什么在容器里面运行一个复杂程序往往比较困难的一个原因。

由于容器实际上是一个“单进程”模型,所以如果你在容器里启动多个进程,只有一个可以作为 PID=1 的进程,而这时候,如果这个 PID=1 的进程挂了,或者说失败退出了,那么其他三个进程就会自然而然的成为孤儿,没有人能够管理它们,没有人能够回收它们的资源,这是一个非常不好的情况。

注意:Linux 容器的“单进程”模型,指的是容器的生命周期等同于 PID=1 的进程(容器应用进程)的生命周期,而不是说容器里不能创建多进程。当然,一般情况下,容器应用进程并不具备进程管理能力,所以你通过 exec 或者 ssh 在容器里创建的其他进程,一旦异常退出(比如 ssh 终止)是很容易变成孤儿进程的。

​反过来,其实可以在容器里面 run 一个 systemd,用它来管理其他所有的进程。这样会产生第二个问题:实际上没办法直接管理我的应用了,因为我的应用被 systemd 给接管了,那么这个时候应用状态的生命周期就不等于容器生命周期。这个管理模型实际上是非常非常复杂的。

Pod = “进程组”

​在 kubernetes 里面,Pod 实际上正是 kubernetes 项目为你抽象出来的一个可以类比为进程组的概念。

​前面提到的,由四个进程共同组成的一个应用 Helloworld,在 Kubernetes 里面,实际上会被定义为一个拥有四个容器的 Pod,这个概念大家一定要非常仔细的理解。

​就是说现在有四个职责不同、相互协作的进程,需要放在容器里去运行,在 Kubernetes 里面并不会把它们放到一个容器里,因为这里会遇到两个问题。那么在 Kubernetes 里会怎么去做呢?它会把四个独立的进程分别用四个独立的容器启动起来,然后把它们定义在一个 Pod 里面。

​所以当 Kubernetes 把 Helloworld 给拉起来的时候,你实际上会看到四个容器,它们共享了某些资源,这些资源都属于 Pod,所以我们说 Pod 在 Kubernetes 里面只有一个逻辑单位,没有一个真实的东西对应说这个就是 Pod,不会有的。真正起来在物理上存在的东西,就是四个容器。这四个容器,或者说是多个容器的组合就叫做 Pod。并且还有一个概念一定要非常明确,Pod 是 Kubernetes 分配资源的一个单位,因为里面的容器要共享某些资源,所以 Pod 也是 Kubernetes 的原子调度单位。

​上面提到的 Pod 设计,也不是 Kubernetes 项目自己想出来的, 而是早在 Google 研发 Borg 的时候,就已经发现了这样一个问题。这个在 Borg paper 里面有非常非常明确的描述。简单来说 Google 工程师发现在 Borg 下面部署应用时,很多场景下都存在着类似于“进程与进程组”的关系。更具体的是,这些应用之前往往有着密切的协作关系,使得它们必须部署在同一台机器上并且共享某些信息。

为什么 Pod 必须是原子调度单位?

我们通过一个例子来解释。

​假如现在有两个容器,它们是紧密协作的,所以它们应该被部署在一个 Pod 里面。具体来说,第一个容器叫做 App,就是业务容器,它会写日志文件;第二个容器叫做 LogCollector,它会把刚刚 App 容器写的日志文件转发到后端的 ElasticSearch 中。

​两个容器的资源需求是这样的:App 容器需要 1G 内存,LogCollector 需要 0.5G 内存,而当前集群环境的可用内存是这样一个情况:Node_A:1.25G 内存,Node_B:2G 内存。

​假如说现在没有 Pod 概念,就只有两个容器,这两个容器要紧密协作、运行在一台机器上。可是,如果调度器先把 App 调度到了 Node_A 上面,接下来会怎么样呢?这时你会发现:LogCollector 实际上是没办法调度到 Node_A 上的,因为资源不够。其实此时整个应用本身就已经出问题了,调度已经失败了,必须去重新调度。

​以上就是一个非常典型的成组调度失败的例子。英文叫做:Task co-scheduling 问题,这个问题不是说不能解,在很多项目里面,这样的问题都有解法。

​比如说在 Mesos 里面,它会做一个事情,叫做资源囤积(resource hoarding):即当所有设置了 Affinity 约束的任务都达到时,才开始统一调度,这是一个非常典型的成组调度的解法。

​所以上面提到的“App”和“LogCollector”这两个容器,在 Mesos 里面,他们不会说立刻调度,而是等两个容器都提交完成,才开始统一调度。这样也会带来新的问题,首先调度效率会损失,因为需要等待。由于需要等还会有外一个情况会出现,就是产生死锁,就是互相等待的一个情况。这些机制在 Mesos 里都是需要解决的,也带来了额外的复杂度。

​另一种解法是 Google 的解法。它在 Omega 系统(就是 Borg 下一代)里面,做了一个非常复杂且非常厉害的解法,叫做乐观调度。比如说:不管这些冲突的异常情况,先调度,同时设置一个非常精妙的回滚机制,这样经过冲突后,通过回滚来解决问题。这个方式相对来说要更加优雅,也更加高效,但是它的实现机制是非常复杂的。这个有很多人也能理解,就是悲观锁的设置一定比乐观锁要简单。

​而像这样的一个 Task co-scheduling 问题,在 Kubernetes 里,就直接通过 Pod 这样一个概念去解决了。因为在 Kubernetes 里,这样的一个 App 容器和 LogCollector 容器一定是属于一个 Pod 的,它们在调度时必然是以一个 Pod 为单位进行调度,所以这个问题是根本不存在的。

Pod要解决的问题

​因为容器之间原本是被 Linux Namespace 和 cgroups 隔开的,所以现在实际要解决的是怎么去打破这个隔离,然后共享某些事情和某些信息。这就是 Pod 的设计要解决的核心问题所在。

所以说具体的解法分为两个部分:网络和存储。

共享网络

在一个Pod中,一个容器 A 和一个容器 B需要共享Network Namespace,Kubernetes会在Pod中额外起一个Infra container小容器来共享整个Pod的Network Namespace。

Infra container 是一个非常小的镜像,大概 100~200KB 左右,是一个汇编语言写的、永远处于“暂停”状态的容器。由于有了这样一个 Infra container 之后,其他所有容器都会通过 Join Namespace 的方式加入到 Infra container 的 Network Namespace 中。

在 Pod 里面,一定有一个 IP 地址,是这个 Pod 的 Network Namespace 对应的地址,也是这个 Infra container 的 IP 地址。所以大家看到的都是一份,而其他所有网络资源,都是一个 Pod 一份,并且被 Pod 中的所有容器共享。这就是 Pod 的网络实现方式。

共享存储

一个 Pod 可以设置一组共享的存储卷。 Pod 中的所有容器都可以访问该共享卷,从而允许这些容器共享数据。卷的存在时间会超出 Pod 中运行的所有容器,并且在容器重新启动时数据也会得到保留。 当 Pod 不再存在时,卷也将不再存在。

Kubernetes—Pod相关推荐

  1. 在Kubernetes Pod中使用Service Account访问API Server

    2019独角兽企业重金招聘Python工程师标准>>> 在Kubernetes Pod中使用Service Account访问API Server 博客分类: Kubernetes ...

  2. 如何查看Kubernetes pod yaml文件的在线语法帮助

    我们在撰写Kubernetes pod的yaml文件时,一定都为Kubernetes yaml文件复杂的语法苦恼过. 其实Kubernetes是提供了很好的在线(online)文档的. 命令: kub ...

  3. 容器编排技术 -- Kubernetes Pod 优先级和抢占

    容器编排技术 -- Kubernetes Pod 优先级和抢占 1 怎么样使用优先级和抢占 2 启用优先级和抢占 3 PriorityClass 3.1 PriorityClass 示例 4 Pod ...

  4. 容器编排技术 -- Kubernetes Pod概述

    容器编排技术 -- Kubernetes Pod概述 1 了解Pod 1.1 Pods如何管理多个容器 1.1.1 网络 1.1.2 存储 2 使用Pod 2.1 Pod和Controller 3 P ...

  5. 容器编排技术 -- Kubernetes Pod 生命周期

    容器编排技术 -- Kubernetes Pod 生命周期 1 Pod phase 2 Pod 状态 3 容器探针 3.1 该什么时候使用存活(liveness)和就绪(readiness)探针? 4 ...

  6. 浅析Kubernetes Pod重启策略和健康检查

    使用Kubernetes的主要好处之一是它具有管理和维护集群中容器的能力,几乎可以提供服务零停机时间的保障.在创建一个Pod资源后,Kubernetes会为它选择worker节点,然后将其调度到节点上 ...

  7. Kubernetes学习总结(11)—— Kubernetes Pod 到底是什么?

    前言 [译]What are Kubernetes Pods Anyway?最近看到了一条关于Kubernetes Pods的推特,来自了不起的Amy Codes(我真的希望这是她的真名): 虽然不是 ...

  8. Kubernetes pod的生命周期

    本文翻译自:Kubernetes: Lifecycle of a Pod 原文出处:Kubernetes: Lifecycle of a Pod - DZone Integration 参考:Cont ...

  9. Kubernetes Pod报错 filed to get sandbox image “k8s.gcr.io/pause:3.6“

    最近工作中在部署Pod后发现无法正常启动,查看Pod详情后看到以下报错信息: Failed to create pod sandbox: rpc error: code = Unknown desc ...

  10. Kubernetes pod 状态出现 ImagePullBackOff 的原因

    通过一个试验作为例子来学习一下. 我们创建一个名为fail 的 deployment,让它故意指向一个实际并不存在的 Docker 镜像: $ kubectl run fail --image=jer ...

最新文章

  1. Day 33 并发编程3
  2. WhatsApp与Gmail用户数均突破10亿大关
  3. CyberLink ColorDirector Ultra(视频调色工具)中文版
  4. 3. Port scanners (端口扫描器 4个)
  5. 【转载】从百度、360、搜狗对新站态度看国内搜索引擎技术现状
  6. 大数据安全分析“架构”
  7. dcdc芯片效率不高的原因_半导体厂商如何做芯片的出厂测试?
  8. p2020开发_2020年最佳开发者社区
  9. matlab数组平方的计算自定义函数_从零开始的matlab学习笔记——(38)简单数论计算函数:取整,gcd,lcm,质数,全排列...
  10. 其实我的直觉告诉了我的未来
  11. 接下来会普及流行能实现《集中授权集中管理,分级授权逐级管理》的标准化权限系统...
  12. 定制WES7紧急修复U盘
  13. halcon轮廓擦除_【Halcon】轮廓处理
  14. 一次 svchost.exe 进程占用大量网络带宽的排查
  15. 西南交大计算机绘图b,网络大学西南交大离线作业计算机绘图B
  16. python strip什么意思_python中strip什么意思
  17. 第二章 软件项目确立
  18. Oracle数据库实训教师评语,教育教学评价系统数据库的设计与实现.doc
  19. 易点易动助力达达-京东到家打通全集团固定资产数字化管理全链条
  20. Java技术Jsoup爬取数据手动登录

热门文章

  1. mediawiki mysql_Windows下安装MediaWiki (iis+php+mysql+mediawiki)
  2. 导入Zip bomb detected
  3. Web3.0世界知识体系分享-免费自动批量生成NFT图片和批量部署NFT
  4. easyui textbox onblur失效
  5. Codeforces 760B Frodo and pillows
  6. html电话号码隐藏样式,打电话不显示号码怎么设置(教你打电话隐藏号码)
  7. Blend for Visual Studio
  8. sample函数—R语言
  9. 97年大学计算机考试是 级,1997年4月等级考试一级笔试试卷、答案
  10. android 9 qq登录,天天练qq登录版