38

.NET Core + Kubernetes:Deployment | Beck's Blog

 3 years ago
source link: http://beckjin.com/2020/05/10/aspnet-k8s-deployment/?
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

.NET Core + Kubernetes:Deployment

发表于 2020-05-10

| 分类于 ASP.NET Core

| 阅读次数: 142

在上篇文章 .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 一层。如下:

deploymentStructure1.png

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

通过以下命令创建 k8sdemo-deployment

1
kubectl apply -f k8sdemo-deployment.yaml

查看 k8sdemo-deployment 的状态信息:

1
kubectl get deployments

getDeployments.png

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

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

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

1
kubectl describe replicaset

describeReplicaset.png

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

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

getPods.png

收缩则类似。

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

1
kubectl describe deployment k8sdemo-deployment

describeDeployment.png

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

查看当前 ReplicaSet 的状态:

getRs.png

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

deploymentStructure2.png

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

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

1
kubectl rollout history deployment/k8sdemo-deployment

history.png

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

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

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

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

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

podNodeNormal.png

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

podNodeDown.png

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

podNodeRecover.png


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK