文章目录

k8s之资源限制以及探针检查

一、资源限制

1、资源限制的使用

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

2、reuqest资源(请求)和limit资源(约束)

  • 当为Pod中的容器指定了request资源时,调度器就使用该信息来决定将Pod调度到哪个节点上。当还为容器指定了limit资源时,kubelet就会确保运行的容器不会使用超出所设的limit资源量。kubelet还会为容器预留所设的request资源量,供该容器使用。
  • 如果Pod所在的节点具有足够的可用资源,容器可以使用超过所设置的request资源量。不过,容器不可以使用超出所设置的limit资源量。
  • 如果给容器设置了内存的limit值,但未设置内存的request值,Kubernetes会自动为其设置与内存limit相匹配的request值。类似的,如果给容器设置了CPU的limit值但未设置CPU的request值,则Kubernetes自动为其设置CPU的request值,并使之与CPU的limit值匹配。

3、官网示例

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

image-20240524094106637

4、Pod和容器的资源请求和限制

spec.containers[].resources.requests.cpu
#定义创建容器时预分配的CPU资源
spec.containers[].resources.requests.memory
#定义创建容器时预分配的内存资源
spec.containers[].resources.requests.hugepages-<size>
#定义创建容器时预分配的巨页资源
spec.containers[].resources.limits.cpu
#定义cpu的资源上限
spec.containers[].resources.limits.memory
#定义内存的资源上限
spec.containers[].resources.limits.hugepages-<size>
#定义巨页的资源上限

5、资源类型

  • CPU 和内存都是资源类型。每种资源类型具有其基本单位。 CPU 表达的是计算处理能力,其单位是 Kubernetes CPUs。 内存的单位是字节。 如果你使用的是 Kubernetes v1.14 或更高版本,则可以指定巨页(Huge Page)资源。 巨页是 Linux 特有的功能,节点内核在其中分配的内存块比默认页大小大得多。
  • 例如,在默认页面大小为 4KiB 的系统上,你可以指定约束 hugepages-2Mi: 80Mi。 如果容器尝试分配 40 个 2MiB 大小的巨页(总共 80 MiB ),则分配请求会失败。
  • 说明:不能过量使用 hugepages- * 资源。 这与 memory 和 cpu 资源不同。

6、CPU资源单位

  • CPU资源的request和limit以cpu为单位。kubernetes中的一个cpu相当于1个vCPU(1个超线程)。
  • Kubernetes也支持带小数CPU的请求。spec.containers[].resources.requests.cpu为0.5的容器能够获得一个cpu的一半CPU资源(类似于cgroup对CPU资源的时间分片)。表达式0.1等价于表达式100m(毫核),表示每1000毫秒内容器可以使用的CPU时间总量为0.1*1000毫秒。

7、内存资源单位

  • 内存的request和limit以字节为单位。可以用证书表示,

  • 也可以用以10为底数的指数的单位(E、P、T、G、M、K)来表示,或者以2为底数的指数的单位(Ei、Pi、Ti、Gi、Mi、Ki)来表示。

  • 如1KB=103=1000,1MB=106=1000000=1000KB,1GB=10^9=1000000000=1000MB

  • 1KiB=210=1024,1MiB=220=1048576=1024KiB

8、官方文档

apiVersion: v1
kind: Pod
metadata:
  name: frontend
spec:
  containers:
  - name: app
    image: images.my-company.example/app:v4
    resources:
    #定义容器的资源请求和限制
      requests:
      #定义容器的资源请求
        memory: "64Mi"
        #容器启动时请求的内存量为64MiB
        cpu: "250m"
        #容器启动时请求的CPU为250m(即0.25个CPU核心)
      limits:
      #定义容器的资源限制
        memory: "128Mi"
        #容器可以使用的最大内存量为128MiB
        cpu: "500m"
        #容器可以使用的最大CPU为500m(即0.5个CPU核心)
  - name: log-aggregator
    image: images.my-company.example/log-aggregator:v6
    resources:
      requests:
        memory: "64Mi"
        cpu: "250m"
      limits:
        memory: "128Mi"
        cpu: "500m"
        
#此例子中 Pod 有两个 Container。每个 Container 的请求为 0.25 cpu 和 64MiB(226 字节)内存, 每个容器的资源约束为 0.5 cpu 和 128MiB 内存。 你可以认为该 Pod 的资源请求为 0.5 cpu 和 128 MiB 内存,资源限制为 1 cpu 和 256MiB 内存。

image-20240525013438869

9、资源限制

9.1 编写yaml资源配置清单
cd /opt/test
#切换目录

#编辑资源配置清单
vim test01.yaml
apiVersion: v1
kind: Pod
metadata:
  name: test1
spec:
  containers:
  - name: web
    image: nginx:1.18
    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: "123456"
    resources:
      requests:
        memory: "64Mi"
        cpu: "250m"
      limits:
        memory: "128Mi"
        cpu: "500m"

image-20240524215759722

9.2 释放内存(node节点,以node01为例)
  • 由于mysql对于内存的使用要求比较高,因此需要先检查内存的可用空间是否能够满足mysql的正常运行,若剩余内存不够,可对其进行释放操作。
9.2.1 查看内存
free -mh
#查看内存

#内存总量为3.7G,实际使用554M,因此可有内存应该为3.1G左右。但是由于有2.5G的内存被用于缓存,导致了free仅为647M。

image-20240524212204487

9.2.2 手动释放缓存
echo [1\2\3] > /proc/sys/vm/drop_caches

cat /proc/sys/vm/drop_caches
#查看清理页面缓存、目录项缓存和 inode 缓存的特殊文件

echo 3 > /proc/sys/vm/drop_caches
#释放页面缓存、目录项缓存和 inode 缓存。

free -mh
#查看内存

0:0是系统默认值,默认情况下表示不释放内存,由操作系统自动管理
1:释放页面缓存(pagecache)。
2:释放目录项缓存(dentries)和 inode 缓存。
3:释放页面缓存、目录项缓存和 inode 缓存。

image-20240524212613937

注意:

  • 如果因为是应用有像内存泄露、溢出的问题,从swap的使用情况是可以比较快速可以判断的,但free上面反而比较难查看。相反,如果在这个时候,我们告诉用户,修改系统的一个值,“可以”释放内存,free就大了。用户会怎么想?不会觉得操作系统“有问题”吗?所以说,既然核心是可以快速清空buffer或cache,也不难做到(这从上面的操作中可以明显看到),但核心并没有这样做(默认值是0),我们就不应该随便去改变它。
  • 一般情况下,应用在系统上稳定运行了,free值也会保持在一个稳定值的,虽然看上去可能比较小。当发生内存不足、应用获取不到可用内存、OOM错误等问题时,还是更应该去分析应用方面的原因,如用户量太大导致内存不足、发生应用内存溢出等情况,否则,清空buffer,强制腾出free的大小,可能只是把问题给暂时屏蔽了。
9.3 创建资源
kubectl apply -f tets01.yaml
#创建配置资源

image-20240524221501166

9.4 查看pod状态
kubectl get pod
#查看pod状态

#OOM(OverOfMemory:表示服务的运行超过了我们所设定的约束值。

kubectl describe pod test1
#查看详细信息

image-20240524221739524

image-20240524222134036

image-20240525013255777

image-20240524222324293

9.5 查看容器日志
kubectl logs test1 -c web
#查看nginx日志信息(nginx启动正常)

kubectl logs test1 -c db
#查看mysql日志信息(锁定问题容器为mysql)

image-20240524222620427

9.6 删除pod
kubectl delete -f test1
#删除pod资源

image-20240524222637799

9.7 修改yaml配置资源清单,提高mysql资源限制
#修改yaml配置资源清单
vim test1.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: test1
spec:
  containers:
  - name: web
    image: nginx:1.18
    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: "123456"
    resources:
      requests:
        memory: "512Mi"
        cpu: "0.5"
      limits:
        memory: "1024Mi"
        cpu: "1"

image-20240524221134175

9.8 再次创建资源
kubectl apply -f test1.yaml
#重新创建资源

image-20240524222731007

9.9 跟踪查看pod状态
kubectl get pod -owide -w
#跟踪查看pod状态

image-20240524222808236

9.10 查看pod详细信息
kubectl describe pod test1
#查看pod详细信息

