如何删除 Kubernetes 'shutdown' pods

How to remove Kubernetes 'shutdown' pods

我最近注意到状态 'Shutdown' 的 pods 大量积累。自 2020 年 10 月以来,我们一直在使用 Kubernetes。

生产和暂存 运行 在相同的节点上进行,只是暂存使用可抢占节点来降低成本。容器在分段时也很稳定。 (故障很少发生,因为它们以前在测试中被捕获过)。

服务提供商Google Cloud Kubernetes。

我熟悉了文档并尝试搜索,但我都没有意识到 google 对这种特殊状态没有帮助。日志中没有错误。

我不介意 pods 被阻止。理想情况下,我希望 K8s 自动删除这些关闭 pods。如果我运行kubectl delete po redis-7b86cdccf9-zl6k9,一眨眼就没了

kubectl get pods | grep Shutdown | awk '{print }' | xargs kubectl delete pod 是手动临时解决方法。

PS。 k 在我的环境中是 kubectl 的别名。

最后一个例子:它发生在所有命名空间//不同的容器中。

我偶然发现了一些解释状态的相关问题 https://github.com/kubernetes/website/pull/28235 https://github.com/kubernetes/kubernetes/issues/102820

“当 pods 在正常节点关闭期间被逐出时,它们被标记为失败。运行 kubectl get pods 将被逐出的 pods 的状态显示为 Shutdown."

首先,尝试使用以下命令强制删除 kubernetes pod:

$ kubectl delete pod <pod_name> -n --grace-period 0 --force

您可以使用以下命令直接删除 pod:

$ kubectl delete pod

然后,使用以下命令检查 pod 的状态:

$ kubectl get pods

在这里,您会看到 pods 已被删除。

您也可以使用 yaml 文件中的 documentation 进行验证。

大多数程序在收到 SIGTERM 时会正常关闭,但如果您使用的是第三方代码或正在管理您无法控制的系统,则 preStop 挂钩是触发正常关闭的好方法,无需修改应用程序。 Kubernetes 将向 pod 中的容器发送 SIGTERM 信号。 此时,Kubernetes 等待一个指定的时间,称为终止宽限期。

更多信息refer

目前 Kubernetes 默认不会删除已驱逐和关闭状态 pods。我们在环境中也遇到了类似的问题。

作为自动修复,您可以创建一个 Kubernetes cronjob,它可以删除处于逐出和关闭状态的 pod。 Kubernetes cronjob pod 可以使用 serviceaccount 和 RBAC 进行身份验证,您可以在其中限制实用程序的动词和命名空间。

您可以使用 https://github.com/hjacobs/kube-janitor。这提供了各种可配置的选项来清理

被驱逐的pods不是故意移除的,正如k8s团队在这里所说1,被驱逐的pods也没有被移除,以便在驱逐后进行检查。

我相信这里最好的方法是创建一个 cronjob 2 如前所述。

apiVersion: batch/v1
kind: CronJob
metadata:
  name: del-shutdown-pods
spec:
  schedule: "* 12 * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: hello
            image: busybox
            imagePullPolicy: IfNotPresent
            command:
            - /bin/sh
            - -c
            - kubectl get pods | grep Shutdown | awk '{print }' | xargs kubectl delete pod
          restartPolicy: OnFailure

您不需要任何 grep - 只需使用 kubectl 提供的选择器。而且,顺便说一句,你不能从 busybox 图像调用 kubectl,因为它根本没有 kubectl。我还创建了一个具有 pods 删除权限的服务帐户。

apiVersion: batch/v1
kind: CronJob
metadata:
  name: del-shutdown-pods
spec:
  schedule: "0 */2 * * *"  
  concurrencyPolicy: Replace
  jobTemplate:
    metadata:
      name: shutdown-deleter
    spec:
      template:
        spec:
          serviceAccountName: deleter
          containers:
          - name: shutdown-deleter
            image: bitnami/kubectl
            imagePullPolicy: IfNotPresent
            command:
              - "/bin/sh"
            args:
              - "-c"
              - "kubectl delete pods --field-selector status.phase=Failed -A --ignore-not-found=true"
          restartPolicy: Never

我对这个问题的看法是这样的(灵感来自这里的其他解决方案):

# Delete all shutdown pods. This is common problem on kubernetes using preemptible nodes on gke
# why awk, not failed pods: https://github.com/kubernetes/kubernetes/issues/54525#issuecomment-340035375
# due fact failed will delete evicted pods, that will complicate pod troubleshooting

---
apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: del-shutdown-pods
  namespace: kube-system
  labels:
    app: shutdown-pod-cleaner
spec:
  schedule: "*/1 * * * *"
  successfulJobsHistoryLimit: 1
  jobTemplate:
    spec:
      template:
        metadata:
          labels:
            app: shutdown-pod-cleaner
        spec:
          volumes:
          - name: scripts
            configMap:
              name: shutdown-pods-scripts
              defaultMode: 0777
          serviceAccountName: shutdown-pod-sa
          containers:
          - name: zombie-killer
            image: bitnami/kubectl
            imagePullPolicy: IfNotPresent
            command:
              - "/bin/sh"
            args:
              - "-c"
              - "/scripts/podCleaner.sh"
            volumeMounts:
              - name: scripts
                mountPath: "/scripts"
                readOnly: true
          restartPolicy: OnFailure
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: shutdown-pod-cleaner
  namespace: kube-system
  labels:
    app: shutdown-pod-cleaner
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["delete", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: shutdown-pod-cleaner-cluster
  namespace: kube-system
subjects:
- kind: ServiceAccount
  name: shutdown-pod-sa
  namespace: kube-system
roleRef:
  kind: ClusterRole
  name: shutdown-pod-cleaner
  apiGroup: ""
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: shutdown-pod-sa
  namespace: kube-system
  labels:
    app: shutdown-pod-cleaner
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: shutdown-pods-scripts
  namespace: kube-system
  labels:
    app: shutdown-pod-cleaner
data:
  podCleaner.sh: |
    #!/bin/sh
    if [ $(kubectl get pods --all-namespaces --ignore-not-found=true | grep Shutdown | wc -l) -ge 1 ]
    then
    kubectl get pods -A | grep Shutdown | awk '{print ,}' | xargs -n2 sh -c 'kubectl delete pod -n [=10=]  --ignore-not-found=true'
    else
    echo "no shutdown pods to clean"
    fi