【云原生kubernets】Pod详解

一、Pod介绍

1.1.概念

Pod是kubernetes中最小的资源管理组件,Pod也是最小化运行容器化应用的资源对象。一个Pod代表着集群中运行的一个进程。kubernetes中其他大多数组件都是围绕着Pod来进行支撑和扩展Pod功能的,例如,用于管理Pod运行的StatefulSet和Deployment等控制器对象,用于暴露Pod应用的Service和Ingress对象,为Pod提供存储的PersistentVolume存储资源对象等。

1.2.图形化描述
1.2.1.Pod
1.2.2.Node
1.2.3.service
1.3.K8S集群中Pod的使用方式

(1)一个Pod中运行一个容器

每个Pod中一个容器"的模式是最常见的用法;在这种使用方式中,你可以把Pod想象成是单个容器的封装,kuberentes管理的是Pod而不是直接管理容器。

(2)在一个Pod中同时运行多个容器。

一个Pod中也可以同时封装几个需要紧密耦合互相协作的容器,它们之间共享资源。这些在同一个Pod中的容器可以互相协作成为一个service单位,比如一个容器共享文件,另一个"sidecar"容器来更新这些文件。Pod将这些容器的存储资源作为一个实体来管理。

1.4.Pod进程描述:

一个Pod下的容器必须运行于同一节点上。现代容器技术建议一个容器只运行一个进程,该进程在容器中PID命令空间中的进程号为1,可直接接收并处理信号,进程终止时容器生命周期也就结束了。若想在容器内运行多个进程,需要有一个类似Linux操作系统init进程的管控类进程,以树状结构完成多进程的生命周期管理。运行于各自容器内的进程无法直接完成网络通信,这是由于容器间的隔离机制导致,k8s中的Pod资源抽象正是解决此类问题,Pod对象是一组容器的集合,这些容器共享Network、UTS及IPC命令空间,因此具有相同的域名、主机名和网络接口,并可通过IPC直接通信。

Pod资源中针对各容器提供网络命令空间等共享机制的是底层基础容器pause,基础容器(也可称为父容器)pause就是为了管理Pod容器间的共享操作,这个父容器需要能够准确地知道如何去创建共享运行环境的容器,还能管理这些容器的生命周期。为了实现这个父容器的构想,kubernetes中,用pause容器来作为一个Pod中所有容器的父容器。这个pause容器有两个核心的功能,一是它提供整个Pod的Linux命名空间的基础。二来启用PID命名空间,它在每个Pod中都作为PID为1进程(init进程),并回收僵尸进程。

1.5.pause容器
1.5.1.pause容器共享两种资源:网络和存储

(1)网络:

每个Pod都会被分配一个唯一的IP地址。Pod中的所有容器共享网络空间,包括IP地址和端口。Pod内部的容器可以使用localhost互相通信。Pod中的容器与外界通信时,必须分配共享网络资源(例如使用宿主机的端口映射)。

(2)存储:

Pod可以指定多个共享的Volume,Pod中的所有容器都可以访问共享的Volume。Volume也可以用来持久化Pod中的存储资源,以防容器重启后文件丢失。

总结:每个Pod都有一个特殊的被称为基础容器的Pause容器,Pause容器对应的镜像属于Kubernetes平台的一部分,除Pause容器,每个Pod还包含一个或多个紧密相关的用户应用容器。

1.5.2.pause容器功能

(1)在pod中担任Linux命名空间(如网络命令空间)共享的基础;

(2)启用PID命名空间,开启init进程。

1.6.pod设计特殊组成结构目的

① 原因一:在一组容器作为一个单元的情况下,难以对整体的容器简单地进行判断及有效地进行行动。比如,一个容器死亡了,此时是算整体挂了么?那么引入与业务无关的Pause容器作为Pod的基础容器,以它的状态代表着整个容器组的状态,这样就可以解决该问题。

② 原因二:Pod里的多个应用容器共享Pause容器的IP,共享Pause容器挂载的Volume,这样简化了应用容器之间的通信问题,也解决了容器之间的文件共享问题。

1.7.Pod 的分类

(1)自主式Pod:这种Pod本身是不能自我修复的,当Pod被创建后不论是由你直接创建还是被其他Controller,都会被Kuberentes调度到集群的Node上。直到Pod的进程终止、被删掉、因为缺少资源而被驱逐。Pod不会自愈,如果Pod运行的Node故障,或者是调度器本身故障,这个Pod就会被删除。同样的,如果Pod所在Node缺少资源或者Pod处于维护状态,Pod也会被驱逐。

(2)控制器管理的Pod:Kubernetes使用更高级的称为Controller的抽象层,来管理Pod实例。Controller可以创建和管理多个Pod,提供副本管理、滚动升级和集群级别的自愈能力。例如,如果一个Node故障,Controller就能自动将该节点上的Pod调度到其他健康的Node上。虽然可以直接使用Pod,但是在Kubernetes中通常是使用Controller来管理Pod的。

二、Pod的yaml文件相关配置

