2.3 Pod

Pod是Kubernetes中创建应用的最小、最简单的基本执行单元。Pod封装了应用程序的容器(一个或多个)、存储资源、网络以及其他相关选项。这表明:

● Kubernetes直接管理Pod,而不是容器。

● Pod可以封装多个协作的容器,类似于Docker Stack。

● 每个Pod仅运行某个应用程序的单个实例,如果要水平扩展,不建议使用Pod部署。

2.3.1 创建Pod

尽管在Kubernetes中可以通过命令来创建对象,但是如果创建对象的参数比较多,本书建议通过声明文件来创建。下面的声明文件用来创建一个镜像为busybox的Pod。

2.3.2 Pod内部多个容器

Pod支持多个协作容器组成一个有凝聚力的服务单元。Pod中的容器自动放置在同一个节点上,共同调度,共享资源和依赖关系,彼此通信,并协调何时可以终止,以及如何终止。Pod具有这种能力,不代表我们可以随意使用这种模式,毕竟在云原生应用中,需要尽量确保每个部件可以自动扩展,并减少彼此的依赖性。而聚合多个容器的Pod则增加了依赖性,所以只能在特定的场景下使用该模式。例如伴生模式下的容器,后文会提到两个容器共享同一个存储卷,从而形成内容管理和内容发布两个容器聚合在同一个Pod中对外透明服务。

图2-2演示了一个Pod内有两个容器,分别是Drupal站点和Drupal后端数据库。但在这种模式下无法横向扩展,只有Drupal站点系统和MySQL数据库分离后在不同的Pod中才能进行扩展。

图2-2 一个Pod多个容器

2.3.3 初始化容器

Pod能够聚合多个容器,应用在容器里面运行,但是它也可能有一个或多个先于应用容器启动的初始化容器(Init container)。

初始化容器与普通容器非常像,除了如下两点:

● 它们总是运行到完成。

● 每个都必须在下一个启动之前成功完成。

如果Pod的初始化容器失败,Kubernetes会不断地重启该Pod,直至初始化容器成功。当然,如果Pod对应的restartPolicy值为Never,则不会重新启动。

在本书所提及的Elasticsearch部署案例中,使用了三个初始化容器,按照以下顺序执行:

● 修正存储卷的权限。

● 修改系统参数vm.max_map_count。

● 修改系统参数ulimit的值。

描述初始化容器:

修正存储卷的权限:

增加系统参数vm.max_map_count到262144:

增加ulimit值:

2.3.4 状态探针

在Kubernetes中,通过kubelet对容器进行持续探测来判断容器是否可用,一旦容器不可用,kubelet将重启该容器。为了更精确地判断容器状态,Kubernetes中提供了就绪探针(Readiness Probe)和存活探针(Liveness Probe)。

存活探针用于判断容器启动就绪后是否还在持续正常服务。业务有可能会因为某种错误而导致系统不可用,或者普通的探测方法不足以判断业务是否正常工作,此时可以通过设置自定义的存活探针来检测。

就绪探针用于判断容器是否可以接受流量,是针对有前端服务的容器来讲的。有些容器可能已经启动完毕,但是业务系统还不能正常处理请求。例如Tomcat启动需要1min,此时要进行存活状态检测将返回不可用,前端服务就不会将请求转给容器。

存活探针的事例代码如下,在该代码中,使用了httpGet方法去探测,访问的path是/healthz,并且在容器启动3s后进行判断,之后每隔3s进行一次探测。

就绪探针和存活探针非常类似,只是将liveness Probe换成readiness Probe。其中几个关键参数说明如下:

● initialDelaySeconds:容器启动后第一次执行探测需要等待多少秒。

● periodSeconds:执行探测的频率。默认间隔是10s,最小1s。

● timeoutSeconds:探测超时时间。默认1s,最小1s。

● successThreshold:探测失败后,最少连续探测成功多少次才被认定为成功。默认是1。对于liveness必须是1。最小值是1。

● failureThreshold:探测成功后,最少连续探测失败多少次才被认定为失败。默认是3。最小值是1。

2.3.5 测试工具

Kubernetes中容器所在的网络与客户端所在的网络是不能直接通信的,这就导致部署一个Pod后,如果需要测试其功能将非常麻烦。为此,Google推出了一个busybox镜像,该镜像含有基本的网络工具,用于在容器网络中测试。

例如,可以通过命令来ping一个名称为test的Pod:

也可以访问容器内的某个网站: