K8s中的多容器Pod和Pod内容器间通讯


容器(Container)常被用来解决好比微服务的单个问题,但在实际场景中,问题的解决每每须要多容器方案。本文会讨论将多个容器整合进单个Kubernetes Pod 中,以及Pod中的容器之间是如何通讯的。nginx

Kubernetes Pod 是什么?

首先咱们来探讨下什么是Pod。Pod是Kubernetes中最小的可部署和管理单元。换句话讲,若是须要在Kubernetes中运行单个容器,那么你就得为这个容器建立一个Pod。同时,一个Pod能够包含多个容器,这些容器每每是紧耦合的。怎么样个紧耦合法呢?试着想象这么一个场景,一个Pod中的多个容器表明须要运行在同一个服务器上的多个进程。这种类比是合理的,由于在许多方面,Pod就相似于一台服务器。好比,经过localhost每一个容器能够访问它所在Pod中的其它容器。web

为何Kubernetes将Pod而不是单个容器做为最小可部署单元呢?

尽管直接部署单个容器也许会更容易,但增长Pod这个新的抽象层会带来新的好处。容器是一个真实存在的实体,它表明一个具体的东西。这个“东西”能够是一个Docker容器,也能够是一个rkt容器。每种“东西”都有不一样的用途。为了管理容器,Kubernetes须要更多的信息,好比重启策略(restart policy),它定义了当容器终止了时怎样重启容器;还有活性检测(liveness probe),它定义了如何从应用视角去检测容器中的进程是否活着,好比Web服务器进程是否能响应HTTP请求。浏览器

 

为了不在容器这个已有的实体上增长这些新的属性,Kubernetes架构师们决定使用一个新的实体,那就是Pod。它逻辑地包含一个或多个容器。服务器

为何Kubernetes容许Pod中存在一个或多个容器?

Pod中的容器们运行在一个逻辑“主机”上。他们使用同一个网络命名空间(network namespace,换句话讲,就是一样的IP地址和端口空间),以及一样的IPC(inter-process communication,进程间通讯)命名空间,他们还使用共享卷(shared volume)。这些特征使得Pod内的容器能互相高效地通讯。同时,Pod使得你能够将多个紧耦合的应用容器当作一个实体来管理。网络

 

那么,若是一个应用须要在同一台服务器上运行多个容器,为何不把全部东西放在一个容器里面呢?好吧,首先,这会违反“一个容器一个进程”规范。这个规范很重要,由于当一个容器中有多个进程时,调试会变得很是困难,由于不一样进程的日志会混在一块儿,并且很难去管理这些进程的生命周期。其次,为一个应用使用多个容器会更简单、更直接、能解耦软件依赖。并且,更细粒度的容器能够在团队间复用。架构

多容器Pod的用例

多容器Pod的主要目的是为了支持同时存在的(co-located)及同时被管理的(co-managed)帮助进程(helper process)。帮助进程有几种通用场景:curl

 

  • 边车容器(sidecarcontainer):好比日志或数据变化监视器等。一个团队建立日志监视器(log watcher)后,它能够被各类应用使用。另外一个边车容器的例子是文件或数据加载器,它负责为主容器产生数据。ide

  • 代理(Proxy)、桥(bridge)和适配器(adapter):它们将主容器链接到外部世界。好比,Apache HTTP 服务器或nginx 会读取静态文件。它们还能被用做主容器中的web应用的反向代理(reverseproxy)。微服务

     

当你在Pod中运行多层应用(好比WordPress)时,推荐的方式是为每层使用单独的Pod。最简单的理由是这样你就能够独立地扩展每层,并将他们分布在不一样节点上。工具

Pod 中容器间的通讯

在Pod中运行多个容器,使得它们之间的通讯很是直接。他们本身的通讯有几种方法。

经过共享卷通讯 

在Kubernetes中,Pod中的容器能够将共享卷当作一种简单和高效的共享数据方式。在大多数场景中,使用主机上的一个目录,并在多个容器间共享,是一种高效的方式。 

 

Kubernetes volume(卷)使得在容器重启后数据能被保存下来。卷具备和Pod同样的生命周期。这意味着,只要Pod存在,卷就存在。若是Pod被删除了,即便如出一辙的Pod被建立出来,原来Pod的共享卷也会被销毁,一个新的共享卷会被建立出来。 

进程间通讯(Inter-processCommunication,IPC)

Pod中的容器共享同一个IPC命名空间,这意味着它们可使用标准的进程间通讯方式来互相通讯,好比SystemV信号量和POSIX共享内存。

 

容器间的网络通讯

Pod中的容器能够经过“localhost”来互相通讯,由于他们使用同一个网络命名空间。并且,对容器来讲,hostname就是Pod的名称。由于Pod中的全部容器共享同一个IP地址和端口空间,你须要为每一个须要接收链接的容器分配不一样的端口。也就是说,Pod中的应用须要本身协调端口的使用。

 

在下面的例子中,咱们会建立一个多容器Pod,其中一个容器中运行Nginx,它做为另外一个容器中运行的web应用的反向代理。

(1)步骤1,为nginx配置文件建立一个ConfigMap。从80端口进来的HTTP请求会被转发到localhost上的5000端口。

(2)步骤2:建立一个两容器Pod,一个容器运行nginx,另外一个容器运行简单的web应用。注意咱们只为Pod定义了80端口。端口5000不能被从Pod外部访问到。

 查看pod中的端口空间,能看到有80 和 5000端口。

 

(3)步骤3:将Pod暴露为一个 NodePort服务

 (4)步骤4:确认服务

如今,就可使用浏览器或者curl工具来访问这个web应用了。

nginx容器的80端口上收到的HTTP请求会被转发到web应用容器的5000端口。

相关文章
相关标签/搜索