k8s Pod 进阶(资源限制,健康检查探针详解,启动退出,pod生命周期,)

本文主要是介绍k8s Pod 进阶(资源限制,健康检查探针详解,启动退出,pod生命周期,),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

资源限制

查看资源控制字段

Pod 资源限制方式

Pod 和容器中定义资源请求和限制的具体字段

CPU资源单位

内存资源单位

示例

健康检查(探针)

探针的三种规则

存活探针(Liveness Probe)

就绪探针(Readiness Probe)

启动探针(Startup Probe)

总结

Pod的生命周期可以分为几个阶段:

探针支持三种检查方法

示例

示例1:exec方式

示例2:httpGet方式

示例3:tcpSocket方式

示例4:就绪检测

示例5:就绪检测2

启动和退出动作


资源限制

Pod 资源限制是指在 Kubernetes 中,可以为每个 Pod 中的容器设置所需的资源数量。这些资源包括 CPU 和内存大小等。Pod 资源限制在 Kubernetes 中是至关重要的,特别是在生产环境中。通过为每个 Pod 设置适当的资源限制,可以避免某个 Pod 消耗过多的 CPU 或内存资源,从而防止一个 Pod 影响整个集群的性能,并避免资源饥饿的情况发生。这有助于提高集群的可靠性和稳定性。

在Kubernetes(k8s)中,对Pod的资源限制包括两个方面:资源请求(requests)和资源限制(limits)。

  • 资源请求(requests):指在调度Pod时,Kubernetes会尝试将Pod调度到满足其资源请求的节点上。这个值应该被设置为Pod所需资源的最低限制,确保Pod能够正常运行。

  • 资源限制(limits):指在运行Pod时,Kubernetes会限制Pod使用的资源量,确保不会超出所设置的限制。这个值应该根据应用程序的需求来设置,以避免资源被过度占用导致其他Pod受影响。

查看资源控制字段

kubectl explain deployment.spec.template.spec.containers.resources
kubectl explain  statefulset.spec.template.spec.containers.resources

kubectl explain命令可以用于查看Kubernetes资源对象的详细信息

Deployment:

kubectl explain deployment.spec.template.spec.containers.resources

这个命令将显示有关Deployment中Pod模板的容器资源的详细信息。这包括关于资源请求和限制的内容,以确保Pod在调度和运行时具有足够的资源。

StatefulSet:

kubectl explain statefulset.spec.template.spec.containers.resources

这个命令将显示有关StatefulSet中Pod模板的容器资源的详细信息。与Deployment类似,StatefulSet也具有相同的容器资源配置,确保Pod有足够的资源。

Pod 资源限制方式

  • 资源需求(Requests):

  • request 是 Pod 对资源的最低需求声明。它告诉 Kubernetes 调度器为 Pod 分配节点时所需的资源量。

  • 对于 CPU,request 表示 Pod 所需的最低 CPU 分配量。例如,"100m" 表示 0.1 个 CPU 核心。

  • 对于内存,request 表示 Pod 所需的最低内存量,例如,"256Mi" 表示 256 兆字节的内存。

  • 资源限制(Limits):

  • limit 是 Pod 对资源的最大使用量声明。它告诉 Kubernetes 控制器在什么情况下限制容器的资源使用。

  • 对于 CPU,limit 表示容器在任何时间点可以使用的最大 CPU 分配量。例如,"500m" 表示 0.5 个 CPU 核心。

  • 对于内存,limit 表示容器可以使用的最大内存量,例如,"1Gi" 表示 1 Gibibyte 的内存。

  • 这些资源限制有助于 Kubernetes 在集群中的资源管理和调度。当 Pod 的资源使用接近或超出 limit 时,Kubernetes 可以采取相应的措施,如强制删除或重新启动 Pod,以保护节点的稳定性和可用性

Pod 和容器中定义资源请求和限制的具体字段

spec.containers[].resources.requests.cpu        //定义创建容器时预分配的CPU资源
spec.containers[].resources.requests.memory        //定义创建容器时预分配的内存资源
spec.containers[].resources.limits.cpu            //定义 cpu 的资源上限 
spec.containers[].resources.limits.memory        //定义内存的资源上限
  • spec.containers[].resources.requests.cpu:指定容器创建时所需的 CPU 资源数量。例如,"100m" 表示 0.1 个 CPU 核心。

  • spec.containers[].resources.requests.memory:指定容器创建时所需的内存资源数量。例如,"256Mi" 表示 256 兆字节的内存。

  • spec.containers[].resources.limits.cpu:指定容器允许使用的最大 CPU 资源数量。例如,"500m" 表示 0.5 个 CPU 核心。

  • spec.containers[].resources.limits.memory:指定容器允许使用的最大内存资源数量。例如,"1Gi" 表示 1 Gibibyte 的内存。

