停机升级 SOP

本章节介绍 Univer 后端服务的停机升级 SOP。如果你对 docker compose 和 K8s 比较熟悉,Univer 建议你参照此 SOP 来制定更适合你们生产环境的 SOP。

docker compose 方式升级 SOP

升级前准备

  1. 自定义配置文件 在准备升级前,你应该查看我们的版本介绍,确定你想要升级的版本,并查看我们的生产部署,其中会介绍从哪个版本开始加入了新的配置项,从哪个版本开始旧的配置项不再支持。根据文档,查看自己的旧版本自定义配置文件 .env.custom 有哪些需要修改、有哪些新增配置需要自定义。确定好后,准备一份新的自定义配置文件 .env.custom,并且保留旧版本的 .env.custom以便后续能安全回滚。
  2. License 文件 你还需要准备好你的 License 文件。
  3. 升级知会 告知使用者预计的停机升级时间段,以便他们做好准备

升级操作

  1. 停止旧版本服务

这里假设旧版本的 Univer 服务部署在目录 universer-old

  • 先禁写

注意:因为协同编辑的特殊性,为了确保所有协同编辑请求都正常保存,最好不要直接停止服务,而是先通过一段时间的禁写操作后再停止服务。你可以使用你们自己的基础设施来达到此目的,或者通过 Univer 服务中的 nginx 来实现。下面介绍使用 Univer 部署的 nginx 来实现的方式。 如下修改 universer-old/nginx/universer.conf,增加路由配置location ~ ^/universer-api {return 403;} 来禁止所有新请求

server {
  listen 8000;
 
  client_max_body_size 100m;
 
  location ~ ^/universer-api {return 403;} # 增加这句来通过 nginx 禁止所有请求
 
  location / {
    proxy_pass http://universer;
  }
 
  location /universer-api/comb/connect {
    proxy_pass http://universer;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $connection_upgrade;
  }
 
  location /universer-api/metrics {
    return 403;
  }
}

修改后,需要让 nginx 重新加载此配置方能生效,执行以下命令让 nginx 重新加载配置: docker exec univer-lb nginx -s reload,其中的 univer-lb 是默认配置的 nginx 容器名,如果你修改了,需要更换下

  • 禁写持续一段时间,建议至少 1 分钟
  • 停止旧版本服务

执行命令 cd universer-old && bash run.sh stop 来停止服务

  1. 数据备份

Univer 建议你在升级前进行重要数据的备份,需要备份的数据包括 RDS 中的文档元数据,使用对应 RDS 的数据备份工具自行备份即可。Object Storage 中的数据只会新增,不会修改,所以不用备份。

  1. 部署选定的版本
  • 执行 Univer 的自定义安装命令 bash -c "$(curl -fsSL https://get.univer.ai/product)" [-- version],下载到你给定的版本,如果未指定 ersion,将下载最新版本
  • 将你的新自定义配置文件 .env.custom 复制到新版本文件夹下,和默认的 .env 文件放在同一目录
  • 将你的 License 文件 license.txtlicenseKey.txt 复制到新版本文件夹下的 /configs/ 目录下
  • 如果你使用的是自己维护的 RDS,请下载数据库更新脚本,完成 Univer 服务的 RDS DDL 更新
  • 修改 load balance 配置,仅允许测试账户使用新版系统

如果你使用的是 Univer 内建的 nginx,可如下配置:

编辑新版本文件夹下 /nginx/universer.conf,在 server 路由配置前增加如下配置:

server {
  listen 8000;
 
  # 配置仅允许携带 header x-request-env=test 的请求
  # 新增此配置以在用户不可用的情况下验证新版本
  underscores_in_headers on;
  if ($http_x_request_env != "test") {
    return 403;
  }
 
  client_max_body_size 100m;
 
  location / {
    proxy_pass http://universer;
  }
 
  ...
}
  • 启动新版本的服务:bash run.sh start,成功后,即可使用测试账号登录,携带 header x-request-env=test 来进行验证

升级后验证

现在,你已经启动了新版服务,并且用户暂时不能访问。接下来你需要全面地验证新版服务是否配置部署正确,是否能如期地稳定地运行。

启用新版本服务

如果新版服务验收通过决定采用,将前面在 /nginx/universer.conf 中配置的只允许特定 header 请求的部分删除,执行命令让nginx重新加载配置:docker exec univer-lb nginx -s reloaduniver-lb 是默认配置的 nginx 容器名,如果你修改了,需要更换下

退回使用旧版服务

如果新版服务验收未通过,或者时间不够完成验收,可先配置继续使用旧版本

  1. 先停止新版的服务,因为此时没有用户在使用,直接停止即可。执行 bash run.sh stop 停止新版服务
  2. 还原旧版本服务的nginx配置:去掉禁写配置 location ~ ^/universer-api {return 403;} (还记得我们在前面停止旧服务前禁写了吗?)
  3. 重新启动旧版服务

k8s 方式升级 SOP

升级前准备

  1. 自定义配置文件

在准备升级前,你应该查看我们的版本介绍,确定你想要升级的版本,并查看我们的生产部署,其中会介绍从哪个版本开始加入了新的配置项,从哪个版本开始旧的配置项不再支持。根据文档,查看自己的旧版本自定义配置文件 values.yaml 有哪些需要修改、有哪些新增配置需要自定义。确定好后,准备一份新的自定义配置文件 values.yaml,并且保留旧版本的 values.yaml,以便后续能安全回滚。

