ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

k8s-Pod的生命周期

k8s-Pod的生命周期 一、什么是资源K8S中所有的内容都抽象为资源资源实例化之后叫做对象。1、资源类别名称空间级别工作负载型资源Pod、ReplicaSet、Deployment ...服务发现及负载均衡型资源Service、Ingress...配置与存储型资源Volume、CSI ...特殊类型的存储卷ConfigMap、Secre集群级资源Namespace、Node、ClusterRole、ClusterRoleBinding元数据型资源HPA、 PodTemplate、 LimitRangeTip名称空间级别可以理解为大学的院系集群级资源可以理解为整个大学元数据型资源不单独存在依附在别的资源对象上二、资源清单的编写1、资源清单结构kubectl api-server列出当前 k8s APISERVER 上所有可用的 API 组与版本最后一个只有版本没有组的原因是这是core核心组组名可省略admissionregistration.k8s.io/v1 apiextensions.k8s.io/v1 apiregistration.k8s.io/v1 apps/v1 authentication.k8s.io/v1 authorization.k8s.io/v1 autoscaling/v1 autoscaling/v2 batch/v1 certificates.k8s.io/v1 coordination.k8s.io/v1 crd.projectcalico.org/v1 discovery.k8s.io/v1 events.k8s.io/v1 flowcontrol.apiserver.k8s.io/v1 flowcontrol.apiserver.k8s.io/v1beta3 networking.k8s.io/v1 node.k8s.io/v1 policy/v1 rbac.authorization.k8s.io/v1 scheduling.k8s.io/v1 storage.k8s.io/v1 v1kubectl explain pod查看 K8s 资源的描述例如查看pod和deployment这两个类型的资源字段这里我们要查的是pod对应的接口版本是多少接口组是什么。第一行若没有GROUP代表是core核心组可以省略[rootk8s-master01 ~]# kubectl explain pod KIND: Pod VERSION: v1 DESCRIPTION: Pod is a collection of containers that can run on a host. This resource is created by clients and scheduled onto hosts. FIELDS: apiVersion string APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources kind string Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds metadata ObjectMeta Standard objects metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata spec PodSpec Specification of the desired behavior of the pod. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status status PodStatus Most recently observed status of the pod. This data may not be up to date. Populated by the system. Read-only. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status [rootk8s-master01 ~]# kubectl explain deployment GROUP: apps KIND: Deployment VERSION: v1 DESCRIPTION: Deployment enables declarative updates for Pods and ReplicaSets. FIELDS: apiVersion string APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources kind string Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds metadata ObjectMeta Standard objects metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata spec DeploymentSpec Specification of the desired behavior of the Deployment. status DeploymentStatus Most recently observed status of the Deployment.资源清单必备的五个核心结构接口组/版本类别元数据期望状态一个创建pod的资源清单结构分析Tip五个核心结构下的子结构信息有没有办法查询呢有的例如要查询期望下的containers下的name[rootk8s-master01 ~]# kubectl explain pod.spec KIND: Pod VERSION: v1 FIELD: spec PodSpec DESCRIPTION: Specification of the desired behavior of the pod. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status PodSpec is a description of a pod. FIELDS: activeDeadlineSeconds integer Optional duration in seconds the pod may be active on the node relative to StartTime before the system will actively try to mark it failed and kill associated containers. Value must be a positive integer. affinity Affinity If specified, the pods scheduling constraints automountServiceAccountToken boolean AutomountServiceAccountToken indicates whether a service account token should be automatically mounted. containers []Container -required- #required代表必填字段 List of containers belonging to the pod. Containers cannot currently be added or removed. There must be at least one container in a Pod. Cannot be updated. ... [rootk8s-master01 ~]# kubectl explain pod.spec.containers.name KIND: Pod VERSION: v1 FIELD: name string DESCRIPTION: Name of the container specified as a DNS_LABEL. Each container in a pod must have a unique name (DNS_LABEL). Cannot be updated.2、一个资源清单示例这是一个创建pod的资源清单使用的时候记得删中文注释vim 1.pod.yamlapiVersion: v1 #核心接口组可省略/v1版本 kind: Pod #类别pod metadata: #元数据 name: pod-demo #名字 namespace: default #放到default名字空间 labels: #标签 app: myapp spec: #期望 containers: #容器组 - name: myapp-1 #容器名字 image: nginx:1.26-alpine #容器所用镜像 - name: busybox-1 #容器名字 image: busybox:1.36 #容器所用镜像 command: #运行命令 - /bin/sh - -c - sleep 3600[rootk8s-master01 4]# kubectl create -f 1.pod.yaml #实例化这个pod资源 pod/pod-demo created [rootk8s-master01 4]# kubectl get pod -n default #-n指定名字空间default是默认名字空间kube-system是k8s组件所在的名字空间 NAME READY STATUS RESTARTS AGE pod-demo 2/2 Running 0 3m26s NAMEpod名称 READYpod内的容器的就绪状态2/2代表两个容器都就绪了 STATUSpod当前状态。Running运行中ContainerCreating正在创建容器 RESTARTSpod里面容器重启次数 AGEpod已经运行了多久创建到现在时间kubectl describe pod查看资源对象的详细描述使用这条命令可以根据最后面返回的事件Events:信息看目前创建pod的进度这里的日志是pod级别的日志如果要查看具体容器级别的日志得用kubectl logs pod名 -c 容器名[rootk8s-master01 ~]# kubectl describe pod pod-demo ... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Pulled 37m (x3 over 157m) kubelet Container image busybox:1.36 already present on machine Normal Created 37m (x3 over 157m) kubelet Created container busybox-1 Normal Started 37m (x3 over 157m) kubelet Started container busybox-1#如果想删除pod可以使用命令kubectl delete -f 1.pod.yaml #根据资源清单删除pod kubectl delete pod pod-demo #根据pod名称删除pod kubectl delete pod --all #删除默认名字空间default下的所有pod3、kubectl常用命令kubectl get pod 获取当前的pod资源-A,--all-namespaces 查看当前所有名称空间的资源-n 指定名称空间默认值 defaultkube-system 空间存放是当前组件资源--show-labels 查看当前的标签-l 筛选资源key、keyvalue-o wide 详细信息包括 IP、分配的节点-w 监视打印当前的资源对象的变化部分。和linux中的watch类似[rootk8s-master01 4]# kubectl get pod #查询默认名字空间default下的pod。相当于在执行kubectl get pod -n default NAME READY STATUS RESTARTS AGE pod-demo 2/2 Running 0 3m26s [rootk8s-master01 4]# kubectl get pod -n kube-system #查询kube-system名字空间下的pod NAME READY STATUS RESTARTS AGE calico-kube-controllers-558d465845-6pt2d 1/1 Running 1 (23h ago) 27h calico-node-gnjwj 1/1 Running 1 (23h ago) 27h calico-node-jr469 1/1 Running 1 (23h ago) 27h calico-node-zm9vn 1/1 Running 1 (23h ago) 27h calico-typha-5b56944f9b-clshm 1/1 Running 1 (23h ago) 27h coredns-857d9ff4c9-7pf86 1/1 Running 1 (23h ago) 29h coredns-857d9ff4c9-bkv4s 1/1 Running 1 (23h ago) 29h etcd-k8s-master01 1/1 Running 1 (23h ago) 29h kube-apiserver-k8s-master01 1/1 Running 1 (23h ago) 29h kube-controller-manager-k8s-master01 1/1 Running 1 (23h ago) 29h kube-proxy-45hl2 1/1 Running 1 (23h ago) 29h kube-proxy-6lkss 1/1 Running 1 (23h ago) 29h kube-proxy-z6fp8 1/1 Running 1 (23h ago) 29h kube-scheduler-k8s-master01 1/1 Running 1 (23h ago) 29h[rootk8s-master01 4]# kubectl get pod -A #查询所有名字空间下的所有pod可以看到查询结果多出NAMESPACE这一列。-A是简写全拼是kubectl get pod --all-namespaces NAMESPACE NAME READY STATUS RESTARTS AGE default pod-demo 2/2 Running 0 9m17s kube-system calico-kube-controllers-558d465845-6pt2d 1/1 Running 1 (23h ago) 27h kube-system calico-node-gnjwj 1/1 Running 1 (23h ago) 27h kube-system calico-node-jr469 1/1 Running 1 (23h ago) 27h kube-system calico-node-zm9vn 1/1 Running 1 (23h ago) 27h kube-system calico-typha-5b56944f9b-clshm 1/1 Running 1 (23h ago) 27h kube-system coredns-857d9ff4c9-7pf86 1/1 Running 1 (23h ago) 29h kube-system coredns-857d9ff4c9-bkv4s 1/1 Running 1 (23h ago) 29h kube-system etcd-k8s-master01 1/1 Running 1 (23h ago) 29h kube-system kube-apiserver-k8s-master01 1/1 Running 1 (23h ago) 29h kube-system kube-controller-manager-k8s-master01 1/1 Running 1 (23h ago) 29h kube-system kube-proxy-45hl2 1/1 Running 1 (23h ago) 29h kube-system kube-proxy-6lkss 1/1 Running 1 (23h ago) 29h kube-system kube-proxy-z6fp8 1/1 Running 1 (23h ago) 29h kube-system kube-scheduler-k8s-master01 1/1 Running 1 (23h ago) 29h[rootk8s-master01 4]# kubectl get pod --show-labels #查看pod标签 NAME READY STATUS RESTARTS AGE LABELS pod-demo 2/2 Running 0 53m appmyapp [rootk8s-master01 ~]# kubectl get pod -l app #也可以通过刷选key或keyvalue的方式查询 NAME READY STATUS RESTARTS AGE pod-demo 2/2 Running 3 (44m ago) 2d13h [rootk8s-master01 ~]# kubectl get pod -l appmyapp NAME READY STATUS RESTARTS AGE pod-demo 2/2 Running 3 (44m ago) 2d13h[rootk8s-master01 4]# kubectl get pod -o wide #宽输出格式在原来基础的列表上额外增加几列信息IP NODE所在节点 NOMINATED NODE READINESS GATES NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pod-demo 2/2 Running 0 9m51s 10.244.85.193 k8s-node01 none none根据查到的信息这个Pod在node01节点被创建去RL-2机器上[rootk8s-node01 ~]# docker ps #可以看到前三个就是刚才的pod创建的nginx、busybox、pause容器 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 91fed91c8b30 73aaf090f3d8 /bin/sh -c sleep 3… 43 seconds ago Up 42 seconds k8s_busybox-1_pod-demo_default_fb38c867-c8f0-496f-bccb-c1ada73eb39b_0 6fc664620f18 1eadbb078203 /docker-entrypoint.… About a minute ago Up About a minute k8s_myapp-1_pod-demo_default_fb38c867-c8f0-496f-bccb-c1ada73eb39b_0 01b2f5d95832 registry.aliyuncs.com/google_containers/pause:3.8 /pause 4 minutes ago Up 4 minutes k8s_POD_pod-demo_default_fb38c867-c8f0-496f-bccb-c1ada73eb39b_0 3fe345e67d4b 93558ecefd9c start_runit 8 hours ago Up 8 hours k8s_calico-node_calico-node-jr469_kube-system_bbbe942e-f1bd-4999-a37f-063594b4061c_1 363a43cd2b47 3e3ddf70a2fd /sbin/tini -- calic… 8 hours ago Up 8 hours k8s_calico-typha_calico-typha-5b56944f9b-clshm_kube-system_545d51d6-53fb-415f-aa30-a2cf098e4bb5_1 0a028e3fc526 e32aa8045573 /usr/local/bin/kube… 8 hours ago Up 8 hours k8s_kube-proxy_kube-proxy-45hl2_kube-system_2b7739b7-471a-45ee-9a5f-cd6fc596a4d7_1 fd59032ad755 registry.aliyuncs.com/google_containers/pause:3.8 /pause 8 hours ago Up 8 hours k8s_POD_calico-node-jr469_kube-system_bbbe942e-f1bd-4999-a37f-063594b4061c_1 2f12cf43a744 registry.aliyuncs.com/google_containers/pause:3.8 /pause 8 hours ago Up 8 hours k8s_POD_calico-typha-5b56944f9b-clshm_kube-system_545d51d6-53fb-415f-aa30-a2cf098e4bb5_1 620a25d505b6 registry.aliyuncs.com/google_containers/pause:3.8 /pause 8 hours ago Up 8 hours k8s_POD_kube-proxy-45hl2_kube-system_2b7739b7-471a-45ee-9a5f-cd6fc596a4d7_1kubectl exec -it podName -c cName -- command 进入Pod内部的容器执行命令#-c 可以省略默认进入唯一的容器内部回到master节点RL-1可以使用下面命令进入容器内部[rootk8s-master01 4]# kubectl exec -it pod-demo -c myapp-1 -- /bin/sh / # -i交互模式 -t打开一个TTY终端 pod-demopod名 -c myapp-1指定容器名为myapp-1容器名就是在资源清单中定义的容器名。如果一个pod只有一个容器pause不算可以省略-c 容器名。 --分割服务后面可以跟要执行的命令kubectl logs pod-demo -c myapp-1 查看pod内部容器的 日志[rootk8s-master01 4]# kubectl logs pod-demo -c myapp-1 #查看容器日志 /docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration /docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/ /docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh 10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf 10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf /docker-entrypoint.sh: Sourcing /docker-entrypoint.d/15-local-resolvers.envsh /docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh /docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh /docker-entrypoint.sh: Configuration complete; ready for start up 2026/09/29 13:33:21 [notice] 1#1: using the epoll event method 2026/09/29 13:33:21 [notice] 1#1: nginx/1.26.3 2026/09/29 13:33:21 [notice] 1#1: built by gcc 13.2.1 20240309 (Alpine 13.2.1_git20240309) 2026/09/29 13:33:21 [notice] 1#1: OS: Linux 5.14.0-687.10.1.el9_8.0.1.x86_64 2026/09/29 13:33:21 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1024:524288 2026/09/29 13:33:21 [notice] 1#1: start worker processes 2026/09/29 13:33:21 [notice] 1#1: start worker process 30 2026/09/29 13:33:21 [notice] 1#1: start worker process 31 2026/09/29 13:33:21 [notice] 1#1: start worker process 32 2026/09/29 13:33:21 [notice] 1#1: start worker process 33 192.168.66.11 - - [29/Sep/2026:14:21:21 0000] GET / HTTP/1.1 200 615 - curl/7.76.1 - 192.168.66.11 - - [29/Sep/2026:14:22:04 0000] GET / HTTP/1.1 200 646 - curl/7.76.1 -三、Pod的生命周期-init、探针、钩子从创建至死亡的全部流程pause容器初始化网络站挂载可能有的存储卷跟其他的容器去共享网络、共享IPC、共享PID回收后续进程的僵尸进程。pause是最先完成的完成之后才有initC、mainC等运行。initC初始化容器只出现在当前容器生命周期前面的一部分里帮我们去完成一定的初始化动作。有多个initC的话不能同时存在超过一个只有前一个完成任务并且死掉才能启下一个。并且死掉的时候返回码为0才能触发后一个initC。这个过程中但凡有一个initC失败了返回码不为0就会推翻所有initC从头部署。initC应用案例必须先启动MySQL的Pod之后再启动NginxPHP的Pod才不会出现访问不到资源的问题就可以通过在NginxPHP的Pod中添加一个探测MySQL启动成功与否的探测型initC只有探测到MySQL启动成功后才会启动NginxPHP。mainC主容器不间断的持续运行守护进程类型initC更像是脚本类型的。mainC可以有多个并且可以并行创建或运行。minC-钩子Pod中一个容器的启动流程1、初始化 2、执行启动命令 3、关闭容器时会发送关闭信号。 在步骤1和步骤2之间存在一个“启动后钩子”这个钩子可能会与启动命令重叠执行。在步骤3之前有一个“关闭前钩子”例如在容器发出关闭信号时先不关闭容器而是等这个钩子运行把数据备份或者其他操作之后才会执行关闭容器。这两个钩子由当前Pod所在节点的kubelet服务承载。mainC-探针1、启动探针startupProbe检测mainC是否启动完成 2、就绪探针readinessProbe检测mainC是否就绪状态 3、存活探针livenessProbe检测mainC是否存活存活不做操作不存活直接干掉之后新建mainC容器。启动探针在就绪探针、存活探针之前运行就绪探针、存活探针可在同一时间段或者非同一时间段运行。探针也是由当前Pod所在节点的kubelet服务承载。当然mainC也可以只选取钩子和探针的一部分进行使用并不是必须全部使用的。1、initCinit容器与普通的容器非常像除了如下两点init 容器总是运行到成功完成为止每个init容器都必须在下一个init容器启动之前成功完成如果Pod 的Init容器失败Kubernetes 会不断地重启该Pod直到 Init容器成功为止。但是如果Pod对应的重启策略restartPolicy为永不Never它不会重新启动。InitC与应用容器具备不同的镜像可以把一些危险的工具放置在initC中进行使用initC多个之间是线性启动的所以可以做一些延迟性的操作initC无法定义就绪探测readinessProbe其它以外同应用容器定义无异2、探针探针是由当前Pod所在节点的kubelet 对容器执行的定期诊断。要执行诊断kubelet需调用由容器实现的Handler。有三种类型的处理程序ExecAction在容器内执行指定命令。如果命令退出时返回码为0则认为诊断成功TCPSocketAction对指定端口上的容器的IP地址进行TCP检查。如果端口打开则诊断被认为是成功的HTTPGetAction对指定的端口和路径上的容器的IP地址执行HTTP Get请求。如果响应的状态码大于等于200且小于400则诊断被认为是成功的每次探测都将获得以下三种结果之一成功容器通过了诊断。失败容器未通过诊断。未知诊断失败因此不会采取任何行动。例如在返回状态码的时候k8s突然崩了就只能返回未知了。探针分类startupProbe启动探测开始检测吗启动探针跑完并成功之后才会跑其他探针。livenessProbe存活探测还活着吗容器进程还在但是内部卡死、死锁进程没退出k8s 感知不到靠存活探针杀了重启。readinessProbe就绪探测准备提供服务了吗判断容器是否可以接收流量。应用还活着但是暂时不能处理请求正在初始化、加载缓存、数据库连接没好先把流量摘掉等就绪了再重新加入 service 接收流量。2.1、readinessProbe 就绪探针介绍k8s通过添加就绪探针解决尤其是在扩容时保证提供给用户的服务都是可用的。选项说明initialDelaySeconds:容器启动后要等待多少秒后就探针开始工作单位“秒”默认是0秒最小值是0periodSeconds:执行探测的时间间隔(单位是秒)默认为10s单位“秒”最小值是1timeoutSeconds:探针执行检测请求后等待响应的超时时间默认为1s单位“秒”最小值是1successThreshold:探针检测失败后认为成功的最小连接成功次数默认值为1。必须为1才能激活和启动。最小值为1。failureThreshold:探测失败的重试次数重试一定次数后将认为失败默认值为3最小值为1总结如果 Pod内部的容器不添加就绪探测默认就绪。如果添加了就绪探测只有就绪通过以后才标记修改为就绪状态。当前Pod内的所有的容器都就绪才标记当前Pod就绪。探测结果|处理方式有下列三种成功将当前的容器标记为就绪失败静默未知静默基于HTTP Get方式HTTPGetActionvim 2.pod.yaml #增加init和就绪探针后的资源清单文件使用的时候需要删中文注释apiVersion: v1 #完整写法core/v1但是core核心组特殊可以省略 kind: Pod #类别pod metadata: #元数据 name: pod-init-probe #pod名字 namespace: default #pod所在名字空间 labels: #标签 app: myapp spec: #期望 initContainers: #初始化容器 - name: init-myservice #容器名字 image: busybox:1.36 #镜像 command: [sh, -c, until wget -T 3 -q --spider http://www.baidu.com; do echo waiting for internet; sleep 2; done;] #循环wget百度直到wget成功才退出 containers: #容器组 - name: myapp-1 #容器名字 image: nginx:1.26-alpine #容器所用镜像 imagePullPolicy: IfNotPresent #镜像下载策略本地有就不下载 readinessProbe: #就绪探测 httpGet: #通过HTTPGetAction的方式访问80端口访问的路径是当前服务根目录下的index.html port: 80 path: /index.html initialDelaySeconds: 1 #延迟1秒以后开始探测 periodSeconds: 3 #每间隔3秒执行一次就绪探测不管上一次成功还是失败kubectl create -f 2.pod.yamlkubectl describe pod pod-init-probe #查看创建过程中的事件发现多了init探针不报错不会在事件中打印内容... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 7m4s default-scheduler Successfully assigned default/pod-init-probe to k8s-node02 Normal Pulling 7m2s kubelet Pulling image busybox:1.36 Normal Pulled 6m14s kubelet Successfully pulled image busybox:1.36 in 48.295s (48.295s including waiting) Normal Created 6m14s kubelet Created container init-myservice Normal Started 6m14s kubelet Started container init-myservice Normal Pulling 6m12s kubelet Pulling image nginx:1.26-alpine Normal Pulled 4m18s kubelet Successfully pulled image nginx:1.26-alpine in 1m54.277s (1m54.277s including waiting) Normal Created 4m17s kubelet Created container myapp-1 Normal Started 4m17s kubelet Started container myapp-1基于EXEC方式ExecAction... readinessProbe: exec: command: [test,-e,/tmp/live] #live文件存在就通过 ...基于TCP Check方式TCPSocketAction... readinessProbe: initialDelaySeconds: 5 timeoutSeconds: 1 tcpSocket: #只要当前应用的80端口能够和我进行TCP连接就通过 port: 802.2、livenessProbe 存活探针介绍k8s 通过添加存活探针解决虽然容器活着但是无法提供服务的问题。选项说明initialDelaySeconds容器启动后要等待多少秒后就探针开始工作单位“秒”默认是 0 秒最小值是 0periodSeconds执行探测的时间间隔单位是秒默认为 10s单位“秒”最小值是 1timeoutSeconds探针执行检测请求后等待响应的超时时间默认为 1s单位“秒”最小值是 1successThreshold探针检测失败后认为成功的最小连接成功次数默认值为 1。必须为 1 才能激活和启动。最小值为1。failureThreshold探测失败的重试次数重试一定次数后将认为失败默认值为 3 最小值为 1。总结如果pod内部不指定存活探测可能会发生容器运行但是无法提供服务的情况。探测结果|处理方式有下列三种情况成功静默失败根据重启的策略进行重启的动作杀死容器然后重启一个新容器未知静默基于 HTTP Get 方式apiVersion: v1 kind: Pod metadata: name: liveness-httpget-pod namespace: default spec: containers: - name: liveness-httpget-container image: nginx:1.26-alpine imagePullPolicy: IfNotPresent ports: - name: http containerPort: 80 livenessProbe: httpGet: port: 80 path: /index.html initialDelaySeconds: 1 periodSeconds: 3 timeoutSeconds: 3基于 Exec 方式apiVersion: v1 kind: Pod metadata: name: liveness-exec-pod namespace: default spec: containers: - name: liveness-exec-container image: nginx:1.26-alpine 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基于 TCP Check 方式apiVersion: v1 kind: Pod metadata: name: liveness-tcp-pod spec: containers: - name: liveness-tcp-container image: nginx:1.26-alpine livenessProbe: initialDelaySeconds: 5 timeoutSeconds: 1 tcpSocket: port: 802.3、startupProbe启动探针介绍k8s 在 1.16 版本后增加 startupProbe 探针主要解决在复杂的程序中 readinessProbe、livenessProbe 探针无法更好的判断程序是否启动、是否存活。选项说明initialDelaySeconds容器启动后要等待多少秒后就探针开始工作单位“秒”默认是 0 秒最小值是 0periodSeconds执行探测的时间间隔单位是秒默认为 10s单位“秒”最小值是 1timeoutSeconds探针执行检测请求后等待响应的超时时间默认为 1s单位“秒”最小值是 1successThreshold探针检测失败后认为成功的最小连接成功次数默认值为 1。必须为 1 才能激活和启动。最小值为1。failureThreshold探测失败的重试次数重试一定次数后将认为失败默认值为 3 最小值为 1。总结保障存活探针在执行的时候不会因为时间设定问题导致无限死亡容器还没启动存活探测没探到服务可用直接杀死容器新启动容器导致无限循环或者延迟很长就绪探测不确定多久容器能启动好因此只能设置一个很长的延时时间initialDelaySeconds的情况。探测结果|处理方式有下列三种成功开始允许存活探测、就绪探测开始执行失败静默未知静默[rootk8s-master01 4]# vim 3.pod.yaml #使用的时候需删中文注释apiVersion: v1 kind: Pod metadata: name: startupprobe-1 namespace: default spec: containers: - name: myapp-container image: nginx:1.26-alpine imagePullPolicy: IfNotPresent ports: - name: http containerPort: 80 readinessProbe: #就绪探测 httpGet: #直到通过80端口访问到index2.html才通过 port: 80 path: /index2.html initialDelaySeconds: 1 periodSeconds: 3 startupProbe: #启动探测 httpGet: #直到通过80端口访问到index1.html才通过 path: /index1.html port: 80 failureThreshold: 30 #探测失败的最大重试次数 periodSeconds: 10 #执行探测的时间间隔和failureThreshold结合起来看应用程序将会有最多300s的时间来完成其启动过程[rootk8s-master01 4]# kubectl create -f 3.pod.yaml[rootk8s-master01 4]# kubectl get pod|grep startupprobe-1startupprobe-1 0/1 Running 0 3s[rootk8s-master01 4]# kubectl exec -it startupprobe-1 -- /bin/sh/ # echo hello1 /usr/share/nginx/html/index2.html #就绪探测的条件是存在index2.html手动创建它/ # exit[rootk8s-master01 4]# kubectl get pod|grep startupprobe-1 #发现还是未就绪状态原因是得先满足启动探测条件才会执行就绪探测startupprobe-1 0/1 Running 0 2m45s[rootk8s-master01 4]# kubectl exec -it startupprobe-1 -- /bin/sh/ # echo success1 /usr/share/nginx/html/index1.html #启动探测的条件是存在index1.html手动创建它/ # exit[rootk8s-master01 4]# kubectl get pod|grep startupprobe-1 #可以看到通过启动探测后才会执行就绪探测现在就是就绪状态了即就是下面的1/1startupprobe-1 1/1 Running 0 4m28s3、钩子Pod hook钩子是由 Kubernetes 管理的 kubelet 发起的当容器中的进程启动前或者容器中的进程终止之前运行这是包含在容器的生命周期之中。可以同时为 Pod 中的所有容器都配置 hook。Hook 的类型包括两种HTTP发送 HTTP 请求exec执行一段命令基于 HTTP Get 方式[rootk8s-master01 4]# docker run -it --rm -p 1234:80 nginx:1.26-alpine #使用镜像nginx:1.26-alpine启动一个交互式临时容器在前台运行将宿主机 1234 端口映射到容器的 80 端口一旦容器停止就自动删掉容器。创建完成后会一直打印日志复制一个xshell窗口执行其他操作[rootk8s-master01 4]# vim 4.pod.yaml #使用的时候需删中文注释apiVersion: v1 kind: Pod metadata: name: lifecycle-httpget-pod labels: name: lifecycle-httpget-pod spec: containers: - name: lifecycle-httpget-container image: nginx:1.26-alpine ports: - containerPort: 80 lifecycle: postStart: httpGet: #通过1234端口访问11这台机器的index.html文件 host: 192.168.66.11 path: index.html port: 1234 preStop: httpGet: #通过1234端口访问11这台机器的hostname.html文件 host: 192.168.66.11 path: hostname.html port: 1234[rootk8s-master01 4]# kubectl create -f 4.pod.yaml[rootk8s-master01 4]# kubectl delete pod --all然后看临时docker打印出的日志执行了启动后钩子的内容和关闭前钩子的内容基于Exec方式[rootk8s-master01 4]# vim 5.pod.yaml #使用的时候需删中文注释apiVersion: v1 kind: Pod metadata: name: lifecycle-exec-pod spec: containers: - name: lifecycle-exec-container image: nginx:1.26-alpine lifecycle: #钩子 postStart: #启动后钩子 exec: command: [/bin/sh, -c, echo postStart /usr/share/message] #写入“postStart”替换message文件内容 preStop: #关闭前钩子 exec: command: [/bin/sh, -c, echo preStop /usr/share/message] #写入“preStop”替换message文件内容[rootk8s-master01 4]# kubectl create -f 5.pod.yaml[rootk8s-master01 4]# kubectl exec -it lifecycle-exec-pod -- /bin/sh/ # while true; do cat /usr/share/message; done #循环打印message文件内容...postStart...[rootk8s-master01 4]# kubectl delete pod --all #删除pod然后回头看那个循环打印最后几行是“preStop”说明触发了关闭前钩子3.1、关于preStop的延伸话题在 k8s 中理想的状态是 pod 优雅释放但是并不是每一个 Pod 都会这么顺利Pod 卡死处理不了优雅退出的命令或者操作优雅退出的逻辑有 BUG陷入死循环代码问题导致执行的命令没有效果对于以上问题k8s 的 Pod终止流程中还有一个最多可以容忍的时间即 grace period ( 在pod.spec.terminationGracePeriodSeconds字段定义)这个值默认是30秒当我们执行kubectldelete的时候也可以通过--grace-period参数显示指定一个优雅退出时间来覆盖Pod中的配置如果我们配置的grace period 超过时间之后k8s就只能选择强制kill Pod。值得注意的是这与preStop Hook和SIGTERM信号并行发生。k8s不会等待preStop Hook完成。如果你的应用程序完成关闭并在terminationGracePeriod完成之前退出k8s会立即进入下一步。4、总结Pod生命周期中的initC、startupProbe、livenessProbe、readinessProbe、hook都是可以同时存在的可以选择全部、部分或者完全不用。下面的示例是包含全部功能的资源清单示例apiVersion: v1 # api版本Pod属于v1组 kind: Pod # 资源类型为Pod metadata: name: lifecycle-pod # Pod的名称 labels: app: lifecycle-pod # Pod标签用于service选择Pod spec: # 初始化容器串行执行全部成功结束之后才会启动业务容器 initContainers: - name: init-myservice image: busybox:1.36 # 循环dns解析myservice服务解析成功才退出等待myservice服务就绪 command: [/bin/sh, -c, until nslookup myservice; do echo waiting for myservice; sleep 2; done;] - name: init-mydb image: busybox:1.36 # 等待mydb服务dns解析成功上一个init容器跑完才执行这个 command: [/bin/sh, -c, until nslookup mydb; do echo waiting for mydb; sleep 2; done;] # Pod内业务容器列表init全部完成后多个业务容器并行启动 containers: - name: busybox-container image: busybox:1.36 # 先创建/tmp/live文件休眠600秒(10分钟)删除该文件再继续休眠3600秒 command: [/bin/sh, -c, touch /tmp/live ; sleep 600; rm -rf /tmp/live; sleep 3600] # 存活探针livenessProbe判断容器是否活着失败就重启容器 livenessProbe: exec: # 执行命令方式探测 command: [test, -e, /tmp/live] # 检测/tmp/live文件是否存在 initialDelaySeconds: 1 # Pod启动后延迟1秒才开始第一次探测 periodSeconds: 3 # 之后每3秒探测一次 # 容器生命周期钩子 lifecycle lifecycle: postStart: # 容器主进程启动完成之后立刻执行的钩子 httpGet: # 发送http get请求 host: 192.168.66.11 path: /index.html port: 1234 preStop: # 容器收到终止信号SIGTERM、销毁之前执行的钩子 httpGet: host: 192.168.66.11 path: /hostname.html port: 1234 - name: myapp-container image: nginx:1.26-alpine # 存活探针httpGet访问/index.html失败重启容器 livenessProbe: httpGet: port: 80 path: /index.html initialDelaySeconds: 1 # 启动延迟1s开始探测 periodSeconds: 3 # 探测间隔3s timeoutSeconds: 3 # 请求3秒没返回判定探测超时失败 # 就绪探针readinessProbe探测失败就把pod从service后端端点摘除不再接收流量不会重启容器 readinessProbe: httpGet: port: 80 path: /index1.html initialDelaySeconds: 1 periodSeconds: 3initC的通过条件可以通过下面方式满足命令式创建一个类型为 ClusterIP名字 myservice 的服务svc 端口 80转发后端 pod80selector 为空没有关联 Pod仅仅先把 DNS 域名 myservice 注册到集群 DNS用来满足 initContainers 里面 nslookup 域名等待逻辑。[rootk8s-master01 4]# kubectl create svc clusterip myservice --tcp80:80[rootk8s-master01 4]# kubectl create svc clusterip mydb --tcp80:80启动后钩子、关闭前钩子的通过条件可以通过下面方式满足[rootk8s-master01 4]# docker run -it --rm -p 1234:80 nginx:1.26-alpine就绪探测的通过条件可以通过下面方式满足[rootak8s-master01 4]# kubectl exec -it lifecycle-pod -c myapp-container -- /bin/sh/ # echo 111222333 /usr/share/nginx/html/index1.html
返回列表