CPU资源单位

对于 CPU 资源,Kubernetes 中的一个 CPU 相当于一个虚拟 CPU(vCPU),也就是一个超线程。您可以使用小数或毫核(m)单位来表示 CPU 资源请求和限制。例如,0.5 表示占用一半的 CPU 资源,而 100m 表示每 1000 毫秒容器可以使用 0.1 个 CPU 核心的 CPU 时间总量。

内存资源单位

对于内存资源,Kubernetes 使用字节作为单位,并支持以10或2为底数的指数单位表示。例如,1KB 等于 1000 字节,1MB 等于 1000KB,1GB 等于 1000MB,而 1KiB 等于 1024 字节,1MiB 等于 1024KiB。

示例

官网示例: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/

https://kubernetes.io/zh-cn/docs/concepts/configuration/manage-resources-containers/

apiVersion: v1
kind: Pod
metadata:name: frontend
spec:containers:- name: appimage: images.my-company.example/app:v4env:- name: MYSQL_ROOT_PASSWORDvalue: "password"resources:requests:memory: "64Mi"cpu: "250m" limits:memory: "128Mi"cpu: "500m"- name: log-aggregatorimage: images.my-company.example/log-aggregator:v6resources:requests:memory: "64Mi"cpu: "250m"limits:memory: "128Mi"cpu: "500m"

这是一个 Kubernetes Pod 的 YAML 配置示例。在这个配置中,有两个容器:一个是名为 "app" 的应用容器,另一个是名为 "log-aggregator" 的日志聚合容器。

对于 "app" 容器:

  • 请求了最少 250 毫核的 CPU 和 64 Mi 的内存。

  • 限制了最多 500 毫核的 CPU 和 128 Mi 的内存。

对于 "log-aggregator" 容器:

  • 请求了最少 250 毫核的 CPU 和 64 Mi 的内存。

  • 限制了最多 500 毫核的 CPU 和 128 Mi 的内存。

这样的配置有助于 Kubernetes 在调度 Pod 时了解每个容器的资源需求和限制,并有效地管理集群中的资源。

vim pod3.yaml
apiVersion: v1
kind: Pod
metadata:name: frontend
spec:containers:- name: webimage: nginxenv:- name: WEB_ROOT_PASSWORDvalue: "password"resources:requests:memory: "64Mi"cpu: "250m"limits:memory: "128Mi"cpu: "500m"- name: dbimage: mysqlenv:- name: MYSQL_ROOT_PASSWORDvalue: "abc123"resources:requests:memory: "512Mi"  128cpu: "0.5"limits:memory: "1Gi"    256cpu: "1"kubectl apply -f pod2.yaml
kubectl describe pod frontendkubectl get pods -o wide
NAME       READY   STATUS    RESTARTS   AGE   IP           NODE     NOMINATED NODE   READINESS GATES
frontend   2/2     Running   5          15m   10.244.2.4   node02   <none>           <none>kubectl describe nodes node02                #由于当前虚拟机有2个CPU,所以Pod的CPU Limits一共占用了50%

这是一个包含两个容器的 Pod 配置示例。其中一个容器是名为 "web" 的 nginx 应用,另一个是名为 "db" 的 MySQL 数据库。

对于 "web" 容器:

  • 请求了最少 250 毫核的 CPU 和 64 Mi 的内存。

  • 限制了最多 500 毫核的 CPU 和 128 Mi 的内存。

对于 "db" 容器:

  • 请求了最少 0.5 个 CPU 和 512 Mi 的内存。

  • 限制了最多 1 个 CPU 和 1 Gi 的内存。

根据结果,Pod 已成功创建并正在运行,其中 "frontend" Pod 中的两个容器都已经准备就绪。

查看节点信息时,可以看到 "frontend" Pod 中的 CPU Limits 已占用了 50%,这是因为每个容器的 CPU Limits 分别为 500m 和 1,加起来为 1100m,占用了节点总计 2 个 CPU 中的一半。

这个配置示例演示了如何定义 Pod 中多个容器的资源请求和限制,并在集群中管理这些资源。

健康检查(探针)

