kubernetes 具有主-辅-仲裁器架构的MongoDB的Helm升级,是否有停机时间?

svujldwt  于 2023-08-03  发布在  Kubernetes
关注(0)|答案(3)|浏览(110)

我正在考虑在K8s中建立一个bitnami mongodb复制集,正如这里所解释的。
但是,作为一个注意,他们在升级时提到了这一点:
注意:如果Arbiter被启用,并且MongoDB副本的数量是两个,则更新将使您的MongoDB副本集离线。Helm同时对MongoDB示例和Arbiter的statefulsets应用更新,这样您就失去了三分之二的法定投票。
我不确定“将复制集脱机”实际上是什么意思:
1.是不是整个mongo服务离线/停机,因此在执行helm升级时服务会停机?
1.是不是在执行升级时,复制集将只有一个mongodb服务器在工作,而另一个mongodb服务器和仲裁器都离线并正在升级?在这种情况下,它不会意味着停机,只是暂时只有一个服务器可用(而不是两个),所以类似于独立设置。

hgqdbh6s

hgqdbh6s1#

Bitnami开发者在这里
是不是在执行升级时,复制集将只有一个mongodb服务器在工作,而另一个mongodb服务器和仲裁器都离线并正在升级?
这将取决于你有多少副本。如果您安装的图表有2个副本+ 1个仲裁器,是的,这意味着。但是,如果您安装了4个副本+ 1个仲裁器的图表,您将只有1个副本和仲裁器同时重启,其他3个副本启动。
在这种情况下,它不会意味着停机,只是暂时只有一台服务器可用(而不是两台),所以类似于独立设置。
正如在前面的响应中提到的,如果没有满足活动副本的最小法定数量,这确实意味着一个小的停机时间。

wpx232ag

wpx232ag2#

我不知道Helm是什么,它是做什么的,也不知道为什么它一次关闭两个节点,但是:
在这种情况下,它不会意味着停机,只是暂时,只有一个服务器可用(而不是两个),所以类似于一个独立的设置。
一个独立的接受写,只要它的了。副本集节点仅在它是主节点时才接受写入,并且要具有主节点,大多数节点必须处于运行状态。因此,如果副本集的三个节点中只有一个处于运行状态,则不可能存在主节点,并且没有节点将接受写入。
三个节点中有一个可用,如果此节点是数据承载节点,您仍然可以使用允许读取的辅助首选项(主要首选项或辅助首选项或辅助首选项)发出读取,但主要读取将不起作用,写入也不起作用。

ws51t4hk

ws51t4hk3#

对于任何试图在不停机的情况下升级bitnami mongoDB Helm chart的人,这里有一些技巧,我在PSA结构下尽可能地消除它,理论上。
bitnami chart的主要问题是,仲裁器和数据节点是两个独立的StatefulSet(mongodb和mongodb-arbiter),因此使用helm的任何更新都会导致两个StatefulSet进入升级状态,并且您可能只有一个数据节点在线一段时间。而一个数据节点,根据定义,复制集将不能选举新的主节点,因此是不健康的。
为了维护主节点,每次复制集中只有一个节点可以关闭,因此您可以在关闭数据节点时简单地添加一些延迟,以便仲裁器将比任何数据节点关闭更快地关闭和备份。您可以简单地使用PreStop Hook。但是,我在关闭之前做了一些检查-基本上确保当数据节点关闭时,复制集中的每个成员都应该是健康的。
下面是一个示例脚本,您可以在其中作为PreStop钩子运行,请记住相应地调整terminationGracePeriodSeconds,以考虑您的示例在给定时间范围内未停止的某些情况。

const startTime = Date.now();
const timeLeft = () => Math.round((Date.now() - startTime) / 1000);
let success = 0;
let failedTimes = 0;
const sleepTime = 60; // seconds
// Match graceful shutdown time here
const forceKillTime = 60; // 60 mins
const exitGap = 5; // Leave 5 minutes just in case
const exitTime = forceKillTime * 60 - exitGap * 60;
const CONSECUTIVE_SUCCESS = 5;

while (true) {
  const elapsedTime = (Date.now() - startTime) / 1000;
  if (elapsedTime > exitTime) {
    print(
      `Operation does not finished within time frame: Elapsed(${elapsedTime}) > exit(${exitTime})`
    );
    quit(1);
  }

  const res = rs.status();
  if (res.members) {
    const everyoneIsHealthy = res.members.every((obj) => obj.health === 1);
    if (everyoneIsHealthy) {
      success += 1;
      if (success >= CONSECUTIVE_SUCCESS) {
        print(
          `success count (${success} >= ${CONSECUTIVE_SUCCESS}) larger than threshold, proceeed with shutdown`
        );
        // First, we try to step down
        // Then, we go ahead to shutdown ourselves
        db.adminCommand({
          replSetStepDown: timeLeft() + 60, // add some space just in case
          secondaryCatchUpPeriodSecs: timeLeft() - 60,
          force: false,
        });

        // If step down has timeout, we basically cannot do anything but proceed to force shutdown anyway
        // to ensure the shutdown happened. However the final killoff is done by k8s, shutdown is also for
        // index task to wrap up, etc.
        db.shutdownServer({
          timeoutSec: timeLeft(),
        });
      } else {
        print(
          `success count (${success} < ${CONSECUTIVE_SUCCESS}), keep checking...`
        );
      }
    } else {
      success = 0;
      failedTimes += 1;
      print(`[Failed ${failedTimes}] not everyone is healthy, reset counter `);
    }
  } else {
    success = 0;
    failedTimes += 1;
    print(`[Failed ${failedTimes}] members info not available, retrying...`);
  }

  sleep(sleepTime * 1000);
}

字符串
要安装脚本,您可以使用bitnami图表参数:extraVolumeMountsextraVolumes。将脚本打包到单独的包中,例如default/mongodb-addon。下面是一个修补StatefulSet以使用helmfiles配置的示例:

- name: mongodb
  needs:
    - default/mongodb-addon
  namespace: default
  version: 9.0.1
  chart: bitnami-full-index/mongodb
  strategicMergePatches:
    - apiVersion: apps/v1
      kind: StatefulSet
      metadata:
        name: mongodb
        namespace: default
      spec:
        template:
          spec:
            # If this value changed, changed the shutdown script timer as well
            terminationGracePeriodSeconds: 3600 # 60 minutes
            containers:
              - name: mongodb
                lifecycle:
                  preStop:
                    exec:
                      command:
                      - /bin/bash
                      # Write some wrapper scripts to execute on *local* container instance only, do not connect as replicaset mode!
                      # such as bash -c "mongosh 'mongodb://localhost' $SCRIPT_DIR/shutdown.js"
                      - /scripts/shutdown.sh


尽管如此,你可以只是保存这些麻烦添加一些睡眠到挂钩,它可能应该罚款在我看来。如果一切正常,你的复制集应该永远不会丢失primary,因为所有示例都正确关闭。示例关闭意味着stepDown。
这里的另一个注意事项是mongoDB Arbiter似乎没有像预期的那样工作。例如,如果您正在从4.2升级到4.4,如果Arbiter映像升级到4.4,则不需要FCV 4.2,因此replset无法恢复到健康状态,并阻止我们的设置中的升级。
我们目前的解决方案是再次修补图表,并将仲裁器版本固定到4.2,首先滚动数据承载节点,并在一切稳定后删除修补程序。

相关问题