首页 > 其他分享 >Kubernetes中Pod容器的资源限制和探针配置

Kubernetes中Pod容器的资源限制和探针配置

时间:2024-05-26 23:34:35浏览次数:32  
标签:容器 Kubernetes demo master01 探针 Pod root pod

前言

在 Kubernetes 中,定义 Pod 时可以选择性地为每个容器设定所需要的资源数量。 最常见的可设定资源是 CPU 和内存大小,以及其他类型的资源;另一方面,通过配置探针,可以确保容器在运行时保持健康,并且只有在准备好接收流量时才会被负载均衡器引导流量。从而提高应用程序的可靠性和稳定性。

目录

一、容器管理资源概念

1. 概述

2. 资源请求和限制

2.1 request 预留资源

2.2 limit 限制资源

3. K8s 中的资源单位 

3.1 CPU 资源单位

3.2 内存资源单位

4. 资源限制配置规则

5. 容器资源示例

5.1 request 与 limit 创建 pod 模板

5.2 OOMKilled 内存耗尽保护机制

二、Pod 容器的探针

1. 概述

2. 探针的三种规则

2.1 存活探针(Liveness Probe)

2.2 就绪探针(Readiness Probe)

2.3 启动探针(Startup Probe)

3. 探针三种检查方法

4. 探针配置示例

4.1 定义存活命令

4.2 定义一个存活态 HTTP 请求接口

4.3 定义 TCP 的存活探测

4.4 定义 readinessProbe 就绪探针

4.5 多资源配置就绪检测

4.6 启动和退出动作

三、补充概念

1. pod 的状态

2. Container 生命周期


一、容器管理资源概念

1. 概述

在 K8s 中,对 Pod 容器的资源限制主要围绕着两个关键参数:request 资源和 limit 资源,用于配置 CPU 和内存的使用情况;避免资源竞争和不必要的浪费,同时确保 Pod 在运行时具有足够的资源支持。

参考官网示例:为 Pod 和容器管理资源 | Kubernetes

2. 资源请求和限制

针对每个容器,你都可以指定其资源限制和请求,包括如下选项:

2.1 request 预留资源

创建 pod 容器时需要预留的资源量,cpu(0.5 或 500m),内存 Mi、Gi(以2为底的幂数),M、G(以10为底)。

spec.containers[].resources.requests.cpu
spec.containers[].resources.requests.memory

2.2 limit 限制资源

pod 容器能够使用资源量的一个上限。如:4Gi 代表内存上限不允许超过上限值;1 代表 cpu 上限不允许超过上限值。

spec.containers[].resources.limits.cpu
spec.containers[].resources.limits.memory

3. K8s 中的资源单位 

3.1 CPU 资源单位

在 K8s 中,一个 CPU 等于 1 个物理 CPU 核 或者 1 个虚拟核, 取决于节点是一台物理主机还是运行在某物理主机上的虚拟机。

当定义一个容器,将其 spec.containers[].resources.requests.cpu 设置为 0.5 时, 所请求的 CPU 是请求 1.0 CPU 时的一半。 对于 CPU 资源单位,数量表达式 0.1 等价于表达式 100m(一百毫核),可以看作 “100 millicpu”。 

注意:K8s 不允许设置精度小于 1m 或 0.001 的 CPU 资源。

3.2 内存资源单位

memory 的限制和请求以字节为单位。 可以使用普通的整数,或者带有以下 数量后缀 的定点数字来表示内存:E、P、T、G、M、k。 也可以使用对应的 2 的幂数:Ei、Pi、Ti、Gi、Mi、Ki。

4. 资源限制配置规则

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

如果给容器设置了内存的 limit 值,但未设置内存的 request 值,Kubernetes 会自动为其设置与内存 limit 相匹配的 request 值;类似的 cpu 同理。

5. 容器资源示例

5.1 request 与 limit 创建 pod 模板

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

[root@master01 demo]# vim demo1.yaml
apiVersion: v1
kind: Pod
metadata:
  name: demo-01
spec:
  containers:
  - name: app
    image: images.my-company.example/app:v4
    env:                         # 定义了容器的环境变量
    - name: MYSQL_ROOT_PASSWORD  # 设置环境变量
      value: "123456"            # 环境变量的值
    resources:                   # 容器的资源限制和请求
      requests:                  # 容器的资源请求
        memory: "64Mi"           # 请求容器使用的内存量为64MiB
        cpu: "250m"              # 请求容器使用的CPU量为250 m
      limits:                    # 容器的资源限制
        memory: "128Mi"          # 限制容器使用的最大内存量为128MiB
        cpu: "500m"              # 限制容器使用的最大CPU量为500 m
  - name: log-aggregator
    image: images.my-company.example/log-aggregator:v6
    resources:                   # 容器的资源限制和请求
      requests:                  # 容器的资源请求
        memory: "64Mi"           # 容器使用的内存量为64MiB
        cpu: "250m"              # 第二个容器使用的CPU量为250 m
      limits:                    # 容器的资源限制
        memory: "128Mi"          # 限制第二个容器使用的最大内存量为128MiB
        cpu: "500m"              # 限制第二个容器使用的最大CPU量为500 m

