1、pod的调度流程及常见状态

1.1、pod的调度流程

Pod创建过程如上图所示,首先用户向apiserver发送创建pod的请求,apiserver收到用于创建pod请求后,对应会对该用户身份信息进行验证,该用户是否是合法的用户,是否具有创建pod的权限,如果能够通过apiserver的验证,则进行下一步,对用户提交的资源进行准入控制,所谓准入控制是指对用户提交的资源做格式,语法的验证,是否满足apiserver中定义的对应资源的api格式和语法;如果上述身份验证和准入控制能够顺利通过,接下来,apiserver才会把对应创建pod的信息存入etcd中,否者就直接拒绝用户创建pod;etcd将对应数据存放好以后,会返回给apiserver一个事件,即创建pod的相关信息已经存入etcd中了;apiserver收到etcd的资源信息存入完成事件后,会返回给用户一个pod创建完成的消息;随后,scheduler通过监视到apiserver上的资源变动事件,会对pod进行调度,调度规则就是先预选(预选就是把不符合pod运行的节点先踢出去,然后在剩下的节点中进行优选),然后再优选(优选就是在满足预选留下的节点中进行打分,得分高者负责运行pod);scheduler最后通过预选+优选的方式把pod调度到后端某个node节点上运行的结果返回给apiserver,由apiserver将最终调度信息存入etcd中,等待etcd将对应调度信息更新完毕后,再返回给apiserver一个pod状态信息更新完毕,apiserver再将对应状态返回给scheduler;随后负责运行pod的node节点上的kubelet通过监视apiserver的资源变动事件,会发现一个和自己相关的事件,此时对应节点上的kubelet会调用本地容器引擎,将对应pod在本地运行起来;当本地容器引擎将pod正常运行起来后,对应容器引擎会返回给本地kubelet一个pod运行完成的事件,随后再由kubelet将对应事件返回给apiserver,随后apiserver再将pod状态信息存入etcd中,etcd将更新pod状态信息完成的事件通过apiserver将对应事件返回给kubelet;如果此时用户查询pod状态,就能够正常通过apiserver在etcd中检索出来的pod状态;以上就是pod创建的一个大概过程;

1.2、pod的常见状态

  • Unschedulable:#Pod不能被调度,kube-scheduler没有匹配到合适的node节点
  • PodScheduled:#pod正处于调度中,在kube-scheduler刚开始调度的时候,还没有将pod分配到指定的node,在筛选出合适的节点后就会更新etcd数据,将pod分配到指定的node。
  • Pending: #正在创建Pod但是Pod中的容器还没有全部被创建完成=[处于此状态的Pod应该检查Pod依赖的存储是否有权限挂载等。
  • Failed:#Pod中有容器启动失败而导致pod工作异常。
  • Unknown:#由于某种原因无法获得pod的当前状态,通常是由于与pod所在的node节点通信错误。
  • Initialized:#所有pod中的初始化容器已经完成了。
  • ImagePullBackOff:#Pod所在的node节点下载镜像失败。
  • Running:#Pod内部的容器已经被创建并且启动。
  • Ready:#表示pod中的容器已经可以提供访问服务。
  • Error: #pod 启动过程中发生错误。
  • NodeLost: #Pod 所在节点失联。
  • Waiting: #Pod 等待启动。
  • Terminating: #Pod 正在被销毁。
  • CrashLoopBackOff:#pod崩溃,但是kubelet正在将它重启。
  • InvalidImageName:#node节点无法解析镜像名称导致的镜像无法下载。
  • ImageInspectError:#无法校验镜像,镜像不完整导致。
  • ErrImageNeverPull:#策略禁止拉取镜像,镜像中心权限是私有等。
  • RegistryUnavailable:#镜像服务器不可用,网络原因或harbor宕机。
  • ErrImagePull:#镜像拉取出错,超时或下载被强制终止。
  • CreateContainerConfigError:#不能创建kubelet使用的容器配置。
  • CreateContainerError:#创建容器失败。
  • RunContainerError:#pod运行失败,容器中没有初始化PID为1的守护进程等。
  • ContainersNotInitialized:#pod没有初始化完毕。
  • ContainersNotReady:#pod没有准备完毕。
  • ContainerCreating:#pod正在创建中。
  • PodInitializing:#pod正在初始化中。
  • DockerDaemonNotReady:#node节点decker服务没有启动。
  • NetworkPluginNotReady:#网络插件没有启动。

2、pause容器及init容器

2.1、pause容器简介

Pause 容器,又叫 Infra 容器,是pod的基础容器,镜像体积只有几百KB左右,配置在kubelet中,主要的功能是一个pod中多个容器的网络通信。

Infra 容器被创建后会初始化 Network Namespace,之后其它容器就可以加入到 Infra 容器中共享Infra 容器的网络了,因此如果一个 Pod 中的两个容器 A 和 B,那么关系如下 :

  • A容器和B容器能够直接使用 localhost 通信;
  • A容器和B容器可以可以看到网卡、IP与端口监听信息。
  • Pod 只有一个 IP 地址,也就是该 Pod 的 Network Namespace 对应的IP 地址(由Infra 容器初始化并创建)。
  • k8s环境中的每个Pod有一个独立的IP地址(前提是地址足够用),并且此IP被当前 Pod 中所有容器在内部共享使用。
  • pod删除后Infra 容器随机被删除,其IP被回收。

2.2、Pause容器共享的Namespace

  • NET Namespace:Pod中的多个容器共享同一个网络命名空间,即使用相同的IP和端口信息。
  • IPC Namespace:Pod中的多个容器可以使用System V IPC或POSIX消息队列进行通信。
  • .UTS Namespace:pod中的多个容器共享一个主机名。MNT Namespace、PID Namespace、User Namespace未共享。

2.3、Pause容器Namespace验证

1、 运行pod,进入容器查看iflink编号



2、到pod所在宿主机验证网卡

2.4、pause容器配置示例

2.4.1、准备nginx配置文件,并配置动静分离

