.NET Core + Kubernetes:Deployment

在上篇文章 .NET Core + Kubernetes:Pod 中,主要介绍了 Pod 的相关内容,
基于 Pod 为单位能更加合理进行容器编排,然而 Pod 只是个启动了一个或一组容器的资源类型,在实际应用中,我们也需要 Pod 能实现动态扩展与收缩、滚动更新等,但 Pod 本身是没有办法做到的,它需要依赖上层的一种控制来达到这样的效果,这就涉及到 Kubernetes 中的控制器(Controller)模型知识,本文将注意介绍 Deployment 这个最基本的控制器对象。

我们继续以 .NET Core + Kubernetes:快速体验 文中配置为例,将以下配置保存为 k8sdemo-deployment.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
apiVersion: apps/v1
kind: Deployment
metadata:
name: k8sdemo-deployment
spec:
replicas: 2
selector:
matchLabels:
name: k8sdemo
template:
metadata:
labels:
name: k8sdemo
spec:
containers:
- name: k8sdemo
image: beckjin/k8sdemo:1.0.0
ports:
- containerPort: 80
imagePullPolicy: IfNotPresent

这个 Deployment 指定创建 2 个含 name=k8sdemo 标签的 Pod,template 字段指定了 Pod 的模板。从表面上来看,Deployment 和 Pod 是直接关系,然而实际上在 Deployment 与 Pod 直接还有 ReplicaSet 一层。如下:

Deployment 实际上一个两层控制器,Deployment 控制 ReplicaSet,ReplicaSet 控制 Pod。ReplicaSet 有版本区分,滚动更新的能力就是基于 ReplicaSet 的版本来实现,下文会介绍。

通过以下命令创建 k8sdemo-deployment

1
kubectl apply -f k8sdemo-deployment.yaml

查看 k8sdemo-deployment 的状态信息:

1
kubectl get deployments

输出结果中含3个状态字段,含义如下:

  • READY:当前处于 Running 状态的 Pod 的个数/用户期望的 Pod 个数(配置文件设置的 replicas);
  • UP-TO-DATE:当前处于最新版本的 Pod 个数(Pod 的 Spec 部分与 Deployment 里 Pod 模板里定义的完全一致),在滚动更新过程中会有不一致的阶段;
  • AVAILABLE:当前可用的 Pod 个数。

查看 k8sdemo-deployment 所控制的 ReplicaSet 信息:

1
kubectl describe replicaset

如上图,Deployment 创建后,Deployment 控制器就会立即创建一个 Pod 个数为 2 的 ReplicaSet,ReplicaSet 的名字是由 Deployment 名字 + 随机字符串,Pod 的名字是由 ReplicaSet 名字 + 随机字符串

动态伸缩

要实现 Pod 的伸缩只需要调整配置文件中的 replicas 字段,如扩展为 3 个,扩展完成后结果如下:

收缩则类似。

滚动更新

假设现在将镜像 beckjin/k8sdemo:1.0.0 升级为 beckjin/k8sdemo:1.1.0,重新 apply 后并查看 Deployment 的 Events 信息,输出内容含 “滚动更新” 的整个流程。

1
kubectl describe deployment k8sdemo-deployment

Deployment 控制器根据修改后的 Pod 模板,创建新的 ReplicaSet(k8sdemo-deployment-68cb864ff6),Pod 数默认是 0,然后老的 ReplicaSet (k8sdemo-deployment-84d777fb7)Pod 数逐渐减少,新的 ReplicaSet 的 Pod 数逐渐增加,两个过程交替进行,新的增加一个,老的减少一个,直到全部升级完成。

查看当前 ReplicaSet 的状态:

可以看出原来的 ReplicaSet 的 Pod 已经缩减为 0 个,新的 ReplicaSet 的 Pod 扩展为 3 个,每次配置修改重新部署都可能创建一个新的 ReplicaSet,所以 Deployment、ReplicaSet 和 Pod 的关系图可扩展如下:

回滚

通过上文的介绍,已经了解应用版本与 ReplicaSet 具有一一对应关系,所以如果要回滚版本其实就是使原来的 ReplicaSet 重新扩展 Pod,当前的 ReplicaSet 收缩至 0 个 Pod。

通过 kubectl rollout history 命令查看每次 Deployment 变更对应的版本。

1
kubectl rollout history deployment/k8sdemo-deployment

由于在创建 Deployment 没有加 –record 参数,所以 CHANGE-CAUSE 都是 none

现在如果需要回滚到版本 1,执行以下命令:

1
kubectl rollout undo deployment/k8sdemo-deployment --to-revision=1

这时 Deployment 控制器还是按 “滚动更新” 的方式,完成对 k8sdemo-deployment 的回滚操作。

故障转移

故障转移主要是指当集群中某个节点挂了,Pod 会自动转移到其他健康的节点上。当前的 Pod 分布情况如下:

可以看出 node1 上分配了 2 个 Pod,node2 分配了 1 个 Pod,接下来将 node1 强制关机,然后当 Kubernetes 检测到 node1 不可用时,node1 上的 Pod 会变成 Terminating 状态,并在 node2 上新建,维持可用 Pod 总数不变。

当 node1 恢复后,Terminating 状态的 Pod 会被自动删除,不过已经转移到 node2 的 Pod 是不会被重新调度回 node1 的。

如果对你有帮助就好