Kubernetes中的健康检查是一种机制,用于监视和确保容器内的应用程序的状态。通过存活性探针和就绪性探针,Kubernetes可以周期性地检查容器内部的应用程序,以确定它们是否处于健康状态。存活性探针用于确定容器内的应用程序是否仍然运行,而就绪性探针用于确定容器是否已准备好接收流量。这些探针允许Kubernetes根据应用程序的状态自动进行故障恢复、水平扩展和负载均衡。

探针的三种规则

  • livenessProbe(存活性探针):用于判断容器是否正在运行。如果存活性探针失败,kubelet会杀死容器,并且根据restartPolicy设置Pod的状态。

  • readinessProbe(就绪性探针):用于判断容器是否准备好接受请求。如果就绪性探针失败,端点控制器将从与Pod匹配的所有service的endpoints中删除该Pod的IP地址。初始延迟之前的就绪状态默认为Failure。

  • startupProbe(启动探针):这是在Kubernetes 1.17版本中新增的。它用于判断容器内的应用程序是否已启动,特别针对于不能确定具体启动时间的应用。在startupProbe状态为Success之前,其他所有探针都处于无效状态。如果startupProbe失败,kubelet将杀死容器,并根据restartPolicy进行重启。

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

存活探针(Liveness Probe)

存活探针的目的是确保应用程序在运行期间保持响应。Kubernetes定期执行存活探针来检查容器是否还活着。如果探针检测到容器不响应,Kubernetes会根据Pod的重启策略重启该容器。

工作流程

  • 初始化:容器启动后,Kubelet开始定期执行存活探针。

  • 检查:执行定义的存活检查(Exec、HTTP GET或TCP Socket)。

  • 评估:根据探针的结果(成功或失败)执行操作。

  • 成功:容器继续运行。

  • 失败:Kubelet根据Pod的重启策略(如Always、OnFailure)杀死并重启容器。

就绪探针(Readiness Probe)

就绪探针的目的是确保容器准备好接受流量。这对于控制流量仅被发送到已准备好处理请求的容器至关重要,尤其是在启动时间较长或有暂时性依赖的应用程序中。

工作流程

  • 初始化:容器启动后,Kubelet开始定期执行就绪探针。

  • 检查:执行定义的就绪检查。

  • 评估:根据探针的结果调整服务状态。

  • 成功:容器标记为就绪,开始接收流量。

  • 失败:容器标记为未就绪,停止接收流量,直到探针再次成功。

启动探针(Startup Probe)

启动探针的目的是确保应用程序启动成功。它在容器启动阶段特别有用,特别是对于启动时间较长的应用程序。一旦启动探针成功,就不再执行,转而执行存活和就绪探针。

工作流程

  • 初始化:容器启动后,Kubelet开始执行启动探针。

  • 检查:执行定义的启动检查。

  • 评估:根据探针的结果执行操作。

  • 成功:停止启动探针,开始执行存活和就绪探针。

  • 失败:根据定义的重试次数和间隔继续尝试,直到成功或超时。

总结

这三种类型的探针协同工作,以确保容器不仅成功启动(启动探针),而且在其生命周期中保持活动状态(存活探针)并准备好接受流量(就绪探针)。通过这种方式,Kubernetes能够更有效地管理容器的生命周期,确保服务的高可用性和稳定性。

Pod的生命周期可以分为几个阶段:

启动、就绪和存活。在这个过程中,探针起着关键的作用。

  • 启动阶段

  • 当Pod启动时,Kubelet会执行启动探针。这个探针的目的是确保应用程序成功启动。如果启动探针失败,Kubelet会在定义的重试次数和间隔内尝试重新启动容器,直到成功或超时。

  • 一旦启动探针成功,Pod将进入下一个阶段。

  • 就绪阶段

  • 在就绪阶段,Kubelet会开始执行就绪探针。这个探针用于检查容器是否已准备好接受流量。如果就绪探针失败,Pod将被标记为未就绪,停止接收流量,直到就绪探针再次成功。

  • 如果就绪探针成功,Pod将被标记为就绪,开始接收流量。

  • 运行阶段

  • 一旦Pod就绪,Kubelet会定期执行存活探针,以确保容器在运行期间保持响应。如果存活探针失败,Kubernetes将根据Pod的重启策略(如Always、OnFailure)杀死并重启容器。

  • 如果存活探针一直成功,Pod将持续处于运行状态,处理传入的请求。

  • 结束阶段

  • 当Pod终止时,不再执行存活和就绪探针。Kubelet会根据终止信号或策略停止容器,结束Pod的生命周期。