image-20240524223016174

image-20240524223124939

image-20240524223157196

9.11 查看node资源使用
kubectl describe node node01
#查看node资源使用

------------------------------------------------------------------------------------------------------
说明:node01的配置为2C4G。

CPU Requests分析:
nginx的requests为250m,mysql的requests为500m,因此node01的CPU Requests为750m,在node01的两个核中使用占比为37%。

CPU Limits分析:
nginx到的limit为500m,mysql的limit为1,因此node01到的CPU Limits为1500m,在node01的两个核中使用占比为75%。

Memory Requests分析:
nginx的requests为64Mi,mysql的requests为512Mi,因此node01的内存Requests为576Mi,在node01的2G内存中使用占比为15%。

Memory Limits分析:
nginx的limits为128Mi,mysql的limit为1Gi,因此node01的1152Mi,在node01的2G内存中使用占比为31%。
------------------------------------------------------------------------------------------------------

image-20240524223731884

二、健康检查

1、健康检查的定义

  • 健康检查又称为探针(Probe),是由kubelet对容器执行的定期诊断。

2、探针的三种规则

2.1 livenessProbe存活探针
  • 判断容器是否正在运行。如果探测失败,则kubelet会杀死容器,并且容器将根据restartPolicy来设置Pod状态,如果容器不提供存活探针,则默认状态为Success。
2.2 readinessProbe就绪探针
  • 判断容器是否准备好接受请求。如果探测失败,端点控制器将从与Pod匹配的所有service endpoints中剔除删除该Pod的IP地址。初始延迟之前的就绪状态默认为Failure。如果容器不提供就绪探针,则默认状态为Success。
2.3 startupProbe启动探针(1.17版本新增)
  • 判断容器内的应用程序是否已启动,主要针对于不能确定具体启动时间的应用。如果匹配了startupProbe探测,则在startupProbe状态为Success之前,其他所有探针都处于无效状态,直到它成功后其他探针才起作用。如果startupProbe失败,kubelet将杀死容器,容器将根据restartPolicy来重启。如果容器没有配置startupProbe,则默认状态为Success。
2.4 同时定义
  • 以上三种规则可同时定义。在readinessProbe检测成功之前,Pod的running状态是不会变成ready状态的。

3、Probe支持的三种检测方法

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

4、探测结果

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

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

5、官方文档

https://kubernetes.io/zh/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/
#官方文档链接

image-20240524224140114

6、exec方式

6.1 官方示例
apiVersion: v1
kind: Pod
metadata:
  labels:
    test: liveness
  name: liveness-exec
spec:
  containers:
  - name: liveness
    image: registry.k8s.io/busybox
    args:
    - /bin/sh
    - -c
    - touch /tmp/healthy; sleep 30; rm -f /tmp/healthy; sleep 600
    livenessProbe:
    #定义存活探针
      exec:
      #执行exec探针命令
        command:
        - cat
        - /tmp/healthy
      initialDelaySeconds: 5
      periodSeconds: 5

#initalDeploySeconds:指定kubelet在执行第一次探测前应该等待5秒,即第一次探测是在容器启动后的第6秒才开始执行。默认是0秒,最小值是0。
#periodSeconds:指定了kubelet应该每5秒执行一次存活探测。默认是10秒,最小值是1

在这个配置文件中,可以看到 Pod 中只有一个容器。 periodSeconds 字段指定了 kubelet 应该每 5 秒执行一次存活探测。 initialDelaySeconds 字段告诉 kubelet 在执行第一次探测前应该等待 5 秒。 kubelet 在容器内执行命令 cat /tmp/healthy 来进行探测。 如果命令执行成功并且返回值为 0,kubelet 就会认为这个容器是健康存活的。 如果这个命令返回非 0 值,kubelet 会杀死这个容器并重新启动它。

------------------------------------------------------------------------------------------------------
补充:
#failureThreshold:当探测失败时,Kubernetes将在放弃之前重试的次数。存活探测情况下的放弃就意味着重新启动容器,就绪探测情况下的放弃Pod会被打上未就绪的标签。默认值是3,最小值是1。
#timeoutSeconds:探测的超时后等待多少秒。默认值是1秒,最小值是1。(在Kubernetes 1.20版本之前,exec探针会忽略timeoutSeconds,探针会无限期地持续运行,甚至可能超过所配置的限期,直到返回结果为止。)
------------------------------------------------------------------------------------------------------

