Pod详解

本文详细介绍了Kubernetes中的Pod基础概念,包括Pod作为调度单位的特性、遇到的问题及解决方案,容器的分类(基础容器、初始化容器和应用容器),以及镜像拉取策略和重启策略。还深入探讨了Pod的资源限制、CPU和内存资源单位,以及健康检查的探针类型和参数设置。
摘要由CSDN通过智能技术生成

Pod基础概念

Pod是Kubernetes中的基本调度单位,它是一组相关容器的集合。这些容器共享相同的网络命名空间、存储卷和调度约束。Pod提供了一种逻辑上独立的环境,使得容器可以共享资源和相互通信。每个Pod都有一个唯一的IP地址,用于与其他Pod进行通信。Pod是Kubernetes中最小的可部署单元,它可以包含一个或多个容器,并且这些容器总是被同时调度和部署到同一台主机上。

Pod有两种使用情况:
●一个Pod中运行一个容器。这种模式是最常见的;在这种使用方式中,Pod就像是单个容器的封装,kuberentes管理的是Pod而不是直接管理容器。
●一个Pod中同时运行多个容器。一个Pod中也可以同时封装几个需要紧密耦合互相协作的容器,它们之间共享资源。

遇到的问题

一个Pod下的容器必须运行于同一节点上。一个容器只运行一个进程,该进程在容器中PID号为1,可直接接收并处理信号,进程终止时容器生命周期也就结束了。若想在容器内运行多个进程,需要有一个类似Linux操作系统init进程的管控类进程,以树状结构完成多进程的生命周期管理。同时运行于各自容器内的进程也无法直接完成网络通信。

寻求解决

为了解决这两个问题,设计出了底层基础容器pause
pause容器作为一个Pod中所有容器的父容器。这个pause容器有两个核心的功能,一是它提供整个Pod的Linux命名空间的基础。二来启用PID命名空间,它在每个Pod中都作为PID为1进程(init进程),并回收僵尸进程。

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

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

容器的分类:

1、基础容器(infrastructure container)

  • 维护整个 Pod 网络和存储空间
  • 每次创建 Pod 时候就会创建,运行的每一个Pod都有一个 pause-amd64 的基础容器自动会运行,对于用户是透明的
    docker ps -a
    在这里插入图片描述

2、初始化容器(initcontainers)

  • Init容器必须在应用程序容器启动之前运行完成,而应用程序容器是并行运行的,所以Init容器能够提供了一种简单的阻塞或延迟应用容器的启动的方法。

  • Init 容器与普通的容器非常像,除了以下两点:

    • Init 容器总是运行到成功完成为止

    • 每个 Init 容器都必须在下一个 Init 容器启动之前成功完成启动和退出
      如果 Pod 的 Init 容器失败,k8s 会不断地重启该 Pod,直到 Init 容器成功为止。如果 Pod 对应的重启策略(restartPolicy)为 Never,它不会重新启动。

  • Init 的容器作用

    • Init 容器可以包含一些安装过程中应用容器中不存在的实用工具或个性化代码。由于Init 容器与应用容器的隔离,Init容器可以安全地运行这些工具,避免这些工具导致应用镜像的安全性降低。
    • 应用镜像的创建者和部署者可以各自独立工作,而没有必要联合构建一个单独的应用镜像。
    • Init 容器能以不同于Pod内应用容器的文件系统视图运行。因此,Init容器可具有访问 Secrets 的权限,而应用容器不能够访问。
    • 由于 Init 容器必须在应用容器启动之前运行完成,因此 Init 容器提供了一种机制来阻塞或延迟应用容器的启动,直到满足了一组先决条件。一旦前置条件满足,Pod内的所有的应用容器会并行启动

3、应用容器(Maincontainer)

  • 并行启动
  • 应用容器就是我们平时使用最多的容器,业务就是部署在应用容器中的。
重点说明:
  • 在Pod启动过程中,Init容器会按顺序在网络和数据卷初始化之后启动。每个容器必须在下一个容器启动之前成功退出。
  • 如果由于运行时或失败退出,将导致容器启动失败,它会根据Pod的restartPolicy指定的策略进行重试。
  • 在所有的Init容器没有成功之前,Pod将不会变成Ready状态。Init容器的端口将不会在Service中进行聚集。
  • 如果Pod重启,所有Init容器必须重新执行。
  • 对Init容器spec的修改被限制在容器image字段,修改其他字段都不会生效。更改Init容器的image字段,等价于重启该Pod。
  • Init容器具有应用容器的所有字段。除了readinessProbe,因为Init容器无法定义不同于完成(completion)的就绪(readiness)之外的其他状态。
  • 在Pod中的每个app和Init容器的名称必须唯一;与任何其它容器共享同一个名称,会在验证时抛出错误。

镜像拉取策略(image PullPolicy):

Pod 启动容器时,需要拉取镜像,k8s 的镜像拉取策略可以由用户指定。

  1. IfNotPresent:在镜像已经存在的情况下,kubelet 将不再去拉取镜像,仅当本地缺失时才从仓库中拉取
  2. Always:每次创建 Pod 都会重新拉取一次镜像;
  3. Never:Pod 不会主动拉取这个镜像,仅使用本地镜像。