在整个过程中,这些探针协同工作,确保Pod在启动、运行和终止的各个阶段都处于健康状态。这种机制有助于提高容器的可用性,确保应用程序在Kubernetes集群中稳定运行。

探针支持三种检查方法

  • exec(执行探针):在容器内执行指定的命令。如果命令的返回码为0,则认为探针检查成功,否则被认为是失败的。

  • tcpSocket(TCP套接字探针):对容器的IP地址上的指定端口执行TCP检查,通过进行三次握手来判断端口是否打开。如果端口是打开的,探针检查被认为是成功的。

  • httpGet(HTTP探针):对容器的IP地址上的指定端口和路径执行HTTP GET请求。如果响应的状态码大于等于200且小于400,则探针检查被认为是成功的。这通常用于检查应用程序是否能够正常响应HTTP请求。

每次探测都会获得以下三种结果之一:

  • 成功:容器通过了诊断,即探针检查成功。

  • 失败:容器未通过诊断,即探针检查失败。

  • 未知:诊断失败,无法确定容器的状态,因此不会采取任何行动。这通常发生在无法与容器进行通信或者探针配置有误时。

示例

官网示例: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/

示例1:exec方式

apiVersion: v1
kind: Pod
metadata:labels:test: livenessname: liveness-exec
spec:containers:- name: livenessimage: k8s.gcr.io/busyboxargs:  - /bin/sh- -c- touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 60livenessProbe:exec:command:- cat- /tmp/healthyfailureThreshold: 1 initialDelaySeconds: 5periodSeconds: 5#initialDelaySeconds:指定 kubelet 在执行第一次探测前应该等待5秒,即第一次探测是在容器启动后的第6秒才开始执行。默认是 0 秒,最小值是 0。
#periodSeconds:指定了 kubelet 应该每 5 秒执行一次存活探测。默认是 10 秒。最小值是 1。
#failureThreshold: 当探测失败时,Kubernetes 将在放弃之前重试的次数。 存活探测情况下的放弃就意味着重新启动容器。就绪探测情况下的放弃 Pod 会被打上未就绪的标签。默认值是 3。最小值是 1。
#timeoutSeconds:探测的超时后等待多少秒。默认值是 1 秒。最小值是 1。(在 Kubernetes 1.20 版本之前,exec 探针会忽略 timeoutSeconds 探针会无限期地 持续运行,甚至可能超过所配置的限期,直到返回结果为止。)可以看到 Pod 中只有一个容器。kubelet 在执行第一次探测前需要等待 5 秒,kubelet 会每 5 秒执行一次存活探测。kubelet 在容器内执行命令 cat /tmp/healthy 来进行探测。如果命令执行成功并且返回值为 0,kubelet 就会认为这个容器是健康存活的。 当到达第 31 秒时,这个命令返回非 0 值,kubelet 会杀死这个容器并重新启动它。

这是一个使用exec方式定义存活性探针的Pod示例。在这个例子中,Pod包含一个容器,该容器运行了一个脚本,负责在/tmp/healthy路径下创建文件、等待30秒、删除文件、再等待60秒。探针使用exec方式,执行cat /tmp/healthy命令,如果成功(返回值为0),则认为容器是健康的。

一些关键的配置参数包括:

  • initialDelaySeconds:kubelet在执行第一次探测前等待的时间,这里是5秒。

  • periodSeconds:kubelet执行探测的间隔,这里是5秒。

  • failureThreshold:探测失败的重试次数,超过次数则认为容器失败,这里是1次。

在这个例子中,当到达第31秒时,exec命令返回非0值,kubelet将杀死容器并重新启动。

vim exec.yaml
apiVersion: v1
kind: Pod
metadata:name: liveness-execnamespace: default
spec:containers:- name: liveness-exec-containerimage: busyboximagePullPolicy: IfNotPresentcommand: ["/bin/sh","-c","touch /tmp/live ; sleep 30; rm -rf /tmp/live; sleep 3600"]livenessProbe:exec:command: ["test","-e","/tmp/live"]initialDelaySeconds: 1periodSeconds: 3kubectl create -f exec.yamlkubectl describe pods liveness-execkubectl get pods -w

Pod配置文件(exec.yaml)定义了一个名为"liveness-exec"的Pod,包含一个名为"liveness-exec-container"的容器。该容器在启动时执行一段命令,创建并删除/tmp/live文件,然后等待3600秒。

