创建pod-base.yaml文件,内容如下:
apiVersion: v1
kind: Pod
metadata:
name: nginx-demo
labels:
type: app
version: 1.0.0
namespace: dev
spec:
containers:
- name: nginx
image: nginx:1.7.9
imagePullPolicy: IfNotPresent
command:
- nginx
- -g
- 'daemon off;'
workingDir: /usr/share/nginx/html
ports:
- name: http
containerPort: 80
hostPort: 80
protocol: TCP
env:
- name: JVM_OPTS
value: 'Xms128m -Xmx128m'
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 200m
memory: 256Mi
restartPolicy: OnFailure
apiVersion: v1 #必选,文档版本号,例如v1
kind: Pod #必选,资源对象类型,例如 Pod,也可以配置为Deployment
metadata: #必选,Pod相关的元数据,用来描述Pod的数据
name: nginx-demo #必选,Pod名称
labels: #定义Pod的标签
type: app #自定义lable标签,名字为type 值为app
version: 1.0.0 #自定义label标签 描述Pod版本号
namespace: dev #Pod所属的命名空间,默认为"default"
spec: #必选,期望Pod按照这个里面的描述进行创建
containers: #必选,Pod中容器列表 对于Pod中的容器描述
- name: nginx #必选,容器名称
image: nginx:1.7.9 #必选,容器的镜像名称
imagePullPolicy: IfNotPresent #获取镜像的策略 指定如果本地有就用本地的,如果没有就拉取远程的
command: #容器的启动命令列表,如不指定,使用打包时使用的启动命令
- nginx
- -g
- 'daemon off;' #nginx -g 'daemon off'
workingDir: /usr/share/nginx/html #容器的工作目录
ports: #需要暴露的端口库号列表
- name: http #端口的名称
containerPort: 80 #容器需要监听的端口号
hostPort: int #容器所在主机需要监听的端口号,默认与Container相同
protocol: TCP #端口协议,支持TCP和UDP,默认TCP
env: #容器运行前需设置的环境变量列表
name: JVM_OPTS #环境变量名称
value: 'Xms128m -Xmx128m' #环境变量的值
resources: #资源限制和请求的设置
requests: #最少需要多少资源
cpu: 100m #限制cpu最少使用0.1个核心
memory: 128Mi #限制内存最少使用128兆
limits: #最多需要多少资源
cpu: 200m #
memory: 256Mi #
restartPolicy: OnFailure #重启策略,只有失败的情况才会重启
# 把上面的内容放进去
[root@k8s-master pods] vi nginx.demo.yaml
# 创建Pod
[root@k8s-master pods]# kubectl apply -f nginx-demo.yaml
pod/nginx-demo created
# 查看Pod状况
# READY 0/1 : 表示当前Pod中有1个容器,未准备就绪
# STATUS ContainerCreating 容器创建中
[root@k8s-master pods]# kubectl get pod -n dev
NAME READY STATUS RESTARTS AGE
nginx-demo 0/1 ContainerCreating 0 36s
#CrashLoopBackOff 表示你的 Pod 在启动后立即崩溃,
#并且 Kubernetes 正在尝试重新启动它,但是这一过程一直在循环中。
[root@k8s-master pods]# kubectl get pod -n dev
NAME READY STATUS RESTARTS AGE
nginx-demo 0/1 CrashLoopBackOff 1 (9s ago) 10s
#查看 Pod 的日志
[root@k8s-master pods]# kubectl logs nginx-demo -n dev
2024/01/02 09:18:06 [emerg] 1#0: unexpected end of parameter, expecting ";" in command line
nginx: [emerg] unexpected end of parameter, expecting ";" in command line
#根据日志的内容,问题似乎是在 Nginx 启动命令行参数中。
#日志指出出现了一个紧急错误,即“unexpected end of parameter,
#expecting ';' in command line”(预期参数结束,期望在命令行中找到 ';')。
#尝试更新你的 YAML 文件中的 Nginx 启动命令,使用正常的 Nginx 启动方式:
#command:
# - nginx
# - -g
# - 'daemon off;'
#发现少了;导致了报错
#修改配置文件
[root@k8s-master pods]# vi nginx-demo.yaml
#创建Pod
[root@k8s-master pods]# kubectl apply -f nginx-demo.yaml -n dev
The Pod "nginx-demo" is invalid: spec: Forbidden: pod updates may not change fields other than `spec.containers[*].image`, `spec.initContainers[*].image`, `spec.activeDeadlineSeconds`, `spec.tolerations` (only additions to existing tolerations) or `spec.terminationGracePeriodSeconds` (allow it to be set to 1 if it was previously negative)
core.PodSpec{
Volumes: {{Name: "kube-api-access-gbfg2", VolumeSource: {Projected: &{Sources: {{ServiceAccountToken: &{ExpirationSeconds: 3607, Path: "token"}}, {ConfigMap: &{LocalObjectReference: {Name: "kube-root-ca.crt"}, Items: {{Key: "ca.crt", Path: "ca.crt"}}}}, {DownwardAPI: &{Items: {{Path: "namespace", FieldRef: &{APIVersion: "v1", FieldPath: "metadata.namespace"}}}}}}, DefaultMode: &420}}}},
InitContainers: nil,
Containers: []core.Container{
{
Name: "nginx",
Image: "nginx:1.7.9",
Command: []string{
"nginx",
"-g",
- "daemon off;",
+ "daemon off",
},
Args: nil,
WorkingDir: "/usr/share/nginx/html",
... // 17 identical fields
},
},
EphemeralContainers: nil,
RestartPolicy: "OnFailure",
... // 26 identical fields
}
#错误提示表明在 Kubernetes 中,你不能直接修改 Pod 中的某些字段,
#除非是 spec.containers[*].image、spec.initContainers[*].image、
#spec.activeDeadlineSeconds、spec.tolerations
#或 spec.terminationGracePeriodSeconds 这些字段。在你的更新中,
#尝试修改了 spec.containers[*].command 字段,这是不允许的。
#为了解决这个问题,需要创建一个新的 Pod 资源而不是直接更新现有的 Pod。
#删除现有的 Pod:
[root@k8s-master pods]# kubectl delete pod nginx-demo -n dev
pod "nginx-demo" deleted
#创建一个新的 Pod:
[root@k8s-master pods]# kubectl apply -f nginx-demo.yaml -n dev
pod/nginx-demo created
# 查看Pod状况 # READY 1/1 : 表示当前Pod中有1个容器,准备就绪
[root@k8s-master pods]# kubectl get pod -n dev
NAME READY STATUS RESTARTS AGE
nginx-demo 1/1 Running 0 15s
# 可以通过describe查看内部的详情
[root@k8s-master pods]# kubectl describe pod nginx-demo -n dev
查看Pod内部的详情中的事件
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 19m default-scheduler Successfully assigned dev/nginx-demo to k8s-node1
Normal Pulled 19m kubelet Container image "nginx:1.7.9" already present on machine
Normal Created 19m kubelet Created container nginx
Normal Started 19m kubelet Started container nginx
# 查看pod详细信息
[root@k8s-master pods]# kubectl get po -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-pod 1/1 Running 0 5d18h 10.244.1.6 k8s-node1 <none> <none>
#从集群内部访问了 Pod 的 IP 地址。这个 IP 地址是由 Kubernetes 分配的集群内部地址
[root@k8s-master pods]# curl 10.244.1.6
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
#路由表显示主机上的 IP 路由信息
[root@k8s-master pods]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.235.2 0.0.0.0 UG 100 0 0 ens33
10.244.0.0 0.0.0.0 255.255.255.0 U 0 0 0 cni0
10.244.1.0 10.244.1.0 255.255.255.0 UG 0 0 0 flannel.1
172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker0
192.168.235.0 0.0.0.0 255.255.255.0 U 100 0 0 ens33
容器内应用的监测机制,根据不同的探针来判断容器应用当前的状态
容器运行成功后会创建一个探针,会一直监控容器,一但发现容器挂掉了,会检查配置文件中是否有对应重启策略,按照要求的重启策略进行重启,或者是否需要重启。 restartPolicy: OnFailure # 重启策略 来重新启动
没有这个配置的话,容器挂掉了就是挂掉了
生命周期探针用于确定容器是否处于运行中 。如果生命周期探针失败,kubelet 会根据配置的重启策略进行重启,若没有配置,默认就认为容器启动成功,不会执行重启策略。.
配置示例:
livenessProbe:
failureThreshold: 5 #失败多少次算失败
httpGet:
path: /health
port: 8080
scheme: HTTP
initialDelaySeconds: 60 # 初始化时间
periodSeconds: 10 # 间隔时间
successThreshold: 1 # 多少此检测成功算成功
timeoutSeconds: 5 # 请求超时时间
总的来说,上述配置表示容器的 Liveness Probe 将会:
就绪性探针(Readiness Probe)
用于探测容器内的程序是否健康 ,它的返回值如果返回 success,那么就认为该容器已经完全启动,并且该容器是可以接收外部流量的。指示容器是否准备好为请求提供服务。如果就绪态探测失败, 端点控制器将从与 Pod 匹配的所有服务的端点列表中删除该 Pod 的 IP 地址。 初始延迟之前的就绪态的状态值默认为 Failure
配置示例:
readinessProbe:
failureThreshold: 3 # 错误次数
httpGet:
path: /ready
port: 8181
scheme: HTTP
periodSeconds: 10 # 间隔时间
successThreshold: 1
timeoutSeconds: 1
k8s 1.16 版本新增的探针,用于判断应用程序是否已经启动了。
当配置了 startupProbe 后,会先禁用其他探针,直到 startupProbe 成功后,其他探针才会继续。
作用:由于有时候不能准确预估应用一定是多长时间启动成功,因此配置另外两种方式不方便配置初始化时长来检测,而配置了 statupProbe 后,只有在应用启动成功了,才会执行另外两种探针,可以更加方便的结合使用另外两种探针使用。
配置示例:
startupProbe:
httpGet:
path: /api/startup
port: 80
exec 方式通过执行容器内的命令检查容器的健康状态,如果返回值为 0,则任务容器时健康的。
livenessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 3
periodSeconds: 5
Liveness Probe 将每 5 秒执行一次 cat /tmp/healthy 命令,如果命令成功执行(返回码为 0),则认为容器是健康的
通过 tcp 连接监测容器内端口是否开放,如果开放则证明该容器健康
livenessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 3
periodSeconds: 5
Liveness Probe 将每 5 秒尝试在容器的 8080 端口上建立一个 TCP 连接,如果连接成功,则认为容器是健康的
httpGet 方式通过发送 HTTP GET 请求检查容器的健康状态。
允许针对 httpGet 配置额外的字段:
- host:连接使用的主机名,默认是 Pod 的 IP。也可以在 HTTP 头中设置 “Host” 来代替。
- scheme:用于设置连接主机的方式(HTTP 还是 HTTPS)。默认是 “HTTP”。
- path:访问 HTTP 服务的路径。默认值为 “/”。
- httpHeaders:请求中自定义的 HTTP 头。HTTP 头字段允许重复。
- port:访问容器的端口号或者端口名。如果数字必须在 1~65535 之间。
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 3
periodSeconds: 5
periodSeconds 字段指定了 kubelet 每隔 3 秒执行一次存活探测。 initialDelaySeconds 字段告诉 kubelet 在执行第一次探测前应该等待 3 秒。 kubelet 会向容器内运行的服务(服务在监听 8080 端口)发送一个 HTTP GET 请求来执行探测。 如果服务器上 /healthz 路径下的处理程序返回成功代码
针对 HTTP 探针,kubelet 除了必需的 Host 头部之外还发送两个请求头部字段:
你可以通过为探测设置 httpHeaders 来重载默认的头部字段值。例如:
livenessProbe:
httpGet:
httpHeaders:
- name: Accept
value: application/json
startupProbe:
httpGet:
httpHeaders:
- name: User-Agent
value: MyUserAgent
httpGet方式:
[root@k8s-master pods]# kubectl get pod -n dev
NAME READY STATUS RESTARTS AGE
nginx-demo 1/1 Running 0 5d19h
#删除现有的 Pod:
[root@k8s-master pods]# kubectl delete pod nginx-demo -n dev
pod "nginx-demo" deleted
#修改配置文件
[root@k8s-master pods]# vi nginx-demo.yaml
# 在command 上面加入以下内容
startupProbe: #应用启动探针配置
httpGet: # 探测方式,基于http请求探测
path: /api/startup # http请求路径 这个是不存在的path请求不到
port: 80 #请求端口
failureThreshold: 3 # 失败多少次算失败
periodSeconds: 10 # 间隔时间
successThreshold: 1 # 多少此检测成功算成功
timeoutSeconds: 5 # 请求超时时间
#创建一个新的 Pod:
[root@k8s-master pods]# kubectl apply -f nginx-demo.yaml -n dev
pod/nginx-demo created
[root@k8s-master pods]# kubectl get pod -n dev
NAME READY STATUS RESTARTS AGE
nginx-demo 0/1 Running 1 (11s ago) 42s
[root@k8s-master pods]# kubectl get pod -n dev
NAME READY STATUS RESTARTS AGE
nginx-demo 0/1 Running 1 (16s ago) 47s
[root@k8s-master pods]# kubectl get pod -n dev
NAME READY STATUS RESTARTS AGE
nginx-demo 0/1 Running 1 (29s ago) 60s
# 可以通过describe查看内部的详情
[root@k8s-master pods]# kubectl describe pod nginx-demo -n dev
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 109s default-scheduler Successfully assigned dev/nginx-demo to k8s-node1
Normal Pulled 18s (x4 over 108s) kubelet Container image "nginx:1.7.9" already present on machine
Normal Created 18s (x4 over 108s) kubelet Created container nginx
Normal Started 18s (x4 over 108s) kubelet Started container nginx
Normal Killing 18s (x3 over 78s) kubelet Container nginx failed startup probe, will be restarted
Warning Unhealthy 8s (x10 over 98s) kubelet Startup probe failed: HTTP probe failed with statuscode: 404
Startup probe failed: HTTP probe failed with statuscode: 404:
Kubernetes 的启动探测(Startup Probe)中,HTTP 探测失败,返回了状态码 404
[root@k8s-master pods]# mv nginx-demo.yaml nginx-po.yaml
[root@k8s-master pods]# ls
nginx-po.yaml
#删除现有的 Pod:
[root@k8s-master pods]# kubectl delete pod nginx-demo -n dev
pod "nginx-demo" deleted
#修改配置文件
[root@k8s-master pods]# vi nginx-po.yaml
# 修改配置
metadata:
name: nginx-po
path: /index.html #http请求路径 这个是存在的路径
#创建一个新的 Pod
[root@k8s-master pods]# kubectl apply -f nginx-po.yaml -n dev
pod/nginx-po created
#通过describe查看内部的详情
[root@k8s-master pods]# kubectl describe pod nginx-po -n dev
打印内部详情: 没有错误信息 打印了对应Startup对应配置信息 探针方式为http-get
# 查看Pod状况
# READY 1/1 : 表示当前Pod中有1个容器,准备就绪
[root@k8s-master pods]# kubectl get pod -n dev
NAME READY STATUS RESTARTS AGE
nginx-po 1/1 Running 0 4m11s
tcpScocket方式: 端口连接成功就算成功的访问
** **把之前httpGet方式的探针注释,改为tcpSocket方式。
startupProbe: #应用启动探针配置
tcpSocket:
port: 80 # 请求端口
按照原来的步骤再来一遍
打印内部详情: 没有错误信息 打印了对应Startup对应配置信息 探针方式为tcp-socket
**exec方式: **
command:
- sh
- -c
- "echo success >/inited;"
在 /inited 文件中写入 “success” 字符串
打印内部详情: 没有错误信息 打印了对应Startup对应配置信息 探针方式为exec 由之前的额发请求变成了命令的方式执行
# 查看Pod状况
# READY 1/1 : 表示当前Pod中有1个容器,准备就绪
[root@k8s-master pods]# kubectl get pod -n dev
NAME READY STATUS RESTARTS AGE
nginx-po 1/1 Running 0 69s
#在名为 "nginx-po" 的 Pod 中的 "nginx" 容器内执行 cat /inited 命令,查看 "/inited" 文件的内容
[root@k8s-master pods]# kubectl exec -it nginx-po -n dev -c nginx -- cat /inited
success
#出现了success 操作成功
# 复制nginx-po.yaml文件内容
[root@k8s-master pods]# cp nginx-po.yaml nginx-livexess-po.yaml
cp:是否覆盖"nginx-livexess-po.yaml"? Y
[root@k8s-master pods]# ls
nginx-livexess-po.yaml nginx-po.yaml
#修改配置文件
[root@k8s-master pods]# vi nginx-livexess-po.yaml
startupProbe: #应用启动探针配置
#tcpSocket:
# port: 80 # 请求端口
exec:
command:
- sh
- -c
- "sllep 3;echo success >/inited;"
failureThreshold: 3 # 失败多少次算失败
periodSeconds: 10 # 间隔时间
successThreshold: 1 # 多少此检测成功算成功
timeoutSeconds: 5 # 请求超时时间
livenessProbe: #应用存活探针配置
httpGet: # 探测方式,基于http请求探测
path: /started.html # http请求路径 这个是不存在的path请求不到
port: 80 #请求端口
failureThreshold: 3 # 失败多少次算失败
periodSeconds: 10 # 间隔时间
successThreshold: 1 # 多少此检测成功算成功
timeoutSeconds: 5 # 请求超时时间
#RESTARTS 重启3次
[root@k8s-master pods]# kubectl get pod -n dev
NAME READY STATUS RESTARTS AGE
nginx-po 0/1 Running 3 (12s ago) 2m12s
#Completed重启5次终止状态
[root@k8s-master pods]# kubectl get pod -n dev
NAME READY STATUS RESTARTS AGE
nginx-po 0/1 Completed 5 5m56s
[root@k8s-master pods]# kubectl cp started.html dev/nginx-po:/usr/share/nginx/html/
#文件存在后启动成功
[root@k8s-master pods]# kubectl get pod -n dev
NAME READY STATUS RESTARTS AGE
nginx-po 1/1 Running 1 (2m ago) 2m40s
有时候,会有一些现有的应用在启动时需要较长的初始化时间。 要这种情况下,若要不影响对死锁作出快速响应的探测,设置存活探测参数是要技巧的。 技巧就是使用相同的命令来设置启动探测,针对 HTTP 或 TCP 检测,可以通过将 failureThreshold * periodSeconds 参数设置为足够长的时间来应对最糟糕情况下的启动时间
这样,前面的例子就变成了:
ports:
- name: liveness-port
containerPort: 8080
hostPort: 8080
livenessProbe:
httpGet:
path: /healthz
port: liveness-port
failureThreshold: 1
periodSeconds: 10
startupProbe:
httpGet:
path: /healthz
port: liveness-port
failureThreshold: 30
periodSeconds: 10
幸亏有启动探测,应用将会有最多 5 分钟(30 * 10 = 300s)的时间来完成其启动过程。 一旦启动探测成功一次,存活探测任务就会接管对容器的探测,对容器死锁作出快速响应。 如果启动探测一直没有成功,容器会在 300 秒后被杀死,并且根据 restartPolicy 来执行进一步处置。
有时候,应用会暂时性地无法为请求提供服务。 例如,应用在启动时可能需要加载大量的数据或配置文件,或是启动后要依赖等待外部服务。 在这种情况下,既不想杀死应用,也不想给它发送请求。 Kubernetes 提供了就绪探针来发现并缓解这些情况。 容器所在 Pod 上报还未就绪的信息,并且不接受通过 Kubernetes Service 的流量。
说明:
就绪探针在容器的整个生命周期中保持运行状态。
注意:
# 复制nginx-livexess-po.yaml文件内容
[root@k8s-master pods]# cp nginx-livexess-po.yaml nginx-rediness-po.yaml
[root@k8s-master pods]# vi nginx-rediness-po.yaml
readinessProbe: #应用就绪探针配置
httpGet: # 探测方式,基于http请求探测
path: /started.html # http请求路径 这个是不存在的path请求不到
port: 80 #请求端口
failureThreshold: 5 # 失败多少次算失败
periodSeconds: 10 # 间隔时间
successThreshold: 1 # 多少此检测成功算成功
timeoutSeconds: 5 # 请求超时时间
# 禁止外部网络访问 不会重启
[root@k8s-master pods]# kubectl get pod -n dev
NAME READY STATUS RESTARTS AGE
nginx-po 0/1 Running 0 21s
#把这个文件放进pod中
[root@k8s-master pods]# kubectl cp started.html nginx-po:/usr/share/nginx/html/ -n dev
# 再次查看pod就为就绪状态了
[root@k8s-master pods]# kubectl get pod -n dev
NAME READY STATUS RESTARTS AGE
nginx-po 1/1 Running 0 2m39s
要检查 Pod 中容器的状态,你可以使用 kubectl describe pod <pod 名称>。 其输出中包含 Pod 中每个容器的状态。
每种状态都有特定的含义:
Waiting (等待)
如果容器并不处在 Running 或 Terminated 状态之一,它就处在 Waiting 状态。 处于 Waiting 状态的容器仍在运行它完成启动所需要的操作:例如, 从某个容器镜像仓库拉取容器镜像,或者向容器应用 Secret 数据等等。 当你使用 kubectl 来查询包含 Waiting 状态的容器的 Pod 时,你也会看到一个 Reason 字段,其中给出了容器处于等待状态的原因。
Running(运行中)
Running 状态表明容器正在执行状态并且没有问题发生。 如果配置了 postStart 回调,那么该回调已经执行且已完成。 如果你使用 kubectl 来查询包含 Running 状态的容器的 Pod 时, 你也会看到关于容器进入 Running 状态的信息。
Terminated(已终止)
处于 Terminated 状态的容器已经开始执行并且或者正常结束或者因为某些原因失败。 如果你使用 kubectl 来查询包含 Terminated 状态的容器的 Pod 时, 你会看到容器进入此状态的原因、退出代码以及容器执行期间的起止时间。
如果容器配置了 preStop 回调,则该回调会在容器进入 Terminated 状态之前执行。
钩子函数能够感知自身生命周期中的事件,并在相应的时刻到来时运行用户指定的程序代码。
kubernetes在主容器的启动之后和停止之前提供了两个钩子函数:
postStart 处理函数与容器的代码是异步执行的,但 Kubernetes 的容器管理逻辑会一直阻塞等待 postStart 处理函数执行完毕。 只有 postStart 处理函数执行完毕,容器的状态才会变成 RUNNING
除非 Pod 宽限期限超时, Kubernetes 的容器管理逻辑会一直阻塞等待 preStop 处理函数执行完毕
钩子处理器支持使用下面三种方式定义动作:
Exec命令:在容器内执行一次命令
……
lifecycle:
postStart:
exec:
command:
- cat
- /tmp/healthy
……
TCPSocket:在当前容器尝试访问指定的socket
……
lifecycle:
postStart:
tcpSocket:
port: 8080
……
HTTPGet:在当前容器中向某url发起http请求
……
lifecycle:
postStart:
httpGet:
path: / #URI地址
port: 80 #端口号
host: 192.168.5.3 #主机地址
scheme: HTTP #支持的协议,http或者https
……
使用 preStop 生命周期钩子时,可以在应用即将终止之前执行一些清理操作。在您的场景中,可以通过 preStop 钩子来实现注册中心下线、数据清理和数据销毁等操作。
如果应用销毁操作耗时需要比较长,可以在 preStop 按照如下方式进行配置
preStop:
exec:
command:
- sh
- -c
- 'sleep 20; kill pgrep java'
但是需要注意,由于 k8s 默认给 pod 的停止宽限时间为 30s,如果我们停止操作会超过 30s 时,不要光设置 sleep 50,还要将 terminationGracePeriodSeconds: 30 也更新成更长的时间,否则 k8s 最多只会在这个时间的基础上再宽限几秒,不会真正等待 50s
以下是一个示例 Pod 配置,其中包含一个具有 preStop 钩子的容器:
apiVersion: v1
kind: Pod
metadata:
name: my-app-pod
spec:
terminationGracePeriodSeconds: 90 # 设置终止期限为 90 秒
containers:
- name: my-app-container
image: my-app-image:latest
lifecycle:
preStop:
exec:
command: ["/bin/sh", "-c", "cleanup-script.sh"]
在这个示例中,cleanup-script.sh 是一个您定义的脚本,其中包含执行清理操作的逻辑。您可以在这个脚本中实现注册中心下线、数据清理和数据销毁等操作。
apiVersion: v1
kind: Pod
metadata:
name: pod-hook-exec
namespace: dev
spec:
terminationGracePeriodSeconds: 45
containers:
- name: main-container
image: nginx:1.17.1
ports:
- name: nginx-port
containerPort: 80
lifecycle:
postStart:
exec:
command: ["/bin/sh", "-c", "echo 'postStart... creating file' > /usr/share/nginx/html/index.html"]
preStop:
exec:
command: ["/bin/sh", "-c", "echo 'preStop... creating file' > /pods/termination-file.html"]
# 创建pod
[root@k8s-master pods]# kubectl apply -f pod-lifecycle-demo.yaml
pod/lifecycle-graceful-pod created
# 查看pod列表
[root@k8s-master pods]# kubectl get pods -n dev
NAME READY STATUS RESTARTS AGE
pod-hook-exec 1/1 Running 0 68s
#查看pod
[root@k8s-master pods]# kubectl get pods pod-hook-exec -n dev -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod-hook-exec 1/1 Running 0 104s 10.244.1.27 k8s-node1 <none> <none>
# 访问pod
[root@k8s-master pods]# curl 10.244.1.27
postStart... creating file
postStart… creating file 这个是postStart钩子函数执行的内容.
强制删除不会等待来自 kubelet 对 Pod 已终止的确认消息。 无论强制删除是否成功杀死了 Pod,它都会立即从 API 服务器中释放该名字。
如果要使用 kubectl 1.5 以上版本强制删除 Pod,请执行下面命令:
kubectl delete pods <pod> --grace-period=0 --force
如果你使用 kubectl 的 1.4 以下版本,则应省略 --force 选项:
kubectl delete pods <pod> --grace-period=0
如果在执行这些命令后 Pod 仍处于 Unknown 状态,请使用以下命令从集群中删除 Pod:
kubectl patch pod <pod> -p '{"metadata":{"finalizers":null}}'
请始终谨慎地执行强制删除 StatefulSet 类型的 Pod,并充分了解强制删除操作所涉及的风险