5.2 OOMKilled 内存耗尽保护机制

为了模拟内存耗尽情况并观察OOMKilled(Out Of Memory Killed)内存耗尽保护机制的效果,我们将调整数据库容器的资源请求(requests)和内存限制(limits)到一个较小的值,以便触发内存不足的情况。

请注意,在生产环境中,调整容器的资源请求和限制应该谨慎进行,以避免对系统产生不可预料的影响。

① 创建 yaml 文件

[root@master01 demo]# vim demo2.yaml
apiVersion: v1
kind: Pod
metadata:
  name: web-db
spec:
  containers:
  - name: web
    image: nginx
    env:
    - name: WEB_ROOT_PASSWORD
      value: "123123"
    resources:
      requests:
        memory: "64Mi"
        cpu: "250m"
      limits:
        memory: "128Mi"
        cpu: "500m"
  - name: db
    image: mysql
    env:
    - name: MYSQL_ROOT_PASSWORD
      value: "123123"
    resources:
      requests:
        memory: "64Mi"
        cpu: "0.25"
      limits:
        memory: "128Mi"
        cpu: "500m"

② 启动 pod

[root@master01 demo]# kubectl apply -f demo2.yaml 
pod/web-db created

③ 查看资源信息

[root@master01 demo]# kubectl get pod web-db -w
NAME     READY   STATUS              RESTARTS   AGE
web-db   0/2     ContainerCreating   0          18s
web-db   2/2     Running             0          63s
web-db   1/2     OOMKilled           0          76s
web-db   2/2     Running             1          93s
web-db   1/2     OOMKilled           1          105s
web-db   1/2     CrashLoopBackOff    1          2m
web-db   2/2     Running             2          2m1s
web-db   1/2     OOMKilled           2          2m14s
web-db   1/2     CrashLoopBackOff    2          2m28s
# 多次出现的 OOMKilled 表示容器由于内存耗尽而被系统终止

[root@master01 demo]# kubectl describe pod web-db 
Events:
  Type     Reason     Age                  From               Message
  ----     ------     ----                 ----               -------
  Normal   Scheduled  3m20s                default-scheduler  Successfully assigned default/web-db to node01
  Normal   Pulling    3m19s                kubelet            Pulling image "nginx"
  Normal   Pulled     3m4s                 kubelet            Successfully pulled image "nginx" in 15.521857377s
  Normal   Created    3m4s                 kubelet            Created container web
  Normal   Started    3m4s                 kubelet            Started container web
  Normal   Pulled     2m18s                kubelet            Successfully pulled image "mysql" in 46.048445572s
  Normal   Pulled     108s                 kubelet            Successfully pulled image "mysql" in 15.474925496s
  Normal   Pulled     80s                  kubelet            Successfully pulled image "mysql" in 399.833869ms
  Normal   Pulling    38s (x4 over 3m4s)   kubelet            Pulling image "mysql"
  Normal   Created    38s (x4 over 2m17s)  kubelet            Created container db
  Normal   Started    38s (x4 over 2m17s)  kubelet            Started container db
  Normal   Pulled     38s                  kubelet            Successfully pulled image "mysql" in 388.467767ms
  Warning  BackOff    13s (x5 over 95s)    kubelet            Back-off restarting failed container
# 容器 "db" 失败并且在多次尝试后仍然无法成功启动,导致触发了 BackOff 机制

④ 调整资源配额限制

[root@master01 demo]# kubectl delete -f demo2.yaml 
pod "web-db" deleted
[root@master01 demo]# vim demo2.yaml
    resources:
      requests:
        memory: "128Mi"
        cpu: "0.5"
      limits:
        memory: "1Gi"
        cpu: "1000m"

⑤ 再次尝试启动 pod 

[root@master01 demo]# kubectl apply -f demo2.yaml 
pod/web-db created

[root@master01 demo]# kubectl get pod web-db 
NAME     READY   STATUS    RESTARTS   AGE
web-db   2/2     Running   0          42s

⑥ 查看 node 节点资源占比

[root@master01 demo]# kubectl get pod web-db -o wide
NAME     READY   STATUS    RESTARTS   AGE   IP            NODE     NOMINATED NODE   READINESS GATES
web-db   2/2     Running   0          94s   10.244.1.22   node01   <none>           <none>

[root@master01 demo]# kubectl describe node node01
  Namespace                   Name                     CPU Requests  CPU Limits   Memory Requests  Memory Limits  AGE
  ---------                   ----                     ------------  ----------   ---------------  -------------  ---
  default                     pod-01                   0 (0%)        0 (0%)       0 (0%)           0 (0%)         4h19m
  default                     web-db                   750m (37%)    1500m (75%)  192Mi (11%)      1152Mi (66%)   2m13s
  kube-flannel                kube-flannel-ds-wz8p2    100m (5%)     0 (0%)       50Mi (2%)        0 (0%)         8d
  kube-system                 kube-proxy-w7vl7         0 (0%)        0 (0%)       0 (0%)           0 (0%)         8d