请注意:如果你发现旧版本的某一自定义配置项不需要修改,新版本的自定义配置仍然需要包含它,否则此配置项将会在升级时使用默认的值。这是由于 helm 在部署时是用 values.yaml 和模板动态地渲染 K8s 所需资源清单的。

  1. License 文件

你还需要准备好你的 License 文件。

  1. 升级知会

告知使用者预计的停机升级时间段,以便他们做好准备

升级操作

  1. 旧版本禁止访问

注意:因为协同编辑的特殊性,为了确保所有协同编辑请求都正常保存,最好不要直接停止服务程序,而是通过其他手段来禁止用户访问。如果你维护的 K8s 集群有方法来配置拒绝所有 path 包含前缀 /universer-api/ 的请求,那么直接配置即可。如果没有,你可以通过禁用universer服务的ingress来达到此目的,可以如下配置:

universer:
  ingress:
    enabled: false  # 禁用 universer 的 ingress

因为 helm 是动态渲染 k8s 资源清单的,为了启用上述配置,你需要在你旧版本自定义配置(假设是 values-1.0.0.yaml)的基础上应用上述配置变更,生成新的配置文件(假设是 values-1.0.0-forbid.yaml),之后使用helm执行更新以应用此配置:

helm upgrade univer-stack \
    oci://univer-acr-registry.cn-shenzhen.cr.aliyuncs.com/helm-charts/univer-stack \
    --version your-current-version \
    -n univer \
    -f values-1.0.0-forbid.yaml \
    --set-file universer.license.licenseV2=your-license.txt-path \
    --set-file universer.license.licenseKeyV2=your-licenseKey.txt-path

命令中,使用 -f 指定新增禁写配置的 values-1.0.0-forbid.yaml。另外,需要注意,我们此时只是配置禁止访问 Univer,并不能现在就升级到新版本服务,因此需要用 --version 指定 chart 版本仍然是当前部署的版本 your-current-version。可以使用下列命令获取当前部署的 chart 版本:

helm list --all-namespaces --filter univer-stack

执行结果如下图,从其中的 chart 字段即可获取到当前部署的版本号,本例中是 0.1.3

升级操作

禁止访问需要持续一段时间,建议至少 1 分钟,之后再往下操作

  1. 数据备份

Univer 建议你在升级前进行重要数据的备份,需要备份的数据包括 RDS 中的文档元数据,使用对应 RDS 的数据备份工具自行备份即可。Object Storage 中的数据只会新增,不会修改,所以不用备份。

  1. 升级到新版本
  • 如果你使用的是自己维护的 RDS,请下载数据库更新脚本,完成 Univer 服务的 RDS DDL 更新
  • 由于我们不想让所有用户直接能访问到新版本服务,又需要测试账户能够访问来测试,你需要配置好只允许特定用户访问。如果你的基础设施能够支持,通过它配置即可。如果不支持,可通过 ingress 如下配置

如果你的 k8s 集群使用的是 nginx ingress controller,以下配置将只允许携带 header x-request-env=test 的请求,你可以将其合并到新版本的自定义配置 values.yaml 来支持带上此 header 进行测试验证:

universer:
  ingress:
    enabled: true
    annotations:
      nginx.ingress.kubernetes.io/configuration-snippet: |
        if ($http_x_request_env != "test") {
          return 403;
        }
  • 执行 helm 命令升级到指定的版本
helm upgrade --install univer-stack \
    oci://univer-acr-registry.cn-shenzhen.cr.aliyuncs.com/helm-charts/univer-stack \
    --version target-version \
    -n univer \
    -f your-values.yaml-path \
    --set-file universer.license.licenseV2=your-license.txt-path \
    --set-file universer.license.licenseKeyV2=your-licenseKey.txt-path

命令中,使用 -f 指定新版本的自定义配置 values.yaml;使用 --version 指定想要升级到的目标版本,如果想直接升级到最新版本,去掉 --version 参数即可。

升级后验证

现在,你已经启动了新版服务,并且用户暂时不能访问。接下来你需要全面地验证新版服务是否配置部署正确,是否能如期地稳定地运行。

启用新版本服务

如果新版服务验收通过决定采用,更新配置让所有用户都能访问即可。如果你是使用 ingress 的方式控制哪些用户可以访问的,需要去除对应的配置,再次执行 helm upgrade 应用配置以开放给所有用户访问。

退回使用旧版服务

如果新版服务验收未通过,或者时间不够完成验收,可如下配置退回到旧版本:

使用旧版本的 chart 版本号和自定义配置更新部署即可:

helm upgrade --install univer-stack \
    oci://univer-acr-registry.cn-shenzhen.cr.aliyuncs.com/helm-charts/univer-stack \
    --version old-version \
    -n univer \
    -f old-values.yaml \
    --set-file universer.license.licenseV2=your-license.txt-path \
    --set-file universer.license.licenseKeyV2=your-licenseKey.txt-path

通过参数 --version 指定旧版本的 chart 版本号,参数 -f 指定旧版本的自定义配置文件。


这个页面对您有帮助吗?