已成功使用kubectl创建了该Pod,并通过kubectl describe命令查看了Pod的事件。从事件中可以看到,在执行liveness探针时,它失败了,并触发了容器的重新启动。Pod状态显示了1次重启,表明liveness探针的失败导致了容器的重新启动。

最后,通过kubectl get pods命令您可以看到该Pod的状态,它现在是Running状态,但经历了1次重启。这表明Kubernetes根据liveness探针的结果进行了自动的容器恢复。

示例2:httpGet方式

apiVersion: v1
kind: Pod
metadata:labels:test: livenessname: liveness-http
spec:containers:- name: livenessimage: k8s.gcr.io/livenessargs:- /serverlivenessProbe:httpGet:path: /healthzport: 8080httpHeaders:- name: Custom-Headervalue: AwesomeinitialDelaySeconds: 3periodSeconds: 3

这个Pod定义了一个名为"liveness-http"的容器,使用了httpGet方式进行存活性探测。容器使用"k8s.gcr.io/liveness"镜像,并在启动时运行/server命令。

存活性探针配置如下:

  • httpGet:执行HTTP GET请求以检查容器的健康状态。

  • path:指定请求的路径为/healthz。

  • port:指定容器的端口为8080。

  • httpHeaders:可选项,用于指定HTTP请求头。这里设置了一个自定义的请求头Custom-Header,值为Awesome。

  • initialDelaySeconds:kubelet在容器启动后等待3秒钟后开始执行第一次探测。

  • periodSeconds:指定kubelet每3秒钟执行一次存活性探测。

这个配置将定期向容器发送HTTP GET请求,检查/healthz路径是否可访问,并检查容器是否正常响应。如果连续探测失败,Kubernetes将根据重启策略采取相应的行动。

vim httpget.yaml
apiVersion: v1
kind: Pod
metadata:name: liveness-httpgetnamespace: default
spec:containers:- name: liveness-httpget-containerimage: soscscs/myapp:v1imagePullPolicy: IfNotPresentports:- name: httpcontainerPort: 80livenessProbe:httpGet:port: httppath: /index.htmlinitialDelaySeconds: 1periodSeconds: 3timeoutSeconds: 10kubectl create -f httpget.yamlkubectl exec -it liveness-httpget -- rm -rf /usr/share/nginx/html/index.htmlkubectl get podshttpget http://IP:80/index.html  delay 延迟 =3  tomout=10s    period(频率)=3s   succes(成功)=1  faulure(失败)=3 机会      杀死容器

创建了一个名为"liveness-httpget"的Pod,并指定了一个名为"liveness-httpget-container"的容器。该容器使用了一个名为"soscscs/myapp:v1"的镜像,并暴露了端口80。

该容器配置了一个HTTP GET方式的存活性探针,它会定期(每3秒)向端口80发送一个HTTP GET请求,检查/index.html路径是否可访问。如果在10秒内没有收到响应,则认为探针失败。初始的探测将在容器启动后1秒钟开始。

已经通过kubectl create命令创建了该Pod,并且模拟了一个故障情况,即删除了/index.html文件。随后,Pod经历了1次重启,这是因为存活性探针探测到/index.html路径不可用,并且达到了重试次数的上限(3次)。因此,Kubernetes将杀死了该容器,并根据重启策略进行了重新启动。

示例3:tcpSocket方式

apiVersion: v1
kind: Pod
metadata:name: goproxylabels:app: goproxy
spec:containers:- name: goproxyimage: k8s.gcr.io/goproxy:0.1ports:- containerPort: 8080readinessProbe:tcpSocket:port: 8080initialDelaySeconds: 5periodSeconds: 10livenessProbe:tcpSocket:port: 8080initialDelaySeconds: 15periodSeconds: 20

这个Pod配置文件定义了一个名为"goproxy"的Pod,该Pod包含一个名为"goproxy"的容器,使用了"k8s.gcr.io/goproxy:0.1"镜像,并将端口8080暴露出来。

该Pod配置了就绪性探针和存活性探针:

  • 就绪性探针(readinessProbe):使用了tcpSocket方式,检查容器的端口8080是否处于就绪状态。它会在容器启动后等待5秒钟后开始进行首次探测,然后每10秒进行一次探测。

  • 存活性探针(livenessProbe):同样使用了tcpSocket方式,检查容器的端口8080是否处于存活状态。它会在容器启动后等待15秒钟后开始进行首次探测,然后每20秒进行一次探测。

