第 4 章 Deployments

4.1. 了解 Deployment 和 DeploymentConfig 对象

OpenShift Container Platform 中的 DeploymentDeploymentConfig API 对象提供了两个类似但不同的方法来对常见用户应用程序进行精细管理。由以下独立 API 对象组成:

  • DeploymentConfigDeployment,各自将应用程序特定组件的所需状态描述为 pod 模板。
  • DeploymentConfig 对象涉及一个或多个 复制控制器,其中包含部署状态的时间点记录,作为 pod 模板。同样, Deployment 对象涉及一个或多个 副本集,即复制控制器的后续。
  • 一个或多个 pod,,表应用程序某一特定版本的实例。

4.1.1. 部署构建块

Deployment 和部署配置分别通过使用原生 Kubernetes API 对象 ReplicaSetReplicationController 来启用,作为构建块。

用户不必操作复制控制器、副本集或 DeploymentConfig 对象或部署所拥有的 pod。部署系统可确保正确传播更改。

提示

如果现有部署策略不适用于您的用例,而且必须在部署的生命周期内执行手动步骤,那么应考虑创建自定义部署策略。

以下部分详细介绍了这些对象。

4.1.1.1. 复制控制器

复制控制器确保任何时候都运行指定数量的 pod 副本。如果 pod 退出或被删除,复制控制器会做出反应,实例化更多 pod 来达到定义的数量。同样,如果运行中的数量超过所需的数目,它会根据需要删除相应数量的 Pod,使其与定义的数量相符。

复制控制器配置包括:

  • 需要的副本数量,可在运行时调整。
  • 创建复制 Pod 时要使用的 Pod 定义。
  • 用于标识受管 pod 的选择器。

选择器是分配给由复制控制器管理的 pod 的一组标签。这些标签包含在复制控制器实例化的 Pod 定义中。复制控制器使用选择器来决定已在运行的 pod 实例数量,以便根据需要进行调整。

复制控制器不会基于负载或流量执行自动扩展,因为复制控制器不会跟踪它们。相反,这需要由外部自动缩放器调整其副本数。

以下是复制控制器的示例定义:

apiVersion: v1
kind: ReplicationController
metadata:
  name: frontend-1
spec:
  replicas: 1  1
  selector:    2
    name: frontend
  template:    3
    metadata:
      labels:  4
        name: frontend 5
    spec:
      containers:
      - image: openshift/hello-openshift
        name: helloworld
        ports:
        - containerPort: 8080
          protocol: TCP
      restartPolicy: Always
1
要运行的 pod 的副本数。
2
要运行的 pod 的标签选择器。
3
控制器创建的 pod 模板。
4
pod 上的标签应该包括标签选择器中的标签。
5
扩展任何参数后的最大名称长度为 63 个字符。

4.1.1.2. 副本集(Replica set)

与复制控制器类似, ReplicaSet 是一个原生 Kubernetes API 对象,可以确保在任意给定时间运行指定数量的 pod 副本。副本集与复制控制器之间的区别在于,副本集支持基于集合的选择器要求,而复制控制器只支持基于相等的选择器要求。

注意

只有您需要自定义更新编配,或根本不需要更新时,才使用副本集。否则,使用部署。副本集可以独立使用,但由部署使用用来编配 pod 创建、删除和更新。部署会自动管理其副本集,为 pod 提供声明性更新,且不需要手动管理它们创建的副本集。

以下是 ReplicaSet 定义示例:

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: frontend-1
  labels:
    tier: frontend
spec:
  replicas: 3
  selector: 1
    matchLabels: 2
      tier: frontend
    matchExpressions: 3
      - {key: tier, operator: In, values: [frontend]}
  template:
    metadata:
      labels:
        tier: frontend
    spec:
      containers:
      - image: openshift/hello-openshift
        name: helloworld
        ports:
        - containerPort: 8080
          protocol: TCP
      restartPolicy: Always
1
对一组资源进行的标签查询。matchLabelsmatchExpressions 的结果在逻辑上是组合在一起的。
2
基于相等的选择器,使用与选择器匹配的标签指定资源。
3
基于集合的选择器,用于过滤键。这将选择键等于 tier 并且值等于 frontend 的所有资源。

4.1.2. DeploymentConfig 对象

在复制控制器的基础上,OpenShift Container Platform 增加了对软件开发和部署生命周期的支持,,及 DeploymentConfig 对象的概念。在最简单的情形中,DeploymentConfig 对象会创建一个新的复制控制器,并允许它启动 pod。

但是,从 DeploymentConfig 对象部署的 OpenShift Container Platform 也支持从镜像的现有部署过渡到新部署,同时还可以定义在创建复制控制器之前或之后运行的 hook。

DeploymentConfig 部署系统提供以下功能:

  • DeploymentConfig 对象,这是运行应用程序的模板。
  • 为响应事件而触发自动化部署的触发器。
  • 用户可自定义的部署策略,用于从上一版本过渡到新版本。在 pod 内运行的策略,通常称为部署过程。
  • 一组 hook(生命周期 hook),用于在部署生命周期的不同点上执行自定义行为。
  • 应用程序的版本控制,以便在部署失败时支持手动或自动的回滚。
  • 复制的手动扩展和自动扩展。

在创建 DeploymentConfig 对象时,会创建一个复制控制器来代表 DeploymentConfig 对象的 pod 模板。如果部署被改变,则会使用最新的 pod 模板创建一个新的复制控制器,并运行部署过程来缩减旧复制控制器并扩展新的复制控制器。

