×

部署策略用于在不中断服务的情况下更改或升级应用程序,以便用户几乎不会注意到更改。

由于用户通常通过路由器处理的路由访问应用程序,因此部署策略可以专注于DeploymentConfig对象功能或路由功能。专注于DeploymentConfig对象功能的策略会影响使用该应用程序的所有路由。使用路由器功能的策略针对单个路由。

大多数部署策略都通过DeploymentConfig对象支持,而一些附加策略则通过路由器功能支持。

选择部署策略

选择部署策略时,请考虑以下几点:

  • 必须优雅地处理长期连接。

  • 数据库转换可能很复杂,必须与应用程序一起完成和回滚。

  • 如果应用程序是微服务和传统组件的混合体,则可能需要停机才能完成转换。

  • 您必须拥有执行此操作的基础设施。

  • 如果您有一个非隔离的测试环境,您可以破坏新旧版本。

部署策略使用就绪检查来确定新的Pod是否可以使用。如果就绪检查失败,则DeploymentConfig对象会重试运行Pod,直到超时。默认超时时间为10m,此值在dc.spec.strategy.*params中的TimeoutSeconds中设置。

滚动策略

滚动部署会缓慢地将应用程序先前版本实例替换为应用程序新版本实例。如果DeploymentConfig对象上未指定任何策略,则滚动策略是使用的默认部署策略。

滚动部署通常会在缩减旧组件之前等待新的Pod通过就绪检查变为ready。如果出现重大问题,则可以中止滚动部署。

何时使用滚动部署

  • 当您希望在应用程序更新期间不中断服务时。

  • 当您的应用程序支持同时运行旧代码和新代码时。

滚动部署意味着您同时运行旧版本和新版本的代码。这通常需要您的应用程序处理N-1兼容性。

滚动策略定义示例
kind: DeploymentConfig
apiVersion: apps.openshift.io/v1
metadata:
  name: example-dc
# ...
spec:
# ...
  strategy:
    type: Rolling
    rollingParams:
      updatePeriodSeconds: 1 (1)
      intervalSeconds: 1 (2)
      timeoutSeconds: 120 (3)
      maxSurge: "20%" (4)
      maxUnavailable: "10%" (5)
      pre: {} (6)
     post: {}
1 个体Pod更新之间等待的时间。如果未指定,则此值默认为1
2 更新后轮询部署状态之间等待的时间。如果未指定,则此值默认为1
3 在放弃之前等待缩放事件的时间。可选;默认值为600。此处,“放弃”表示自动回滚到之前的完整部署。
4 maxSurge是可选的,如果未指定,则默认为25%。请参阅以下过程下面的信息。
5 maxUnavailable是可选的,如果未指定,则默认为25%。请参阅以下过程下面的信息。
6 prepost都是生命周期钩子。

滚动策略

  1. 执行任何pre生命周期钩子。

  2. 根据激增计数向上扩展新的复制控制器。

  3. 根据最大不可用计数向下扩展旧的复制控制器。

  4. 重复此缩放操作,直到新的复制控制器达到所需的副本数,并且旧的复制控制器已缩减为零。

  5. 执行任何post生命周期钩子。

缩减时,滚动策略会等待Pod变为就绪,以便它可以决定进一步缩减是否会影响可用性。如果扩展的Pod从未变为就绪,则部署过程最终会超时并导致部署失败。

maxUnavailable参数是在更新期间可能不可用的Pod的最大数量。maxSurge参数是可以比原始Pod数量多调度Pod的最大数量。这两个参数都可以设置为百分比(例如,10%)或绝对值(例如,2)。两者的默认值均为25%

这些参数允许调整部署的可用性和速度。例如:

  • maxUnavailable*=0maxSurge*=20%确保在更新期间保持满负荷运转并快速扩展。

  • maxUnavailable*=10%maxSurge*=0使用无额外容量执行更新(就地更新)。

  • maxUnavailable*=10%maxSurge*=10%快速向上和向下扩展,但可能导致容量损失。

通常,如果您想要快速推出,请使用maxSurge。如果您必须考虑资源配额并可以接受部分不可用性,请使用maxUnavailable

在 AWS 上的 Red Hat OpenShift 服务中,所有机器配置池的 maxUnavailable 默认设置为 1。建议不要更改此值,一次更新一个控制平面节点。不要将控制平面池的此值更改为 3

金丝雀部署

AWS 上的 Red Hat OpenShift 服务中的所有滚动部署都是金丝雀部署;在新版本(金丝雀)替换所有旧实例之前对其进行测试。如果就绪检查从未成功,则会移除金丝雀实例,并且 DeploymentConfig 对象将自动回滚。

就绪检查是应用程序代码的一部分,可以根据需要进行复杂的设置以确保新实例已准备好使用。如果您必须实现更复杂的应用程序检查(例如将实际用户工作负载发送到新实例),请考虑实现自定义部署或使用蓝绿部署策略。

创建滚动部署

滚动部署是 AWS 上 Red Hat OpenShift 服务中的默认类型。您可以使用 CLI 创建滚动部署。

步骤
  1. 基于在 Quay.io 中找到的示例部署镜像创建应用程序

    $ oc new-app quay.io/openshifttest/deployment-example:latest

    此镜像不公开任何端口。如果您想通过外部 LoadBalancer 服务公开您的应用程序或通过公共互联网启用对应用程序的访问,请在完成此步骤后使用 oc expose dc/deployment-example --port=<port> 命令创建一个服务。

  2. 如果您已安装路由器,请通过路由使应用程序可用,或直接使用服务 IP。

    $ oc expose svc/deployment-example
  3. 浏览至 deployment-example.<project>.<router_domain> 上的应用程序,以验证您是否看到 v1 镜像。

  4. DeploymentConfig 对象扩展到三个副本

    $ oc scale dc/deployment-example --replicas=3
  5. 通过将新版本的示例标记为 latest 标记来自动触发新的部署

    $ oc tag deployment-example:v2 deployment-example:latest
  6. 在您的浏览器中,刷新页面直到您看到 v2 镜像。

  7. 使用 CLI 时,以下命令显示有多少 pod 处于版本 1,有多少 pod 处于版本 2。在 Web 控制台中,pod 会逐渐添加到 v2 并从 v1 中移除。

    $ oc describe dc deployment-example

在部署过程中,新的复制控制器会逐渐扩展。在新 pod 被标记为 ready(通过传递其就绪检查)后,部署过程将继续。

如果 pod 未准备好,则进程将中止,并且部署将回滚到其先前版本。

使用开发者视角编辑部署

您可以使用**开发者**视角编辑部署的部署策略、镜像设置、环境变量和高级选项。

先决条件
  • 您处于 Web 控制台的**开发者**视角。

  • 您已创建了一个应用程序。

步骤
  1. 导航到**拓扑**视图。

  2. 单击您的应用程序以查看**详细信息**面板。

  3. 在**操作**下拉菜单中,选择**编辑部署**以查看**编辑部署**页面。

  4. 您可以编辑部署的以下**高级选项**

    1. 可选:您可以单击**暂停发布**,然后选择**为此部署暂停发布**复选框来暂停发布。

      通过暂停发布,您可以更改应用程序而不会触发发布。您可以随时恢复发布。

    2. 可选:单击**缩放**以通过修改**副本**数量来更改镜像实例的数量。

  5. 单击**保存**。

使用开发者视角启动滚动部署

您可以通过启动滚动部署来升级应用程序。

先决条件
  • 您处于 Web 控制台的**开发者**视角。

  • 您已创建了一个应用程序。

步骤
  1. 在**拓扑**视图中,单击应用程序节点以查看侧面板中的**概述**选项卡。请注意,**更新策略**设置为默认的**滚动**策略。

  2. 在**操作**下拉菜单中,选择**启动发布**以启动滚动更新。滚动部署将启动应用程序的新版本,然后终止旧版本。

    odc rolling update
    图 1. 滚动更新

重新创建策略

重新创建策略具有基本的发布行为,并支持用于将代码注入部署过程的生命周期挂钩。

重新创建策略示例定义
kind: Deployment
apiVersion: apps/v1
metadata:
  name: hello-openshift
# ...
spec:
# ...
  strategy:
    type: Recreate
    recreateParams: (1)
      pre: {} (2)
      mid: {}
      post: {}
1 recreateParams 是可选的。
2 premidpost 是生命周期挂钩。

重新创建策略

  1. 执行任何pre生命周期钩子。

  2. 将之前的部署缩减到零。

  3. 执行任何 mid 生命周期挂钩。

  4. 扩展新的部署。

  5. 执行任何post生命周期钩子。

在扩展过程中,如果部署的副本数量大于 1,则会在完全扩展部署之前验证部署的第一个副本的就绪情况。如果第一个副本的验证失败,则部署将被视为失败。

何时使用重新创建部署

  • 当您必须在新的代码启动之前运行迁移或其他数据转换时。

  • 当您不支持同时运行新旧版本的应用程序代码时。

  • 当您想要使用不支持在多个副本之间共享的 RWO 卷时。

重新创建部署会造成停机时间,因为在短暂的时间内,您的应用程序没有运行任何实例。但是,您的旧代码和新代码不会同时运行。

使用开发者视角编辑部署

您可以使用**开发者**视角编辑部署的部署策略、镜像设置、环境变量和高级选项。

先决条件
  • 您处于 Web 控制台的**开发者**视角。

  • 您已创建了一个应用程序。

步骤
  1. 导航到**拓扑**视图。

  2. 单击您的应用程序以查看**详细信息**面板。

  3. 在**操作**下拉菜单中,选择**编辑部署**以查看**编辑部署**页面。

  4. 您可以编辑部署的以下**高级选项**

    1. 可选:您可以单击**暂停发布**,然后选择**为此部署暂停发布**复选框来暂停发布。

      通过暂停发布,您可以更改应用程序而不会触发发布。您可以随时恢复发布。

    2. 可选:单击**缩放**以通过修改**副本**数量来更改镜像实例的数量。

  5. 单击**保存**。

使用开发者视角启动重新创建部署

您可以使用 Web 控制台中的**开发者**视角将部署策略从默认的滚动更新切换到重新创建更新。

先决条件
  • 确保您处于 Web 控制台的**开发者**视角。

  • 确保您已使用**添加**视图创建了一个应用程序,并看到它已部署在**拓扑**视图中。

步骤

要切换到重新创建更新策略并升级应用程序

  1. 单击您的应用程序以查看**详细信息**面板。

  2. 在**操作**下拉菜单中,选择**编辑部署配置**以查看应用程序的部署配置详细信息。

  3. 在 YAML 编辑器中,将 spec.strategy.type 更改为 Recreate 并单击**保存**。

  4. 在**拓扑**视图中,选择节点以查看侧面板中的**概述**选项卡。**更新策略**现在设置为**重新创建**。

  5. 使用**操作**下拉菜单选择**启动发布**以使用重新创建策略启动更新。重新创建策略首先终止旧版本应用程序的 pod,然后启动新版本的 pod。

    odc recreate update
    图 2. 重新创建更新

自定义策略

自定义策略允许您提供自己的部署行为。

自定义策略示例定义
kind: DeploymentConfig
apiVersion: apps.openshift.io/v1
metadata:
  name: example-dc
# ...
spec:
# ...
  strategy:
    type: Custom
    customParams:
      image: organization/strategy
      command: [ "command", "arg1" ]
      environment:
        - name: ENV_1
          value: VALUE_1

在上面的示例中,organization/strategy 容器镜像提供了部署行为。可选的 command 数组会覆盖镜像的 Dockerfile 中指定的任何 CMD 指令。提供的可选环境变量将添加到策略进程的执行环境中。

此外,AWS 上的 Red Hat OpenShift 服务还会向部署过程提供以下环境变量

环境变量 描述

OPENSHIFT_DEPLOYMENT_NAME

新部署(一个复制控制器)的名称。

OPENSHIFT_DEPLOYMENT_NAMESPACE

新部署的名称空间。

新部署的副本数量最初将为零。策略的职责是使用最能满足用户需求的逻辑使新部署生效。

或者,使用customParams对象将自定义部署逻辑注入到现有的部署策略中。提供自定义shell脚本逻辑并调用openshift-deploy二进制文件。用户无需提供其自定义部署程序容器镜像;在这种情况下,将使用默认的AWS上的Red Hat OpenShift Service部署程序镜像。

kind: DeploymentConfig
apiVersion: apps.openshift.io/v1
metadata:
  name: example-dc
# ...
spec:
# ...
  strategy:
    type: Rolling
    customParams:
      command:
      - /bin/sh
      - -c
      - |
        set -e
        openshift-deploy --until=50%
        echo Halfway there
        openshift-deploy
        echo Complete

这将导致以下部署

Started deployment #2
--> Scaling up custom-deployment-2 from 0 to 2, scaling down custom-deployment-1 from 2 to 0 (keep 2 pods available, don't exceed 3 pods)
    Scaling custom-deployment-2 up to 1
--> Reached 50% (currently 50%)
Halfway there
--> Scaling up custom-deployment-2 from 1 to 2, scaling down custom-deployment-1 from 2 to 0 (keep 2 pods available, don't exceed 3 pods)
    Scaling custom-deployment-1 down to 1
    Scaling custom-deployment-2 up to 2
    Scaling custom-deployment-1 down to 0
--> Success
Complete

如果自定义部署策略流程需要访问AWS上的Red Hat OpenShift Service API或Kubernetes API,则执行该策略的容器可以使用容器内可用的服务帐户令牌进行身份验证。

使用开发者视角编辑部署

您可以使用**开发者**视角编辑部署的部署策略、镜像设置、环境变量和高级选项。

先决条件
  • 您处于 Web 控制台的**开发者**视角。

  • 您已创建了一个应用程序。

步骤
  1. 导航到**拓扑**视图。

  2. 单击您的应用程序以查看**详细信息**面板。

  3. 在**操作**下拉菜单中,选择**编辑部署**以查看**编辑部署**页面。

  4. 您可以编辑部署的以下**高级选项**

    1. 可选:您可以单击**暂停发布**,然后选择**为此部署暂停发布**复选框来暂停发布。

      通过暂停发布,您可以更改应用程序而不会触发发布。您可以随时恢复发布。

    2. 可选:单击**缩放**以通过修改**副本**数量来更改镜像实例的数量。

  5. 单击**保存**。

生命周期钩子

滚动和重新创建策略支持生命周期钩子或部署钩子,允许在策略中预定义的点注入部署过程中的行为。

pre生命周期钩子示例
pre:
  failurePolicy: Abort
  execNewPod: {} (1)
1 execNewPod是一个基于Pod的生命周期钩子。

每个钩子都有一个失败策略,它定义了当遇到钩子失败时策略应采取的操作。

中止

如果钩子失败,则部署过程将被视为失败。

重试

应重试钩子执行,直到成功。

忽略

应忽略任何钩子失败,并继续部署。

钩子具有一个类型特定的字段,用于描述如何执行钩子。目前,基于Pod的钩子是唯一支持的钩子类型,由execNewPod字段指定。

基于Pod的生命周期钩子

基于Pod的生命周期钩子在从DeploymentConfig对象中的模板派生的新Pod中执行钩子代码。

以下简化的部署示例使用滚动策略。为简洁起见,省略了触发器和其他一些次要细节。

kind: DeploymentConfig
apiVersion: apps.openshift.io/v1
metadata:
  name: frontend
spec:
  template:
    metadata:
      labels:
        name: frontend
    spec:
      containers:
        - name: helloworld
          image: openshift/origin-ruby-sample
  replicas: 5
  selector:
    name: frontend
  strategy:
    type: Rolling
    rollingParams:
      pre:
        failurePolicy: Abort
        execNewPod:
          containerName: helloworld (1)
          command: [ "/usr/bin/command", "arg1", "arg2" ] (2)
          env: (3)
            - name: CUSTOM_VAR1
              value: custom_value1
          volumes:
            - data (4)
1 helloworld名称指的是spec.template.spec.containers[0].name
2 command将覆盖openshift/origin-ruby-sample镜像定义的任何ENTRYPOINT
3 env是钩子容器的可选环境变量集。
4 volumes是钩子容器的可选卷引用集。

在此示例中,pre钩子将使用helloworld容器中的openshift/origin-ruby-sample镜像在新Pod中执行。钩子Pod具有以下属性:

  • 钩子命令是/usr/bin/command arg1 arg2

  • 钩子容器具有CUSTOM_VAR1=custom_value1环境变量。

  • 钩子失败策略为中止,这意味着如果钩子失败,则部署过程将失败。

  • 钩子Pod继承了DeploymentConfig对象Pod中的data卷。

设置生命周期钩子

您可以使用CLI为部署设置生命周期钩子或部署钩子。

步骤
  1. 使用oc set deployment-hook命令设置所需的钩子类型:--pre--mid--post。例如,要设置预部署钩子:

    $ oc set deployment-hook dc/frontend \
        --pre -c helloworld -e CUSTOM_VAR1=custom_value1 \
        --volumes data --failure-policy=abort -- /usr/bin/command arg1 arg2