K8S中Pod的概念和定义

关于 Pod 最重要的一个理解是:它只是一个逻辑概念。也就是说,Kubernetes 真正处理的,还是宿主机操作系统上 Linux 容器的 Namespace 和 Cgroups,而并不存在一个所谓的 Pod 的边界或者隔离环境。那么,Pod 又是怎么被“创建”出来的呢?答案是:Pod,其实是一组共享了某些资源的容器。具体的说:Pod 里的所有容器,共享的是同一个 Network Namespace,并且可以声明共享同一个 Volume,甚至根据pod多资源限制,更加贴近应用,而不必针对每个docker容器做cgroup的限制(这样会更麻烦,也不贴近应用)。
因此可以理解为Pod=windows进程组,一个pod中包含多个容器(单进程),共同完成一个任务,共享一组网络栈和存储卷。当容器故障后,只需要产生新的容器,即可快速接管,而应用容器无需关注它运行所依赖的网络、存储等。如果开发k8s的容器插件,也只需要跟pod打交道,而不用关注容器应用(如nginx)本身。这也是容器比虚拟机灵活、高效的地方。
总结一下,Pod也是k8s管理的最小原子单位,通过调度pod实现一组应用容器的部署。而容器的本质天生就是单进程,基于linux操作系统开发的应用,无论如何也是无法无缝移植到一个容器中,而pod通过共享存储和网络的模型,能够容纳多个容器运行,基本上对等于linux操作系统中进程组。而K8s更像调度各类进程组Pod的指挥中心,k8s更像操作系统级别的。

Pod 网络共享的实现

每个pod中的所有容器共用一套网络设计,只有一个ip地址,这个实现是通过pod默认的infra容器实现的,infra只有几百k的汇编语言,当pod启动时,infra默认首先启动,会处理网络挂载。pod的网络和生命周期依赖于infra容器,当用户容器A、B在pod中运行或关闭,都不用考虑网络的实现,因为pod的生命周期与infra容器密切相关。

多容器组合以及Volume共享

在一个pod中把两个容器组合起来,实现某些操作。譬如在下面涛哥的pod yaml文件中,要启动两个容器war和tomacat。实际如果data文件被绑死到一个tomcat容器,那么更新网站文件,tomcat容器也要更新与数据卷相关的操作,这样及其不便。通过war容器实现war包copy到宿主机的/app目录,然后挂载到容器的app-volume,这样采用initcontainer的方式,在初始化pod是首先启动了war容器,实现了数据卷的copy和挂载。然后再启动tomcat容器时,app-volume已经有war的数据了,tomcat直接使用这个文件启动网站。实现数据和tomcat容器的解耦。这种机制也称之为sidecar。如果实现容器的日志分析,同样的方法,构建一个event容器,从tomcat运行的日志文件中拿到数据,存储到event容器的volume中,实现日志和容器的解耦。

apiVersion: v1
kind: Pod
metadata:
  name: javaweb-2
spec:
  **initContainers**:
  - image: taoge/sample:v2
    name: war
    command: ["cp", "/sample.war", "/app"]
    volumeMounts:
    - mountPath: /app
      name: app-volume
  containers:
  - image: taoge/tomcat:7.0
    name: tomcat
    command: ["sh","-c","/root/apache-tomcat-7.0.42-v2/bin/start.sh"]
    volumeMounts:
    - mountPath: /root/apache-tomcat-7.0.42-v2/webapps
      name: app-volume
    ports:
    - containerPort: 8080
      hostPort: 8001 
  volumes:
  - name: app-volume
    emptyDir: {}

形象化理解:Pod,而不是容器,才是 Kubernetes 项目中的最小编排单位。将这个设计落实到 API 对象上,容器(Container)就成了 Pod 属性里的一个普通的字段。那么,一个很自然的问题就是:到底哪些属性属于 Pod 对象,而又有哪些属性属于 Container 呢?要彻底理解这个问题,你就一定要牢记一个结论:Pod 扮演的是传统部署环境里”虚拟机“的角色。这样的设计,是为了使用户从传统环境(虚拟机环境)向 Kubernetes(容器环境)的迁移,更加平滑。而如果你能把 Pod 看成传统环境里的“机器”、把容器看作是运行在这个“机器”里的“用户程序”,那么很多关于 Pod 对象的设计就非常容易理解了。而如果把 Pod 看成传统环境里的“机器”、把容器看作是运行在这个“机器”里的“用户程序”,那么很多关于 Pod 对象的设计就非常容易理解了。比如,凡是调度、网络、存储,以及安全相关的属性,基本上是 Pod 级别的。

暂无评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注


虚拟化 | 云计算 | 机器学习 | 股市复盘
© 2024 涛哥,版权所有, 京ICP备20014492-2号