我创建了一个副本数为2的Pod,它运行一个应用程序(一个简单的Web服务器),基本上它总是运行命令 - 但是由于配置错误,有时命令退出,然后pod终止。
由于restartPolicy
的默认Always
,pod(以及容器)重新启动,最终Pod状态为CrashLoopBackOff
。
如果我做一个kubectl describe deployment
,它显示条件为Progressing=True
和Available=False
。
这看起来很好 - 问题是 - 在上述情况下如何将我的部署标记为“失败”?
添加spec.ProgressDeadlineSeconds
似乎没有效果。
简单地说restartPolicy
作为Never
在Pod规范中是否足够?
一个相关的问题,有没有办法将这些信息作为触发/ webhook,而不做rollout status
手表?
“失败”部署没有Kubernetes概念。编辑部署会注册您要创建新ReplicaSet的意图,而k8s将反复尝试使该意图发生。在此过程中遇到的任何错误都会导致推出阻止,但它们不会导致k8s中止部署。
AFAIK,你可以做的最好(截至1.9)是在部署时应用截止日期,这将添加一个条件,你可以在部署卡住时检测到;看看https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#failed-deployment和https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#progress-deadline-seconds。
可以在k8s提供的状态之上叠加自己的失败定义,但这很难以通用方式完成;关于这个问题的一个(长!)讨论,请看这个问题:https://github.com/kubernetes/kubernetes/issues/1899
这是我前一段时间写的一些Python代码(使用pykube
)实现了我自己的ready定义;如果5分钟后没有获得此条件,我将中止部署脚本。
def _is_deployment_ready(d, deployment):
if not deployment.ready:
_log.debug('Deployment not completed.')
return False
if deployment.obj["status"]["replicas"] > deployment.replicas:
_log.debug('Old replicas not terminated.')
return False
selector = deployment.obj['spec']['selector']['matchLabels']
pods = Pod.objects(d.api).filter(namespace=d.namespace, selector=selector)
if not pods:
_log.info('No pods found.')
return False
for pod in pods:
_log.info('Is pod %s ready? %s.', pod.name, pod.ready)
if not pod.ready:
_log.debug('Pod status: %s', pod.obj['status'])
return False
_log.info('All pods ready.')
return True
请注意单独的pod检查,这是必需的,因为在部署完成时(即所有pod已创建),部署似乎被认为是“就绪”,而不是在所有pod都准备就绪时。