注意:对于标签为“:latest”的镜像文件,其默认的镜像获取策略即为“Always”;而对于其他标签的镜像,其默认策略则为“IfNotPresent”。

重启策略(restartPolicy)

当 Pod 中的容器退出时通过节点上的 kubelet 重启容器。适用于 Pod 中的所有容器。

  1. Always:当容器终止退出后,总是重启容器,默认策略
  2. OnFailure:当容器异常退出(退出状态码非0)时,重启容器;正常退出则不重启容器
  3. Never:当容器终止退出,从不重启容器。

#注意:K8S 中不支持重启 Pod 资源,只有删除重建

Pod进阶

资源限制

当定义 Pod 时可以选择性地为每个容器设定所需要的资源数量。 最常见的可设定资源是CPU内存大小,以及其他类型的资源。

request值:预留资源,容器运行所需的最小资源,即使没有使用这么多,kubelet也会为容器预留这么多资源
limit值:上限资源,容器最多可以使用的资源量。

如果 Pod 运行所在的节点具有足够的可用资源,容器可以使用超出 request 值的资源量,但是不可以使用超出 limit 值的资源量。

如果给容器设置了内存的 limit 值,但未设置内存的 request 值,Kubernetes 会自动为其设置与内存 limit 相匹配的 request 值。 类似的,如果给容器设置了 CPU 的 limit 值但未设置 CPU 的 request 值,则 Kubernetes 自动为其设置 CPU 的 request 值 并使之与 CPU 的 limit 值匹配。

Pod 和 容器 的资源请求和限制:

spec.containers[].resources.requests.cpu //定义创建容器时预分配的CPU资源
spec.containers[].resources.requests.memory //定义创建容器时预分配的内存资源
spec.containers[].resources.limits.cpu //定义 cpu 的资源上限
spec.containers[].resources.limits.memory //定义内存的资源上限

CPU 资源单位

CPU 资源的 request 和 limit 以 cpu 为单位。Kubernetes 中的一个 cpu 相当于1个 vCPU(1个超线程)。
Kubernetes 也支持带小数 CPU 的请求。spec.containers[].resources.requests.cpu 为 0.5 的容器能够获得一个 cpu 的一半资源。0.5 等价500m(毫核),表示每 1000 毫秒内容器可以使用的 CPU 时间总量为 0.5*1000 毫秒。
Kubernetes 不允许设置精度小于 1m 的 CPU 资源。

内存 资源单位

内存的 request 和 limit 以字节为单位。可以以整数表示,或者以10为底数的指数的单位(E、P、T、G、M、K)来表示, 或者以2为底数的指数的单位(Ei、Pi、Ti、Gi、Mi、Ki)来表示。
如:1KB=103=1000,1MB=106=1000000=1000KB,1GB=109=1000000000=1000MB
1KiB=210=1024,1MiB=220=1048576=1024KiB

示例:

kind: Pod
metadata:
  name: frontend
spec:
  containers:
  - name: app
    image: images.my-company.example/app:v4
    env:
    - name: MYSQL_ROOT_PASSWORD
      value: "password"
    resources:
      requests:
        memory: "64Mi"
        cpu: "250m" 
      limits:
        memory: "128Mi"
        cpu: "500m"
  - name: log-aggregator
    image: images.my-company.example/log-aggregator:v6
    resources:
      requests:
        memory: "64Mi"
        cpu: "250m"
      limits:
        memory: "128Mi"
        cpu: "500m"

此例子中的 Pod 有两个容器。每个容器的 request 值为 0.25 cpu 和 64MiB 内存,每个容器的 limit 值为 0.5 cpu 和 128MiB 内存。那么可以认为该 Pod 的总的资源 request 为 0.5 cpu 和 128 MiB 内存,总的资源 limit 为 1 cpu 和 256MiB 内存。

健康检查:又称为探针(Probe)

探针是由kubelet对容器执行的定期诊断。

三种探针:
  • livenessProbe(存活探针):判断容器是否正在运行。如果探测失败,则kubelet会杀死容器,并且容器将根据 restartPolicy 来设置 Pod 状态。 如果容器不提供存活探针,则默认状态为Success。

  • readinessProbe(就绪探针):判断容器是否准备好接受请求。如果探测失败,端点控制器将从与 Pod 匹配的所有 service endpoints 中删除该Pod的IP地。如果容器不提供就绪探针,则默认状态为Success。

  • startupProbe(1.17版本增加):判断容器内的应用程序是否已启动。如果配置了 startupProbe 探测,则在 startupProbe 状态为 Success 之前,其他所有探针都处于无效状态,直到它成功后其他探针才起作用。 如果 startupProbe 失败,kubelet 将杀死容器,容器将根据 restartPolicy 来重启。如果容器没有配置 startupProbe, 则默认状态为 Success。

:以上规则可以同时定义。在readinessProbe检测成功之前,Pod的running状态是不会变成ready状态的。

