我有一个基于Kubernetes的应用程序,包含使用头盔图管理的多个服务(和pod)。
Postgres用作所有服务的数据库。
当应用程序升级到较新版本时,我正在通过initContainers
运行数据库迁移脚本。
当迁移脚本需要对DB的独占访问(所有其他连接应该终止)时,会出现问题,否则脚本将被阻止。
理想的解决方案是停止所有pod,运行迁移并重新创建它们。但我不确定如何使用Kubernetes正确实现它。
TNX
答案 0 :(得分:6)
理想的解决方案是停止所有pod,运行迁移和 重新创造它们。但我不确定如何正确实现它 Kubernetes。
我从其中一条评论中看到你使用Helm,所以我想提出一个利用Helm钩子的解决方案:
Helm提供了一种钩子机制,允许图表开发人员进行干预 在发布的生命周期中的某些点。例如,您可以使用 挂钩:
在安装过程中加载ConfigMap或Secret,然后再显示其他任何图表 加载。
执行作业以在安装新数据库之前备份数据库 图表,然后在升级后执行第二个作业 恢复数据。
在删除版本之前运行作业以优雅地获取 在移除之前服务不旋转。
https://github.com/kubernetes/helm/blob/master/docs/charts_hooks.md
您可以将迁移打包为k8s Job
,并利用pre-install
或pre-upgrade
挂钩来运行作业。这些钩子在渲染模板后运行,但在Kubernetes中创建任何新资源之前运行。因此,您的迁移将在部署Pod之前运行。
要在运行迁移之前删除部署,请创建第二个预安装/升级前挂钩,其中helm.sh/hook-weight
更低,以删除目标部署:
apiVersion: batch/v1
kind: Job
metadata:
name: "pre-upgrade-hook1"
annotations:
"helm.sh/hook": pre-upgrade
"helm.sh/hook-weight": "-1"
"helm.sh/hook-delete-policy": hook-succeeded
spec:
template:
metadata:
name: "pre-upgrade-hook1"
spec:
restartPolicy: Never
serviceAccountName: "<an SA with delete RBAC permissions>"
containers:
- name: kubectl
image: "lachlanevenson/k8s-kubectl:latest"
command: ["delete","deployment","deploy1","deploy2"]
较低的钩子重量将确保此作业在迁移作业之前运行。这将确保以下一系列事件:
helm upgrade
请确保将所有相关部署保留在同一个图表中。
答案 1 :(得分:1)
从自动化/编排的角度来看,我的感觉是,使用最近发布的运营商框架,运营商可以解决这样的问题:
https://github.com/operator-framework
我的想法是会有一个Postgres迁移运算符 - 据我所知还不存在 - 它会闲置等待自定义资源定义,描述迁移要发布到集群/命名空间。
操作员会醒来,了解预期迁移中涉及的内容,对群集进行一些分析以构建迁移计划,然后按照您的描述执行步骤 -
但是现在这对你没有帮助。
答案 2 :(得分:0)
理想的解决方案是停止所有pod,运行迁移和 重新创造它们。但我不确定如何正确实现它 Kubernetes。
这在很大程度上取决于您的方法,特别是您的CI / CD工具。您可以应用几种策略,但是,作为一个例子,假设您有Gitlab管道(Jenkins可以这样做,术语不同等),这里是步骤:
同样的原则也可以在其他编排/部署工具中使用,你甚至可以制作一个简单的脚本,如果前一个成功,就可以一次性直接运行这些kubectl命令。