Allocated resources:
  (Total limits may be over 100 percent, i.e., overcommitted.)
  Resource           Requests     Limits
  --------           --------     ------
  cpu                850m (42%)   1500m (75%)
  memory             242Mi (14%)  1152Mi (66%)
  ephemeral-storage  0 (0%)       0 (0%)
  hugepages-1Gi      0 (0%)       0 (0%)
  hugepages-2Mi      0 (0%)       0 (0%)

Pod "web-db" 的资源请求和限制如下:

  • CPU 请求:750m,CPU 限制:1500m
  • 内存请求:192Mi,内存限制:1152Mi

已分配的资源情况如下:

  • CPU 请求总量:850m(42%),CPU 限制总量:1500m(75%)
  • 内存请求总量:242Mi(14%),内存限制总量:1152Mi(66%) 

二、Pod 容器的探针

1. 概述

探针是由 kubelet 对容器执行的定期诊断。容器的探针是一种关键的机制,用于监测和管理容器的健康状态,确保容器在各种情况下都能正常运行。通过配置适当的探针,可以提高容器的可靠性和稳定性,确保容器能够有效应对各种运行时情况,并及时处理健康状态的变化。

2. 探针的三种规则

在 Kubernetes 中,探针(Probes)用于监测容器的健康状态和确定容器是否已准备好接收流量。主要有三种类型的探针:

2.1 存活探针(Liveness Probe)

用于确定容器是否正在运行并且健康。如果存活探针失败,Kubernetes 将根据重启策略(如 `RestartPolicy`)尝试重新启动容器。如果容器不提供存活探针,则默认状态为 Success。

2.2 就绪探针(Readiness Probe)

用于确定容器是否已准备好接收流量。如果就绪探针失败,容器将被从 Service 的负载均衡池中移除该 Pod 的 IP 地址,直到就绪探针再次成功。初始延迟之前的就绪状态默认为 Failure。如果容器不提供就绪探针,则默认状态为 Success。

2.3 启动探针(Startup Probe)

1.17版本增加的。用于确定容器是否已经启动并且已经准备好接收其它探针的检查。启动探针在容器启动后执行,但在就绪探针和存活探针之前执行。

如果 startupProbe 失败,kubelet 将杀死容器,容器将根据 restartPolicy 来重启。如果容器没有配置 startupProbe, 则默认状态为 Success。

以上规则可以同时定义。在 readinessProbe 检测成功之前,Pod 的 running 状态是不会变成 ready 状态的。通过配置这些探针,可以确保容器在运行时保持健康,并且只有在准备好接收流量时才会被负载均衡器引导流量。这有助于提高应用程序的可靠性和稳定性。

3. 探针三种检查方法

  • exec :在容器内执行指定命令。如果命令退出时返回码为0则认为诊断成功;
  • tcpSocket :对指定端口上的容器的IP地址进行TCP检查(三次握手)。如果端口打开,则诊断被认为是成功的;
  • httpGet :对指定的端口和路径上的容器的IP地址执行HTTPGet请求。如果响应的状态码大于等于200且小于400,则诊断被认为是成功的。

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

  • 成功:容器通过了诊断;
  • 失败:容器未通过诊断;
  • 未知:诊断失败,因此不会采取任何行动。

4. 探针配置示例

4.1 定义存活命令

许多长时间运行的应用最终会进入损坏状态,除非重新启动,否则无法被恢复。 Kubernetes 提供了存活探针来发现并处理这种情况。

示例1:livenessProbe 规则,配合 exec 检查方法。

① 编辑 pod 的 yaml 配置文件

[root@master01 demo]# vim demo3.yaml
apiVersion: v1
kind: Pod
metadata:                     # 元数据
  labels:                     # Pod 的标签
    test: liveness
  name: liveness-exec
spec:                         # Pod 的规格
  containers:                 # 容器列表
  - name: liveness            # 容器的名称
    image: busybox            # 一个轻量级的 BusyBox 镜像
    imagePullPolicy: IfNotPresent # 镜像拉取策略,先本地后仓库
    args:                     # 容器的启动参数部分
    - /bin/sh
    - -c                      # 后面的内容将作为 shell 的命令执行
    - touch /tmp/healthy; sleep 10; rm -rf /tmp/healthy; sleep 10
# 在容器启动时执行的命令,首先创建一个/tmp/healthy文件,然后等待10秒,接着删除该文件,最后再等待10秒
    livenessProbe:            # 定义存活探针的配置
      exec:                   # 使用 exec 方式执行命令
        command:              # 要执行的命令
        - cat
        - /tmp/healthy        # 读取 /tmp/healthy 文件的内容
      failureThreshold: 1     # 存活探针的失败阈值为1,即连续失败1次后认为探针失败,默认值是3。最小值是1
      initialDelaySeconds: 3  # 容器启动后等待3秒开始进行存活探测,其实是4秒,默认是0秒,最小值是0
      periodSeconds: 2        # 每隔2秒进行一次存活探测,默认是10秒。最小值是1。

这个容器生命的前 10 秒,/tmp/healthy 文件是存在的。 所以在这最开始的 10 秒内,执行命令 cat /tmp/healthy 会返回成功代码。 10 秒之后,执行命令 cat /tmp/healthy 就会返回失败代码。

② 启动 pod

[root@master01 demo]# kubectl apply -f demo3.yaml 
pod/liveness-exec created

③ 查看容器状态详情信息

[root@master01 demo]# kubectl get pod liveness-exec -w
NAME            READY   STATUS    RESTARTS   AGE
liveness-exec   1/1     Running   0          3s
liveness-exec   1/1     Running   1          22s
liveness-exec   1/1     Running   2          43s
liveness-exec   1/1     Running   3          63s
liveness-exec   1/1     Running   4          83s
liveness-exec   0/1     CrashLoopBackOff   4          103s
# Pod中的容器liveness由于存活探针失败而不断重启,并最终进入了CrashLoopBackOff状态
# 输出结果显示RESTARTS的值增加了1。 请注意,一旦失败的容器恢复为运行状态,RESTARTS计数器就会加1

查看 Pod 的事件:
[root@master01 demo]# kubectl describe pod liveness-exec
Events:
  Type     Reason     Age                  From               Message
  ----     ------     ----                 ----               -------
  Normal   Scheduled  2m24s                default-scheduler  Successfully assigned default/liveness-exec to node01
  Normal   Pulled     62s (x5 over 2m24s)  kubelet            Container image "busybox" already present on machine
  Normal   Created    62s (x5 over 2m24s)  kubelet            Created container liveness
  Normal   Started    62s (x5 over 2m24s)  kubelet            Started container liveness
  Warning  Unhealthy  51s (x5 over 2m13s)  kubelet            Liveness probe failed: cat: can't open '/tmp/healthy': No such file or directory
  Normal   Killing    51s (x5 over 2m13s)  kubelet            Container liveness failed liveness probe, will be restarted
# 显示存活探针失败了,这个失败的容器被杀死并且被重建了
# 是否重启还是根据重启策略来决定,这里明显是always

4.2 定义一个存活态 HTTP 请求接口

另外一种类型的存活探测方式是使用 HTTP GET 请求。

示例2:livenessProbe 规则,配合 httpGet 检查方法。

① 编辑 pod 的 yaml 配置文件

[root@master01 demo]# vim demo4.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              # 容器内部的端口号为 80
    livenessProbe:                   # 定义存活探针的配置
      httpGet:                       # 使用HTTP GET请求方式进行探测
        port: http                   # 探测请求发送到的端口为http,即容器内部的80端口
        path: /index.html            # 探测请求的路径为 /index.html
      initialDelaySeconds: 1         # 容器启动后等待1秒后开始进行存活探测
      periodSeconds: 3               # 每隔3秒进行一次存活探测
      timeoutSeconds: 5              # 超时时间为5秒

如果存活探针发送的 HTTPGET 请求返回成功(即能够访问到 /index.html),则认为容器是健康的。如果请求失败(无法访问到 /index.html 或返回错误),则认为容器不健康处理程序返回失败代码,kubelet 会杀死这个容器并且重新启动它。

② 启动 pod 

[root@master01 demo]# kubectl apply -f demo4.yaml 
pod/liveness-httpget created

[root@master01 demo]# kubectl get pod liveness-httpget -o wide
NAME               READY   STATUS    RESTARTS   AGE   IP            NODE     NOMINATED NODE   READINESS GATES
liveness-httpget   1/1     Running   0          65s   10.244.1.24   node01   <none>           <none>

尝试访问页面:
[root@master01 demo]# curl 10.244.1.24
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
[root@master01 demo]# curl 10.244.1.24 -I
Server: nginx/1.12.2

③ 删除容器中 index.html

[root@master01 demo]# kubectl exec -it liveness-httpget -- rm -f /usr/share/nginx/html/index.html

③ 查看容器状态详情信息

[root@master01 demo]# kubectl get pod liveness-httpget 
NAME               READY   STATUS    RESTARTS   AGE
liveness-httpget   1/1     Running   2          5m42s