error_log stderr;
events { worker_connections 1024; }
http {
access_log /dev/stdout;
server {
listen 80 default_server;
server_name www.mysite.com;
location / {
index index.html index.php;
root /usr/share/nginx/html;
}
location ~ \.php$ {
root /usr/share/nginx/html;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
}

2.4.2、部署pause容器

2.4.2.1、下载pause镜像

nerdctl pull registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.8

2.4.2.2、运行pause镜像为容器

nerdctl run -d -p 80:80 --name pause-container-test registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.8

2.4.3、准备测试web页面

root@deploy:~# mkdir html
root@deploy:~# cd html
root@deploy:~/html# echo "<h1>pause container web test</h1>" >index.html
root@deploy:~/html# cat >> index.php << EOF
> <?php
> phpinfo();
> ?>
> EOF
root@deploy:~/html# ll
total 16
drwxr-xr-x 2 root root 4096 May 26 00:03 ./
drwxr-xr-x 9 root root 4096 May 26 00:02 ../
-rw-r--r-- 1 root root 34 May 26 00:02 index.html
-rw-r--r-- 1 root root 25 May 26 00:03 index.php
root@deploy:~/html# cat index.html
<h1>pause container web test</h1>
root@deploy:~/html# cat index.php
<?php
phpinfo();
?>
root@deploy:~/html#

2.4.4、部署nginx 容器,并使用pause容器网络

nerdctl run -d --name nginx-container-test \
-v `pwd`/nginx.conf:/etc/nginx/nginx.conf \
-v `pwd`/html:/usr/share/nginx/html \
--net=container:pause-container-test \
nginx:1.20.2

2.4.5、部署php容器,并使用pause容器网络

nerdctl run -d --name php-container-test \
-v `pwd`/html:/usr/share/nginx/html \
--net=container:pause-container-test \
php:5.6.40-fpm

2.4.6、pause容器验证

访问宿主机的80端口的index.php,看看是否能够访问到php页面?

2.5、init容器简介

2.5.1、init容器的作用

  • 可以为业务容器提前准备好业务容器的运行环境,比如将业务容器需要的配置文件提前生成并放在指定位置、检查数据权限或完整性、软件版本等基础运行环境。
  • 可以在运行业务容器之前准备好需要的业务数据,比如从OSS下载、或者从其它位置copy。
  • 检查依赖的服务是否能够访问。

2.5.2、init容器的特点

  • 一个pod可以有多个业务容器还能在有多个init容器,但是每个init容器和业务容器的运行环境都是隔离的。
  • init容器会比业务容器先启动。
  • init容器运行成功之后才会继续运行业务容器。
  • 如果一个pod有多个init容器,则需要从上到下逐个运行并且全部成功,最后才会运行业务容器。
  • init容器不支持探针检测(因为初始化完成后就退出再也不运行了)。

2.5.3、init容器示例

kind: Deployment
#apiVersion: extensions/v1beta1
apiVersion: apps/v1
metadata:
labels:
app: myserver-myapp
name: myserver-myapp-deployment-name
namespace: myserver
spec:
replicas: 1
selector:
matchLabels:
app: myserver-myapp-frontend
template:
metadata:
labels:
app: myserver-myapp-frontend
spec:
containers:
- name: myserver-myapp-container
image: nginx:1.20.0
#imagePullPolicy: Always
volumeMounts:
- mountPath: "/usr/share/nginx/html/myserver"
name: myserver-data
- name: tz-config
mountPath: /etc/localtime
initContainers:
- name: init-web-data
image: centos:7.9.2009
command: ['/bin/bash','-c',"for i in `seq 1 10`;do echo '<h1>'$i web page at $(date +%Y%m%d%H%M%S) '<h1>' >> /data/nginx/html/myserver/index.html;sleep 1;done"]
volumeMounts:
- mountPath: "/data/nginx/html/myserver"
name: myserver-data
- name: tz-config
mountPath: /etc/localtime
- name: change-data-owner
image: busybox:1.28
command: ['/bin/sh','-c',"/bin/chmod 644 /data/nginx/html/myserver/* -R"]
volumeMounts:
- mountPath: "/data/nginx/html/myserver"
name: myserver-data
- name: tz-config
mountPath: /etc/localtime
volumes:
- name: myserver-data
hostPath:
path: /tmp/data/html
- name: tz-config
hostPath:
path: /etc/localtime ---
kind: Service
apiVersion: v1
metadata:
labels:
app: myserver-myapp-service
name: myserver-myapp-service-name
namespace: myserver
spec:
type: NodePort
ports:
- name: http
port: 80
targetPort: 80
nodePort: 30080
selector:
app: myserver-myapp-frontend

上述配置清单,主要利用两个初始化容器对nginx主容器生成数据和修改数据文件权限的操作;在spec.template.spec字段下用initcontainers来定义初始化容器相关内容;

应用配置清单

访问nginx服务,看看对应数据是否生成?

2.6、Health Check

health check是指对容器做健康状态检测;该检测主要确保容器里的某些服务是否处于健康状态;该检测是一个周期性的动作,即每隔几秒或指定时间周期内进行检测;

2.6.1、docker health check实现方式

2.6.1.1、在docker-compose实现健康状态检测

version: '3.6'
services:
nginx-service:
image: nginx:1.20.2
container_name: nginx-web1
expose:
- 80
- 443
ports:
- "80:80"
- "443:443"
restart: always
healthcheck: #添加服务健康状态检查
test: ["CMD", "curl", "-f", "http://localhost"]
interval: 5s #健康状态检查的间隔时间,默认为30s
timeout: 5s #单次检查的失败超时时间,默认为30s
retries: 3 #连续失败次数默认3次,当连续失败retries次数后将容器置为unhealthy状态
start_period: 60s #60s后每间隔interval的时间检查一次,连续retries次后才将容器置为unhealthy状态, 但是start_period时间内检查成功就认为是检查成功并装容器置于healthy状态

应用配置清单

docker-compose -f docker-compose-demo.yaml up -d

验证容器健康状态

2.6.1.2、在dockerfile实现健康状态检测

FROM nginx:1.20.2

HEALTHCHECK --interval=5s --timeout=2s --retries=3 \
CMD curl --silent --fail localhost:80 || exit 1

生成镜像

docker build -t mynginx:1.20.2 -f ./dockerfile .

运行容器

docker run -it -d -p 80:80 mynginx:1.20.2

验证健康状态检测

root@k8s-deploy:/compose# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c3af9bdd5a41 mynginx:1.20.2 "/docker-entrypoint.…" 4 seconds ago Up 2 seconds (health: starting) 0.0.0.0:80->80/tcp, :::80->80/tcp keen_brown
root@k8s-deploy:/compose# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c3af9bdd5a41 mynginx:1.20.2 "/docker-entrypoint.…" 9 seconds ago Up 8 seconds (healthy) 0.0.0.0:80->80/tcp, :::80->80/tcp keen_brown
root@k8s-deploy:/compose#

在检测通过之前容器处于starting状态,检测通过(检测返回状态码为 0)之后为healthy状态,检测失败(检测返回状态码为 1)之后为unhealthy状态;

3、kubernetes pod生命周期

pod的生命周期( pod lifecycle),从pod start时候可以配置postStart检测,运行过程中可以配置livenessProbe和readinessProbe,最后在 stop前可以配置preStop操作。

3.1、探针简介

探针是由 kubelet 对容器执行的定期诊断,以保证Pod的状态始终处于运行状态,要执行诊断,kubelet 调用由容器实现的Handler(处理程序),也成为Hook(钩子),有三种类型的处理程序:

  1. ExecAction #在容器内执行指定命令,如果命令退出时返回码为0则认为诊断成功。
  2. TCPSocketAction #对指定端口上的容器的IP地址进行TCP检查,如果端口打开,则诊断被认为是成功的。
  3. HTTPGetAction:#对指定的端口和路径上的容器的IP地址执行HTTPGet请求,如果响应的状态码大于等于200且小于 400,则诊断被认为是成功的。

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

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

Pod 重启策略:Pod 一旦配置探针,在检测失败时候,会基于restartPolicy 对 Pod进行下一步操作:

  • restartPolicy (容器重启策略):

    • Always:当容器异常时,k8s自动重启该容器,ReplicationController/Replicaset/Deployment,默认为Always。
    • OnFailure:当容器失败时(容器停止运行且退出码不为0),k8s自动重启该容器。
    • Never:不论容器运行状态如何都不会重启该容器,Job或CronJob
  • imagePullPolicy (镜像拉取策略):
    • IfNotPresent:node节点没有此镜像就去指定的镜像仓库拉取,node有就使用node本地镜像。
    • Always:每次重建pod都会重新拉取镜像。
    • Never:从不到镜像中心拉取镜像,只使用本地镜像。

3.2、探针类型

  • startupProbe: #启动探针,kubernetes v1.16引入

    判断容器内的应用程序是否已启动完成,如果配置了启动探测,则会先禁用所有其它的探测,直到startupProbe检测成功为止,如果startupProbe探测失败,则kubelet将杀死容器,容器将按照重启策略进行下一步操作,如果容器没有提供启动探测,则默认状态为成功
  • livenessProbe: #存活探针

    检测容器容器是否正在运行,如果存活探测失败,则kubelet会杀死容器,并且容器将受到其重启策略的影响,如果容器不提供存活探针,则默认状态为 Success,livenessProbe用于控制是否重启pod。
  • readinessProbe: #就绪探针

    如果就绪探测失败,端点控制器将从与Pod匹配的所有Service的端点中删除该Pod的IP地址,初始延迟之前的就绪状态默认为Failure(失败),如果容器不提供就绪探针,则默认状态为 Success,readinessProbe用于控制pod是否添加至service。

3.3、探针配置参数

探针有很多配置字段,可以使用这些字段精确的控制存活和就绪检测的行为,官方文档https://kubernetes.io/zh/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/

  • initialDelaySeconds: 120 #初始化延迟时间,告诉kubelet在执行第一次探测前应该等待多少秒,默认是0秒,最小值是0。
  • periodSeconds: 60 #探测周期间隔时间,指定了kubelet应该每多少秒秒执行一次存活探测,默认是 10 秒。最小值是 1。
  • timeoutSeconds: 5 #单次探测超时时间,探测的超时后等待多少秒,默认值是1秒,最小值是1。
  • successThreshold: 1 #从失败转为成功的重试次数,探测器在失败后,被视为成功的最小连续成功数,默认值是1,存活探测的这个值必须是1,最小值是 1。
  • failureThreshold:3 #从成功转为失败的重试次数,当Pod启动了并且探测到失败,Kubernetes的重试次数,存活探测情况下的放弃就意味着重新启动容器,就绪探测情况下的放弃Pod 会被打上未就绪的标签,默认值是3,最小值是1。

3.3.1、探针http配置参数

HTTP 探测器可以在 httpGet 上配置额外的字段

  • host: #连接使用的主机名,默认是Pod的 IP,也可以在HTTP头中设置 “Host” 来代替。
  • scheme: http #用于设置连接主机的方式(HTTP 还是 HTTPS),默认是 HTTP。
  • path: /monitor/index.html #访问 HTTP 服务的路径。
  • httpHeaders: #请求中自定义的 HTTP 头,HTTP 头字段允许重复。
  • port: 80 #访问容器的端口号或者端口名,如果数字必须在 1 ~ 65535 之间。

3.4、探针示例

3.4.1、使用httpGet实现pod存活性探测

apiVersion: apps/v1
kind: Deployment
metadata:
name: myserver-myapp-frontend-deployment
namespace: myserver
spec:
replicas: 1
selector:
matchLabels: #rs or deployment
app: myserver-myapp-frontend-label
#matchExpressions:
# - {key: app, operator: In, values: [myserver-myapp-frontend,ng-rs-81]}
template:
metadata:
labels:
app: myserver-myapp-frontend-label
spec:
containers:
- name: myserver-myapp-frontend-label
image: nginx:1.20.2
ports:
- containerPort: 80
readinessProbe:
livenessProbe:
httpGet:
#path: /monitor/monitor.html
path: /index.html
port: 80
initialDelaySeconds: 5
periodSeconds: 3
timeoutSeconds: 1
successThreshold: 1
failureThreshold: 3
---
apiVersion: v1
kind: Service
metadata:
name: myserver-myapp-frontend-service
namespace: myserver
spec:
ports:
- name: http
port: 81
targetPort: 80
nodePort: 40012
protocol: TCP
type: NodePort
selector:
app: myserver-myapp-frontend-label

上述配置清单,主要描述了使用httpget探针对nginxpod进行存活性探测,探测方法就是对容器的80端口,路径为/index.html进行每隔3秒访问一次,探测超时等待1秒,如果连续3次访问失败,则该pod存活性探测失败;只要有一次访问成功,则该pod存活性探测成功;

3.4.2、使用tcpSocket实现pod存活性探测

apiVersion: apps/v1
kind: Deployment
metadata:
name: myserver-myapp-frontend-deployment
namespace: myserver
spec:
replicas: 1
selector:
matchLabels: #rs or deployment
app: myserver-myapp-frontend-label
#matchExpressions:
# - {key: app, operator: In, values: [myserver-myapp-frontend,ng-rs-81]}
template:
metadata:
labels:
app: myserver-myapp-frontend-label
spec:
containers:
- name: myserver-myapp-frontend-label
image: nginx:1.20.2
ports:
- containerPort: 80
livenessProbe:
#readinessProbe:
tcpSocket:
port: 80
#port: 8080
initialDelaySeconds: 5
periodSeconds: 3
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 3
---
apiVersion: v1
kind: Service
metadata:
name: myserver-myapp-frontend-service
namespace: myserver
spec:
ports:
- name: http
port: 81
targetPort: 80
nodePort: 40012
protocol: TCP
type: NodePort
selector:
app: myserver-myapp-frontend-label

3.4.3、使用exec执行命令的方式实现pod存活性探测

apiVersion: apps/v1
kind: Deployment
metadata:
name: myserver-myapp-redis-deployment
namespace: myserver
spec:
replicas: 1
selector:
matchLabels: #rs or deployment
app: myserver-myapp-redis-label
#matchExpressions:
# - {key: app, operator: In, values: [myserver-myapp-redis,ng-rs-81]}
template:
metadata:
labels:
app: myserver-myapp-redis-label
spec:
containers:
- name: myserver-myapp-redis-container
image: redis
ports:
- containerPort: 6379
livenessProbe:
#readinessProbe:
exec:
command:
#- /apps/redis/bin/redis-cli
- /usr/local/bin/redis-cli
- quit
initialDelaySeconds: 5
periodSeconds: 3
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 3 ---
apiVersion: v1
kind: Service
metadata:
name: myserver-myapp-redis-service
namespace: myserver
spec:
ports:
- name: http
port: 6379
targetPort: 6379
nodePort: 40016
protocol: TCP
type: NodePort
selector:
app: myserver-myapp-redis-label

3.4.4、启动探针示例

apiVersion: apps/v1
kind: Deployment
metadata:
name: myserver-myapp-frontend-deployment
namespace: myserver
spec:
replicas: 1
selector:
matchLabels: #rs or deployment
app: myserver-myapp-frontend-label
#matchExpressions:
# - {key: app, operator: In, values: [myserver-myapp-frontend,ng-rs-81]}
template:
metadata:
labels:
app: myserver-myapp-frontend-label
spec:
containers:
- name: myserver-myapp-frontend-label
image: nginx:1.20.2
ports:
- containerPort: 80
startupProbe:
httpGet:
path: /index.html
port: 80
initialDelaySeconds: 5 #首次检测延迟5s
failureThreshold: 3 #从成功转为失败的次数
periodSeconds: 3 #探测间隔周期
---
apiVersion: v1
kind: Service
metadata:
name: myserver-myapp-frontend-service
namespace: myserver
spec:
ports:
- name: http
port: 81
targetPort: 80
nodePort: 40012
protocol: TCP
type: NodePort
selector:
app: myserver-myapp-frontend-label

3.4.5、启动探针,存活探针,就绪探针示例

apiVersion: apps/v1
kind: Deployment
metadata:
name: myserver-myapp-frontend-deployment
namespace: myserver
spec:
replicas: 3
selector:
matchLabels: #rs or deployment
app: myserver-myapp-frontend-label
#matchExpressions:
# - {key: app, operator: In, values: [myserver-myapp-frontend,ng-rs-81]}
template:
metadata:
labels:
app: myserver-myapp-frontend-label
spec:
terminationGracePeriodSeconds: 60
containers:
- name: myserver-myapp-frontend-label
image: nginx:1.20.2
ports:
- containerPort: 80
startupProbe:
httpGet:
path: /index.html
port: 80
initialDelaySeconds: 5 #首次检测延迟5s
failureThreshold: 3 #从成功转为失败的次数
periodSeconds: 3 #探测间隔周期
readinessProbe:
httpGet:
#path: /monitor/monitor.html
path: /index.html
port: 80
initialDelaySeconds: 5
periodSeconds: 3
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 3
livenessProbe:
httpGet:
#path: /monitor/monitor.html
path: /index.html
port: 80
initialDelaySeconds: 5
periodSeconds: 3
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 3
---
apiVersion: v1
kind: Service
metadata:
name: myserver-myapp-frontend-service
namespace: myserver
spec:
ports:
- name: http
port: 81
targetPort: 80
nodePort: 40012
protocol: TCP
type: NodePort
selector:
app: myserver-myapp-frontend-label

3.5、postStart and preStop handlers简介

官方文档https://kubernetes.io/zh/docs/tasks/configure-pod-container/attach-handler-lifecycle-event/

postStart 和 preStop handlers 处理函数

  • postStart:Pod启动后立即执行指定的擦操作:

    • Pod被创建后立即执行,即不等待pod中的服务启动。
    • 如果postStart执行失败pod不会继续创建。
  • preStop:
    • pod被停止之前执行的动作。
    • 如果preStop一直执行不完成,则最后宽限2秒后强制删除。

3.5.1、postStart and preStop handlers示例

apiVersion: apps/v1
kind: Deployment
metadata:
name: myserver-myapp1-lifecycle
labels:
app: myserver-myapp1-lifecycle
namespace: myserver
spec:
replicas: 1
selector:
matchLabels:
app: myserver-myapp1-lifecycle-label
template:
metadata:
labels:
app: myserver-myapp1-lifecycle-label
spec:
terminationGracePeriodSeconds: 60
containers:
- name: myserver-myapp1-lifecycle-label
image: tomcat:7.0.94-alpine
lifecycle:
postStart:
exec:
#command: 把自己注册到注册在中心
command: ["/bin/sh", "-c", "echo 'Hello from the postStart handler' >> /usr/local/tomcat/webapps/ROOT/index.html"] #httpGet:
# #path: /monitor/monitor.html
# host: www.magedu.com
# port: 80
# scheme: HTTP
# path: index.html
preStop:
exec:
#command: 把自己从注册中心移除
command:
- /bin/bash
- -c
- 'sleep 10000000'
#command: ["/usr/local/tomcat/bin/catalina.sh","stop"]
#command: ['/bin/sh','-c','/path/preStop.sh']
ports:
- name: http
containerPort: 8080 ---
apiVersion: v1
kind: Service
metadata:
name: myserver-myapp1-lifecycle-service
namespace: myserver
spec:
ports:
- name: http
port: 80
targetPort: 8080
nodePort: 30012
protocol: TCP
type: NodePort
selector:
app: myserver-myapp1-lifecycle-label

3.6、Pod的终止流程

  1. 向API-Server提交删除请求、API-Server完成鉴权和准入并将事件写入etcd
  2. Pod被设置为”Terminating”状态、从service的Endpoints列表中删除并不再接受客户端请求。
  3. pod执行PreStop
  4. kubelet向pod中的容器发送SIGTERM信号(正常终止信号)终止pod里面的主进程,这个信号让容器知道自己很快将会被关闭terminationGracePeriodSeconds: 60 #可选终止等待期(pod删除宽限期),如果有设置删除宽限时间,则等待宽限时间到期,否则最多等待30s,Kubernetes等待指定的时间称为优雅终止宽限期,默认情况下是30秒,值得注意的是等待期与preStop Hook和SIGTERM信号并行执行,即Kubernetes可能不会等待preStop Hook完成(最长30秒之后主进程还没有结束就就强制终止pod)。
  5. SIGKILL信号被发送到Pod,并删除Pod

K8s Pod状态与容器探针的更多相关文章

  1. 掌握SpringBoot-2.3的容器探针:基础篇

    欢迎访问我的GitHub 地址:https://github.com/zq2599/blog_demos 内容:原创文章分类汇总,及配套源码,涉及Java.Docker.K8S.DevOPS等 关于& ...

  2. k8s的Pod状态和生命周期管理

    Pod状态和生命周期管理   一.什么是Pod? 二.Pod中如何管理多个容器? 三.使用Pod 四.Pod的持久性和终止 五.Pause容器 六.init容器 七.Pod的生命周期 (1)Pod p ...

  3. Pod——状态和生命周期管理及探针和资源限制

    一.什么是Podkubernetes中的一切都可以理解为是一种资源对象,pod,rc,service,都可以理解是 一种资源对象.pod的组成示意图如下,由一个叫”pause“的根容器,加上一个或多个 ...

  4. dubbo 协议的 K8s pod 存活探针配置

    背景 某项目采用微服务架构,dubbo 框架,K8s 方式部署. 其中 HTTP 协议由网关应用统一处理,大部分应用仅提供 dubbo 协议. 目标 应用某个实例(pod)状态异常时,尝试自动重启恢复 ...

  5. K8S容器探针

    容器探针 探针是由 kubelet对容器执行的定期诊断.要执行诊断, kubelet 调用由容器实现的    Handler .有三种类型的处理程序:   ExecAction :在容器内执行指定命令 ...

  6. K8s中的多容器Pod和Pod内容器间通信

    容器(Container)常被用来解决比如微服务的单个问题,但在实际场景中,问题的解决往往需要多容器方案.本文会讨论将多个容器整合进单个Kubernetes Pod 中,以及Pod中的容器之间是如何通 ...

  7. Kubernetes学习之路(十一)之Pod状态和生命周期管理

    一.什么是Pod? Pod是kubernetes中你可以创建和部署的最小也是最简的单位.一个Pod代表着集群中运行的一个进程. Pod中封装着应用的容器(有的情况下是好几个容器),存储.独立的网络IP ...

  8. 2.k8s.Pod生命周期,健康检查

    #Pod生命周期,健康检查 pod创建过程 Init容器 就绪探测 存活探测 生命周期钩子 #Pod创建过程 master节点:kubectl -> kube-api -> kubenle ...

  9. 掌握SpringBoot-2.3的容器探针:深入篇

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:原创分类汇总及配套源码,涉及Java.Docker.K8S.DevOPS等 关于<Spr ...

  10. 掌握SpringBoot-2.3的容器探针:实战篇

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:原创文章分类汇总,及配套源码,涉及Java.Docker.K8S.DevOPS等 经过多篇知识 ...

随机推荐

  1. 暗夜发光,独自闪耀,盘点网页暗黑模式(DarkMode)下的特效和动效,CSS3实现

    众所周知,网页的暗黑模式可以减少屏幕反射和蓝光辐射,减少眼睛的疲劳感,特别是在夜间使用时更为明显.其实暗黑模式也给霓虹灯效应(Neon Effect)提供了发挥的环境. 霓虹灯效应是一种视觉效果,其特 ...

  2. 1688关键字搜索新品数据API接口(item_search_new-按关键字搜索新品数据)

    1688关键字搜索新品数据API接口(item_search_new-按关键字搜索新品数据)代码接口教程如下: 公共参数 名称 类型 必须 描述key String 是 调用key(必须以GET方式拼 ...

  3. vue之箭头函数

    目录 说明 解决方法一 重新定义this 解决方法二 使用箭头函数 无参数的箭头函数 有一个参数的箭头函数 有两个参数的箭头函数 有一个参数一个返回值的箭头函数 说明 当在一个方法(函数)里面再定义一 ...

  4. 使用kubeadm快速启用一个集群

    使用kubeadm快速启用一个集群 CentOS 配置YUM源 cat <<EOF > /etc/yum.repos.d/kubernetes.repo [kubernetes] n ...

  5. MySQL匿名空用户名处理

    问题描述:公司漏扫发现数据库内出现空用户名及密码,需要对这些用户进行整改 1.首先出现了疑问,这些空的用户名是怎么出现的,而且不附带密码. 2.可以手动这样创建这样的用户名和密码形式么. 3.如果能这 ...

  6. 【SpringCloud】(二)Eureka注册中心和Feign远程调用

    1 SpringCloud 核心 SpringCloud基于HTTP协议,这是和Dubbo最本质的区别,Dubbo的核心是RPC(远程方法调用) Eureka:注册中心 Ribbon:客户端负载均衡 ...

  7. Ubuntu18搭建vue3

    第一步我们可以先更新源(我所有的步骤都在root账户下操作的) sudo apt-get update 然后安装node sudo apt-get install nodejs 安装成功后可以查看版本 ...

  8. FBV和CBV的区别(源码分析)

    FBV和CBV源码分析 FBV直接调用user方法执行业务代码 CBV相当于在FBV上面封装了一层 from django.contrib import admin from django.urls ...

  9. Array.prototype.at。Arrat和 String 中的 at 方法

    一篇有关新 js 特性 at 方法的思考 入参只能是number 类型,允许入参有小数(按照 chrome DevTools Console 测试确实可以带小数) 有返回值,如果对应下标在实例中存在, ...

  10. springboot mybatis 动态调用oracle存储过程,通过存储过程名称,就能动态调用存储过程、java动态调用oracle存储过程

    由于在开发业务时,可能同时调用的存储过程不知道参数,但是参数从界面.或已经存储在数据库的获取,所以就不希望手动写存储过程的参数,通过简化的调用. 能不能写个动态的业务,只输入存储过程名称,自动获取存储 ...