preStop挂钩未执行

时间:2019-03-21 12:16:49

标签: kubernetes google-kubernetes-engine

我正在测试生命周期挂钩,并且启动后的wotks很好,但是我认为停止前永远不会执行。还有另一个answer,但是它不起作用,实际上,如果可行,它将与k8s文档矛盾。因此,从文档中:

  

PreStop

     

此挂接在容器终止之前立即被调用    API请求或管理事件(例如,活动探测失败),   抢占,资源争用等。调用preStop挂钩   如果容器已经处于终止或完成状态,则失败。

因此,API请求使我认为我可以轻松完成kubectl delete pod POD,我很好。

文档(pod shutdown process)的更多内容:

  

1.-用户发送命令删除Pod,默认宽限期为30秒

     

2.- API服务器中的Pod随时间更新,超过该时间Pod被视为“死亡”以及宽限期。

     

3.-在客户端命令中列出Pod时显示为“正在终止”

     

4 .-(与3相同)当Kubelet看到由于设置了2中的时间而将Pod标记为终止时,它将开始Pod关闭过程。

     

4.1.-如果Pod的一个容器定义了preStop挂钩,则会在容器内部调用它。如果宽限期到期后preStop挂钩仍在运行,则以较小的(2秒)扩展宽限期调用步骤2。

     

4.2.-向容器发送TERM信号。请注意,并非Pod中的所有容器都会同时收到TERM信号,并且如果它们关闭的顺序很重要,则每个容器都可能需要一个preStop钩子。

     

...

因此,由于您执行kubectl delete pod POD时,吊舱会停在Terminating上,因此我认为我可以做到。

从另一个答案来看,我不能这样做,但是方法是进行滚动更新。好吧,我尝试了所有可能的方式,但是也没有用。

我的测试:

我有一个部署:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: my-deploy
spec:
  replicas: 1
  template:
    metadata:
      name: lifecycle-demo
      labels:
        lifecycle: demo
    spec:
      containers:
      - name: nginx
        image: nginx
        lifecycle:
          postStart:
            exec:
              command:
              - /bin/sh 
              - -c
              - echo "Hello at" `date` > /usr/share/post-start
          preStop:
            exec:
              command:
              - /bin/sh"
              - -c
              - echo "Goodbye at" `date` > /usr/share/pre-stop
        volumeMounts:
        - name: hooks
          mountPath: /usr/share/
      volumes:
      - name: hooks
        hostPath:
          path: /usr/hooks/

我希望pre-stoppost-start文件将在主机(运行pod的节点)上的/usr/hooks/中创建。启动后就在那里,但停止前永远不会。

  • 我尝试了kubectl delete pod POD,但没有成功。
  • 我尝试了kubectl replace -f deploy.yaml,但使用了另一张图片,当我执行kubectl get rs时,可以看到创建了新的copysetSet,但是文件不存在。
  • 我尝试了kubectl set image ...,然后再次看到新创建的replicaSet,但是文件不存在。
  • 我什至尝试将它们放在完全分开的卷中,因为我认为可能是我杀死吊舱并且重新创建了吊舱之后,它重新创建了应创建文件的文件夹,因此它删除了该文件夹并停止文件,但事实并非如此。 注意:它总是在同一节点上重新创建。我确定了。

我没有尝试过炸毁容器并通过设置较低的CPU限制来破坏它,但这不是我所需要的。

您知道在什么情况下preStop挂钩会被触发吗?

1 个答案:

答案 0 :(得分:1)

将其发布为社区Wiki,以获得更好的可见性。

第二个“ / bin / sh”中有一个错字;用于preStop。还有一个额外的双引号(“)。它让我创建了部署,但是原因是它没有创建文件。现在一切正常。

问题所在的确切位置在这里:

          preStop:
            exec:
              command:
              - /bin/sh" # <- this quotation
              - -c
              - echo "Goodbye at" `date` > /usr/share/pre-stop

为正确起见,它应该像这样:

          preStop:
            exec:
              command:
              - /bin/sh
              - -c
              - echo "Goodbye at" `date` > /usr/share/pre-stop

在撰写此社区Wiki帖子时,此Deployment清单已过时。为了能够运行此清单,需要进行以下更改:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: good-deployment
spec:
  selector:
    matchLabels:
      lifecycle: demo 
  replicas: 1
  template:
    metadata:
      labels:
        lifecycle: demo
    spec:
      containers:
      - name: nginx
        image: nginx
        lifecycle:
          postStart:
            exec:
              command:
              - /bin/sh 
              - -c
              - echo "Hello at" `date` > /usr/share/post-start
          preStop:
            exec:
              command:
              - /bin/sh
              - -c
              - echo "Goodbye at" `date` > /usr/share/pre-stop
        volumeMounts:
        - name: hooks
          mountPath: /usr/share/
      volumes:
      - name: hooks
        hostPath:
          path: /usr/hooks/

更改如下:

1。 apiVersion

+--------------------------------+---------------------+
|               Old              |          New        |
+--------------------------------+---------------------+
| apiVersion: extensions/v1beta1 | apiVersion: apps/v1 |
+--------------------------------+---------------------+

StackOverflow答案以获取更多参考:

2。 selector

selector下添加了spec部分:

spec:
  selector:
    matchLabels:
      lifecycle: demo 

其他参考链接: