根据时间自动重启Pod是否可能?
例如,我希望每天早上8点重启我的集群的Pod。
使用 cronjob,但不是用来运行您的 pod,而是安排一个 Kubernetes API 命令来每天重启部署 (kubectl rollout restart
)。这样,如果出现问题,旧的 pod 将不会关闭或删除。
Rollouts 创建新的 ReplicaSets,并等待它们启动后,才会杀死旧的 pod 并重新路由流量。服务将继续不间断地运行。
您必须设置 RBAC,以便从集群内部运行的 Kubernetes 客户端具有执行对 Kubernetes API 所需调用的权限。
---
# Service account the client will use to reset the deployment,
# by default the pods running inside the cluster can do no such things.
kind: ServiceAccount
apiVersion: v1
metadata:
name: deployment-restart
namespace: <YOUR NAMESPACE>
---
# allow getting status and patching only the one deployment you want
# to restart
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: deployment-restart
namespace: <YOUR NAMESPACE>
rules:
- apiGroups: ["apps", "extensions"]
resources: ["deployments"]
resourceNames: ["<YOUR DEPLOYMENT NAME>"]
verbs: ["get", "patch", "list", "watch"] # "list" and "watch" are only needed
# if you want to use `rollout status`
---
# bind the role to the service account
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: deployment-restart
namespace: <YOUR NAMESPACE>
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: deployment-restart
subjects:
- kind: ServiceAccount
name: deployment-restart
namespace: <YOUR NAMESPACE>
并且cron作业规范本身:
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: deployment-restart
namespace: <YOUR NAMESPACE>
spec:
concurrencyPolicy: Forbid
schedule: '0 8 * * *' # cron spec of time, here, 8 o'clock
jobTemplate:
spec:
backoffLimit: 2 # this has very low chance of failing, as all this does
# is prompt kubernetes to schedule new replica set for
# the deployment
activeDeadlineSeconds: 600 # timeout, makes most sense with
# "waiting for rollout" variant specified below
template:
spec:
serviceAccountName: deployment-restart # name of the service
# account configured above
restartPolicy: Never
containers:
- name: kubectl
image: bitnami/kubectl # probably any kubectl image will do,
# optionaly specify version, but this
# should not be necessary, as long the
# version of kubectl is new enough to
# have `rollout restart`
command:
- 'kubectl'
- 'rollout'
- 'restart'
- 'deployment/<YOUR DEPLOYMENT NAME>'
如果您希望该cronjob等待部署完成后再执行,可以将cronjob命令更改为:
command:
- bash
- -c
- >-
kubectl rollout restart deployment/<YOUR DEPLOYMENT NAME> &&
kubectl rollout status deployment/<YOUR DEPLOYMENT NAME>
对于具有重启策略为Always的Pod(这是不应该由cron job处理的 - 请参阅创建cron job规范Pod模板),另一种快速而粗糙的选项是一个只测试时间并按计划重新启动pod的livenessProbe。
例如:启动后等待1小时,然后每分钟检查一次,如果时间是3点(上午),则失败并重新启动,否则通过。
livenessProbe:
exec:
command:
- exit $(test $(date +%H) -eq 3 && echo 1 || echo 0)
failureThreshold: 1
initialDelaySeconds: 3600
periodSeconds: 60
时间粒度取决于你返回日期和测试的方式 ;)
当然,如果您已经将活动探针用作实际 活动探针,则此方法不起作用 ¯ \ _(ツ)_/¯
我借鉴了@Ryan Lowe的想法,但做了一些修改。它将重新启动24小时以上的Pod。
livenessProbe:
exec:
command:
- bin/sh
- -c
- "end=$(date -u +%s);start=$(stat -c %Z /proc/1 | awk '{print int($1)}'); test $(($end-$start)) -lt 86400"
/proc/1
不是一个可靠的信息源,时间戳可能与实际情况非常不同。当可用并且进程ID已知(在我的情况下为“1”)时,我会使用 ps -p 1 -o etimes --no-headers
。 - kivagantapiVersion: batch/v1beta1
kind: CronJob
metadata:
name: your-cron
spec:
schedule: "*/20 8-19 * * 1-5"
concurrencyPolicy: Forbid
jobTemplate:
spec:
template:
metadata:
labels:
app: your-periodic-batch-job
spec:
containers:
- name: my-image
image: your-image
imagePullPolicy: IfNotPresent
restartPolicy: OnFailure
如果您想在启动新pod时替换旧pod,请将spec.concurrencyPolicy
更改为Replace
。使用Forbid
,如果旧的pod仍在运行,则新的pod创建将被跳过。
your-image
命令会触发Pod重新启动。 - Stuart Harlandyour-image
是你的服务,并且它会一直运行,直到下一次cron作业启动时,Replace
停止它并启动一个新实例。当然,你提出的方式也可以工作,但似乎过于复杂了。 - tgdavieskind: CronJob
,其中包含一个具有containers
的jobTemplate
。因此,您的CronJob将启动这些容器,并且activeDeadlineSeconds
为一天(直到重启)。根据您的示例,然后将是schedule: 0 8 * * ?
,表示上午8点。livenessProbe:
exec:
command:
- bash
- -c
- "exit 1"
failureThreshold: 1
periodSeconds: 86400
其中86400是所需的时间段,以秒为单位(在此示例中每天重新启动1次)
spec:
# replicas: 1
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 50%
maxUnavailable: 0%
这将产生新的Pod,然后终止旧的Pod。
batch/v1beta1
更改为batch/v1
以使其正常工作。 - chill appreciator