这些探针将帮助Kubernetes确保Pod的健康状态,并在需要时进行自动恢复或者负载均衡。

vim tcpsocket.yaml
apiVersion: v1
kind: Pod
metadata:name: probe-tcp
spec:containers:- name: nginximage: soscscs/myapp:v1livenessProbe:initialDelaySeconds: 5timeoutSeconds: 1tcpSocket:port: 8080periodSeconds: 10failureThreshold: 2kubectl create -f tcpsocket.yamlkubectl exec -it probe-tcp  -- netstat -natpkubectl get pods -w
NAME        READY   STATUS    RESTARTS   AGE
probe-tcp   1/1     Running             0          1s
probe-tcp   1/1     Running             1          25s       #第一次是 init(5秒) + period(10秒) * 2
probe-tcp   1/1     Running             2          45s       #第二次是 period(10秒) + period(10秒)  重试了两次
probe-tcp   1/1     Running             3          65s

在这个示例中,创建了一个名为"probe-tcp"的Pod,其中包含一个名为"nginx"的容器,使用了"soscscs/myapp:v1"镜像。该容器配置了一个使用tcpSocket方式的存活性探针,检查端口8080的状态。

存活性探针的配置如下:

  • initialDelaySeconds:容器启动后等待5秒钟后开始首次探测。

  • timeoutSeconds:设置探测超时时间为1秒。

  • tcpSocket:指定使用tcpSocket方式进行探测,检查端口8080的状态。

  • periodSeconds:设置每10秒进行一次探测。

  • failureThreshold:设置在失败2次后触发重新启动容器。

通过kubectl create命令创建了该Pod,并通过kubectl exec命令查看了容器内的网络状态。使用了netstat命令来查看端口监听状态,显示端口80处于监听状态。

随后,通过kubectl get pods命令观察了Pod的状态变化。Pod经历了3次重启,这是因为存活性探针探测到端口8080失败,并且达到了失败次数的上限(failureThreshold为2次)。因此,Kubernetes根据重启策略进行了重新启动容器。

示例4:就绪检测

vim readiness-httpget.yaml
apiVersion: v1
kind: Pod
metadata:name: readiness-httpgetnamespace: default
spec:containers:- name: readiness-httpget-containerimage: soscscs/myapp:v1imagePullPolicy: IfNotPresentports:- name: httpcontainerPort: 80readinessProbe:httpGet:port: 80path: /index1.htmlinitialDelaySeconds: 1periodSeconds: 3livenessProbe:httpGet:port: httppath: /index.htmlinitialDelaySeconds: 1periodSeconds: 3timeoutSeconds: 10kubectl create -f readiness-httpget.yaml//readiness探测失败,无法进入READY状态
kubectl get pods 
NAME                READY   STATUS    RESTARTS   AGE
readiness-httpget   0/1     Running   0          18skubectl exec -it readiness-httpget sh# cd /usr/share/nginx/html/# ls
50x.html    index.html# echo 123 > index1.html # exitkubectl get pods kubectl exec -it readiness-httpget -- rm -rf /usr/share/nginx/html/index.htmlkubectl get pods -w

这个YAML文件描述了一个Pod,其中包含一个容器,名为readiness-httpget-container,使用了一个名为soscscs/myapp:v1的镜像。该容器暴露了端口80,并配置了就绪探测和存活探测。就绪探测尝试在端口80上发送HTTP GET请求到路径/index1.html,而存活探测尝试在端口http上发送HTTP GET请求到路径/index.html。初始延迟为1秒,间隔为3秒。如果就绪探测失败,Pod将不会被视为READY状态。存活探测具有相同的初始延迟和间隔,并设置了超时时间为10秒。

在操作中,readiness探测一开始失败,因为无法访问/index1.html。然后通过在容器中创建index1.html文件,成功使得就绪探测通过,Pod进入READY状态。接着,删除了/index.html文件,导致存活探测失败,并且Pod被重启。

示例5:就绪检测2

