发布时间:2023-01-08 14:30
目录
一、为什么需要pod
二、pod实现原理
三、什么是pod
四、pod本质
4.1 关于虚拟机里的应用无缝迁移到容器中
4.2 docker本质
五、pod和Container属性划分
本章将介绍k8s一个重中之重的概念pod
Pod,是 Kubernetes 项目中最小的 API 对象。如果换一个更专业的说法,我们可以这样描述:Pod,是 Kubernetes 项目的原子调度单位。是 Kubernetes 项目中的最小编排单位
Pod,它只是一个逻辑概念。
Pod 里的所有容器,共享的是同一个 Network Namespace,并且可以声明共享同一个 Volume。
如果你能把 Pod 看成传统环境里的“机器”、把容器看作是运行在这个“机器”里的“用户程序”,那么很多关于 Pod 对象的设计就非常容易理解了
我们知道容器可以让我们更好的打包应用,Docker 镜像可以“一次构建,到处运行”,前提是要相同的系统类型。
直接用k8s管理docker不就行了吗,还要搞出一下pod?那我反过来推
首先说一下pod的作用,pod是以一个容器集合方式出现的,可以一个容器,也可以多个容器。
也就是说在k8s世界,最小的调度单位是Pod(即是容器集合方式 ),并非是docker。
Pod作为 Kubernetes 项目中的最小编排单位,既然是编排,那么单单是一下跑多少个容器,这是不够的,还要在必要的时候你能够描述容器之差的”关系“,Pod 对象,其实就是容器的升级版。它对容器进行了组合,添加了更多的属性和字段。这就好比给集装箱四面安装了吊环,使得 Kubernetes 这架“吊车”,可以更轻松地操作它
举个简单的例子,nginx+php,我们一般分了2个容器,但是nginx配置的虚拟主机所在的目录和php目录是一样啊!如果不一样的话,访问php的时候,php会提示找不到文件。k8s上运行nginx和php两个容器,肯定是放同一个节点上,你总不同一个放在node1和个放在node2吧?
还有一个经典的就是war包和tocat的关系,就是我有一个容器是专门放war包的,另一个是专业跑tomcat的,那它们必须在一起吧,必须同一个节点吧,而且在tomcat没运行之前必须跑挂载war包吧。
docker要达处理复杂一点的容器间关系还是太弱了,既然docker不行,那么我就弄一个概念出来,不但把需要运行多少台容器,还把它们的属性、关系等等都进行描述。这样就方便k8s做管理了,也可以处理复杂的关系、生产环境。
这样pod是不是比docker方便很多了,是不是相当于docker的升级版本了?!
我为讲什么需要pod了,这次我讲一个pod实现原理
pod只是一个逻辑概念
Kubernetes 真正处理的,还是宿主机操作系统上 Linux 容器的 Namespace 和 Cgroups,而并不存在一个所谓的 Pod 的边界或者隔离环境。
pod,其实是一组共享了某些资源的容器。
具体的说:Pod 里的所有容器,共享的是同一个 Network Namespace,并且可以声明共享同一个 Volume。
一个有 A、B 两个容器的 Pod,不就是等同于一个容器(容器 A)共享另外一个容器(容器 B)的网络和 Volume 的玩儿法么?
$ docker run --net=B --volumes-from=B --name=A image-A ...
如果真这样做的话,容器 B 就必须比容器 A 先启动,这样一个 Pod 里的多个容器就不是对等关系,而是拓扑关系了。
所以,在 Kubernetes 项目里,Pod 的实现需要使用一个中间容器,这个容器叫作 Infra 容器。在这个 Pod 中,Infra 容器永远都是第一个被创建的容器,而其他用户定义的容器,则通过 Join Network Namespace 的方式,与 Infra 容器关联在一起。这样的组织关系,可以用下面这样一个示意图来表达:
如上图所示,这个 Pod 里有两个用户容器 A 和 B,还有一个 Infra 容器。很容易理解,在 Kubernetes 项目里,Infra 容器一定要占用极少的资源,所以它使用的是一个非常特殊的镜像,叫作:k8s.gcr.io/pause。这个镜像是一个用汇编语言编写的、永远处于“暂停”状态的容器,解压后的大小也只有 100~200 KB 左右。
而在 Infra 容器“Hold 住”Network Namespace 后,用户容器就可以加入到 Infra 容器的 Network Namespace 当中了。所以,如果你查看这些容器在宿主机上的 Namespace 文件(这个 Namespace 文件的路径,我已经在前面的内容中介绍过),它们指向的值一定是完全一样的。
注:Pause容器 全称infrastucture container(又叫infra)基础容器。
上面说了那么多,大概对pod的概念应该也有所了解了吧,不理解的可以看一下k8d官方pod解释
Pod 是 Kubernetes 应用程序的基本执行单元,即它是 Kubernetes 对象模型中创建或部署的最小和最简单的单元。Pod 表示在 集群 上运行的进程。
Pod 封装了应用程序容器(或者在某些情况下封装多个容器)、存储资源、唯一网络 IP 以及控制容器应该如何运行的选项。 Pod 表示部署单元:Kubernetes 中应用程序的单个实例,它可能由单个 容器 或少量紧密耦合并共享资源的容器组成。
就记住一句话就行:
Pod是 Kubernetes 项目中的最小编排单位
很多人把容器跟虚拟机相提并论,他们把容器当做性能更好的虚拟机,喜欢讨论如何把应用从虚拟机无缝地迁移到容器中。
但实际上,无论是从具体的实现原理,还是从使用方法、特性、功能等方面,容器与虚拟机几乎没有任何相似的地方;也不存在一种普遍的方法,能够把虚拟机里的应用无缝迁移到容器中。因为,容器的性能优势,必然伴随着相应缺陷,即:它不能像虚拟机那样,完全模拟本地物理机环境中的部署方法。
所以,这个“上云”工作的完成,最终还是要靠深入理解容器的本质,即:进程。
可是对于容器来说,一个容器永远只能管理一个进程。更确切地说,一个容器,就是一个进程。这是容器技术的“天性”,不可能被修改。所以,将一个原本运行在虚拟机里的应用,“无缝迁移”到容器中的想法,实际上跟容器的本质是相悖的。
这也是当初 Swarm 项目无法成长起来的重要原因之一:一旦到了真正的生产环境上,Swarm 这种单容器的工作方式,就难以描述真实世界里复杂的应用架构了。
所以,你现在可以这么理解 Pod 的本质:
Pod,实际上是在扮演传统基础设施里“虚拟机”的角色;而容器,则是这个虚拟机里运行的用户程序。
然后,你就可以把整个虚拟机想象成为一个 Pod,把这些进程分别做成容器镜像,把有顺序关系的容器,定义为 Init Container。这才是更加合理的、松耦合的容器编排诀窍,也是从传统应用架构,到“微服务架构”最自然的过渡方式。
注意:Pod 这个概念,提供的是一种编排思想,而不是具体的技术方案。所以,如果愿意的话,你完全可以使用虚拟机来作为 Pod 的实现,然后把用户容器都运行在这个虚拟机里。比如,Mirantis 公司的virtlet 项目就在干这个事情。甚至,你可以去实现一个带有 Init 进程的容器项目,来模拟传统应用的运行方式。这些工作,在 Kubernetes 中都是非常轻松的,也是我们后面讲解 CRI 时会提到的内容。
相反的,如果强行把整个应用塞到一个容器里,甚至不惜使用 Docker In Docker 这种在生产环境中后患无穷的解决方案,恐怕最后往往会得不偿失。
你已经非常清楚:Pod,而不是容器,才是 Kubernetes 项目中的最小编排单位。将这个设计落实到 API 对象上,容器(Container)就成了 Pod 属性里的一个普通的字段。那么,一个很自然的问题就是:到底哪些属性属于 Pod 对象,而又有哪些属性属于 Container 呢?
好面提到:Pod 扮演的是传统部署环境里“虚拟机”的角色。这样的设计,是为了使用户从传统环境(虚拟机环境)向 Kubernetes(容器环境)的迁移,更加平滑。
如果你能把 Pod 看成传统环境里的“机器”、把容器看作是运行在这个“机器”里的“用户程序”,那么很多关于 Pod 对象的设计就非常容易理解了。
比如,凡是调度、网络、存储,以及安全相关的属性,基本上是 Pod 级别的。
这些属性的共同特征是,它们描述的是“机器”这个整体,而不是里面运行的“程序”。比如,配置这个“机器”的网卡(即:Pod 的网络定义),配置这个“机器”的磁盘(即:Pod 的存储定义),配置这个“机器”的防火墙(即:Pod 的安全定义)。更不用说,这台“机器”运行在哪个服务器之上(即:Pod 的调度)。
2018年全国高校教师“Python编程、应用及华为大数据”培训班
Proteus 8.9 模拟仿真Arduino控制点亮LED
R语言线性回归模型拟合诊断异常值分析家庭燃气消耗量和卡路里实例带自测题
百度java开发要求有多高?大学本科如何三个月逆袭拿offer
在MATLAB中快速画圆(给出圆心坐标和半径就能直接画的那种)
OpenCV4学习笔记(72)——ArUco模块之aruco标记的创建与检测
九章云极DataCanvas公司荣获机器之心三大奖项,助力产业数智化升级
eslint - vue 项目中 package.json 和 .eslintrc.js 配置