[root@master01 demo]# kubectl describe pod liveness-httpget
Events:
  Type     Reason     Age                  From               Message
  ----     ------     ----                 ----               -------
  Normal   Scheduled  6m32s                default-scheduler  Successfully assigned default/liveness-httpget to node01
  Normal   Pulling    6m32s                kubelet            Pulling image "soscscs/myapp:v1"
  Normal   Pulled     6m14s                kubelet            Successfully pulled image "soscscs/myapp:v1" in 18.054706565s
  Normal   Created    66s (x3 over 6m13s)  kubelet            Created container liveness-httpget-container
  Warning  Unhealthy  66s (x6 over 2m54s)  kubelet            Liveness probe failed: HTTP probe failed with statuscode: 404
  Normal   Killing    66s (x2 over 2m48s)  kubelet            Container liveness-httpget-container failed liveness probe, will be restarted
  Normal   Pulled     66s (x2 over 2m48s)  kubelet            Container image "soscscs/myapp:v1" already present on machine
  Normal   Started    65s (x3 over 6m13s)  kubelet            Started container liveness-httpget-container

容器中的存活探针失败是因为 HTTP 探测返回了状态码 404,表示无法访问到指定的路径 /index.html。因此,容器被标记为不健康,被 Kubernetes 系统自动重新启动以尝试恢复其健康状态。 

4.3 定义 TCP 的存活探测

使用这种配置时,kubelet 会尝试在指定端口和容器建立套接字链接。 如果能建立连接,这个容器就被看作是健康的,如果不能则这个容器就被看作是有问题的。

示例3:livenessProbe 规则,配合 tcpSocket 检查方法。

① 编辑 pod 的 yaml 配置文件

[root@master01 demo]# vim demo5.yaml
apiVersion: v1
kind: Pod
metadata:
  name: probe-tcp
spec:
  containers:
  - name: nginx
    image: soscscs/myapp:v1
    livenessProbe:
      initialDelaySeconds: 5 # 容器启动后等待 5 秒后开始执行存活探针
      timeoutSeconds: 1      # 探测超时时间为 1 秒
      tcpSocket:             # 使用 TCP 探测方式
        port: 8080           # 探测的端口为 8080
      periodSeconds: 10      # 每隔 10 秒执行一次存活探针
      failureThreshold: 2    # 如果连续 2 次探测失败,则认为容器不健康

上面的 YAML 文件描述了一个名为 probe-tcp 的 Pod,其中包含一个名为 nginx 的容器,使用镜像 soscscs/myapp:v1,配置了一个针对端口 8080 的 TCP 探测器,用于检测容器的健康状态。由于业务本身端口是 80,所有这步就是探针肯定是失败的,持续查看探针过程。 

② 启动 pod 

[root@master01 demo]# kubectl apply -f demo5.yaml 
pod/probe-tcp created

使用kubectl工具在名为probe-tcp的容器中执行netstat -natp命令:
[root@master01 demo]# kubectl exec -it probe-tcp  -- netstat -natp
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      1/nginx: master pr

③ 持续查看容器状态详情信息

[root@master01 demo]# kubectl get pod -w
NAME        READY   STATUS    RESTARTS   AGE
probe-tcp   0/1     Pending   0          0s
probe-tcp   0/1     Pending   0          0s
probe-tcp   0/1     ContainerCreating   0          0s
probe-tcp   1/1     Running             0          2s
probe-tcp   1/1     Running             1          18s
probe-tcp   1/1     Running             2          38s
probe-tcp   1/1     Running             3          57s
probe-tcp   1/1     Running             4          78s
# 由于探测8080端口失败,可以看到 Pod 重启了多次
# 理论上第一次重启时间为:5+1+10=16秒
# 理论上第二次重启时间为:+20秒
# 理论上第三次重启时间为:+20秒
# 理论上第四次重启时间为:+20秒

4.4 定义 readinessProbe 就绪探针

有时候,应用会暂时性地无法为请求提供服务。 例如,应用在启动时可能需要加载大量的数据或配置文件,或是启动后要依赖等待外部服务。 在这种情况下,既不想杀死应用,也不想给它发送请求。 Kubernetes 提供了就绪探针来发现并缓解这些情况。 容器所在 Pod 上报还未就绪的信息,并且不接受通过 Kubernetes Service 的流量。

示例4: readinessProbe 和 livenessProbe 规则,配合 httpGet 检查方法。

① 编辑 pod 的 yaml 配置文件

[root@master01 demo]# vim demo6.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      # 指定容器将监听的端口为 80
    readinessProbe:          # 定义容器的就绪性探针
      httpGet:               # 指定用于就绪性检查的 HTTP GET 请求
        port: 80             # 指定进行就绪性检查的端口(端口 80)
        path: /index1.html   # 指定就绪性检查期间请求的路径("/index1.html")
      initialDelaySeconds: 1 # 指定容器启动后开始就绪性探针的等待时间(1 秒)
      periodSeconds: 3       # 指定连续就绪性探针之间的间隔(3 秒)
    livenessProbe:           # 定义容器的存活性探针
      httpGet:               # 指定用于存活性检查的 HTTP GET 请求
        port: http           # 指定进行存活性检查的端口("http"端口)
        path: /index.html    # 指定存活性检查期间请求的路径("/index.html")
      initialDelaySeconds: 1 # 指定容器启动后开始存活性探针的等待时间(1 秒)
      periodSeconds: 3       # 指定连续存活性探针之间的间隔(3 秒)
      timeoutSeconds: 10     # 指定存活性探针在等待响应的最大时间(10 秒)

② 启动 pod 

[root@master01 demo]# kubectl apply -f demo6.yaml 
pod/readiness-httpget created

③ 查看容器状态详情信息

[root@master01 demo]# kubectl get pod
NAME                READY   STATUS    RESTARTS   AGE
readiness-httpget   0/1     Running   0          17s
# 0/1表示该Pod中的容器当前处于未就绪状态

[root@master01 demo]# kubectl describe pod readiness-httpget 
Events:
  Type     Reason     Age                From               Message
  ----     ------     ----               ----               -------
  Normal   Scheduled  39s                default-scheduler  Successfully assigned default/readiness-httpget to node01
  Normal   Pulled     38s                kubelet            Container image "soscscs/myapp:v1" already present on machine
  Normal   Created    38s                kubelet            Created container readiness-httpget-container
  Normal   Started    38s                kubelet            Started container readiness-httpget-container
  Warning  Unhealthy  3s (x12 over 36s)  kubelet            Readiness probe failed: HTTP probe failed with statuscode: 404
# 就绪性探针失败,因为 HTTP 探测返回了状态码 404,由于就绪性探针配置中指定的路径/index1.html不存在或有误。

④ 创建 index1.html 页面

[root@master01 demo]# kubectl exec -it readiness-httpget sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
/ # echo "index1" > /usr/share/nginx/html/index1.html
/ # exit

⑤ 再次查看 pod 状态

[root@master01 demo]# kubectl get pod
NAME                READY   STATUS    RESTARTS   AGE
readiness-httpget   1/1     Running   0          5m36s
# 已就绪

⑥ 删除原有 index.html,查看存活探针结果

[root@master01 demo]# kubectl get pod
NAME                READY   STATUS    RESTARTS   AGE
readiness-httpget   0/1     Running   1          9m32s

[root@master01 demo]# kubectl describe pod readiness-httpget
  Warning  Unhealthy  33s                     kubelet            Liveness probe failed: HTTP probe failed with statuscode: 404
# 无法找到 index.html 页面

4.5 多资源配置就绪检测

下面这个 YAML 文件定义了三个名为 myapp1、myapp2 和 myapp3 的 Pod,它们使用相同的镜像并具有相似的配置,以及一个名为 myapp 的 Service,用于将流量路由到这些 Pod 上的端口 80。

测试目的:readiness 探测失败,pod 无法进入 ready 状态,则端点控制器会将 pod 从 endpoints 中剔除删除该 pod 的 IP 地址。

示例5: readinessProbe 规则,配合 httpGet 检查方法。

① 编辑 pod 的 yaml 配置文件

[root@master01 demo]# vim readiness-httpget.yaml
apiVersion: v1
kind: Pod
metadata:
  name: myapp1
  labels:
     app: myapp
spec:
  containers:
  - name: myapp
    image: soscscs/myapp:v1
    ports:
    - name: http
      containerPort: 80       # 容器内部的端口号为 80
    readinessProbe:           # 定义了就绪性探针
      httpGet:                # 指定了使用 HTTP GET 请求进行探测
        port: 80              # 指定了探测的端口为 80
        path: /index.html     # 指定健康检查发送请求的路径为 /index.html
      initialDelaySeconds: 5  # 容器创建后等待 5 秒开始执行健康检查
      periodSeconds: 5        # 每隔 5 秒进行一次健康检查
      timeoutSeconds: 10      # 健康检查的超时时间为 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

② 启动 pod 

[root@master01 demo]# kubectl apply -f readiness-httpget.yaml 
pod/myapp1 created
pod/myapp2 created
pod/myapp3 created
service/myapp created

③ 查看 pod、svc 以及关联后端的节点信息

[root@master01 demo]# kubectl get pod,svc,endpoints -o wide
NAME         READY   STATUS    RESTARTS   AGE   IP            NODE     NOMINATED NODE   READINESS GATES
pod/myapp1   1/1     Running   0          28s   10.244.1.27   node01   <none>           <none>
pod/myapp2   1/1     Running   0          28s   10.244.2.10   node02   <none>           <none>
pod/myapp3   1/1     Running   0          27s   10.244.1.28   node01   <none>           <none>

NAME                       TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)           AGE   SELECTOR
service/kubernetes         ClusterIP   10.96.0.1       <none>        443/TCP           10d   <none>
service/myapp              ClusterIP   10.96.35.59     <none>        80/TCP            27s   app=myapp
service/nginx              NodePort    10.96.75.23     <none>        80:32165/TCP      10d   app=nginx
service/nginx-deployment   NodePort    10.96.101.251   <none>        30000:31603/TCP   9d    app=nginx-deployment