在kubernetes中基本所有资源的一级属性都是一样的,主要包含5部分:

  • apiVersion <string> 版本,由kubernetes内部定义,版本号必须可以用 kubectl api-versions 查询到
  • kind <string> 类型,由kubernetes内部定义,必须可以用 kubectl api-resources 查询到
  • metadata <Object> 元数据,主要是资源标识和说明,常用的有name、namespace、labels等
  • spec <Object> 描述,这是配置中最重要的一部分,里面是对各种资源配置的详细描述
  • status <Object> 状态信息,里面的内容不需要定义,由kubernetes自动生成

在上面的属性中,spec是接下来研究的重点,继续看下它的常见子属性:

  • containers <[]Object> 容器列表,用于定义容器的详细信息
  • nodeName <String> 根据nodeName的值将pod调度到指定的Node节点上
  • nodeSelector <map[]> 根据NodeSelector中定义的信息选择将该Pod调度到包含这些label的Node 上
  • hostNetwork <boolean> 是否使用主机网络模式,默认为false,如果设置为true,表示使用宿主机网络
  • volumes <[]Object> 存储卷,用于定义Pod上面挂在的存储信息
  • restartPolicy <string> 重启策略,表示Pod在遇到故障的时候的处理策略
2.1.Pod的基本yaml配置:
apiVersion: v1
kind: Pod
metadata:
  name: pod-base
  namespace: dev
  labels:
    user: heima
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
  - name: busybox
    image: busybox:1.30
2.2.镜像拉取pod-imagepullpolicy.yaml

imagePullPolicy,用于设置镜像拉取策略,kubernetes支持配置三种拉取策略:

  • Always:总是从远程仓库拉取镜像(一直远程下载)

  • IfNotPresent:本地有则使用本地镜像,本地没有则从远程仓库拉取镜像

  • Never:只使用本地镜像,从不去远程仓库拉取,本地没有就报错 (一直使用本地)

    apiVersion: v1
    kind: Pod
    metadata:
    name: pod-imagepullpolicy
    namespace: dev
    spec:
    containers:
    - name: nginx
    image: nginx:1.17.1
    imagePullPolicy: Always # 用于设置镜像拉取策略
    - name: busybox
    image: busybox:1.30

2.3.启动命令command

command,用于在pod中的容器初始化完毕之后运行一个命令

apiVersion: v1
kind: Pod
metadata:
  name: pod-command
  namespace: dev
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
  - name: busybox
    image: busybox:1.30
    command: ["/bin/sh","-c","touch /tmp/hello.txt;while true;do /bin/echo $(date +%T) >> /tmp/hello.txt; sleep 3; done;"]
2.4.env 环境变量,用于在pod中的容器设置环境变量
apiVersion: v1
kind: Pod
metadata:
  name: pod-env
  namespace: dev
spec:
  containers:
  - name: busybox
    image: busybox:1.30
    command: ["/bin/sh","-c","while true;do /bin/echo $(date +%T);sleep 60; done;"]
    env: # 设置环境变量列表
    - name: "username"
      value: "admin"
    - name: "password"
      value: "123456"
2.5.端口设置
apiVersion: v1
kind: Pod
metadata:
  name: pod-ports
  namespace: dev
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
    ports: # 设置容器暴露的端口列表
    - name: nginx-port
      containerPort: 80
      protocol: TCP
2.6.资源配额

容器中的程序要运行,肯定是要占用一定资源的,比如cpu和内存等,如果不对某个容器的资源做限制,那么它就可能吃掉大量资源,导致其它容器无法运行。针对这种情况,kubernetes提供了对内存和cpu的资源进行配额的机制,这种机制主要通过resources选项实现,他有两个子选项:

(1)limits:用于限制运行时容器的最大占用资源,当容器占用资源超过limits会被终止,并重启

(2)requests :用于设置容器需要的最小资源,如果环境资源不够,容器将无法启动

apiVersion: v1
kind: Pod
metadata:
  name: pod-resources
  namespace: dev
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
    resources: # 资源配额
      limits:  # 限制资源(上限)
        cpu: "2" # CPU限制,单位是core数
        memory: "10Gi" # 内存限制
      requests: # 请求资源(下限)
        cpu: "1"  # CPU限制,单位是core数
        memory: "10Mi"  # 内存限制

三、深入Pod 了解探针

2.1.Pod中的三种探针简要介绍

在容器的containers中存在三个属性: startupProbe启动探针, livenessProbe存活探针, readinessProbe就绪探针

(1)startupProbe启动探针: 用来探测当前容器是否启动成功

(2)livenessProbe存活探针: 用来判断当前容器是否存活,例如当探测到容器不存活时,会重新拉起

(3)readinessProbe就绪探针: 用来探测当前容器是否就绪,能否能够对外提供服务,以调用服务负载均衡为例,当接收到请求后如果通过该探针探测到某个服务节点不可用,则不会将该节点加入负载均衡。

2.2.Pod 中探针详细介绍
2.2.1. livenessProbe存活探针

(1)livenessProbe存活探针用于判断容器是不是健康,如果不满足健康条件,Kubelet 将根据 Pod 中设置的 restartPolicy 重启策略来判断,Pod 是否要进行重启。

