k8s学习-pod的生命周期

文章目录


前言

本文是k8s的学习笔记,资源是
【k8s教程】薪享宏福Kubernetes v1.29 |2024最新版!B站最强!百万播放汪洋授课,轻松拿捏k8s


一、pod的生命周期

pod的生命周期主要有两大块内容

分别是initc,mainc

mainc又有两大特性,分别是钩子和探针

探针这里分为了启动探测,就绪探测,存活探测

钩子分为启动前钩子和启动后钩子

本文主要就围绕这些内容进行展开。

二、initC

initC是一个init容器,它跟普通的容器是很像的

但是有以下几点点

1.initc是线性执行的,每个init容器都必须在下一个init容器启动之前成功完成,否则阻塞

2.init容器总是运行到成功完成为止,如果有一个init容器失败,都从头重新开始

3.如果 Pod 的 Init 容器失败,Kubernetes会不断地重启该Pod,直到Init 容器成功为止。然而,如果Pod 对应的restartPolicy为Never,它不会重新启动

实验一

新创建下面这个pod,观察get pod 和 describe,

再分别执行下面的命令,就可以看到pod的特性--线性执行

yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: initc-1
  labels:
    app: initc
spec:
  containers:
  - name: myapp-container
    image: wangyanglinux/tools:busybox
    command: ['sh', '-c', 'echo The app is running! && sleep 3600']
  initContainers:
  - name: init-myservice
    image: wangyanglinux/tools:busybox
    command: ['sh', '-c', 'until nslookup myservice; do echo waiting for myservice; sleep 2; done;']
  - name: init-mydb
    image: wangyanglinux/tools:busybox
    command: ['sh', '-c', 'until nslookup mydb; do echo waiting for mydb; sleep 2; done;']
bash 复制代码
kubectl  create svc clusterip myservice --tcp=80:80
kubectl  create svc clusterip mydb --tcp=80:80

实验二

新创建这个pod,观察get pod ,describe,和logs

就会发现init失败,原因是init的返回码是1,也就是没有成功。

把下面的返回码和name给再改一下,再新创建一个pod

就会发现成功了。也就是印证了init的另外一个特性,成功的返回码为0

yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
  labels:
    app: myapp
spec:
  containers:
  - name: myapp
    image: wangyanglinux/myapp:v1.0
  initContainers:
  - name: randexit
    image: wangyanglinux/tools:randexitv1
    args: ["--exitcode=1"]

三、探针

探针是由当前节点的kubelet对容器执行的定期诊断

探针的方式

要执行诊断,kubelet调用由容器实现的Handler

有三种类型

  • ExecAction:在容器内执行指定命令
  • TCPSocketAction:对指定端口上的容器的IP地址进行TCP检查
  • HTTPGetAction:对指定的端口和路径上的容器的IP地址进行HTTPGet请求。

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

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

探针类型

在上面我们说了探针有三种类型

分别是

  • 开始检测 startupProbe
  • 存活检测 livenessProbe
  • 就绪探测 readinessProbe

就绪探测

如果pod内部的容器不添加就绪探测,默认就绪。

如果添加了就绪探测,只有就绪通过以后,才标记修改为就绪状态。

当前pod内的所有的容器都就绪,才标记当前Pod就绪

成功:将当前的C标记为就绪

失败:静默(不进行任何处理,本身就是非就绪的)

未知:静默

实验

下面我们要体验就绪探测,按照下面这张图进行pod的创建和svc的创建

svc有两大特性

1.标签的子集匹配

2.pod必须是就绪状态

关于svc,后面还会有详细的讲解

首先要先把我们之前创建的pod和service给删除了

bash 复制代码
kubectl delete pod --all
bash 复制代码
kubectl delete service svc名称

1.创建pod
bash 复制代码
mkdir 6

1.pod.yaml

yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: pod-1
  namespace: default
  labels:
    app: myapp
spec:
  containers:
  - name: myapp-1
    image: wangyanglinux/myapp:v1.0

2.pod.yaml

yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: pod-2
  namespace: default
  labels:
    app: myapp
    version: v1
spec:
  containers:
  - name: myapp-1
    image: wangyanglinux/myapp:v1.0
2.创建svc
bash 复制代码
kubectl create svc clusterip myapp --tcp=80:80
3.实验标签子集

创建这个3.pod.yaml

yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: pod-3
  namespace: default
  labels:
    app: test
    version: v1
spec:
  containers:
  - name: myapp-1
    image: wangyanglinux/myapp:v1.0
bash 复制代码
kubectl create -f 3.pod.yaml

然后再

bash 复制代码
curl myapp的ip/hostname.html

会发现,没有pod-3,因为这个pod的label,并不在我们的子集匹配里面

4.实验基于HTTP的就绪探测

创建4.pod.yaml

yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: readiness-httpget-pod
  namespace: default
  labels:
    app: myapp
    env: test
spec:
  containers:
  - name: readiness-httpget-container
    image: wangyanglinux/myapp:v1.0
    imagePullPolicy: IfNotPresent
    readinessProbe:
      httpGet:
        port: 80
        path: /index1.html
      initialDelaySeconds: 1
      periodSeconds: 3

然后再

bash 复制代码
curl myapp的ip/hostname.html

会发现也没有这个,因为这个就绪探测是通不过的

我们可以手动的创建这个HTML

5.实验基于exec的就绪探测

创建5.pod.yaml

这个会检查这个文件是否存在

在新创建的时候,就可以

kubectl get pod -w 监测pod的状态

yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: readiness-exec-pod
  namespace: default
spec:
  containers:
  - name: readiness-exec-container
    image: wangyanglinux/tools:busybox
    imagePullPolicy: IfNotPresent
    command: ["/bin/sh","-c","touch /tmp/live ; sleep 60; rm -rf /tmp/live; sleep 3600"]
    readinessProbe:
      exec:
        command: ["test","-e","/tmp/live"]
      initialDelaySeconds: 1
      periodSeconds: 3
6.实验基于TCP的就绪探测

TCP是作为补充的一种方式,但是有了HTTP和exec基本够用了,知道了就行。

yaml 复制代码
 apiVersion: v1
 kind: Pod
 metadata:
  name: readiness-tcp-pod
 spec:
  containers:
  - name: readiness-exec-container
    image: wangyanglinux/myapp:v1.0
    readinessProbe:
      initialDelaySeconds: 5
      timeoutSeconds: 1
      tcpSocket:
        port: 80

存活探测

如果pod内部不指定存活探测,可能会发生容器运行但是无法提供服务的情况

成功:静默

失败:根据重启的策略进行重启的动作

未知:静默

存活探测如果探测失败,是会把现在容器给杀死,再重新创建一个容器

实验

创建7.pod.yaml

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

过段时间会发现,重启了1次

创建下面的这个pod,然后把index给删除,进行实验

yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: liveness-httpget-pod
  namespace: default
spec:
  containers:
  - name: liveness-httpget-container
    image: wangyanglinux/myapp:v1.0
    imagePullPolicy: IfNotPresent
    ports:
    - name: http
    containerPort: 80
    livenessProbe:
      httpGet:
        port: 80
        path: /index.html
      initialDelaySeconds: 1
      periodSeconds: 3
      timeoutSeconds: 3

启动探测

实验

先创建pod,然后进入到这个容器里面

先创建/usr/local/nginx/html/index2.html,会发现pod没有处于就绪状态

然后再创建/usr/local/nginx/html/index1.html,会发现pod处于就绪状态

该实验说明了,启动探测执行完,再执行就绪探测

yaml 复制代码
apiVersion: v1
 kind: Pod
 metadata:
  name: startupprobe-1
  namespace: default
 spec:
  containers:
  - name: myapp-container
    image: wangyanglinux/myapp:v1.0
    imagePullPolicy: IfNotPresent
    ports:
    - name: http
      containerPort: 80
    readinessProbe:
      httpGet:
        port: 80
        path: /index2.html
      initialDelaySeconds: 1
      periodSeconds: 3
    startupProbe:
      httpGet:
        path: /index1.html
        port: 80
      failureThreshold: 30
      periodSeconds: 10

四、钩子

钩子分为启动后钩子和关闭前钩子

启动后钩子可能会没有执行完就执行到了容器的启动命令

关闭前钩子是在容器被杀死前执行。

执行方式跟探针相比,少了一个TCP,不过TCP的方式真的很low

实验

基于exec的

创建 10.pod.yaml,然后创建这个pod

当容器创建好之后,进入到容器里面

我们就会看到/usr/share/message里面写入了postStart

yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: lifecycle-exec-pod
spec:
  containers:
  - name: lifecycle-exec-container
    image: wangyanglinux/myapp:v1
    lifecycle:
      postStart:
        exec:
          command: ["/bin/sh", "-c", "echo postStart > /usr/share/message"]
      preStop:
        exec:
          command: ["/bin/sh", "-c", "echo preStop > /usr/share/message"]

然后执行一个小脚本

bash 复制代码
while true;
do
cat message
done

再把这个容器给delete掉,就会看到打印preStop

基于HTTP的

先开启这个

bash 复制代码
docker run -it --rm -p 1234:80 wangyanglinux/myapp:v1.0

11.pod.yaml

然后把下面的这个pod创建再删除

yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: lifecycle-httpget-pod
  labels:
    name: lifecycle-httpget-pod
spec:
  containers:
  - name: lifecycle-httpget-container
    image: wangyanglinux/myapp:v1.0
    ports:
      - containerPort: 80
    lifecycle:
      postStart:
        httpGet:
          host: 192.168.66.11
          path: index.html
          port: 1234
      preStop:
        httpGet:
          host: 192.168.66.11
          path: hostname.html
          port: 1234

就会发现请求了两次

这里还有一个符合的实验。想做可以做一下

yaml 复制代码
apiVersion: v1
 kind: Pod
 metadata:
  name: lifecycle-pod
  labels:
    app: lifecycle-pod
 spec:
  containers:
  - name: busybox-container
    image: wangyanglinux/tools:busybox
    command: ["/bin/sh","-c","touch /tmp/live ; sleep 600; rm -rf /tmp/live; 
sleep
 3600"]
    livenessProbe:
      exec:
        command: ["test","-e","/tmp/live"]
      initialDelaySeconds: 1
      periodSeconds: 3
    lifecycle:
      postStart:
        httpGet:
          host: 192.168.66.11
          path: index.html
          port: 1234
      preStop:
        httpGet:
          host: 192.168.66.11
          path: hostname.html
          port: 1234
  - name: myapp-container
    image: wangyanglinux/myapp:v1.0
    livenessProbe:
      httpGet:
        port: 80
        path: /index.html
      initialDelaySeconds: 1
      periodSeconds: 3
      timeoutSeconds: 3
    readinessProbe:
      httpGet:
        port: 80
path: /index1.html
 initialDelaySeconds: 1
 periodSeconds: 3
 initContainers:- name: init-myservice
 image: wangyanglinux/tools:busybox
 command: ['sh', '-c', 'until nslookup myservice; do echo waiting for 
myservice; sleep 2; done;']- name: init-mydb
 image: wangyanglinux/tools:busybox
 command: ['sh', '-c', 'until nslookup mydb; do echo waiting for mydb; sleep 
2; done;']
相关推荐
nvd112 小时前
用terraform 创建一个GKE private cluster
云原生·kubernetes·terraform·gke
Q飞了2 小时前
深入理解k8s中pod、service、deployment和statefulSet等工作负载--图文篇
云原生·容器·kubernetes
charlie1145141912 小时前
理解C++20的革命特性——协程支持2:编写简单的协程调度器
c++·学习·算法·设计模式·c++20·协程·调度器
李宥小哥3 小时前
C#基础10-结构体和枚举
java·开发语言·c#
文火冰糖的硅基工坊3 小时前
[人工智能-综述-21]:学习人工智能的路径
大数据·人工智能·学习·系统架构·制造
领创工作室3 小时前
安卓设备分区作用详解-测试机红米K40
android·java·linux
JJJJ_iii3 小时前
【深度学习01】快速上手 PyTorch:环境 + IDE+Dataset
pytorch·笔记·python·深度学习·学习·jupyter
好奇龙猫3 小时前
日语学习-日语知识点小记-进阶-JLPT-N1阶段应用练习(5):语法 +考え方18+2022年7月N1
学习
朝新_4 小时前
【EE初阶 - 网络原理】网络通信
java·开发语言·网络·php·javaee