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: 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"

这是一个 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: web
    image: nginx
    env:
    - name: WEB_ROOT_PASSWORD
      value: "password"
    resources:
      requests:
        memory: "64Mi"
        cpu: "250m"
      limits:
        memory: "128Mi"
        cpu: "500m"
  - name: db
    image: mysql
    env:
    - name: MYSQL_ROOT_PASSWORD
      value: "abc123"
    resources:
      requests:
        memory: "512Mi"  128
        cpu: "0.5"
      limits:
        memory: "1Gi"    256
        cpu: "1"




kubectl apply -f pod2.yaml
kubectl describe pod frontend

kubectl 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: liveness
  name: liveness-exec
spec:
  containers:
  - name: liveness
    image: k8s.gcr.io/busybox
    args:  
    - /bin/sh
    - -c
    - touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 60
    livenessProbe:
      exec:
        command:
        - cat
        - /tmp/healthy
      failureThreshold: 1 
      initialDelaySeconds: 5
      periodSeconds: 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-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

kubectl create -f exec.yaml

kubectl describe pods liveness-exec

kubectl 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: liveness
  name: liveness-http
spec:
  containers:
  - name: liveness
    image: k8s.gcr.io/liveness
    args:
    - /server
    livenessProbe:
      httpGet:
        path: /healthz
        port: 8080
        httpHeaders:
        - name: Custom-Header
          value: Awesome
      initialDelaySeconds: 3
      periodSeconds: 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-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 exec -it liveness-httpget -- rm -rf /usr/share/nginx/html/index.html

kubectl get pods

httpget 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: goproxy
  labels:
    app: goproxy
spec:
  containers:
  - name: goproxy
    image: k8s.gcr.io/goproxy:0.1
    ports:
    - containerPort: 8080
    readinessProbe:
      tcpSocket:
        port: 8080
      initialDelaySeconds: 5
      periodSeconds: 10
    livenessProbe:
      tcpSocket:
        port: 8080
      initialDelaySeconds: 15
      periodSeconds: 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: nginx
    image: soscscs/myapp:v1
    livenessProbe:
      initialDelaySeconds: 5
      timeoutSeconds: 1
      tcpSocket:
        port: 8080
      periodSeconds: 10
      failureThreshold: 2

kubectl create -f tcpsocket.yaml

kubectl exec -it probe-tcp  -- netstat -natp

kubectl 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-httpget
  namespace: default
spec:
  containers:
  - name: readiness-httpget-container
    image: soscscs/myapp:v1
    imagePullPolicy: IfNotPresent
    ports:
    - name: http
      containerPort: 80
    readinessProbe:
      httpGet:
        port: 80
        path: /index1.html
      initialDelaySeconds: 1
      periodSeconds: 3
    livenessProbe:
      httpGet:
        port: http
        path: /index.html
      initialDelaySeconds: 1
      periodSeconds: 3
      timeoutSeconds: 10

kubectl create -f readiness-httpget.yaml

//readiness探测失败,无法进入READY状态
kubectl get pods 
NAME                READY   STATUS    RESTARTS   AGE
readiness-httpget   0/1     Running   0          18s

kubectl exec -it readiness-httpget sh
 # cd /usr/share/nginx/html/
 # ls
50x.html    index.html
 # echo 123 > index1.html 
 # exit

kubectl get pods 

kubectl exec -it readiness-httpget -- rm -rf /usr/share/nginx/html/index.html

kubectl 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: myapp1
  labels:
     app: myapp
spec:
  containers:
  - name: myapp
    image: soscscs/myapp:v1
    ports:
    - name: http
      containerPort: 80
    readinessProbe:
      httpGet:
        port: 80
        path: /index.html
      initialDelaySeconds: 5
      periodSeconds: 5
      timeoutSeconds: 10 
---
apiVersion: v1
kind: Pod
metadata:
  name: myapp2
  labels:
     app: myapp
spec:
  containers:
  - name: myapp
    image: soscscs/myapp:v1
    ports:
    - name: http
      containerPort: 80
    readinessProbe:
      httpGet:
        port: 80
        path: /index.html
      initialDelaySeconds: 5
      periodSeconds: 5
      timeoutSeconds: 10 
---
apiVersion: v1
kind: Pod
metadata:
  name: myapp3
  labels:
     app: myapp
spec:
  containers:
  - name: myapp
    image: soscscs/myapp:v1
    ports:
    - name: http
      containerPort: 80
    readinessProbe:
      httpGet:
        port: 80
        path: /index.html
      initialDelaySeconds: 5
      periodSeconds: 5
      timeoutSeconds: 10 
---
apiVersion: v1
kind: Service
metadata:
  name: myapp
spec:
  selector:
    app: myapp
  type: ClusterIP
  ports:
  - name: http
    port: 80
    targetPort: 80

kubectl create -f readiness-myapp.yaml

kubectl get pods,svc,endpoints -o wide

kubectl 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-container
    image: soscscs/myapp:v1
    lifecycle:   #此为关键字段
      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-log
      mountPath: /var/log/nginx/
      readOnly: false
  initContainers:
  - name: init-myservice
    image: soscscs/myapp:v1
    command: ["/bin/sh", "-c", "echo 'Hello initContainers'   >> /var/log/nginx/message"]
    volumeMounts:
    - name: message-log
      mountPath: /var/log/nginx/
      readOnly: false
  volumes:
  - name: message-log
    hostPath:
      path: /data/volumes/nginx/log/
      type: DirectoryOrCreate

kubectl create -f post.yaml

kubectl 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 事件,执行了相应的处理器,向日志中添加了新的消息

  • 8
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值