带有需要作业的 initContainer 的水平 Pod 自动缩放 (HPA)
Horizontal Pod Autoscaling (HPA) with an initContainer that requires a Job
我有一个特定的场景,我希望部署由水平 pod 自动缩放控制。为了在推送新部署时处理 pods 中的数据库迁移,我遵循了 Andrew Lock here 的优秀教程。
简而言之,您必须为 Kubernetes Job
定义 waits
的 initContainer
以在新的 pods可以运行.
这很好用,但是,我不确定在初始部署后如何处理 HPA,因为如果系统检测到需要在我的节点中添加另一个 Pod
,initContainer
定义在我的部署中,需要部署 Job
和 运行,但由于 Jobs
是一次性进程,因此 pod 无法正确初始化和 运行(ttlSecondsAfterFinished
属性删除 Job
无论如何)。
我如何在部署我的应用程序时将 initContainer
定义为 运行,以便我可以在 Job
中推送我的数据库迁移,同时允许 HPA 控制动态添加Pod
不需要 initContainer
?
这是我的 deployment
的样子:
apiVersion: apps/v1
kind: Deployment
metadata:
name: graphql-deployment
spec:
replicas: 1
selector:
matchLabels:
app: graphql-pod
template:
metadata:
labels:
app: graphql-pod
spec:
initContainers:
- name: wait-for-graphql-migration-job
image: groundnuty/k8s-wait-for:v1.4 # This is an image that waits for a process to complete
args:
- job
- graphql-migration-job # this job is defined next
containers:
- name: graphql-container
image: image(graphql):tag(graphql)
以下Job
也部署
apiVersion: batch/v1
kind: Job
metadata:
name: graphql-migration-job
spec:
ttlSecondsAfterFinished: 30
template:
spec:
containers:
- name: graphql-migration-container
image: image(graphql):tag(graphql)
command: ["npm", "run", "migrate:reset"]
restartPolicy: Never
所以基本上发生的事情是:
- 我将这两个资源部署到我的节点
Job
已初始化
initContainer
在 Pod
上等待 Job
使用名为 groundnuty/k8s-wait-for:v1.4
的图像完成
Job
完成
initContainer
完成
Pod
初始化
- (30 TTL 秒后)
Job
从节点 中删除
(大量流量)
- HPA 意识到需要另一个 pod
initContainer
新 pod 已启动,但不能 运行 因为 Job
不存在
- ...crashLoopBackOff
希望了解处理这种情况的正确方法!
很遗憾,没有简单的 Kubernetes 功能可以解决您的问题。
我建议扩展您的部署 tooling/scripts 以将迁移作业与您的部署分开。在部署过程中,您首先执行迁移作业,然后部署您的部署。如果没有附加作业,HPA 可以很好地扩展您的 pods.
有多种方法可以实现这一点:
- 先有一个 bash 等脚本来执行作业,等待然后更新您的部署
- 利用 Helm 等更复杂的部署工具,它允许您向作业添加 'pre-install hook' 以在部署应用程序时执行它们
我有一个特定的场景,我希望部署由水平 pod 自动缩放控制。为了在推送新部署时处理 pods 中的数据库迁移,我遵循了 Andrew Lock here 的优秀教程。
简而言之,您必须为 Kubernetes Job
定义 waits
的 initContainer
以在新的 pods可以运行.
这很好用,但是,我不确定在初始部署后如何处理 HPA,因为如果系统检测到需要在我的节点中添加另一个 Pod
,initContainer
定义在我的部署中,需要部署 Job
和 运行,但由于 Jobs
是一次性进程,因此 pod 无法正确初始化和 运行(ttlSecondsAfterFinished
属性删除 Job
无论如何)。
我如何在部署我的应用程序时将 initContainer
定义为 运行,以便我可以在 Job
中推送我的数据库迁移,同时允许 HPA 控制动态添加Pod
不需要 initContainer
?
这是我的 deployment
的样子:
apiVersion: apps/v1
kind: Deployment
metadata:
name: graphql-deployment
spec:
replicas: 1
selector:
matchLabels:
app: graphql-pod
template:
metadata:
labels:
app: graphql-pod
spec:
initContainers:
- name: wait-for-graphql-migration-job
image: groundnuty/k8s-wait-for:v1.4 # This is an image that waits for a process to complete
args:
- job
- graphql-migration-job # this job is defined next
containers:
- name: graphql-container
image: image(graphql):tag(graphql)
以下Job
也部署
apiVersion: batch/v1
kind: Job
metadata:
name: graphql-migration-job
spec:
ttlSecondsAfterFinished: 30
template:
spec:
containers:
- name: graphql-migration-container
image: image(graphql):tag(graphql)
command: ["npm", "run", "migrate:reset"]
restartPolicy: Never
所以基本上发生的事情是:
- 我将这两个资源部署到我的节点
Job
已初始化initContainer
在Pod
上等待Job
使用名为groundnuty/k8s-wait-for:v1.4
的图像完成
Job
完成initContainer
完成Pod
初始化- (30 TTL 秒后)
Job
从节点 中删除
(大量流量)
- HPA 意识到需要另一个 pod
initContainer
新 pod 已启动,但不能 运行 因为Job
不存在- ...crashLoopBackOff
希望了解处理这种情况的正确方法!
很遗憾,没有简单的 Kubernetes 功能可以解决您的问题。
我建议扩展您的部署 tooling/scripts 以将迁移作业与您的部署分开。在部署过程中,您首先执行迁移作业,然后部署您的部署。如果没有附加作业,HPA 可以很好地扩展您的 pods.
有多种方法可以实现这一点:
- 先有一个 bash 等脚本来执行作业,等待然后更新您的部署
- 利用 Helm 等更复杂的部署工具,它允许您向作业添加 'pre-install hook' 以在部署应用程序时执行它们