NAME                         ENDPOINTS                                      AGE
endpoints/kubernetes         192.168.190.100:6443                           10d
endpoints/myapp              10.244.1.27:80,10.244.1.28:80,10.244.2.10:80   27s
endpoints/nginx              <none>                                         10d
endpoints/nginx-deployment   10.244.1.10:80,10.244.1.11:80,10.244.2.6:80    9d

④ 删除 index.html

[root@master01 demo]# kubectl exec -it myapp3 -- rm -rf /usr/share/nginx/html/index.html

⑤ 再次查看关联后端的节点

[root@master01 demo]# kubectl get pod,svc,endpoints -o wide
NAME         READY   STATUS    RESTARTS   AGE     IP            NODE     NOMINATED NODE   READINESS GATES
pod/myapp1   1/1     Running   0          2m42s   10.244.1.27   node01   <none>           <none>
pod/myapp2   1/1     Running   0          2m42s   10.244.2.10   node02   <none>           <none>
pod/myapp3   0/1     Running   0          2m41s   10.244.1.28   node01   <none>           <none>

NAME                       TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)           AGE     SELECTOR
service/kubernetes         ClusterIP   10.96.0.1       <none>        443/TCP           10d     <none>
service/myapp              ClusterIP   10.96.35.59     <none>        80/TCP            2m41s   app=myapp
service/nginx              NodePort    10.96.75.23     <none>        80:32165/TCP      10d     app=nginx
service/nginx-deployment   NodePort    10.96.101.251   <none>        30000:31603/TCP   9d      app=nginx-deployment

NAME                         ENDPOINTS                                     AGE
endpoints/kubernetes         192.168.190.100:6443                          10d
endpoints/myapp              10.244.1.27:80,10.244.2.10:80                 2m41s
endpoints/nginx              <none>                                        10d
endpoints/nginx-deployment   10.244.1.10:80,10.244.1.11:80,10.244.2.6:80   9d

此时可以看到对于 readiness 探测失败,pod myapp3 无法进入  reday 状态,端点控制器将 pod myapp3 的 ip  从 endpoints 中剔除删除。

4.6 启动和退出动作

以下将演示在 Kubernetes 中如何定义容器的生命周期事件,包括容器启动后和终止前的操作,以及如何使用初始化容器来执行特定任务。

示例6:根据日志反馈的内容了解容器处于生命周期的哪个阶段

① 编辑 pod 的 yaml 配置文件