(2)LivenessProbe按照配置去探测 ( 进程、或者端口、或者命令执行后是否成功等等),来判断容器是不是正常。如果探测不到,代表容器不健康(可以配置连续多少次失败才记为不健康),则 kubelet 会杀掉该容器,并根据容器的重启策略做相应的处理。

(3)如果未配置存活探针,则默认容器启动为Success通过状态。即Success后pod状态是RUNING

2. 2.2.readinessProbe就绪探针

(1)readinessProbe就绪探针,用于判断容器内的程序是否存活或者说是否健康,是否启动完成并就绪,正常对外提供服务。

(2)容器启动后会按照readinessProbe的配置进行探测, 探测成功返回 Success。pod的READY状态变为 true,更新pod成功数量比如1/1,否则还是0/1。

(3)若未配置就绪探针,则默认容器启动后状态Success。此时pod、pod关联的Service、EndPoint 等资源都会进入Ready 状态,进行相关设置

后续程序运行中还可以通过readinessProbe继续监测, 如果探测失败,更新Pod 的 Ready 状态变为 false,系统则会在对应的Service关联的 EndPoint 列表中去除此pod地址,实现服务的异常踢除。如果 Pod 恢复为 Ready 状态。将再会被加回 Endpoint 列表。kube-proxy也将有概率通过负载机制会引入流量到此pod中

2.2.3. startupProbe启动探针

(1)启动探针时 k8s 在1.16版本后增加startupProbe探针,主要解决在复杂的程序中readinessProbe、livenessProbe探针无法更好的判断程序是否启动、是否存活。进而引入startupProbe探针为readinessProbe、livenessProbe探针服务,

(2)startupProbe探针与另两种区别: 如果三个探针同时存在,先执行startupProbe探针,其他两个探针将会被暂时禁用,直到pod满足startupProbe探针配置的条件,其他2个探针启动,如果不满足按照规则重启容器, 另外两种探针在容器启动后,会按照配置,直到容器消亡才停止探测,而startupProbe探针只是在容器启动后按照配置满足一次后,不在进行后续的探测

2.2.Pod探针相关配置

(1)initialDelaySeconds:容器启动后要等待多少秒后存活和就绪探测器才被初始化,默认是 0 秒,最小值是 0。

(2)periodSeconds:执行探测的时间间隔(单位是秒)。默认是 10 秒。最小值是 1。

(3)timeoutSeconds:探测的超时后等待多少秒。默认值是 1 秒。最小值是 1。

(4)successThreshold:探测器在失败后,被视为成功的最小连续成功数。默认值是 1。存活探测的这个值必须是 1。最小值是 1。

(5)failureThreshold:当 Pod 启动了并且探测到失败,Kubernetes 的重试次数。存活探测情况下的放弃就意味着重新启动容器。就绪探测情况下的放弃 Pod 会被打上未就绪的标签。默认值是 3。最小值是 1。优先级低于pod默认重启策略,更改后也不会按照该参数执行。

2.3.Pod探针检测的三种方式

(1)exec: 在容器内执行指定命令。如果命令退出时返回码为 0 则认为诊断成功。

    livenessProbe:
      exec:
        command: ["cat /tmp/health"]
      initialDelaySeconds: 5
      periodSeconds: 5

(2)httpGet: 对指定的端口和路径上的容器的 IP 地址执行 HTTP Get 请求。如果响应的状态码大于等于200 且小于 400,则诊断被认为是成功的。path字段必须有。

    livenessProbe:
      httpGet:
        path: /doc.html
        port: 40017
      failureThreshold: 1
      periodSeconds: 10

(3)tcpSocket: 对指定端口上的容器的 IP 地址进行 TCP 检查。如果端口打开,则诊断被认为是成功的。

    livenessProbe:
      tcpSocket:
        port: 80
      initialDelaySeconds: 15
      periodSeconds: 20
相关推荐
石牌桥网管2 小时前
OpenSSL 生成根证书、中间证书和网站证书
网络协议·https·openssl
YCyjs2 小时前
K8S群集调度二
云原生·容器·kubernetes
Hoxy.R2 小时前
K8s小白入门
云原生·容器·kubernetes
为什么这亚子8 小时前
九、Go语言快速入门之map
运维·开发语言·后端·算法·云原生·golang·云计算
阿尔帕兹8 小时前
构建 HTTP 服务端与 Docker 镜像:从开发到测试
网络协议·http·docker
FeelTouch Labs9 小时前
Netty实现WebSocket Server是否开启压缩深度分析
网络·websocket·网络协议
ZHOU西口10 小时前
微服务实战系列之玩转Docker(十八)
分布式·docker·云原生·架构·数据安全·etcd·rbac
千天夜10 小时前
使用UDP协议传输视频流!(分片、缓存)
python·网络协议·udp·视频流
牛角上的男孩10 小时前
Istio Gateway发布服务
云原生·gateway·istio
follycat11 小时前
[极客大挑战 2019]HTTP 1
网络·网络协议·http·网络安全