Pod
background
K8s的基本调度单位,一个Pod可以运行一个或者以上数量的容器.
我们知道Docker的一个container实际上是一个进程,那么每一个container只能运行一个进程(除非产生子进程).
由于不能把多个进程聚集在一个单独的容器中,因此我们需要一个更高级的结构来组织容器,把他们作为一个单独的单元进行管理.
隔离程度
一个Pod内的所有容器共享Linux Namespace,包括UTC namespace,Network namespace, IPC namespace等
也就意味着:
-
一个pod内的容器能够共享相同的host和网络接口
-
容器能够通过进程间通信
-
PID也可以共享,共享之后能够看到彼此运行的进程
-
但是文件系统是没有共享的,要靠Volume来实现共享文件目录
-
一个Pod中所有容器都有相同的回环网络接口,因此容器可以通过localhost和同一个pod的其他容器进行通信
-
Pod之间的网络是平坦的(无需NAT进行网络地址转换),就是说pod之间的关系类似于局域网中的主机,每个pod都有相应的IP地址,并且可以通过这个网络实现Pod之间的相互访问
因此可以把Pod当做一个逻辑主机,Pod内部运行的container相当于主机内运行的进程
存活指针 liveness probe
下面介绍pod是如何保证容器的健康的
K8s有三种探测容器的机制:
-
HTTP GET探测 尝试对容器的ip地址发起HTTP GET请求,根据响应码来判断容器是否健康
-
TCP套接字探针 尝试与容器指定端口建立TCP链接,如果链接成功建立,则说明成功建立
-
Exec探针 在容器内执行任意命令,并且检查命令的退出状态吗,如果退出状态码是0,说明探测成功
创建基于HTTP的存活指针
容器开始后,会在端口8080路径上执行HTTP GET请求,以确定容器是否健康
apiVersion: v1
kind: Pod
metadata:
name: kubia-liveness
spec:
containers:
- image: luksa/kubia-unhealthy
name: kubia
livenessProbe:
httpGet:
path: /
port: 8080
initialDelaySeconds: 15
配置存活探针的初始属性
如果没有设置初始延迟,那么探针将会在启动的时候立即开始探测容器,通常会导致探测失败,因为应用程序还没有准备好开始接受请求.
因此通常在创建探测指针的时候,需要设定初始延迟时间
如何创建有效的存活指针
- 探针配置为请求特定的URL路径,让应用从内部对内部所有重要组件执行状态检查,以确保没有终止或者停止响应
- 保持探针的轻量级
不应该消耗太多计算资源,例如运行JVM程序,应该使用HTTP GET探针而不是exec探针,因为启动JVM的时候要大量的计算资源 - 无需在探针中实现重试循环
小结
- 如果容器崩溃或者存活探针失败的时候,需要重启容器,这项工作是由Kubelet进行的
- 但是如果节点本身崩溃,kubelet也崩溃了,需要使用ReplicationController或者类似机制来管理Pod
- 也就是在其他节点重启崩溃节点上的所有Pod
ReplicationController
如果Pod因为任何原因消失,ReplicationController将会注意到缺少了Pod进而创建替代的Pod
简而言之,RC是为了让当前的运行状态向"期望"状态靠拢
当集群节点发生故障的时候,会为故障节点上运行的所有Pod创建全新的替代副本
一个ReplicationController由三个部分组成:
- label selector 用于确定RC作用于有哪些Pod,确定RC的作用范围
- replica count
- pod template
apiVersion: v1
kind: ReplicationController
metadata:
name