[root@master01 demo]# 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 Start >> /var/log/nginx/message"]  
# 执行的命令是往日志中写入启动信息
      preStop:          # 容器终止前执行的操作
        exec:           # 使用执行命令的方式
          command: ["/bin/sh", "-c", "echo Hello Stop >> /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         # 类型为目录或创建

② 启动 pod

[root@master01 demo]# kubectl create -f post.yaml
pod/lifecycle-demo created

③ 查看 pod 详情

[root@master01 demo]# kubectl get pods -o wide
NAME             READY   STATUS    RESTARTS   AGE   IP            NODE     NOMINATED NODE   READINESS GATES
lifecycle-demo   1/1     Running   0          6s    10.244.1.29   node01   <none>           <none>

④ 查看容器日志

[root@master01 demo]# kubectl exec -it lifecycle-demo -- cat /var/log/nginx/message
Hello initContainers
Start

由此可见,首先启动了 init 容器,然后启动成功后返回信息“Start”,代表启动成功。

⑤ 在 node01 节点查看日志

[root@node01 ~]# cd /data/volumes/nginx/log/
[root@node01 log]# ls
access.log  error.log  message
[root@node01 log]# cat message 
Hello initContainers
Start

⑥ 删除 pod 后,再在 node01 节点上查看日志

[root@master01 demo]# kubectl delete pod lifecycle-demo
pod "lifecycle-demo" deleted

[root@node01 log]# cat message 
Hello initContainers
Start
Stop

由此课件,当在容器被终结之前, Kubernetes 将发送一个 preStop 事件,即探针关闭生命周期结束。

三、补充概念

1. pod 的状态

pending

  • pod已经被系统认可了,但是内部的container还没有创建出来。这里包含调度到node上的时间以及下载镜像的时间,会持续一小段时间;

Running

  • pod已经与node绑定了(调度成功),而且pod中所有的container已经创建出来,至少有一个容器在运行中,或者容器的进程正在启动或者重启状态。--这里需要注意pod虽然已经Running了,但是内部的container不一定完全可用。因此需要进一步检测container的状态;

Succeeded

  • 这个状态很少出现,表明pod中的所有container已经成功的terminated了,而且不会再被拉起了;

Failed

  • pod中的所有容器都被terminated,至少一个container是非正常终止的。(退出的时候返回了一个非0的值或者是被系统直接终止)

unknown

  • 由于某些原因pod的状态获取不到,有可能是由于通信问题。 一般情况下pod最常见的就是前两种状态。而且当Running的时候,需要进一步关注container的状态。

2. Container 生命周期

Waiting

  • 启动到运行中间的一个等待状态;

Running

  • 运行状态;

Terminated

  • 终止状态。 如果没有任何异常的情况下,container应该会从Waiting状态变为Running状态,这时容器可用。

如果容器长时间处于 Waiting 状态,可以查看容器的 reason 字段,该字段会显示容器所处的状态和原因。如果 reason 显示容器再也无法启动,例如 ContainerCannotRun,整个服务启动就会迅速返回。这是一个失败状态返回的特性。

标签:容器,Kubernetes,demo,master01,探针,Pod,root,pod
From: https://blog.csdn.net/qq_64612585/article/details/139181809

相关文章

  • 改造 Kubernetes 自定义调度器
    原文出处:改造Kubernetes自定义调度器|Jayden'sBlog(jaydenchang.top)OverviewKubernetes默认调度器在调度Pod时并不关心特殊资源例如磁盘、GPU等,因此突发奇想来改造调度器,在翻阅官方调度器框架[1]、调度器配置[2]和参考大佬的文章[3]后,自己也来尝试改写一下。环境......
  • Kubernetes Service 之原理与 ClusterIP 和 NodePort 用法
    KubernetesService之原理与ClusterIP和NodePort用法Service定义在Kubernetes中,由于Pod是有生命周期的,如果Pod重启它的IP可能会发生变化以及升级的时候会重建Pod,我们需要Service服务去动态的关联这些Pod的IP和端口,从而使我们前端用户访问不受后端变更......
  • 部署kubernetes集群机器
    前言:部署Kubernetes集群机器是一项涉及多个步骤和要求的重要任务。以下是一些关于部署Kubernetes集群机器前言的要点:简介:Kubernetes(通常简称为K8s)是一个开源的容器编排系统,用于自动化部署、扩展和管理容器化应用程序。通过Kubernetes,您可以轻松地在集群中运行和管理多个容器......
  • 【K8s】专题八:Kubernetes 安装方法之 RKE
    以下内容均来自个人笔记并重新梳理,如有错误欢迎指正!如果对您有帮助,烦请点赞、关注、转发!欢迎扫码关注个人公众号!一、RKE简介RKE即 RancherKubernetesEngine,是由Rancher发布的一个极其简单、快速的Kubernetes安装程序,简化了Kubernetes集群的部署过程。RKE经过......
  • kubernetes部署mongoDB 单机版 自定义配置文件、密码、日志路径等
    官方镜像地址:https://hub.docker.com/_/mongo?tab=descriptiondocker版的mongo移除了默认的/etc/mongo.conf,修改了db数据存储路径为/data/db.创建configmap配置,注意不能加fork=true,否则Pod会变成Completed。apiVersion:v1kind:ConfigMapmetadata:name:mongodb-confdat......
  • 为什么网络流量监控如此重要?深入探讨网络流量探针的作用
    在当今高速发展的信息时代,网络流量监控已经成为维护网络安全与优化网络性能的关键手段。那么,什么是网络流量监控?为什么它如此重要?网络流量探针又扮演着怎样的角色?本文将带您深入了解这些关键问题。什么是网络流量监控?网络流量监控是指通过分析和管理网络中的数据流动来确保网络......
  • 私有云和多云管理平台 | Cloudpods v3.10.15 正式发布
    功能优化【主机】裸金属详情页增加部分属性信息【监控】优化告警策略,支持同时设置多监控指标【主机】支持透传设备自动探测【主机】LVM块存储支持快照【监控】简化Telegraf容器的挂载点【主机】新建VMware支持同时填写备注信息【存储】KVM支持对接LVM存储问题修......
  • Kubernetes-ConfigMap详解
    简介:一、ComfigMap的创建1.使用目录创建2.使用文件创建3.使用命令行创建二、Pod中使用ConfigMap1.使用ConfigMap代替环境变量2.使用ConfigMap设置命令行参数3.使用ConfigMap用做数据卷插件三、ConfigMap的热更新简介:ConfigMap功能在Kubernetes1.2版本中引入,许......
  • k8s(pod)详解
    一:Pod介绍pod资源的各种配置和原理关于很多yaml文件的编写,都是基于配置引出来的1:pod的结构和定义 每个Pod中都可以包含一个或者多个容器,这些容器可以分为2大类:1:用户所在的容器,数量可多可少(用户容器)2:pause容器,这是每个pod都会有的一个跟容器,作用有2个1、......
  • k8s——pod的资源配置文件详解(manifest)
    pod的资源配置文件(manifest)详细介绍pod的资源配置文件(mannifest)的各个字段的含义元数据字段是否必须类型含义由用户提供备注name必须strpod的名称用户提供在同一个namspace中唯一labels不必须map[str]str用户自主标识的k/y键值对由用户提供多用于ser......