3.4.1 Pod概览
理解Pod
Pod是kubernetes中可以创建和部署的最小也最简的单位。
Pod代表着集群中运行的进程。
Pod中封装着应用的容器,存储、独立的网络IP,管理容器如何运行的策略选项。
Pod代表着部署的一个单位:kubernetes中应用的一个实例,可能由一个或多个容器组合在一起共享资源。
Pod中如何管理多个容器
Pod中可以同时运行多个进程(作为容器运行)协同工作。
同一个Pod中的容器会自动的分配到同一个Node上。
同一个Pod中的容器共享资源、网络环境和依赖,它们总是被同时调度。
例如:你有一个容器作为Web服务器运行,需要用到共享的Volume,有另外一个sidecar容器来从远端获取资源更新这些文件。
Pod中可以共享两种资源:网络和存储。
网络
每个Pod中都会被分配一个唯一的IP地址。
Pod中的所有容器共享网络空间,包括IP地址和端口。
Pod内部的容器可以使用localhost互相通信。
Pod中的容器与外界通信时,必须分配共享网络资源(例如使用宿主机的端口映射)。
存储
可以为一个Pod指定多个共享的volume。
Pod中的所有容器都可以访问共享的volume。
Volume也可以用来持久化Pod中的存储资源,防止容器重启后文件丢失。
使用Pod
当Pod被创建后,它会被KUbernetes调度到集群的Node上。直到Pod的进程终止、被删除、因为缺少资源被驱逐或者Node故障之前都会保持在那个Node上。
注意:重启Pod中的容器和重启Pod不是一回事。Pod只提供容器的运行环境和保持容器的运行状态,重启容器不会造成Pod重启。
Pod不会自愈。
如果运行Pod的Node故障,或者是调度器本身故障,这个Pod就会被删除。
如果Pod所在Node缺少资源或者Pod处于维护状态,Pod也会被驱逐。
在Kubernetes中通常使用Controller来管理Pod。
Pod和Controller
Controller可以创建和管理多个Pod,提供副本管理、滚动升级和集群级别的自愈能力。
如果一个Pod出现故障,Controller就能自动将该节点上的Pod到其他健康的Node上。
包含一个或多个的Controller实例:
- Deployment
- StatefulSet
- DaemonSet
通常,Controller会用你提供的Template来创建相应的Pod。
3.4.2 Pod解析
什么是Pod?
Docker是最常用的运行时环境。
Pod中共享的环境包括Linux的namespace、cgroup和其他可能的隔绝环境。
Pod中的容器共享IP地址和端口号,它们之间可以使用localhost互相发现。可以通过进程间互相通信(例如SystemV信号或者POSIX共享内存)。
不同Pod之间的容器具有不同的IP地址,不能直接通过IPC通信。
Pod中容器也有访问共享Volume的权限,这些volume会被定义为Pod的一部分并挂载到应用容器的文件系统中。
Pod中的容器共享namespace和volume,不支持共享PID的namespace。
Pod被创建后,被分配一个唯一的ID(UID),调度到节点上,并一直维持期望的状态直到被终结或者被删除。
Volume和Pod有着相同的生命周期(当其UID存在时)。
当Pod因为某种原因被删除或者被新创建的相同的Pod取代,它相关的东西(例如volume)也会被销毁和再创建一个新的volume。
Pod中应用容器的hostname被设置成Pod的名字。
通常单个Pod中不会运行一个应用的多个实例。
其他替代选择
为什么不直接在一个容器中运行多个应用程序呢?
- 透明。让Pod中的容器对基础设施可见。以便基础设施为这些容器提供服务,例如进程管理和资源监控。这可以为用户带来极大的便利。
- 解耦软件依赖。每个容器都可以进行版本管理、独立编译和发布。
- 使用方便。用户不必运行自己的进程管理器,还要担心错误信号传播等。
- 效率。因为由基础架构提供更多的职责,容器变的更加轻量级。
Pod的终止
示例流程如下:
- 用户发送删除pod的命令,默认宽限期是30秒;
- 在Pod超过该宽限期后API server就会更新Pod的状态为“dead”;
- 在客户端命令行上显示的Pod状态为“terminating”;
跟第三步同时,当kubelet发现pod被标记为“terminating”状态时,开始停止pod进程:
i.如果在pod中定义了preStop hook,在停止pod前会被调用。如果在宽限期过后,preStop hook依然在 运行,第二步会再增加2秒的宽限期;<br /> ii.向Pod中的进程发送TERM信号;<br /> 5.跟第三步同时,该Pod将从该service的端点列表中删除,不再是replication controller的一部分。关闭的慢的pod将继续处理load balancer转发的流量;<br /> 6.过了宽限期后,将向Pod中依然运行的进程发送SIGKILL信号而杀掉进程。<br /> 7.Kubelet会在API server中完成Pod的的删除,通过将优雅周期设置为0(立即删除)。Pod在API中消失,并且在客户端也不可见。
3.4.3 Init容器
Init容器
它是一种专用容器,在应用程序容器启动之前运行,用来包含一些应用镜像中不存在的实用工具或安装脚本。
理解Init容器
Init容器与普通容器很相似,除了以下两点:
- Init容器总是运行到成功完成为止;
- 每个Init容器都必须在下一个Init容器启动之前成功完成。
Init容器支持应用容器的全部字段和特性,包括资源限制、数据卷和安全设置。
Init容器不支持Readiness Probe,因为他们必须在Pod之前运行完成。
Init容器使用Linux namespace,因此它们能够具有访问Secret的权限。而应用容器则不能。
3.4.4 Pause容器
Pause容器特性:
- 镜像非常小,目前在700k左右;
- 永远处于Pause状态。
Pause容器主要是解决Pod中的网络问题。
Pause容器的作用:
kubernetes中的Pause容器主要为每个业务容器提供如下功能:
- 在Pod中担任Linux命名空间共享的基础;
- 启动pid命名空间,开启init进程。
3.4.6 Pod生命周期
Pod phase
Pod的phase是Pod在其生命周期中的简单宏观概述。
下面是phase可能的值:
- 挂起(pending):Pod被kubernetes系统接受,但有一个或者多个容器镜像尚未创建。等待时间包括调度Pod的时间和通过网络下载镜像的时间,这可能需要花点时间。
- 运行中(Running):该Pod已经绑定到了一个节点上,Pod中所有的容器都已被创建。至少有一个容器正在运行,或者正处于启动或者重启状态。
- 成功(Succeeded): Pod中的所有容器都被成功终止,并且不会再重启。
- 失败(Failed):Pod中的所有容器都已终止了,并且至少有一个容器是因为失败终止。也就是说,容器以非0状态退出或者被系统终止。
- 未知(Unknown):因为某些原因无法取得Pod的状态,通常是因为与Pod所在主机通信失败。
容器探针
探针是由kubelet对容器执行的定期诊断。
要执行诊断,kubelet调用由容器实现的Handler。有三种类型的处理程序:
- ExecAction:在容器内执行指定命令。如果命令退出时返回码为0则认为诊断成功。
- TCPSocketAction:对指定端口上的容器的IP地址进行TCP检查。如果端口打开,则诊断被认为是成功的。
- HTTPGetAction:对指定端口和路径上的容器的IP地址执行HTTP Get请求。如果响应的状态码大于等于200且小于400,则诊断被认为是成功的。
Kubelet可以选择是否执行在容器上运行两种探针执行和作出反应:
- livenessProbe:指示容器是否正在运行。如果存活探测失败,则kubelet会杀死容器,并且容器将受到其重启策略的影响。如果容器不提供存活探针,则默认状态为Success.
- readiness Probe:指示容器是否准备好服务请求。如果就绪探测失败,端点控制器将从与Pod匹配的所有Service的端点中删除该Pod的IP地址。初始延迟之前的就绪状态默认为Failure。如果容器不提供就绪探针,则默认状态为Success。
Pod的重启策略:Always、OnFailure和Never。
存活探针由kubelet来执行,因此所有的请求都在kubelet的网络命名空间中进行。
3.4.7 Pod hook
Pod hook由kubernetes管理的kubelet发起,当容器中的进程启动前或者容器中的进程终止之前运行。包含在容器的生命周期之中。
可以同时为Pod中的所有容器都配置hook。
Hook的类型包括两种:
- exec: 执行一段命令
- HTTP:发送HTTP请求。