image-20240524234633453

6.2 编写yaml资源配置清单
#编辑资源配置清单
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"]
        #检查/tmp/live文件是否存在。如果存在,探针会成功;如果不存在,探针会失败
      initialDelaySeconds: 1
      periodSeconds: 3

------------------------------------------------------------------------------------------------------
说明:
在这个配置文件中,可以看到Pod只有一个容器。
容器中的command字段表示创建一个/tmp/live文件后休眠30秒,休眠结束后删除该文件,并休眠10分钟。
仅使用livenessProbe存活探针,并使用exec检查方式,对/tmp/live文件进行存活检测。
initialDelaySeconds字段表示kubelet在执行第一次探测前应该等待1秒。
periodSeconds字段表示kubelet每隔3秒执行一次存活探测。
------------------------------------------------------------------------------------------------------

image-20240524224430810

6.3 创建资源
kubectl create -f exec.yaml
#创建资源

image-20240524224908847

6.4 跟踪查看pod状态
kubectl get pod -o wide -w
#跟踪查看pod状态,发现71秒时容器重启

image-20240524225055935

6.5 查看pod事件描述
kubectl describe pod liveness-exec
#查看pod资源详细信息

在容器启动37秒时,健康检查三次失败(倒推第一次检查在31秒),kubelet启动了killing程序并在70秒时拉取镜像创建新的容器,在71秒时完成第一次容器重启

image-20240524225756974

7、httpGet方式

7.1 官网示例
apiVersion: v1
kind: Pod
metadata:
  labels:
    test: liveness
  name: liveness-http
spec:
  containers:
  - name: liveness
    image: registry.k8s.io/e2e-test-images/agnhost:2.40
    args:
    - liveness
    livenessProbe:
      httpGet:
      #指定使用HTTP GET请求进行探测
        path: /healthz
        port: 8080
        httpHeaders:
        - name: Custom-Header
          value: Awesome
      initialDelaySeconds: 3
      periodSeconds: 3

------------------------------------------------------------------------------------------------------
在这个配置文件中,可以看到Pod只有一个容器。initialDealySeconds字段告诉kubelet再执行第一次探测前应该等待3秒。preiodSeconds字段指定了kubelet每隔3秒执行一次存活探测。kubelet会向容器内运行的服务(服务会监听8080端口)发送一个认为容器是健康存活的。如果处理程序返回失败代码,则kubelet会杀死这个容器并且重新启动它。
任何大于或等于200并且小于400的返回代码标示成功,其他返回代码都标示失败。
------------------------------------------------------------------------------------------------------

image-20240524234853881

7.2 编写yaml资源配置清单
#编辑资源配置清单
vim httpget.yaml
apiVersion: v1
kind: Pod
metadata:
  name: liveness-httpget
  namespace: default
spec:
  containers:
  - name: liveness-httpget-container
    image: nginx
    imagePullPolicy: IfNotPresent
    ports:
    - name: nginx
    #定义端口名称,下面探测时使用
      containerPort: 80
      #定义端口
    livenessProbe:
    #定义存活探针
      httpGet:
      #指定使用HTTP GET请求进行探测
        port: nginx
        #指定了要访问的容器的端口,为上面的nginx端口名称
        path: /index.html
        #这是要访问的nginx路径。表示站点目录下的index.html
      initialDelaySeconds: 1
      periodSeconds: 3
      timeoutSeconds: 10

image-20240524235335667

7.3 创建资源
kubectl apply -f httpget.yaml
#创建资源

kubectl get pod
#查看pod资源信息

kubectl describe pod liveness-httpget
#查看详细信息

image-20240524235715378

image-20240524235753723

7.4 删除Pod的index.html文件
kubectl exec -it liveness-httpget -- rm -f /usr/share/nginx/html/index.html
#删除index.html文件

image-20240525000207204

7.5 查看pod状态
kubectl get pod -w
#追踪查看pod状态,容器发生重启

image-20240525000259528

7.6 查看容器事件
kubectl describe pod liveness-httpget
#查看详细信息

#重启原因是HTTP探测得到的状态返回码是404,HTTP probe failed with statuscode: 404。
#重启完成后,不会再次重启,因为重新拉取的镜像中包含了index.html文件。

image-20240525000633280

8、tcpSocket方式

8.1 官方示例
apiVersion: v1
kind: Pod
metadata:
  name: goproxy
  labels:
    app: goproxy
spec:
  containers:
  - name: goproxy
    image: registry.k8s.io/goproxy:0.1
    ports:
    - containerPort: 8080
    readinessProbe:
      tcpSocket:
        port: 8080
      initialDelaySeconds: 15
      periodSeconds: 10
    livenessProbe:
    #定义了存活探针的配置
      tcpSocket:
      #定义了使用 TCP 套接字进行探针检查
        port: 8080
        #探针将尝试连接容器的8080端口
      initialDelaySeconds: 15
      #在容器启动后,等待15秒才开始进行存活检查
      periodSeconds: 20
      #每隔20秒执行一次存活检查
  
------------------------------------------------------------------------------------------------------
这个例子同时使用readinessProbe和livenessProbe探测。kubelet会在容器启动15秒后发送第一个readiness就绪探测。这会尝试连接goproxy容器的8080端口。如果探测成功,kubelet将继续每隔10秒运行一次检测。
除了readinessProbe探测,这个配置包括了一个livenessProbe探测。kubelet会在容器启动15秒后进行第一次livenessProbe探测。就像readinessProbe探测一样,会尝试连接goproxy容器的8080端口。如果livenessProbe探测失败,这个容器会被重新启动。
------------------------------------------------------------------------------------------------------

image-20240525000728086

8.2 编写yaml资源配置清单
#编辑资源配置清单
vim tcpsocket.yaml
apiVersion: v1
kind: Pod
metadata:
  name: liveness-tcpsocket
spec:
  containers:
  - name: liveness-tcpsocket-container
    image: nginx
    livenessProbe:
      initialDelaySeconds: 5
      timeoutSeconds: 1
      tcpSocket:
        port: 8080
      periodSeconds: 3

image-20240525001111610

8.3 创建资源
kubectl apply -f tcpsocket.yaml
#创建资源

kubectl get pod -w
#追踪查看pod信息,pod异常重启

image-20240525001853342

8.4 查看pod事件
kubectl describe pod liveness-tcpsocket
#查看详细信息
#重启原因是nginx使用的默认端口为80,8080端口的健康检查被拒绝访问

image-20240525002051149

8.5 删除pod资源
kubectl delete -f tcpsocket.yaml
#删除pod资源

image-20240525002117539

8.6 修改tcpSocket端口
#修改资源配置清单
vim tcpsocket.yaml
apiVersion: v1
kind: Pod
metadata:
  name: liveness-tcpsocket
spec:
  containers:
  - name: liveness-tcpsocket-container
    image: nginx
    livenessProbe:
    #定义了存活探针的配置
      initialDelaySeconds: 5
      #在容器启动后,等待5秒才开始进行存活检查
      timeoutSeconds: 1
      #每次存活探针尝试的超时时间设置为 1 秒
      tcpSocket:
      #定义了使用 TCP 套接字进行探针检查
        port: 80
        #修改端口为80
      periodSeconds: 3
      #每隔10秒执行一次存活检查

image-20240525001533435

8.7 重新创建资源
kubectl apply -f tcpsocket.yaml
#重新创建资源

kubectl get pod -o wide -w
#跟踪查看pod状态,启动正常,并未出现重启

image-20240525002315104

8.8 查看pod事件
kubectl describe pod liveness-tcpsocket
#查看详细信息,启动正常

image-20240525002410223

9、readinessProbe就绪探针1

9.1 编写yaml资源配置清单
#编辑资源配置清单
vim readiness-httpget.yaml
apiVersion: v1
kind: Pod
metadata:
  name: readiness-httpget
  namespace: default
spec:
  containers:
  - name: readiness-httpget-container
    image: nginx
    imagePullPolicy: IfNotPresent
    ports:
    - name: http
      containerPort: 80
    readinessProbe:
    #定义就绪探针的配置,用于确定容器是否准备好接受流量
      httpGet:
      #使用 HTTP GET 请求进行探针检查
        port: 80
        path: /index1.html
        #注意,这里设置个错误地址,#探针将尝试访问/index1.html路径
      initialDelaySeconds: 1
      #在容器启动后,等待1秒才开始进行就绪检查
      periodSeconds: 3
      #每隔 3 秒执行一次就绪检查
    livenessProbe:
    #定义存活探针的配置
      httpGet:
      #同样使用HTTP GET请求方式
        port: http
        #探针将尝试访问名为http的端口
        path: /index.html
        #探针将尝试访问/index.html 路径,Nginx的默认路径
      initialDelaySeconds: 1
      #等待1秒才开始进行存活检查
      periodSeconds: 3
      #每隔3秒执行一次存活检查
      timeoutSeconds: 10
      #每次存活探针尝试的超时时间设置为10秒

image-20240525003801794

9.2 创建资源
kubectl apply -f readiness-httpget.yaml
#创建资源

kubectl get pod
#查看pod状态
#STATUS为Running,但无法进入READY状态

image-20240525004216354

9.3 查看pod事件
kubectl describe pod readiness-httpget
#查看详细信息
#异常原因为readinessProbe检测的状态返回值为404,kubelet阻止pod进入READY状态

image-20240525004407339

9.4 查看日志
kubectl logs readiness-httpget
#查看日志信息

image-20240525004607171

9.5 为容器创建index1.html
kubectl exec -it readiness-httpget -- touch /usr/share/nginx/html/index1.html
#为容器新建文件

kubectl get pod
#查看pod状态

image-20240525004712805

10、readinessProbe就绪探针2

10.1 编写yaml资源配置清单
  • service探测
  • 如果探测失败,端点控制器将从与 Pod 匹配的所有service地址址endpoints中剔除删除该Pod的IP地。 初始延迟之前的就绪状态默认为Failure。如果容器不提供就绪探针,则默认状态为Success
#编辑资源配置清单
vim readiness-multi-nginx.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: nginx1
  labels:
    app: nginx
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
    ports:
    - name: http
      containerPort: 80
    readinessProbe:
      httpGet:
        port: http
        path: /index.html
      initialDelaySeconds: 5
      periodSeconds: 5
      timeoutSeconds: 10
---
apiVersion: v1
kind: Pod
metadata:
  name: nginx2
  labels:
    app: nginx
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
    ports:
    - name: http
      containerPort: 80
    readinessProbe:
      httpGet:
        port: http
        path: /index.html
      initialDelaySeconds: 5
      periodSeconds: 5
      timeoutSeconds: 10
---
apiVersion: v1
kind: Pod
metadata:
  name: nginx3
  labels:
    app: nginx
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
    ports:
    - name: http
      containerPort: 80
    readinessProbe:
      httpGet:
        port: http
        path: /index.html
      initialDelaySeconds: 5
      periodSeconds: 5
      timeoutSeconds: 10
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-svc
spec:
  selector:
  #service通过selector绑定到nginx集群中
    app: nginx
  type: ClusterIP
  ports:
  - name: http
    port: 80
    targetPort: 80

image-20240525005036993

image-20240525005206980

10.2 创建资源
kubectl apply -f readiness-multi-nginx.yaml
#创建资源

kubectl get pod,svc -owide
#查看pod,service状态,运行成功

image-20240525005615227

10.3 删除nginx1中的index.html,查看pod状态
kubectl exec -it nginx1 -- rm -f /usr/share/nginx/html/index.html
#删除nginx1中的index.html文件

kubectl get pod -owide -w
#追踪查看pod状态详细信息,nginx1的READY状态变为0/1

image-20240525005925631

10.4 查看pod事件
kubectl describe pod nginx1
#查看详细信息

#由于httpGet检测到的状态返回码为404,所以readinessProbe失败,kubelet将其设定为noready状态。

image-20240525010043238

10.5 查看service详情
kubectl describe svc nginx-svc
#查看service详细信息,nginx1被剔除出了service的终端列表

image-20240525010220516

10.6 查看终端
kubectl get endpoints
#查看关联的后端地址,终端中无nginx1的ip

image-20240525010320821

三、启动、退出动作

  • 启动探针会在容器启动后立即开始探测,并在探测成功前阻止其他探针(如存活探针和就绪探针)的探测。这有助于确保容器在完全启动并准备好之前不会被错误地终止或加入到服务负载均衡中。

1、编写yaml资源配置清单

#编辑资源配置清单
vim post.yaml
apiVersion: v1
kind: Pod
metadata:
  name: lifecycle-test
spec:
  containers:
  - name: lifecycle-test-container
    image: nginx
    lifecycle:
    #定义容器的生命周期钩子
      postStart:
      #容器启动后立即执行的命令(启动钩子)
        exec:
        #使用exec的方式进入容器执行命令
          command: ["/bin/sh","-c","echo Hello from the postStart handler >> /var/log/nginx/message"]
          #表示在容器启动后,立即输出Hello from the postStart handler到 /var/log/nginx/message文件中
      preStop:
      #容器停止前执行的命令
        exec:
        #使用exec的方式进入容器执行命令
          command: ["/bin/sh","-c","echo Hello from the postStop handler >> /var/log/nginx/message"]
          #表示在容器停止前,立即输出Hello from the postStop handler到 /var/log/nginx/message文件中
    volumeMounts:
    #定义容器内的卷挂载点
    - name: message-log
    #挂载的卷的名字
      mountPath: /var/log/nginx/
      #容器内的挂载路径
      readOnly: false
      #卷是否以只读方式挂载。false表示否
  initContainers:
  #定义Pod启动前运行的初始化容器列表
  - name: init-nginx
    image: nginx
    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:
    #将宿主机上的一个目录或文件挂载到Pod中
      path: /data/volumes/nginx/log/
      #宿主机上的文件或目录路径
      type: DirectoryOrCreate
      #如果指定的路径不存在,则会创建这个目录

image-20240525011501910

2、创建资源

kubectl apply -f post.yaml
#创建资源

kubectl get pod -owide -w
#跟踪查看pod状态

image-20240525011632256

3、查看pod事件

kubectl describe pod lifecycle-test
#查看详细信息

image-20240525011831044

4、查看容器日志

kubectl exec -it lifecycle-test -- cat /var/log/nginx/message
#查看容器日志

#init容器先执行,然后当一个主容器启动后,kubernetes将立即发送postStart事件。

image-20240525011957777

5、关闭容器后查看节点挂载文件

kubectl delete -f post.yaml
#删除,关闭容器

node01节点操作:

cat /data/volumes/nginx/log/message 
#查看节点挂载的文件

#当在容器被终结之前,kubernetes将发送一个postStop事件。

image-20240525012336461

6、重新创建资源,查看容器日志

kubectl apply -f post.yaml
#重新创建资源

kubectl exec -it lifecycle-test -- cat /var/log/nginx/message
#查看容器日志,再次发送postStart事务

image-20240525012850164

四、总结

1、探针

探针分为3种

  • livenessProbe(存活探针)∶判断容器是否正常运行,如果失败则杀掉容器(不是pod),再根据重启策略是否重启容器
  • readinessProbe(就绪探针)∶判断容器是否能够进入ready状态,探针失败则进入noready状态,并从service的endpoints中剔除此容器
  • startupProbe∶判断容器内的应用是否启动成功,在success状态前,其它探针都处于无效状态

2、检查方式

检查方式分为3种

  • exec∶使用 command 字段设置命令,在容器中执行此命令,如果命令返回状态码为0,则认为探测成功
  • httpget∶通过访问指定端口和url路径执行http get访问。如果返回的http状态码为大于等于200且小于400则认为成功
  • tcpsocket∶通过tcp连接pod(IP)和指定端口,如果端口无误且tcp连接成功,则认为探测成功

3、常用的探针可选参数

常用的探针可选参数有4个

  • initialDelaySeconds∶ 容器启动多少秒后开始执行探测
  • periodSeconds∶探测的周期频率,每多少秒执行一次探测
  • failureThreshold∶探测失败后,允许再试几次
  • timeoutSeconds ∶ 探测等待超时的时间
Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