Probe的三种检查方法:

exec :在容器内执行指定命令。如果命令退出时返回码为0则认为诊断成功。
示例:
vim exec.yaml

apiVersion: v1
kind: Pod
metadata:
  name: liveness-exec
  namespace: default
spec:
  containers:
  - name: liveness-exec-container
    image: busybox
    imagePullPolicy: IfNotPresent
    command: ["/bin/sh","-c","touch /tmp/live; sleep 30; rm -rf /tmp/live; sleep 3600"]
    livenessProbe:
      exec:
        command: ["test","-e","/tmp/live"]
      initialDelaySeconds: 1
      periodSeconds: 3

示例中容器在启动时创建/tmp/live,并在30s后删除。使用存活探针livenessProbe的exec方法进行“test -e /tmp/live”检查。
执行yaml并观察探测结果:
kubectl apply -f exec.yaml
kubectl describe pods liveness-exec
刚开始正常:
在这里插入图片描述
30秒后异常:
在这里插入图片描述

tcpSocket :对指定端口上的容器的IP地址进行TCP检查(三次握手)。如果端口打开,则诊断被认为是成功的。
示例:
vim tcpsock.yaml

apiVersion: v1
kind: Pod
metadata:
  name: probe-tcp
spec:
  containers:
  - name: nginx
    image: soscscs/myapp:v1
    livenessProbe
      initialDelaySeconds: 5
      tcpSocket:
        port: 8080
      periodSeconds: 10
      failureThreshold: 2

这个示例是去检查8080端口,但是nginx默认是80端口,所以会探测失败。
创建并观察:
kubectl create -f tcpsock.yaml
kubectl describe pods probe-tcp
在这里插入图片描述
httpGet :对指定的端口和路径上的容器的IP地址执行HTTPGet请求。如果响应的状态码大于等于200且小于400,则诊断被认为是成功的
示例:
vim httpget.yaml

apiVersion: v1
kind: Pod
metadata:
  name: liveness-httpget
  namespace: default
spec:
  containers:
  - name: liveness-httpget-container
    image: soscscs/myapp:v1
    imagePullPolicy: IfNotPresent
    ports:
    - name: http
      containerPort: 80
    livenessProbe:
      httpGet:
        port: http
        path: /index.html
      initialDelaySeconds: 1
      periodSeconds: 3
      timeoutSeconds: 10

创建
kubectl create -f httpget.yaml
目前来说肯定是没有什么问题的
kubectl describe pods liveness-httpget
在这里插入图片描述
那么如果我们把index.html页面给删掉,此时访问页面会报404的错误,那么httpGet的检查方式就会失败
kubectl exec -it liveness-httpget – rm -rf /usr/share/nginx/html/index.html
kubectl describe pods liveness-httpget
在这里插入图片描述

探测的三种结果
  • 成功:容器通过了诊断。
  • 失败:容器未通过诊断。
  • 未知:诊断失败,因此不会采取任何行动
探测的可选参数
  • initialDelaySeconds 5:指定 kubelet 在执行第一次探测前应该等待5秒,即第一次探测是在容器启动后的第5秒才开始执行。默认是 0 秒,最小值是 0。
  • periodSeconds 5:指定了 kubelet 应该每 5 秒执行一次存活探测。默认是 10 秒。最小值是 1。
  • failureThreshold 1:当探测失败时,Kubernetes 将在放弃之前重试的次数。 存活探测下的放弃就意味着重新启动容器。就绪探测下的放弃 Pod 会被打上未就绪的标签。默认值是 3。最小值是 1。
  • timeoutSeconds:探测的超时后等待多少秒。默认值是 1 秒。最小值是 1。(在 Kubernetes 1.20 版本之前,exec 探针会忽略 timeoutSeconds 探针会无限期地 持续运行,甚至可能超过所配置的限期,直到返回结果为止。)

pod的状态

  1. pending:pod已经被系统认可了,但是内部的container还没有创建出来。这里包含调度到node上的时间以及下载镜像的时间,会持续一小段时间。
  2. Running:pod已经与node绑定了(调度成功),而且pod中所有的container已经创建出来,至少有一个容器在运行中,或者容器的进程正在启动或者重启状态。–这里需要注意pod虽然已经Running了,但是内部的container不一定完全可用。因此需要进一步检测container的状态。
  3. Succeeded:这个状态很少出现,表明pod中的所有container已经成功的terminated了,而且不会再被拉起了。
  4. Failed:pod中的所有容器都被terminated,至少一个container是非正常终止的。(退出的时候返回了一个非0的值或者是被系统直接终止)
  5. unknown:由于某些原因pod的状态获取不到,有可能是由于通信问题。 一般情况下pod最常见的就是前两种状态。而且当Running的时候,需要进一步关注container的状态

Container生命周期

  1. Waiting:启动到运行中间的一个等待状态。
  2. Running:运行状态。
  3. Terminated:终止状态。 如果没有任何异常的情况下,container应该会从Waiting状态变为Running状态,这时容器可用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值