赞
踩
Pod,是Kubernetes项目中最小的API对象,更准确地说,是Kubernetes项目的原子调度单位。Kubernetes项目的调度器,是统一按照Pod而非容器的资源需求进行计算的。
本质上看,容器就是进程,与之对应,Kubernetes可以认为是一种调度容器的“操作系统”。
Kubernetes项目所做的,其实就是将“进程组”的概念映射到了容器技术中,并使其成为了这个云计算“操作系统”里的“一等公民”。
“超亲密关系”容器的典型特征包括但不限于:互相之间会发生直接的文件交换、使用localhost或者Socket文件进行本地通信、会发生非常频繁的远程调用、需要共享某些Linux Namespace(比如,一个容器要加入另一个容器的Network Namespace)等等。Kubernetes会将具有“超亲密关系”的容器组合成一个Pod,统一调度。
Pod最重要的一个事实是:它只是一个逻辑概念。Kubernetes真正处理的,还是宿主机操作系统上Linux容器的Namespace和Cgroups,而并不存在一个所谓的Pod的边界或者隔离环境。Pod,其实是一组共享了某些资源的容器。Pod里的所有容器,共享的是同一个Network Namespace,并且可以声明共享同一个Volume。
Kubernetes项目里,Pod的实现需要使用一个中间容器,这个容器叫作Infra容器。在这个Pod中,Infra容器永远都是第一个被创建的容器,而其他用户定义的容器,则通过Join Network Namespace的方式,与Infra容器关联在一起。
在Kubernetes项目里,Infra容器一定要占用极少的资源,所以它使用的是一个非常特殊的镜像,叫作:k8s.gcr.io/pause。这个镜像是一个用汇编语言编写的、永远处于“暂停”状态的容器,解压后的大小也只有100~200 KB左右。
而在Infra容器“Hold住”Network Namespace后,用户容器就可以加入到Infra容器的Network Namespace当中了。所以,如果你查看这些容器在宿主机上的Namespace文件,它们指向的值一定是完全一样的。
对于Pod里的容器A和容器B来说:
而对于同一个Pod里面的所有用户容器来说,它们的进出流量,也可以认为都是通过Infra容器完成的。这一点很重要,因为将来如果你要为Kubernetes开发一个网络插件时,应该重点考虑的是如何配置这个Pod的Network Namespace,而不是每一个用户容器如何使用你的网络配置,这是没有意义的。
这就意味着,如果你的网络插件需要在容器里安装某些包或者配置才能完成的话,是不可取的:Infra容器镜像的rootfs里几乎什么都没有,没有你随意发挥的空间。当然,这同时也意味着你的网络插件完全不必关心用户容器的启动与否,而只需要关注如何配置Pod,也就是Infra容器的Network Namespace即可。
对于共享Volume:Kubernetes项目只要把所有Volume的定义都设计在Pod层级即可。
这样,一个Volume对应的宿主机目录对于Pod来说就只有一个,Pod里的容器只要声明挂载这个Volume,就一定可以共享这个Volume对应的宿主机目录。
Pod这种“超亲密关系”容器的设计思想,实际上就是希望,当用户想在一个容器里跑多个功能并不相关的应用时,应该优先考虑它们是不是更应该被描述成一个Pod里的多个容器。
边车sidecar,是容器设计模式里最常用的一种模式,就是我们可以在一个Pod中,启动一个辅助容器,来完成一些独立于主进程(主容器)之外的工作。
Pod,实际上是在扮演传统基础设施里“虚拟机”的角色;而容器,则是这个虚拟机里运行的用户程序。当你需要把一个运行在虚拟机里的应用迁移到Docker容器中时,一定要仔细分析到底有哪些进程(组件)运行在这个虚拟机里。你可以把整个虚拟机想象成为一个Pod,把这些进程分别做成容器镜像,把有顺序关系的容器,定义为Init Container。这才是更加合理的、松耦合的容器编排诀窍,也是从传统应用架构,到“微服务架构”最自然的过渡方式
此文章为3月Day13学习笔记,内容来源于极客时间《深入剖析Kubernetes》
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。