如何解决吊舱PreStop挂钩处于挂起状态,仅在终止后挂起GracePeriodSeconds
我在statefulset pod资源中定义了一个preStop钩子,该钩子运行bash脚本,以确保在应用程序中很少有进程完成/取消/错误之前,不要杀死pod。我没有定义terminationGracePeriodSeconds。现在,当我删除吊舱时,我测试了作为preStop挂钩一部分的脚本是否按预期运行。但是在添加了terminationGracePeriodSeconds 10分钟之后,首先bash脚本作为preStop hook的一部分成功运行了几分钟,并且应该杀死该pod。但是吊舱处于TERMINATING状态,只有10分钟后才会被杀死。
- 为什么吊舱是吊着的?无法为此找到答案。
- 未添加terminationGracePeriodSeconds时,该流正在按预期方式工作,方法是在完成脚本后或在30秒内(即terminationGracePeriodSeconds)杀死Pod。但是,当我添加10分钟或更长时间的宽限期时,它会等到那个时候再杀死吊舱。
如何解决此问题。有没有一种方法可以将SIGTERM或SIGKILL发送到吊舱。有任何想法吗?预先谢谢你!
STATEFULSET.YAML
apiVersion: apps/v1
kind: StatefulSet
Metadata:
labels:
app: appx
name: appx
spec:
serviceName: appx
replicas: 1
updateStrategy:
type: RollingUpdate
selector:
matchLabels:
app: appx
template:
Metadata:
labels:
app: appx
spec:
#removed some of the sensitive info
terminationGracePeriodSeconds: 600
containers:
- image: appx
imagePullPolicy: IfNotPresent
name: appx
lifecycle:
preStop:
exec:
command: ["/bin/sh","-c","sleep 30 && bash /var/tmp/runscript.sh; sleep10"]
KUBECTL DESCRIBE POD
**kubectl describe pod appx**
Name: appx
Namespace: default
Priority: 0
Node: docker-desktop/192.168.65.3
Start Time: Mon,21 Sep 2020 07:30:55 -0500
Labels: app=appx
Annotations: <none>
Status: Running
IP: x.x.x.x
Controlled By: StatefulSet/appx
Containers:
appx:
Container ID: docker://dfdgfgfgfgfgfgfg
Image: appx
Image ID: docker://sha256:49dfgfgfgfgfgfgfgfgfg96a6fc
Port: <none>
Host Port: <none>
State: Running
Started: Mon,21 Sep 2020 07:30:56 -0500
Ready: True
Restart Count: 0
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
data:
Type: EmptyDir (a temporary directory that shares a pod's lifetime)
Medium:
SizeLimit: <unset>
appx-token-xj6q9:
Type: Secret (a volume populated by a Secret)
SecretName: appx-token-fhfdlf
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
normal Scheduled 2m43s default-scheduler Successfully assigned default/appx to docker-desktop
normal Pulled 2m42s kubelet,docker-desktop Container image "appx" already present on machine
normal Created 2m42s kubelet,docker-desktop Created container appx
normal Started 2m42s kubelet,docker-desktop Started container appx
解决方法
preStop
钩子和terminationGracePeriodSeconds
是异步的。这意味着,只要kubelet看到Pod已被标记为终止,kubelet就会立即开始本地Pod关闭过程。这意味着如果容器在宽限期内没有终止,则无论preStop挂钩中的命令是否完成,SIGKILL信号都会被发送,并且容器将被杀死。
始终添加
- 未添加terminationGracePeriodSeconds时,该流正在按预期方式工作,方法是在完成脚本后立即杀死该pod 或在30秒内终止GracePeriodSeconds。但当 我添加了10分钟或更长时间的宽限期,它一直等到 时间,然后杀死豆荚。
terminationGracePeriodSeconds
宽限期。正如我在评论中已经提到的,它默认为30秒。那么,如果terminationGracePeriodSeconds
少于完成preStop挂钩的时间呢?
然后,容器将在terminationGracePeriodSeconds
的结尾处终止,并且preStop钩子将不会完成/运行。
将TerminationGracePeriodSeconds设置为600s时,preStop挂钩脚本将挂起(目前尚不清楚它是否能正常工作,因为由于抢占式终止而未使用默认的30s terminationGracePeriodSeconds进行正确测试)。这意味着某些进程无法正确处理SIGTERM,而当前在preStop挂钩中尚未对其进行纠正,这意味着容器将在等待10分钟终止GracePeriod结束后等待发送SIGKILL。
如果您查看here,您会发现,即使用户指定了preStop挂钩,他们也需要对Nginx进行SIGTERM正常关闭。
在您将terminationGracePeriodSeconds
设置为10分钟的情况下,即使您成功执行了preStop挂钩,Kubernetes仍在终止容器之前等待了10分钟,因为这正是您告诉他的操作。终止信号是通过kubelet发送的,但没有传递到容器内部的应用程序。最常见的原因是,当您的容器运行运行应用程序进程的外壳程序时,该信号可能会被外壳程序本身消耗/中断,而不是传递给子进程。另外,由于不清楚您的runscript.sh
在做什么,因此很难对哪些进程无法处理SIGTERM提出其他建议。
在这种情况下您可以做什么?提前结束的选项是:
- 减少terminationGracePeriodSeconds
- 通过确保正确处理SIGTERM,并且所有正在运行的进程都在侦听终止,发送信号以正常关闭。 here是如何执行此操作的示例。您可以看到他们对NGINX使用了“退出”命令。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。