kubernetes之多容器pod以及通信

容器经常是为了解决单一的,窄范围的问题,比如说微服务.然而现实中,一些复杂问题的完成往往需要多个容器.这里我们讨论一下如何把多个容器放在同一个pod里以及容器间的通信

什么是pod

pod是kubernetes里的一个基本概念,可能我们从一开始接触kubernetes的时候就开始接触pod,并被灌输pod是kubernetes里最小的不可分割的工作单元,这里再从多容器的角度对其进行一些基本阐释.

简言之,pod是kubernetes可以部署和管理的最小单元,换言之也就是说如果你想要运行一个容器,你先要为这个容器创建一个pod.同时,一个pod也可以包含多个容器,之所以多个容器包含在一个pod里,前面讲到过的初始容器为普通应用容器准备环境是一种使用场景,往往由于业务上的紧密耦合,一组容器也需要放在同一个pod里.

需要注意的是,以上场景都非必须把不同的容器放在同一个pod里,但是这样往往更便于管理,甚至后面会讲到的,紧密耦合的业务容器放置在同一个容器里通信效率更高.具体怎么使用还要看实际情况,综合权衡.

kubernetes为什么使用pod作为最小单元,而不是container

直接部署一个容器看起来更简单,但是这里也有更好的原因为什么在容器基础上抽象一层.容器是一个存在的实体,并指向一个具体的事物.这个具体的事物可能是一个docker容器,但也可能是一个rtk容器,或者一个Virtlet管理的虚拟机.它们有不同的要求.

更深层的原因是为了管理容器,kubernetes需要更多的信息,比如重启策略,它定义了容器终止后要采取的策略;或者是一个可用性探针,从应用程序的角度去探测是否一个进程还存活着.

基于这些原因,kubernetes架构师决定使用一个新的实体,也就是pod,而不是重载容器的信息添加更多属性,用来在逻辑上包装一个或者多个容器的管理所需要的信息

kubernetes为什么允许一个pod里有多个容器

pod里的容器运行在一个逻辑上的"主机"上,它们使用相同的网络名称空间(也就是说,同一pod里的容器使用相同的ip和相同的端口段区间)和相同的IPC名称空间.它们也可以共享存储卷.这些特性使它们可以更有效的通信.并且pod可以使你把紧密耦合的应用容器作为一个单元来管理.

因此一个应用如果需要多个运行在同一主机上的容器时,为什么为把它们放在同一个容器里呢?首先,这样何故违反了一个容器只负责一个应用的原则.这点非常重要,如果我们把多个应用放在同一个容器里,这将使解决问题变得非常麻烦因为它们的日志记录混合在了一起,并且它们的生命周期也很难管理.因此一个应用使用多个容器将更简单,更透明,并且使应用依赖解偶.并且粒度更小的容器更便于不同的开发团队共享和复用.

这里说到为了解偶把应用分别放在不同容器里,前面我们也强调为了便于管理管紧耦合的应用把它们的容器放在同一个pod里.一会强调耦合,一个强调解偶看似矛盾,实际上普遍存在,高内聚低耦合是我们的追求,然而一个应用的业务逻辑模块不可能完全完独立不存在耦合,这就需要我们从实际上来考量,做出决策.

多容器pod的使用场景举例

Sidecar containers "帮助"主容器,比如日志文件监视器.一个日志监视器构建完成以后,可以由不同的应用来使用.另一个示例是sidecar 容器为主容器加载文件和运行需要的数据

代理,桥接和适配器 使主容器与外部世界联通.比如Apache http服务器或者nginx可承载静态文件.也可以做为一个web的反向代理服务器.

你可以使用一个pod来承载一个多层应用(比如wordpress),但是更建议使用不同的pod来承载不同的层,因这这样你可以为每一个层单独扩容并且把它们分布到集群的不同节点上.

同一pod间的容器通信

把不同的容器放在同一个pod里让它们之间的通信变得非常直接和简单,它们可以通过以下几种方法达到通信目的.

同一pod内的容器共识存储卷

你可以使用一个共享的存储卷来简单高效的地在容器间共享数据.大多数情况下,使用一个共享目录在同一pod里的不同容器间共享数据就够了.

一个标准的同一pod内容器共享存储卷的用例是一个容器往共享存储卷里写入数据,其它的则从共享目录里读取数据

apiVersion: v1 kind: Pod metadata: name: mc1 spec: volumes: - name: html emptyDir: {} containers: - name: 1st image: nginx volumeMounts: - name: html mountPath: /usr/share/nginx/html - name: 2nd image: debian volumeMounts: - name: html mountPath: /html command: ["/bin/sh", "-c"] args: - while true; do date >> /html/index.html; sleep 1; done

这个示例里我们定义了一个存储卷叫作html,它是emptyDir类型的.当一个pod在一个节点上创建的时候,它就被分配,只要pod一直运行在这个节点上它就一直存在(emptyDir生命周期和pod相同).就像它的名字所暗示的一样,它是一个空的目录,第一个容器运行了一个nginx server并且把它挂载到/usr/share/nginx/html,第二个容器使用了一个Debian镜像并把emptyDir挂载到/html.每一秒钟,第二个容器就会把当前日期写入到index.html里,它位于共享存储卷里.当用户发起一个http请求,nginx就会读取它并响应给用户.

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpzgdy.html