第 8 章 Deployments
8.1. 了解 Deployment 和 DeploymentConfig 对象
OpenShift Container Platform 中的 Deployment
和 DeploymentConfig
API 对象提供了两个类似但不同的方法来对常见用户应用程序进行精细管理。由以下独立 API 对象组成:
-
一个
Deployment
或DeploymentConfig
对象,用于将应用程序特定组件的所需状态描述为 pod 模板。 -
Deployment
对象涉及一个或多个 replica sets(复制集),其中包含部署状态的一个时间点的记录,作为 pod 模板。同样,DeploymentConfig
对象涉及一个或多个 replication controllers(复制控制器),它在副本集之前。 - 一个或多个 pod,,表应用程序某一特定版本的实例。
使用 Deployment
对象,除非需要由 DeploymentConfig
对象提供的特定功能或行为。
8.1.1. 部署构建块
Deployment 和部署配置分别通过使用原生 Kubernetes API 对象 ReplicaSet
和 ReplicationController
来启用,作为构建块。
用户不必操作由 Deployment
或 DeploymentConfig
对象拥有的副本集、复制控制器或 pod。部署系统可确保正确传播更改。
如果现有部署策略不适用于您的用例,而且必须在部署的生命周期内执行手动步骤,那么应考虑创建自定义部署策略。
以下部分详细介绍了这些对象。
8.1.1.1. 副本集(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
8.1.1.2. 复制控制器
与副本集类似,复制控制器确保始终运行指定数量的 pod 副本。如果 pod 退出或被删除,复制控制器会做出反应,实例化更多 pod 来达到定义的数量。同样,如果运行中的数量超过所需的数目,它会根据需要删除相应数量的 Pod,使其与定义的数量相符。副本集与复制控制器之间的区别在于,副本集支持基于集合的选择器要求,而复制控制器只支持基于相等的选择器要求。
复制控制器配置包括:
- 需要的副本数量,可在运行时调整。
-
创建复制
Pod
时要使用的 Pod 定义。 - 用于标识受管 pod 的选择器。
选择器是分配给由复制控制器管理的 pod 的一组标签。这些标签包含在复制控制器实例化的 Pod
定义中。复制控制器使用选择器来决定已在运行的 pod 实例数量,以便根据需要进行调整。
复制控制器不会基于负载或流量执行自动扩展,因为复制控制器不会跟踪它们。相反,这需要由外部自动缩放器调整其副本数。
使用 DeploymentConfig
创建复制控制器,而不是直接创建复制控制器。
如果您需要自定义编配或不需要更新,请使用副本集而不是复制控制器。
以下是复制控制器的示例定义:
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
8.1.2. 部署
Kubernetes 在 OpenShift Container Platform 中提供了一流的原生 API 对象类型,名为 Deployment
。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
8.1.3. 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
对象定义以下详细信息:
-
ReplicationController
定义的元素。 - 自动创建新部署的触发器。
- 在部署之间过渡的策略。
- 生命周期 hook。
每次触发部署时,无论是手动还是自动,部署器 Pod 均管理部署(包括缩减旧复制控制器、扩展新复制控制器以及运行 hook)。部署 pod 在完成部署后会无限期保留,以便保留其部署日志。当部署被另一个部署替换时,以前的复制控制器会被保留,以便在需要时轻松回滚。
DeploymentConfig
定义示例
apiVersion: apps.openshift.io/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
8.1.4. Deployment 和 DeploymentConfig 对象的比较
OpenShift Container Platform 支持 Kubernetes Deployment
对象和 OpenShift Container Platform 提供的 DeploymentConfig
对象,但建议您使用 Deployment
对象,除非您需要 DeploymentConfig
对象提供的特定功能或行为。
以下部分详细阐述两种对象之间的区别,以进一步协助您决定使用哪一种类型。
8.1.4.1. 设计
Deployment
和 DeploymentConfig
对象之间的一个重要区别是为推出(rollout)过程所选择的 CAP theorem 属性。DeploymentConfig
对象以一致性为先,而 Deployments
对象优先于可用性。
对于 DeploymentConfig
对象,如果运行一个部署器 pod 的节点停机,它不会被替换掉。流程会等待节点重新在线或被手动删除。手动删除节点也会删除对应的 pod。这意味着您无法删除 pod 来取消推出部署,因为 kubelet 负责删除相关联的 pod。
但是,部署推出由控制器管理器驱动。控制器管理器在 master 上运行高可用性模式,并使用群首选举算法提高可用性与一致性相比的价值。在故障期间,其他 master 有可能同时对同一部署做出反应,但这个问题会在故障发生后很快进行调节。
8.1.4.2. 针对部署的功能
滚动
Deployment
的部署过程是由控制器循环推动的,这与使用部署器 Pod 进行每次新推出部署的 DeploymentConfig
相反。这意味着 Deployment
对象可以拥有尽可能多的活跃副本集,最终部署控制器将缩减所有旧副本集,并扩展最新的副本集。
DeploymentConfig
对象最多可以有一个部署器 pod 运行,否则多个部署器在试图扩展其认为是最新的复制控制器时会导致冲突。因此,任何时间点上只能有两个复制控制器处于活跃状态。最终,这可以更快地为 Deployment
对象推出部署。
按比例扩展
因为部署控制器是适合由 Deployment
对象拥有的新和旧副本集的大小的唯一来源,所以它能够扩展持续推出部署。额外副本会根据每个副本集的大小按比例分发。
当推出(rollout)进行的过程中,DeploymentConfig
对象无法被扩展,因为控制器会遇到部署器进程中有关新 ReplicationController 大小的问题。
中途暂停推出部署
Deployment 可以在任何时间暂停,这意味着可以暂停正在进行的推出部署。但是,当前还无法暂停部署器 Pod。因此,如果您尝试在推出部署进行期间暂停部署,则部署器进程不受影响,它会继续运行直到完成为止。
8.1.4.3. deploymentConfig 对象相关的功能
自动回滚
目前,在出现故障时,部署不支持自动回滚到上次成功部署的副本集。
触发器
部署有一个隐式配置更改触发器,每次更改部署的 Pod 模板都会自动触发新的推出部署。如果您不想在 Pod 模板更改时进行新的推出部署,请暂停部署:
$ oc rollout pause deployments/<name>
生命周期 hook
Deployment 尚不支持任何生命周期 hook。
自定义策略
部署不支持用户指定的自定义部署策略。