vim readiness-myapp.yaml
apiVersion: v1
kind: Pod
metadata:name: myapp1labels:app: myapp
spec:containers:- name: myappimage: soscscs/myapp:v1ports:- name: httpcontainerPort: 80readinessProbe:httpGet:port: 80path: /index.htmlinitialDelaySeconds: 5periodSeconds: 5timeoutSeconds: 10 
---
apiVersion: v1
kind: Pod
metadata:name: myapp2labels:app: myapp
spec:containers:- name: myappimage: soscscs/myapp:v1ports:- name: httpcontainerPort: 80readinessProbe:httpGet:port: 80path: /index.htmlinitialDelaySeconds: 5periodSeconds: 5timeoutSeconds: 10 
---
apiVersion: v1
kind: Pod
metadata:name: myapp3labels:app: myapp
spec:containers:- name: myappimage: soscscs/myapp:v1ports:- name: httpcontainerPort: 80readinessProbe:httpGet:port: 80path: /index.htmlinitialDelaySeconds: 5periodSeconds: 5timeoutSeconds: 10 
---
apiVersion: v1
kind: Service
metadata:name: myapp
spec:selector:app: myapptype: ClusterIPports:- name: httpport: 80targetPort: 80kubectl create -f readiness-myapp.yamlkubectl get pods,svc,endpoints -o widekubectl exec -it pod/myapp1 -- rm -rf /usr/share/nginx/html/index.html//readiness探测失败,Pod 无法进入READY状态,且端点控制器将从 endpoints 中剔除删除该 Pod 的 IP 地址
kubectl get pods,svc,endpoints -o wide

这个YAML文件描述了三个Pod,每个Pod都有一个名为myapp的容器,使用了相同的镜像soscscs/myapp:v1。每个容器都暴露了端口80,并配置了就绪探测,尝试在端口80上发送HTTP GET请求到路径/index.html。初始延迟为5秒,间隔为5秒,超时时间为10秒。

创建完这些Pod后,我删除了myapp1 Pod中的/index.html文件,导致就绪探测失败,该Pod无法进入READY状态。端点控制器从endpoints中移除了该Pod的IP地址。

现在,endpoints/myapp仅显示了myapp2和myapp3 Pod的IP地址,因为myapp1 Pod已经被从其中剔除了。

启动和退出动作

vim post.yaml
apiVersion: v1
kind: Pod
metadata:name: lifecycle-demo
spec:containers:- name: lifecycle-demo-containerimage: soscscs/myapp:v1lifecycle:   #此为关键字段postStart:exec:command: ["/bin/sh", "-c", "echo Hello from the postStart handler >> /var/log/nginx/message"]      preStop:exec:command: ["/bin/sh", "-c", "echo Hello from the poststop handler >> /var/log/nginx/message"]volumeMounts:- name: message-logmountPath: /var/log/nginx/readOnly: falseinitContainers:- name: init-myserviceimage: soscscs/myapp:v1command: ["/bin/sh", "-c", "echo 'Hello initContainers'   >> /var/log/nginx/message"]volumeMounts:- name: message-logmountPath: /var/log/nginx/readOnly: falsevolumes:- name: message-loghostPath:path: /data/volumes/nginx/log/type: DirectoryOrCreatekubectl create -f post.yamlkubectl get pods -o wide<none>kubectl exec -it lifecycle-demo -- cat /var/log/nginx/message

"lifecycle-demo" 的 Pod,其中包含了一个容器以及一个初始化容器。关键字段是 lifecycle,它定义了在容器生命周期中执行的操作。在这个例子中,定义了 postStartpreStop 两个生命周期处理器。postStart 处理器在容器启动后执行,用来执行一些初始化任务,而 preStop 处理器在容器停止前执行,用来执行一些清理任务。

postStart 处理器中,通过执行 /bin/sh -c 命令来向文件 /var/log/nginx/message 中添加一条消息。在 preStop 处理器中,也通过执行相似的命令向同一个文件中添加另一条消息。

最后,通过 kubectl create -f post.yaml 创建 Pod,然后通过 kubectl get pods -o wide 查看 Pod 的状态,并通过 kubectl exec -it lifecycle-demo -- cat /var/log/nginx/message 命令查看容器中 /var/log/nginx/message 文件的内容,确认了消息的输出。

在 node02 节点上查看

在 node02 节点上查看
[root@node02 ~]# cd /data/volumes/nginx/log/
[root@node02 log]# ls
access.log  error.log  message
[root@node02 log]# cat message 
Hello initContainers
Hello from the postStart handler
#由上可知,init Container先执行,然后当一个主容器启动后,Kubernetes 将立即发送 postStart 事件。//删除 pod 后,再在 node02 节点上查看
kubectl delete pod lifecycle-demo[root@node02 log]# cat message 
Hello initContainers
Hello from the postStart handler
Hello from the poststop handler
#由上可知,当在容器被终结之前, Kubernetes 将发送一个 preStop 事件。

在第一次查看日志时,我们可以看到在 initContainers 中的消息 "Hello initContainers",然后是主容器中的消息 "Hello from the postStart handler"。这证实了初始化容器会在主容器之前启动,并且 postStart 事件会在主容器启动后立即执行。

在删除 Pod 后,再次查看日志,我们可以看到新增了 "Hello from the poststop handler",这是因为在 Pod 被终结之前,Kubernetes 发送了 preStop 事件,执行了相应的处理器,向日志中添加了新的消息

这篇关于k8s Pod 进阶(资源限制,健康检查探针详解,启动退出,pod生命周期,)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/753701

相关文章

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

Java进阶13讲__第12讲_1/2

多线程、线程池 1.  线程概念 1.1  什么是线程 1.2  线程的好处 2.   创建线程的三种方式 注意事项 2.1  继承Thread类 2.1.1 认识  2.1.2  编码实现  package cn.hdc.oop10.Thread;import org.slf4j.Logger;import org.slf4j.LoggerFactory

MySQL数据库宕机,启动不起来,教你一招搞定!

作者介绍:老苏,10余年DBA工作运维经验,擅长Oracle、MySQL、PG、Mongodb数据库运维(如安装迁移,性能优化、故障应急处理等)公众号:老苏畅谈运维欢迎关注本人公众号,更多精彩与您分享。 MySQL数据库宕机,数据页损坏问题,启动不起来,该如何排查和解决,本文将为你说明具体的排查过程。 查看MySQL error日志 查看 MySQL error日志,排查哪个表(表空间

OpenHarmony鸿蒙开发( Beta5.0)无感配网详解

1、简介 无感配网是指在设备联网过程中无需输入热点相关账号信息,即可快速实现设备配网,是一种兼顾高效性、可靠性和安全性的配网方式。 2、配网原理 2.1 通信原理 手机和智能设备之间的信息传递,利用特有的NAN协议实现。利用手机和智能设备之间的WiFi 感知订阅、发布能力,实现了数字管家应用和设备之间的发现。在完成设备间的认证和响应后,即可发送相关配网数据。同时还支持与常规Sof

springboot3打包成war包,用tomcat8启动

1、在pom中,将打包类型改为war <packaging>war</packaging> 2、pom中排除SpringBoot内置的Tomcat容器并添加Tomcat依赖,用于编译和测试,         *依赖时一定设置 scope 为 provided (相当于 tomcat 依赖只在本地运行和测试的时候有效,         打包的时候会排除这个依赖)<scope>provided

内核启动时减少log的方式

内核引导选项 内核引导选项大体上可以分为两类:一类与设备无关、另一类与设备有关。与设备有关的引导选项多如牛毛,需要你自己阅读内核中的相应驱动程序源码以获取其能够接受的引导选项。比如,如果你想知道可以向 AHA1542 SCSI 驱动程序传递哪些引导选项,那么就查看 drivers/scsi/aha1542.c 文件,一般在前面 100 行注释里就可以找到所接受的引导选项说明。大多数选项是通过"_

6.1.数据结构-c/c++堆详解下篇(堆排序,TopK问题)

上篇:6.1.数据结构-c/c++模拟实现堆上篇(向下,上调整算法,建堆,增删数据)-CSDN博客 本章重点 1.使用堆来完成堆排序 2.使用堆解决TopK问题 目录 一.堆排序 1.1 思路 1.2 代码 1.3 简单测试 二.TopK问题 2.1 思路(求最小): 2.2 C语言代码(手写堆) 2.3 C++代码(使用优先级队列 priority_queue)

90、k8s之secret+configMap

一、secret配置管理 配置管理: 加密配置:保存密码,token,其他敏感信息的k8s资源 应用配置:我们需要定制化的给应用进行配置,我们需要把定制好的配置文件同步到pod当中容器 1.1、加密配置: secret: [root@master01 ~]# kubectl get secrets ##查看加密配置[root@master01 ~]# kubectl get se

[MySQL表的增删改查-进阶]

🌈个人主页:努力学编程’ ⛅个人推荐: c语言从初阶到进阶 JavaEE详解 数据结构 ⚡学好数据结构,刷题刻不容缓:点击一起刷题 🌙心灵鸡汤:总有人要赢,为什么不能是我呢 💻💻💻数据库约束 🔭🔭🔭约束类型 not null: 指示某列不能存储 NULL 值unique: 保证某列的每行必须有唯一的值default: 规定没有给列赋值时的默认值.primary key: