• [云原生] K8s之pod进阶


    一、pod的状态说明

    (1)Pod 一直处于Pending状态

    Pending状态意味着Pod的YAML文件已经提交给Kubernetes,API对象已经被创建并保存在Etcd当中。但是,这个Pod里有些容器因为某种原因而不能被顺利创建。比如,调度不成功(可以通过kubectl describe pod命令查看到当前Pod的事件,进而判断为什么没有调度)。

    可能原因:资源不足(集群内所有的Node都不满足该Pod请求的CPU、内存、GPU等资源);      HostPort  已被占用(通常推荐使用Service对外开放服务端口)。

    (2)Pod一直处于Waiting 或 ContainerCreating状态

    首先还是通过 kubectl describe pod命令查看当前Pod的事件。可能的原因有:
    1)镜像拉取失败,比如镜像地址配置错误、拉取不了国外镜像源(gcr.io)、私有镜像密钥配置错误、镜像太大导致拉取超时 (可以适当调整kubelet的-image-pull-progress-deadline和-runtime-request-timeout选项)等。
    2)CNI网络错误,一般需要检查CNI网络插件的配置,比如:无法配置Pod 网络、无法分配IP地址。
    3)容器无法启动,需要检查是否打包了正确的镜像或者是否配置了正确的容器参数
    4)Failed create pod sandbox,查看kubelet日志,原因可能是磁盘坏道(input/output error)。

    (3)Pod 一直处于ImagePullBackOff状态


    通常是镜像名称配置错误或者私有镜像的密钥配置错误导致。

    (4)Pod 一直处于CrashLoopBackOff状态

     
    此状态说明容器曾经启动了,但又异常退出。这时可以先查看一下容器的日志。
    通过命令kubectl logs 和kubectl logs --previous 可以发下一些容器退出的原因,比如:容器进程退出、健康检查失败退出;此时如果还未发现线索,还而已到容器内执行命令(kubectl exec cassandra - cat /var.log/cassandra/system.loq)来进一步查看退出原因;如果还是没有线索,那就需要SSH登录该Pod所在的Node上,查看Kubelet或者Docker的日志进一步排查。

    (5)  Pod处于Error状态


    通常处于Error状态说明Pod启动过程中发生了错误。

    常见的原因:依赖的ConfigMap、Secret或PV等不存在;请求的资源超过了管理员设置的限制,比如超过了LimitRange等;违反集群的安全策略,比如违反了PodSecurityPolicy.等;容器无法操作集群内的资源,比如开启RDAC后,需要为ServiceAccount配置角色绑定。

    (6)  Pod 处于Terminating或 Unknown状态

     从v1.5开始,Kubernetes不会因为Node失联而删除其上正在运行的Pod,而是将其标记为Terminating 或 Unknown 状态。想要删除这些状态的Pod有三种方法:

    1)从集群中删除Node。使用公有云时,kube-controller-manager会在VM删除后自动删除对应的Node。而在物理机部署的集群中,需要管理员手动删除Node(kubectl delete node)。

    2)Node恢复正常。kubelet会重新跟kube-apiserver通信确认这些Pod的期待状态,进而再决定删除或者继续运行这些Pod。用户强制删除,用户可以执行(kubectl delete pods pod-name --grace-period=0 --force)强制删除Pod。除非明确知道Pod的确处于停止状态(比如Node所在VM或物理机已经关机),否则不建议使用该方法。特别是StatefulSet 管理的Pod,强制删除容易导致脑裂或数据丢失等问题。

    3)Pod行为异常,这里所说的行为异常是指Pod没有按预期的行为执行,比如没有运行podSpec 里面设置的命令行参数。这一般是podSpec yaml文件内容有误,可以尝试使用 --validate 参数重建容器,比如(kubectl delete pod mypod 和 kubectl create --validate -f mypod.yaml);也可以查看创建后的podSpec是否是对的,比如(kubectl get pod mypod -o yaml);修改静态Pod的Manifest后未自动重建,kubelet 使用inotify 机制检测 /etc/kubernetes/manifests 目录(可通过 kubelet 的 -pod-manifest-path 选项指定)中静态Pod的变化,并在文件发生变化后重新创建相应的 Pod。但有时也会发现修改静态Pod的 Manifest后未自动创建新 Pod的情景,此时已过简单的修复方法是重启 Kubelet。

    Unknown 这个异常状态意味着Pod的状态不能持续地被 kubelet汇报给 kube-apiserver,这很有可能是主从节点(Master 和 Kubelet)间的通信出现了问题。

    (7)pod从创建到成功或失败的事件

    PodScheduled
    pod正处于调度中,刚开始调度的时候,hostip还没绑定上,持续调度之后,有合适的节点就会绑定hostip,然后更新etcd数据

    Initialized
    pod中的所有初始化容器已经初启动完毕

    Ready
    pod中的容器可以提供服务了

    Unschedulable
    不能调度,没有合适的节点

     
    CrashLoopBackOff:    容器退出,kubelet正在将它重启
    InvalidImageName:    无法解析镜像名称
    ImageInspectError:   无法校验镜像
    ErrImageNeverPull:   策略禁止拉取镜像
    ImagePullBackOff:    正在重试拉取
    RegistryUnavailable: 连接不到镜像中心
    ErrImagePull:        通用的拉取镜像出错
    CreateContainerConfigError: 不能创建kubelet使用的容器配置
    CreateContainerError: 创建容器失败
    m.internalLifecycle.PreStartContainer 执行hook报错
    RunContainerError:   启动容器失败
    PostStartHookError:   执行hook报错
    ContainersNotInitialized: 容器没有初始化完毕
    ContainersNotReady:   容器没有准备完毕
    ContainerCreating:    容器创建中
    PodInitializing:pod   初始化中
    DockerDaemonNotReady:  docker还没有完全启动
    NetworkPluginNotReady: 网络插件还没有完全启动
    Evicte:     pod被驱赶

    二、Pod 容器资源限制 

    2.1 资源限制的了解 

      在我前面Docker的Cgroup文章中,就提到过,为什么我们对容器进行资源限制。同理:首先K8s中pod使用宿主机的资源默认情况下是无节制的,但是当一个集群搭建成功后并投入生产环境中。如果其中的某一个pod因为不明原因出现了bug,疯狂占用宿主机资源,抢占其他pod的资源。势必会导致整个集群的瘫痪,所以pod资源的限制是非常有必要的

     在资源控制器中我们也可以准确的找到相应的资源控制字段:

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

    在官方文档中(资源配额 | Kubernetes) 我们可以得知:pod控制的资源总共为三大类:

    cpu,memory,hugepages(巨页)。其中我们运用最多的限制还是cpu和memory。

     (1)cpu限制的参数了解

     pod对于cpu限制的参数有两种表达形式:

    第一种是指定个数的表达形式,例如:1 ,2, 0.5 ,0.2 ,0.3 指定cpu的个数(该个数可以为整数,也可以为小数点后一位的小数)

    第二种是以毫核为单位的表达形式:100m  500m   1000m   2000m (这里1000m等价于一个cpu,该方式来自于cpu时间分片原理得来) 

    (2)memory的表达形式 

    pod对内存参数的要求十分严谨。对硬件有过研究的朋友,应该会了解到,我们常常提到的GB,MB,TB其实是于实际字节总数是有误差的(原因是GB是以10为底数计量,而真正的换算是以2为底数计量。导致了总量的误差。)而真正没有此误差的单位是Ki  Mi  Gi  Ti 

    所以k8s中pod资源限制为了对pod的内存限制更为精准,采用的单位是 Ki  Mi  Gi  Ti 

    2.2 实例运用 

    需求:创建一个deployment资源,镜像使用nginx:latest,创建3个pod副本,镜像拉取策略使用IfNotPresent,重启策略使用Always,容器资源预留cpu 0.25个,内存128MiB,上限最多1个cpu,1g内存

    1. kubectl create deployement nginx-test --images=nginx:latest --dry-run=client -o yaml >test.yaml
    2. vim test.yaml
    3. apiVersion: apps/v1
    4. kind: Deployment
    5. metadata:
    6. creationTimestamp: null
    7. labels:
    8. app: nginx-test
    9. name: nginx-test
    10. spec:
    11. replicas: 3
    12. selector:
    13. matchLabels:
    14. app: nginx-test
    15. template:
    16. metadata:
    17. labels:
    18. app: nginx-test
    19. spec:
    20. containers:
    21. - image: nginx:latest
    22. name: nginx
    23. resources:
    24. requests:
    25. memory: "128Mi"
    26. cpu: "250m"
    27. limits:
    28. memory: "1Gi"
    29. cpu: "1"
    30. imagePullPolicy: IfNotPresent
    31. restartPolicy: Always
    32. kubectl apply -f test.yaml
    1. #查看pod的资源使用情况
    2. kubectl describe pod nginx-test

    1. #查看node节点pod资源使用详情
    2. kubectl describe node node02

    三、Pod 容器的探针 

    3.1 探针的概念及其作用 

     探针是由 kubelet 对容器执行的定期诊断(pod中探针又分为三类):

     存活探针(livenessProbe)探测容器是否运行正常。如果探测失败则kubelet杀掉容器(不是Pod),容器会根据重启策略决定是否重启

    就绪探针(readinessProbe)探测Pod是否能够进入READY状态,并做好接收请求的准备。如果探测失败Pod则会进入NOTREADY状态(READY为0/1)并且从所关联的service资源的端点(endpoints)中踢出,service将不会再把访问请求转发给这个Pod

    启动探针(startupProbe)探测容器内的应用是否启动成功,在启动探针探测成功之前,其它类型的探针都会暂时处于禁用状态 

     注意:启动探针只是在容器启动后按照配置满足一次后就不再进行后续的探测了。存活探针和就绪探针会一直探测到Pod生命周期结束为止

    kubectl explain pod.spec.containers

    3.2 探针的探测方式  

    exec : 通过command字段设置在容器内执行的Linux命令来进行探测,如果命令返回码为0,则认为探测成功,返回码非0则探测失败

    httpGet : 通过向容器的指定端口和uri路径发起HTTP GET请求,如果HTTP返回状态码为 >=200且<400的(2XX,3XX),则认为探测成功,返回状态码为4XX,5XX则探测失败

    tcpSocket1 : 通过向容器的指定端口发送tcp三次握手连接,如果端口正确却tcp连接成功,则认为探测成功,tcp连接失败则探测失败 

    探针探测结果有以下值:
    Success:表示通过检测。
    Failure:表示未通过检测。
    Unknown:表示检测没有正常进行。
     

    3.3 探针字段 

    探针(Probe)有许多可选字段,可以用来更加精确的控制Liveness和Readiness两种探针的行为(Probe):

    • initialDelaySeconds:容器启动后要等待多少秒后就探针开始工作,单位“秒”,默认是 0s,最小值是 0s;
    • periodSeconds:执行探测的时间间隔(单位是秒),默认为 10s,最小值是 1s,
    • timeoutSeconds:探针执行检测请求后,等待响应的超时时间,默认为 1s,最小值是 1s,
    • successThreshold:探针检测失败后认为成功的最小连接成功次数,默认为 1,在 Liveness和startup探针中必须为 1,最小值为 1。
    • failureThreshold:探测失败的重试次数,重试一定次数后将认为失败,默认为 3,最小值为 1

    3.4 探针实验测试 

     (1)LivenessProbe 探针使用

    1) 通过exec方式做健康探测 
    1. apiVersion: v1
    2. kind: Pod
    3. metadata:
    4. name: demo-live
    5. labels:
    6. app: demo-live
    7. spec:
    8. containers:
    9. - name: demo-live
    10. image: centos:7
    11. args: #创建测试探针探测的文件
    12. - /bin/sh
    13. - -c
    14. - touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600
    15. livenessProbe:
    16. initialDelaySeconds: 10 #延迟检测时间
    17. periodSeconds: 5 #检测时间间隔
    18. exec: #使用命令检查
    19. command: #指令,类似于运行命令sh
    20. - cat #sh 后的第一个内容,直到需要输入空格,变成下一行
    21. - /tmp/healthy #由于不能输入空格,需要另外声明,结果为sh cat"空格"/tmp/healthy
    22. 容器在初始化后,执行(/bin/sh -c "touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600")首先创建一个 /tmp/healthy 文件,然后执行睡眠命令,睡眠 30 秒,到时间后执行删除 /tmp/healthy 文件命令。而设置的存活探针检检测方式为执行 shell 命令,用 cat 命令输出 healthy 文件的内容,如果能成功执行这条命令一次(默认successThreshold:1),存活探针就认为探测成功,由于没有配置(failureThreshold、timeoutSeconds),所以执行(cat /tmp/healthy)并只等待1s,如果1s内执行后返回失败,探测失败。在前 30 秒内,由于文件存在,所以存活探针探测时执行 cat /tmp/healthy 命令成功执行。30 秒后 healthy 文件被删除,所以执行命令失败,Kubernetes 会根据 Pod 设置的重启策略来判断,是否重启 Pod。

    2)通过HTTP方式做健康探测  
    1. vim httpget.yaml
    2. apiVersion: v1
    3. kind: Pod
    4. metadata:
    5. name: liveness-httpget
    6. namespace: default
    7. spec:
    8. containers:
    9. - name: liveness-httpget-container
    10. image: soscscs/myapp:v1
    11. imagePullPolicy: IfNotPresent
    12. ports:
    13. - name: http
    14. containerPort: 80
    15. livenessProbe:
    16. httpGet:
    17. port: http
    18. path: /index.html
    19. initialDelaySeconds: 1
    20. periodSeconds: 3
    21. timeoutSeconds: 10
    22. kubectl create -f httpget.yaml
    23. kubectl exec -it liveness-httpget -- rm -rf /usr/share/nginx/html/index.html
    24. kubectl get pods
    25. 在这个配置文件中,可以看到 Pod 也只有一个容器。initialDelaySeconds 字段告诉 kubelet 在执行第一次探测前应该等待 3 秒。periodSeconds 字段指定了 kubelet 每隔 3 秒执行一次存活探测。kubelet 会向容器内运行的服务(服务会监听 8080 端口)发送一个 HTTP GET 请求来执行探测。如果服务器上 /healthz 路径下的处理程序返回成功代码,则 kubelet 认为容器是健康存活的。如果处理程序返回失败代码,则 kubelet 会杀死这个容器并且重新启动它。
    26. 任何大于或等于 200 并且小于 400 的返回代码标示成功,其它返回代码都标示失败。

    3)通过TCP方式做健康探测 
    1. vim tcpsocket.yaml
    2. apiVersion: v1
    3. kind: Pod
    4. metadata:
    5. name: probe-tcp
    6. spec:
    7. containers:
    8. - name: nginx
    9. image: soscscs/myapp:v1
    10. livenessProbe:
    11. initialDelaySeconds: 5
    12. timeoutSeconds: 1
    13. tcpSocket:
    14. port: 8080
    15. periodSeconds: 10
    16. failureThreshold: 2
    17. kubectl create -f tcpsocket.yaml
    18. kubectl exec -it probe-tcp -- netstat -natp
    19. Active Internet connections (servers and established)
    20. Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
    21. tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 1/nginx: master pro
    22. kubectl get pods -w
    23. NAME READY STATUS RESTARTS AGE
    24. probe-tcp 1/1 Running 0 1s
    25. probe-tcp 1/1 Running 1 25s #第一次是 init(5秒) + period(10秒) * 2
    26. probe-tcp 1/1 Running 2 45s #第二次是 period(10秒) + period(10秒) 重试了两次
    27. probe-tcp 1/1 Running
    28. 这个例子同时使用 readinessProbe 和 livenessProbe 探测。kubelet 会在容器启动 5 秒后发送第一个 readinessProbe 探测。这会尝试连接 goproxy 容器的 8080 端口。如果探测成功,kubelet 将继续每隔 10 秒运行一次检测。除了 readinessProbe 探测,这个配置包括了一个 livenessProbe 探测。kubelet 会在容器启动 15 秒后进行第一次 livenessProbe 探测。就像 readinessProbe 探测一样,会尝试连接 goproxy 容器的 8080 端口。如果 livenessProbe 探测失败,这个容器会被重新启动。

    (2)就绪检测(ReadinessProbe) 探针使用 

    1. vim readiness-httpget.yaml
    2. apiVersion: v1
    3. kind: Pod
    4. metadata:
    5. name: readiness-httpget
    6. namespace: default
    7. spec:
    8. containers:
    9. - name: readiness-httpget-container
    10. image: soscscs/myapp:v1
    11. imagePullPolicy: IfNotPresent
    12. ports:
    13. - name: http
    14. containerPort: 80
    15. readinessProbe:
    16. httpGet:
    17. port: 80
    18. path: /index1.html
    19. initialDelaySeconds: 1
    20. periodSeconds: 3
    21. livenessProbe:
    22. httpGet:
    23. port: http
    24. path: /index.html
    25. initialDelaySeconds: 1
    26. periodSeconds: 3
    27. timeoutSeconds: 10
    28. kubectl create -f readiness-httpget.yaml
    29. //readiness探测失败,无法进入READY状态
    30. kubectl get pods
    31. kubectl exec -it readiness-httpget sh
    32. # cd /usr/share/nginx/html/
    33. # ls
    34. 50x.html index.html
    35. # echo 123 > index1.html
    36. # exit
    37. kubectl get pods
    38. kubectl exec -it readiness-httpget -- rm -rf /usr/share/nginx/html/index.html
    39. kubectl get pods -w

     

    1. vim readiness-myapp.yaml
    2. apiVersion: v1
    3. kind: Pod
    4. metadata:
    5. name: myapp1
    6. labels:
    7. app: myapp
    8. spec:
    9. containers:
    10. - name: myapp
    11. image: soscscs/myapp:v1
    12. ports:
    13. - name: http
    14. containerPort: 80
    15. readinessProbe:
    16. httpGet:
    17. port: 80
    18. path: /index.html
    19. initialDelaySeconds: 5
    20. periodSeconds: 5
    21. timeoutSeconds: 10
    22. ---
    23. apiVersion: v1
    24. kind: Pod
    25. metadata:
    26. name: myapp2
    27. labels:
    28. app: myapp
    29. spec:
    30. containers:
    31. - name: myapp
    32. image: soscscs/myapp:v1
    33. ports:
    34. - name: http
    35. containerPort: 80
    36. readinessProbe:
    37. httpGet:
    38. port: 80
    39. path: /index.html
    40. initialDelaySeconds: 5
    41. periodSeconds: 5
    42. timeoutSeconds: 10
    43. ---
    44. apiVersion: v1
    45. kind: Pod
    46. metadata:
    47. name: myapp3
    48. labels:
    49. app: myapp
    50. spec:
    51. containers:
    52. - name: myapp
    53. image: soscscs/myapp:v1
    54. ports:
    55. - name: http
    56. containerPort: 80
    57. readinessProbe:
    58. httpGet:
    59. port: 80
    60. path: /index.html
    61. initialDelaySeconds: 5
    62. periodSeconds: 5
    63. timeoutSeconds: 10
    64. ---
    65. apiVersion: v1
    66. kind: Service
    67. metadata:
    68. name: myapp
    69. spec:
    70. selector:
    71. app: myapp
    72. type: ClusterIP
    73. ports:
    74. - name: http
    75. port: 80
    76. targetPort: 80
    77. kubectl create -f readiness-myapp.yaml
    78. kubectl get pods,svc,endpoints -o wide
    79. NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
    80. pod/myapp1 1/1 Running 0 3m42s 10.244.2.13 node02 <none> <none>
    81. pod/myapp2 1/1 Running 0 3m42s 10.244.1.15 node01 <none> <none>
    82. pod/myapp3 1/1 Running 0 3m42s 10.244.2.14 node02 <none> <none>
    83. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
    84. ......
    85. service/myapp ClusterIP 10.96.138.13 <none> 80/TCP 3m42s app=myapp
    86. NAME ENDPOINTS AGE
    87. ......
    88. endpoints/myapp 10.244.1.15:80,10.244.2.13:80,10.244.2.14:80 3m42s
    89. kubectl exec -it pod/myapp1 -- rm -rf /usr/share/nginx/html/index.html
    90. //readiness探测失败,Pod 无法进入READY状态,且端点控制器将从 endpoints 中剔除删除该 Pod 的 IP 地址
    91. kubectl get pods,svc,endpoints -o wide
    92. NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
    93. pod/myapp1 0/1 Running 0 5m17s 10.244.2.13 node02 <none> <none>
    94. pod/myapp2 1/1 Running 0 5m17s 10.244.1.15 node01 <none> <none>
    95. pod/myapp3 1/1 Running 0 5m17s 10.244.2.14 node02 <none> <none>
    96. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
    97. ......
    98. service/myapp ClusterIP 10.96.138.13 <none> 80/TCP 5m17s app=myapp
    99. NAME ENDPOINTS AGE
    100. ......
    101. endpoints/myapp 10.244.1.15:80,10.244.2.14:80 5m17s

    (3)启动探针的使用  

    启动探针存在的必要:

    有时候,会有一些现有的应用在启动时需要较长的初始化时间。 要这种情况下,若要不影响对死锁作出快速响应的探测,设置存活探测参数是要技巧的。 技巧就是使用相同的命令来设置启动探测,针对 HTTP 或 TCP 检测,可以通过将 failureThreshold * periodSeconds 参数设置为足够长的时间来应对糟糕情况下的启动时间。(因为启动探针在启动后,其他的两种探针就会进入短暂的禁用装态,于是给容器启动预留了充足的时间,保证容器中业务启动的顺利进行。而且启动探针只会启动一次,后续工作就完全交给其他两个探针,直到容器的生命周期结束)。

    1. ports:
    2. - name: liveness-port
    3. containerPort: 8080
    4. hostPort: 8080
    5. livenessProbe:
    6. httpGet:
    7. path: /healthz
    8. port: liveness-port
    9. failureThreshold: 1
    10. periodSeconds: 10
    11. startupProbe:
    12. httpGet:
    13. path: /healthz
    14. port: liveness-port
    15. failureThreshold: 30
    16. periodSeconds: 10

    在这里,幸亏有了启动探测,应用程序将会有最多 5 分钟(30 * 10 = 300s)的时间来完成其启动过程。 一旦启动探测成功一次,存活探测任务就会接管对容器的探测,对容器死锁作出快速响应。 如果启动探测一直没有成功,容器会在 300 秒后被杀死,并且根据 restartPolicy 来执行进一步处置。 

    四、Pod 容器的启动和退出动作 

    postStart    配置 exec.command 字段设置 Linux 命令,实现当应用容器启动时,会执行的额外操作

    preStop      配置 exec.command 字段设置 Linux 命令,实现当应用容器退出时,会执行的最后一个操作

    实例运用
    1. apiVersion: v1
    2. kind: Pod
    3. metadata:
    4. name: lifecycle-demo
    5. spec:
    6. containers:
    7. - name: lifecycle-demo-container
    8. image: soscscs/myapp:v1
    9. lifecycle: #此为关键字段
    10. postStart:
    11. exec:
    12. command: ["/bin/sh", "-c", "echo Hello from the postStart handler >> /var/log/nginx/message"]
    13. preStop:
    14. exec:
    15. command: ["/bin/sh", "-c", "echo Hello from the prestop handler >> /var/log/nginx/message"]
    16. volumeMounts:
    17. - name: message-log
    18. mountPath: /var/log/nginx/
    19. readOnly: false
    20. initContainers:
    21. - name: init-myservice
    22. image: soscscs/myapp:v1
    23. command: ["/bin/sh", "-c", "echo 'Hello initContainers' >> /var/log/nginx/message"]
    24. volumeMounts:
    25. - name: message-log
    26. mountPath: /var/log/nginx/
    27. readOnly: false
    28. volumes:
    29. - name: message-log
    30. hostPath:
    31. path: /data/volumes/nginx/log/
    32. type: DirectoryOrCreate
    1. kubectl create -f post.yaml
    2. kubectl get pods -o wide
    3. NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
    4. lifecycle-demo 1/1 Running 0 2m8s 10.244.2.28 node02 <none> <none>
    5. kubectl exec -it lifecycle-demo -- cat /var/log/nginx/message
    6. Hello initContainers
    7. Hello from the postStart handler
    8. //在 node02 节点上查看
    9. [root@node02 ~]# cd /data/volumes/nginx/log/
    10. [root@node02 log]# ls
    11. access.log error.log message
    12. [root@node02 log]# cat message
    13. Hello initContainers
    14. Hello from the postStart handler
    15. #由上可知,init Container先执行,然后当一个主容器启动后,Kubernetes 将立即发送 postStart 事件。
    16. //删除 pod 后,再在 node02 节点上查看
    17. kubectl delete pod lifecycle-demo
    18. [root@node02 log]# cat message
    19. Hello initContainers
    20. Hello from the postStart handler
    21. Hello from the poststop handler
    22. #由上可知,当在容器被终结之前, Kubernetes 将发送一个 preStop 事件。

     

  • 相关阅读:
    Web标准
    【趣味随笔】农业机器人的种类与发展前景
    旭日3SDB,安装原版ros
    c++获取当前时间的字符串
    12.(vue3.x+vite)组件间通信方式之$attrs与$listeners
    C语言力扣第60题之排列序列。广度优先搜索、简单除法定位
    报错解决:java.security.InvalidKeyException: Illegal key size(微信支付v3遇到的问题)
    腾讯云便宜服务器有哪些?腾讯云这个服务器一个月7块钱!
    浅析泵站自动化技术的发展趋势
    mysql数据库中的索引-2
  • 原文地址:https://blog.csdn.net/Cnm_147258/article/details/136375842