【深入剖析K8s】第五章 1 为什么我们需要Pod
Docker容器存在的问题
Docker容器的本质: ’‘‘Namespace做隔离,Cgroups做限制,rootfS做文件系统”。 我们为啥需要Pod?
# 展示当前系统中正在运行的进程的树状结构
pstree -g
在一个真正的操作系统里,是以进程组的方式‘有原则”地组织在—起。
容器的单进程模型,并不是指容器里只能运行‘‘一个”进程,而是指容器无法管理多个进程。这是因为容器里PID=1的进程就是应用本身,其他进程都是这个PlD=1进程的子进程。
- 容器的资源调度上,对于超亲密关系的容器的调度存在难度。
- Pod在Kubemetes项目里还有更重要的意义’那就是容器设计模式。
多容器的Pod
所有“超亲密关系”的容器都属于同一个Pod。可以把容器间的这种紧密协作称为超亲密关系。这些具有‘超亲密关系”的容器的典型特征包括但不限于:
- 互相之间会发生直接的文件交换、
- 使用localhost或者Sockct文件进行本地通信
- 发生非常频繁的远程调用
- 需要共享某些LinuxNamespace(比如—个容器要加人另—
个容器的NetworkNamespace)
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里的多个容器就不是对等关系。
在Kubemetes项目里’Pod的实现需要使用—个中间容器’这个容器叫作Infra容器。在这个Pod中Infra容器永远是第—个被创建的容器,用户定义的其他容器则通过Jojn Network Namespace的方式与Infra容器关联在—起。
Infra容器—定要占用极少的资源,所以它使用的是—个非常特殊的镜像’
叫作k8s.gcr.io/pause。这个镜像是—个用汇编语言编写的,永远处于“暂停’,状态的容器
网络、Volume 都是真的Pod 来定义的。Kubemetes项目只要把所有Volume的定义都设计在Pod层级即可。
Pod这种‘超亲密关系”容器的设计思想’实际上就是希望,当用户想在一个容器里运行多个功能无关的应用时,应该优先考虑它们是否更应该被描述成—个Pod里的多个容器。
举例说明Pod
1 是wAR包与web服务器
现在有—个JavaWeb应用的WAR包’它需要放在TOmcat的webapps目录下运,那该如何处理这个组合关系呢。
两个容器都挂载了shared-data 的Volume。
这就是nginx-container 可以从它的/usr/share/ngjnx/html目录中读取到debian-container 生成的 indexhtml文件的原因。
2
在Pod中所有Init Container定义的容器’都会比speccontainers定义的用户容器先启动。并且Init Container容器会按顺序逐一启动,而直至它们都启动并且退出了,用户容器才会启动。
我执行了—句cp /sample.war /app,把应用的WAR包复制到/app目录下’然后退出
而后这个/app目录就挂载了一个名叫app-volume的Volume。
等Tomcat容器启动时,它的webapps目录下就—定会存在sample.war文件:这个文件正是WAR包容器启动时复制到这个Volume里面的,而这个Volume是被这两个容器共享的。
总结:
- Kubemetes项目中Pod的实现原理: In仕a容器永远是第—个被创建的容器’用户定义的其他容器则通过JojnNetworkNamespace的方式与InfTa容器关联在—起。
- Pod 的本质: Pod实际上是在扮演传统基础设拖里‘‘虚拟机’’的角色’容器则是这个虚拟机里运行的用户程序。
- 容器与虚拟机几乎没有任何相似之处。虚拟机里运行的应用,是在systemd或者supervisord管理之下的一组进程。