在创建时,自动从服务负载均衡器和路由器中添加和移除应用程序的实例。只要应用程序支持接收 TERM 信号时安全关机,您可以确保运行的用户连接拥有正常完成的机会。

OpenShift Container Platform DeploymentConfig 对象定义以下详细信息:

  1. ReplicationController 定义的元素。
  2. 自动创建新部署的触发器。
  3. 在部署之间过渡的策略。
  4. 生命周期 hook。

每次触发部署时,无论是手动还是自动,部署器 Pod 均管理部署(包括缩减旧复制控制器、扩展新复制控制器以及运行 hook)。部署 pod 在完成部署后会无限期保留,以便保留其部署日志。当部署被另一个部署替换时,以前的复制控制器会被保留,以便在需要时轻松回滚。

DeploymentConfig 定义示例

apiVersion: v1
kind: DeploymentConfig
metadata:
  name: frontend
spec:
  replicas: 5
  selector:
    name: frontend
  template: { ... }
  triggers:
  - type: ConfigChange 1
  - imageChangeParams:
      automatic: true
      containerNames:
      - helloworld
      from:
        kind: ImageStreamTag
        name: hello-openshift:latest
    type: ImageChange  2
  strategy:
    type: Rolling      3

1
配置更改触发器会在部署配置的容器集模板中检测到更改时产生新的复制控制器。
2
镜像更改触发器会在命名镜像流中每次有新版本的后备镜像可用时创建新部署。
3
默认的 Rolling 策略会在部署之间实现无停机过渡。

4.1.3. 部署

Kubernetes 在 OpenShift Container Platform 中提供了一流的原生 API 对象类型,名为 DeploymentDeployment 对象充当针对一个 OpenShift Container Platform DeploymentConfig 的后代。

DeploymentConfig 对象一样, Deployment 对象将应用程序特定组件的所需状态描述为 pod 模板。Deployment 创建副本集,用于编配 pod 生命周期。

例如,以下部署定义会创建一个副本集来启动一个 hello-openshift pod:

Deployment 定义

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-openshift
spec:
  replicas: 1
  selector:
    matchLabels:
      app: hello-openshift
  template:
    metadata:
      labels:
        app: hello-openshift
    spec:
      containers:
      - name: hello-openshift
        image: openshift/hello-openshift:latest
        ports:
        - containerPort: 80

4.1.4. Deployment 和 DeploymentConfig 对象的比较

OpenShift Container Platform 支持 Kubernetes Deployment 对象和 OpenShift Container Platform 提供的 DeploymentConfig 对象,但建议您使用 Deployment 对象,除非您需要 DeploymentConfig 对象提供的特定功能或行为。

以下部分详细阐述两种对象之间的区别,以进一步协助您决定使用哪一种类型。

4.1.4.1. 设计

DeploymentDeploymentConfig 对象之间的一个重要区别是为推出(rollout)过程所选择的 CAP theorem 属性。DeploymentConfig 对象以一致性为先,而 Deployments 对象优先于可用性。

对于 DeploymentConfig 对象,如果运行一个部署器 pod 的节点停机,它不会被替换掉。流程会等待节点重新在线或被手动删除。手动删除节点也会删除对应的 pod。这意味着您无法删除 pod 来取消推出部署,因为 kubelet 负责删除相关联的 pod。

但是,部署推出由控制器管理器驱动。控制器管理器在 master 上运行高可用性模式,并使用群首选举算法提高可用性与一致性相比的价值。在故障期间,其他 master 有可能同时对同一部署做出反应,但这个问题会在故障发生后很快进行调节。

4.1.4.2. deploymentConfig 对象相关的功能

自动回滚

目前,在出现故障时,部署不支持自动回滚到上次成功部署的副本集。

触发器

部署有一个隐式配置更改触发器,每次更改部署的 Pod 模板都会自动触发新的推出部署。如果您不想在 Pod 模板更改时进行新的推出部署,请暂停部署:

$ oc rollout pause deployments/<name>
生命周期 hook

Deployment 尚不支持任何生命周期 hook。

自定义策略

部署尚不支持用户指定的自定义部署策略。

4.1.4.3. 针对部署的功能

滚动

Deployment 的部署过程是由控制器循环推动的,这与使用部署器 Pod 进行每次新推出部署的 DeploymentConfig 相反。这意味着 Deployment 对象可以拥有尽可能多的活跃副本集,最终部署控制器将缩减所有旧副本集,并扩展最新的副本集。

DeploymentConfig 对象最多可以有一个部署器 pod 运行,否则多个部署器在试图扩展其认为是最新的复制控制器时会导致冲突。因此,任何时间点上只能有两个复制控制器处于活跃状态。最终,这会转化为 Deployment 能够更快地进行推出部署。

按比例扩展

因为部署控制器是 Deployment 对象所拥有的新旧副本集的大小的唯一来源,所以它可以扩展正在进行的推出部署。额外副本会根据每个副本集的大小按比例分发。

当一个推出部署(rollout)正在进行时无法扩展 DeploymentConfig 对象,因为控制器会遇到部署器进程中有关新复制控制器大小的问题。

中途暂停推出部署

Deployment 可以在任何时间暂停,这意味着可以暂停正在进行的推出部署。另一方面,当前还无法暂停部署器 Pod。因此,如果您尝试在推出部署进行期间暂停部署,则部署器进程不受影响,它会继续运行直到完成为止。