[TOC]

前言

1、无状态应用(文件共享存储)

​ 无状态应用指的是那些不需要持久存储数据、请求之间没有上下文关联的应用。每个请求都是独立的,应用的所有实例都可以处理任意请求,无需依赖其他实例或持久化存储的数据。

  • 无需持久化存储:应用运行时不依赖磁盘上的数据存储,即使应用实例重启或迁移到另一个节点,也不会影响其正常运行。
  • 实例间无依赖:应用的不同实例之间没有状态依赖,它们是完全独立的,任何实例可以处理用户的请求。
  • 水平扩展简单:无状态应用非常适合水平扩展,多个实例可以随时被创建、销毁,Kubernetes 可以轻松进行自动扩缩容。

2、有状态服务(块存储)

​ 状态应用是那些需要持久化存储数据并且实例之间存在状态依赖的应用。它们的请求与先前的请求有关联,应用实例通常需要记住某些数据,即使在实例重启、重新调度或迁移时,数据仍需保持不变。

  • 需要持久化存储:有状态应用需要某种形式的持久化存储,比如数据库,确保实例重启时数据不丢失。
  • 实例间存在状态依赖:有些有状态应用的实例不能随意替换,因为每个实例可能存储了特定的数据,或依赖某些特定的存储卷。
  • 有序部署和终止:有状态应用通常要求实例的创建、删除是有顺序的,因为实例的状态需要依赖之前的状态。Kubernetes 需要保证这些应用实例按照顺序进行部署或关闭。

3、ReplicaSet(简称RS)

用来确保指定数量的Pod副本始终在集群中运行的资源对象。ReplicaSet是Kubernetes中一个较低层次的控制器,是Deployment等更高层次控制器的基础。ReplicaSet的主要作用是确保在任何时间点,始终有指定数量的Pod副本在集群中运行。ReplicaSet会自动创建和删除Pod,以达到和维持所需的Pod副本数量。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$ rs-nginx.yaml
---
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: nginx-replicaset
labels:
app: nginx
spec:
replicas: 3 # 定义3个副本
selector:
matchLabels:
app: nginx # 选择器匹配标签
template:
metadata:
labels:
app: nginx # Pod 模板的标签
spec:
containers:
- name: nginx
image: registry.cn-hangzhou.aliyuncs.com/hujiaming/nginx:1.24.0 # 使用 Nginx 镜像
ports:
- containerPort: 80
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#>>> 创建资源
$ kubectl apply -f rs-nginx.yaml
replicaset.apps/nginx-replicaset created

#>>> 查看RS
$ kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-replicaset 3 3 0 6s

#>>> 查看指定标签的Pod
$ kubectl get po -l app=nginx
NAME READY STATUS RESTARTS AGE
nginx-replicaset-6m2cq 1/1 Running 0 25s
nginx-replicaset-pg9jf 1/1 Running 0 25s
nginx-replicaset-rvw6b 1/1 Running 0 25s

#>>> 扩充RS副本数
$ kubectl scale rs nginx-replicaset --replicas=5
replicaset.apps/nginx-replicaset scaled

#>>> 查看RS
$ kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-replicaset 5 5 5 4m2s

1、Deployment:无状态资源管理

1.1 简介

image-20240916152152851

Deployment 是一种用于管理和部署容器化应用程序的资源。它提供了一种声明式的方法来管理应用程序的副本,支持滚动更新回滚扩展自动修复等功能。

​ 一般用于部署公司的无状态服务,也是最常用的控制器,企业内部现在以微服务为主,而微服务实现无状态化也是最佳实践,可以利用Deployment的高级功能做到无缝迁移、自动扩容缩容、自动灾难恢复、一键回滚等功能。通过定义Deployment,你可以描述应用的期望状态,Kubernetes会负责将实际状态调整为期望状态。

1.2 Deployment部署方式:

​ 首先在控制端定义了一个3副本的kind为Deployment的yaml文件时,在执行kubectl create 是会提交给apiserver;然后持久化实例到etcd,在yaml中指定的命名空间下,可以看到有个nginx Deployment资源,然后会先创建一个名为nginx-xxx(随机字符串)的RS复制集,然后由复制集会选出最优节点部署Pod(有可能一台节点,有可能多台节点;没有固定的节点)。

  1. kubectl向apiserver发送创建请求;

  2. apiserver将 Deployment 持久化到etcd,etcd与apiserver进行一次http通信。

  3. controller manager通过watch api监听 apiserver ,deployment controller看到了一个新创建的deplayment对象更后,将其从队列中拉出,根据deployment的描述创建一个ReplicaSet并将 ReplicaSet 对象返回apiserver并持久化回etcd。以此类推,当replicaset控制器看到新创建的replicaset对象,将其从队列中拉出,根据描述创建pod对象。

  4. 接着scheduler调度器看到未调度的pod对象,根据调度规则选择一个可调度的节点,加载到pod描述中nodeName字段,并将pod对象返回apiserver并写入etcd。kubelet在看到有pod对象中nodeName字段属于本节点,将其从队列中拉出,通过控制容器运行时创建pod中描述的容器。

创建一个Deployment的yaml文件

1
2
3
4
5
6
$ kubectl create \
deploy nginx \
--image=registry.cn-zhangjiakou.aliyuncs.com/taosweet/nginx:1.24.0-alpine \
--replicas=3 \
-oyaml \
--dry-run=client > nginx-deploy.yaml

参数解释:
--replicas=3 Pod的副本数为3。
--dry-run=client 输出给apiserver但不创建Pod。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
$ vim nginx-deploy.yaml
---
apiVersion: apps/v1 # 资源的 API 版本
kind: Deployment # 资源的类型
metadata: # 资源的元数据信息
name: nginx-deployment # 资源的名称
labels: # 资源的标签,为这个Deployment资源打上标签,以便将来选择和过滤。
app: nginx
spec: # 定义Deployment的详细规格
replicas: 3 # 定义Pod的副本
selector: # 标签选择器,
matchLabels: # 只有带有指定标签的Pod才会被这个Deployment管理。
app: nginx # 指定需要管理的Pod的标签
template: # 定义 Pod 模板,用于创建 Pod。
metadata: # Pod元数据
labels: # 定义Pod的标签,以供deploy的selector选择,输入该deploy管理
app: nginx # Pod的标签
spec: # 定义Pod规格,包括容器配置。
containers: # 定义容器列表
- name: nginx # Pod名称
image: registry.cn-zhangjiakou.aliyuncs.com/taosweet/nginx:1.24.0-alpine # 容器镜像
ports: # 指定容器端口
- containerPort: 80 # 容器的端口
--------------------------------------------------------------------------------------------------------

---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: registry.cn-zhangjiakou.aliyuncs.com/taosweet/nginx:1.24.0-alpine
ports:
- containerPort: 80

#>>> 创建deploy资源
$ kubectl create -f nginx-deploy.yaml
deployment.apps/nginx created

#>>> 查看ReplicaSet资源
$ kubectl get rs

image-20240619224610590

提示:
NAME :RS名称
DESIRED:期望的 Pod 副本数。
CURRENT:当前实际的 Pod 副本数
READY:就绪的 Pod 副本数。
AGE:存在时长

1
2
#>>> 查看创建deploy的pod
$ kubectl get po -owide

image-20240619224858434

提示:
可以看到pod的前缀和RS的前缀一致。

1
2
#>>> 查看deploy资源
$ kubectl get deploy -owide

image-20240619225325942

NAME: Deployment名称
READY:Pod的状态,已经Ready的个数
UP-TO-DATE:已经达到期望状态的被更新的副本数
AVAILABLE:已经可以用的副本数
AGE:显示应用程序运行的时间
CONTAINERS:容器名称
IMAGES:容器的镜像
SELECTOR:管理的Pod的标签

测试删除某个Pod

image-20240619231712261

1
2
3
4
5
6
#>>> 删除某个Pod
$ kubectl delete po nginx-deployment-7bcc989f8f-97gsf
pod "nginx-deployment-7bcc989f8f-97gsf" deleted

#>>> 再次查看Pod
$ kubectl get po

image-20240619231915103

解释:
自愈机制。期望状态 vs 当前状态

Deployment 会创建一个 ReplicaSet 来管理 Pod 副本。ReplicaSet 持续监控当前实际的 Pod 副本数量与期望数量之间的差异。

监控与调谐:当一个 Pod 被删除时(无论是手动删除还是因故障被删除),当前实际的 Pod 数量会减少。ReplicaSet Controller 会立即检测到这种变化,因为它不断地与 API Server 进行通信。
创建新 Pod:当检测到当前 Pod 数量少于期望数量时,ReplicaSet Controller 会自动创建新的 Pod 来补足。这些新的 Pod 会根据 Pod 模板(在 Deployment 的 spec.template 中定义)创建,确保新 Pod 的配置与原始 Pod 一致。

1.3 Deployment资源更新

1.3.1 使用场景

​ 程序升级,变革更新

1.3.2 更新配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#>>> 通过kubectl命令更新deploy的image
$ kubectl set image deploy nginx-deployment nginx=registry.cn-hangzhou.aliyuncs.com/hujiaming/nginx:1.24.0 --record

#>>> 查看更新过程
$ kubectl rollout status deploy nginx-deployment

#>>> 通过yaml文件更新Deploy,首先查看deploy的名称
kubectl replace -f
$ kubectl get deploy nginx-deployment

#>>> 更新
$ kubectl edit deploy nginx-deployment
找到images修改镜像Tag

#>>> 查看Deployment详细的更新过程
$ kubectl describe deploy nginx-deployment

image-20240620125712778

解释:
在describe中可以看出,第一次创建时,它创建了一个名为nginx-deployment-786479c6df的ReplicaSet,并直接将其扩展为3个副本。更新部署时,它创建了一个新的ReplicaSet,命名为nginx-deployment-c5dcb4544,并将其副本数扩展为1,然后将旧的ReplicaSet缩小为2,这样至少可以有2个Pod可用,最多创建了4个Pod。以此类推,使用相同的滚动更新策略向上和向下扩展新旧ReplicaSet,最终新的ReplicaSet可以拥有3个副本,并将旧的ReplicaSet缩小为0。

1.3.3 deployment更新过程

  1. 创建新的 ReplicaSet:当 Deployment 检测到 Pod 模板发生变化(例如镜像版本更新)时,会创建一个新的 ReplicaSet 来管理新的 Pod。
  2. 生成新 ReplicaSet:新 ReplicaSet 的名称类似 nginx-deployment-xxxxxx,包含新的镜像版本信息。
  3. 逐步更新:Deployment Controller 会逐步替换旧的 Pod,而不是一次性删除所有旧 Pod 并创建新 Pod。
  4. 更新策略:默认情况下,Kubernetes 使用滚动更新策略,即每次终止一部分旧的 Pod 并创建一部分新的 Pod。
  5. 新旧 Pod 共存:在更新过程中,新旧版本的 Pod 会共存一段时间,确保在任何时间点都有足够的 Pod 提供服务。
  6. 健康检查:新的 Pod 在替换旧的 Pod 之前,必须通过健康检查,确保其能够正常运行。
  7. 终止旧 Pod:当新的 Pod 通过健康检查后,Deployment Controller 会逐步终止旧的 Pod。
  8. 创建新 Pod:与此同时,创建新的 Pod,直到新的 ReplicaSet 中的 Pod 数量达到期望值。
  9. 更新完成:当所有新的 Pod 都被创建并通过健康检查,且旧的 Pod 被终止后,滚动更新过程完成。

1.4 Deployment回滚(生产环境用的较多)

使用场景:当新发的版本出现BUG或者因为某些原因无法正常使用时,就需要进行版本回退。一般情况都是回滚到上一个版本(deploy回滚不推荐使用修改yaml的方式,有可能历代版本有其他修改的参数)

1
2
#>>> 查看历史更新记录
$ kubectl rollout history deploy nginx-deployment

image-20240620130319537

1
2
3
#>>> 查看更新历史的第2个版本的详细信息
$ kubectl rollout history deploy nginx-deployment --revision=2
# --revision=2 查看第二个版本

image-20240621002324924

1
2
3
4
5
6
7
#>>> kubectl命令行回滚到上一个版本(生产使用最多,不推荐使用edit)
$ kubectl rollout undo deploy nginx-deployment
deployment.apps/nginx-deployment rolled back

#>>> kubectl 命令行回滚到第二个版本
$ kubectl rollout undo deploy nginx-deployment --to-revision=2
deployment.apps/nginx-deployment rolled back

1.5 Deployment扩容和缩容

使用场景:当公司业务增大,Deploy的个数不足以支撑业务的正常运行,所以增加Pod的个数。或者公司推出某些活动需要临时增加Pod的个数。

1
2
3
4
5
6
7
8
9
10
11
#>>> kubectl命令行扩容
$ kubectl scale deploy nginx-deployment --replicas=5


#>>> 查看deploy的Pod
$ kubectl get po


#>>> 修改yaml文件的方式进行扩缩容(不推荐,容易导致资源清单和启动的Pod配置不一致)
$ kubectl edit deploy nginx-deployment
找到容器数量修改参数

1.6 Deployment更新策略

==滚动更新(RollingUpdate)==:默认的更新策略,确保应用程序在更新过程中不会中断运行。滚动更新会逐渐用新的 Pod 替换旧的 Pod,在替换的过程中,集群始终保持可用状态。

  • maxUnavailable:在更新过程中,最多允许多少个 Pod 不可用。默认值是 25%。
  • maxSurge:更新时可以超过期望副本数的最多的 Pod 数量。默认值是 25%。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
---
kind: Deployment
metadata:
labels:
app: nginx
name: nginx-deployment
namespace: default
spec:
replicas: 6
selector:
matchLabels:
app: nginx
strategy:
rollingUpdate:
maxSurge: 3 # 更新时最多允许增加 3个 Pod
maxUnavailable: 1 # 更新过程中最多允许 1 个 Pod不可用
type: RollingUpdate
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: registry.cn-hangzhou.aliyuncs.com/hujiaming/nginx:1.24.0
imagePullPolicy: IfNotPresent
name: nginx
ports:
- containerPort: 80
protocol: TCP
restartPolicy: Always

==重建(Recreate)==Recreate 策略下,Kubernetes 会先删除所有现有的 Pod,然后再启动新的 Pod。在更新过程中,应用程序会有一段时间不可用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
name: nginx-deployment
namespace: default
spec:
replicas: 6
selector:
matchLabels:
app: nginx
strategy:
type: Recreate # 更新时,先删除旧版本所有的Pod,再启动新的Pod。
# rollingUpdate:
# maxSurge: 3
# maxUnavailable: 1
# type: RollingUpdate
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: registry.cn-zhangjiakou.aliyuncs.com/taosweet/nginx:1.24.0-alpine
imagePullPolicy: IfNotPresent
name: nginx
ports:
- containerPort: 80
protocol: TCP
restartPolicy: Always

2、StatefulSet 有状态资源调度

​ StatefulSet(有状态集,缩写sts)常用于部署有状态的且需要有序启动的应用程序。

2.1 前言

​ 在IT世界里,有状态的应用被类比为宠物,无状态的应用则被类比为牛羊,每个宠物在主人那里都是“唯一的存在”,宠物生病了,我们是要花很多钱去治疗的,需要我们用心照料,而无差别的牛羊则没有这个待遇。

2.2 简介

  • 每个节点都有固定的身份ID,通过这个ID,集群中的成员可以 相互发现并通信。
  • 集群的规模是比较固定的,集群规模不能随意变动。
  • 集群中的每个节点都是有状态的,通常会持久化数据到永久存储中,每个节点在重启后都需要使用原有的持久化数据。
  • 集群中成员节点的启动顺序(以及关闭顺序)通常也是确定的。
  • 如果磁盘损坏,则集群里的某个节点无法正常运行,集群功能受损。

2.3 StatefulSet特性

  • 需要稳定的独一无二的网络标识符

    • StatefulSet里的每个Pod都有稳定、唯一的网络标识,可以用来发现集群内的其他成员。每个 Pod 都会被赋予一个唯一且稳定的 DNS 名称。例如,第一个 Pod 的名称可能是 myapp-0,第二个是 myapp-1,依此类推,即使 Pod 被删除或重新创建,它们的名称依然保持不变。
  • 需要有序的、优雅的部署和扩展

    • StatefulSet控制的Pod副本的启停顺序是受控的,启动第n个Pod 时,前n-1个Pod已经是运行且准备好的状态。
    • 如 MySQL集群,要先启动主节点, 若从节点没有要求,则可一起启动,若从节点有启动顺序要求,可先启动第一个从节点,接着第二从节点;这个过程就是有顺序,平滑安全的启动。
  • 需要持久化数据;

    • 需要持久存储,新增或减少pod,存储不会随之发生变化。
  • 需要有序的自动滚动更新

    • MySQL在更新时,应该先更新从节点,全部的从节点都更新完了,最后在更新主节点,因为新版本一般可兼容老版本,但是一定要注意,若新版本不兼容老版本就很麻烦。

2.4 Headless Service 无头服务

2.4.1 前言

​ Headless Service的概念是这种服务没有入口访问地址(无ClusterIP 地址),kube-proxy不会为其创建负载转发规则,而服务名(DNS域名)的解析机制取决于该Headless Service是否设置了Label Selector。无头服务为每个匹配的 Pod 生成独立的 DNS A 记录,而不是单一的服务 IP。客户端可以通过这些 DNS 记录直接与某个特定的 Pod 通信。

2.5.2 介绍

​ 和Deployment类似,一个StatefulSet也同样管理着基于相同容器规范的Pod。不同的是,StatefulSet为每个Pod维护了一个粘性标识。而StatefulSet创建的Pod一般使用Headless Service(无头服务)进行Pod之前的通信,和普通的Service的区别在于Headless Service没有ClusterlP,它使用的是Endpoint进行互相通信,Headless一般的格式为:

statefulSetName-{0..N-1}.serviceName.namespace.svc.cluster.local

  • serviceName为Headless Service的名字,创建StatefulSet时必须指定Headless Service名称;
  • 0..N-1为Pod所在的序号,从0开始到N-1;
  • statefulSetName为StatefulSet的名字;
  • namespace服务所在的命名空间;
  • svc.cluster.local为Cluster Domain(集群域)。

2.5 StatefulSet的yaml创建

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
$ vim nginx-sts.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
app: nginx
spec:
ports:
- port: 80
name: web
clusterIP: None
selector:
app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
serviceName: "nginx" # servive名称
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: registry.cn-zhangjiakou.aliyuncs.com/taosweet/nginx:1.24.0-alpine
ports:
- containerPort: 80
name: web

1
2
3
4
5
6
7
8
9
10
11
12
13
#>>> 创建sts
$ kubectl create -f nginx-sts.yaml
#>>> 查看pod
$ kubectl get po
执行结果:
NAME READY STATUS RESTARTS AGE
web-0 1/1 Running 0 4m7s
web-1 1/1 Running 0 4m6s
#>>> 查看sts
$ kubectl get sts
执行结果:
NAME READY AGE
web 2/2 5m12s

2.6 StatefulSet创建和删除

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#>>> 查看多副本创建过程
$ kubectl get po -w

NAME READY STATUS RESTARTS AGE
web-0 1/1 Running 0 11m
web-1 1/1 Running 0 11m
web-2 1/1 Running 0 103s
web-3 1/1 Running 0 101s
web-4 1/1 Running 0 100s
web-5 1/1 Running 0 1s
web-6 0/1 ContainerCreating 0 0s
web-6 0/1 ContainerCreating 0 1s
web-6 1/1 Running 0 2s
web-7 0/1 Pending 0 0s
web-7 0/1 Pending 0 0s
web-7 0/1 ContainerCreating 0 0s
web-7 0/1 ContainerCreating 0 1s
web-7 1/1 Running 0 2s
web-8 0/1 Pending 0 0s
web-8 0/1 Pending 0 0s
web-8 0/1 ContainerCreating 0 0s
web-8 0/1 ContainerCreating 0 1s
web-8 1/1 Running 0 1s
# 结果发现是其次创建,且前一个pod完全启动且可以使用才会在再次创建

#>>> 查看删除过程
$ kubectl get po -w
执行结果:
NAME READY STATUS RESTARTS AGE
web-0 1/1 Running 0 16m
web-1 1/1 Running 0 16m
web-2 1/1 Running 0 6m16s
web-3 1/1 Running 0 6m14s
web-4 1/1 Running 0 6m13s
web-5 1/1 Running 0 4m34s
web-6 1/1 Running 0 4m33s
web-7 1/1 Terminating 0 4m31s
web-7 0/1 Terminating 0 4m32s
web-7 0/1 Terminating 0 4m32s
web-7 0/1 Terminating 0 4m32s
web-6 1/1 Terminating 0 4m34s
web-6 1/1 Terminating 0 4m34s
web-6 0/1 Terminating 0 4m35s
web-6 0/1 Terminating 0 4m35s
web-6 0/1 Terminating 0 4m35s
web-5 1/1 Terminating 0 4m36s
web-5 1/1 Terminating 0 4m36s
web-5 0/1 Terminating 0 4m37s
web-5 0/1 Terminating 0 4m37s
web-5 0/1 Terminating 0 4m37s
web-4 1/1 Terminating 0 6m16s
web-4 1/1 Terminating 0 6m16s
web-4 0/1 Terminating 0 6m17s
web-4 0/1 Terminating 0 6m17s
web-4 0/1 Terminating 0 6m17s
web-3 1/1 Terminating 0 6m18s
web-3 1/1 Terminating 0 6m18s
web-3 0/1 Terminating 0 6m19s
web-3 0/1 Terminating 0 6m19s
web-3 0/1 Terminating 0 6m19s
web-2 1/1 Terminating 0 6m21s
web-2 1/1 Terminating 0 6m21s
web-2 0/1 Terminating 0 6m22s
web-2 0/1 Terminating 0 6m22s
web-2 0/1 Terminating 0 6m22s
web-1 1/1 Terminating 0 16m
web-1 1/1 Terminating 0 16m
web-1 0/1 Terminating 0 16m
web-1 0/1 Terminating 0 16m
web-1 0/1 Terminating 0 16m
# 结果发现是倒序依次删除,且前一个pod完全删除后才会在从新删除

3、DaemonSet 守护进程集

​ 简介:DaemonSet(守护进程集,缩写为ds)和守护进程类似,它在符合匹配条件的节点上均部署一个Pod。当有新节点加入集群时,也会为它们新增一个Pod,当节点从集群中移除时,这些Pod也会被回收,删除DaemonSet将会删除它创建的所有Pod。

  • 运行集群存储daemon(守护进程),例如在每个节点上运行Glusterd、Ceph等;
  • 在每个节点运行日志收集daemon,例如Fluentd、 Logstash;
  • 在每个节点运行监控daemon,比如Prometheus Node Exporter、Collectd、Datadog代理、New Relic代理或Ganglia gmond。

3.1 DaemonSet守护进程集yaml文件编写

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
$ vim nginx-ds.yaml
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
labels:
app: nginx
name: nginx
spec:
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: registry.cn-zhangjiakou.aliyuncs.com/taosweet/nginx:1.24.0-alpine
name: nginx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#>>> 创建DaemonSet 
$ kubectl apply -f nginx-ds.yaml

#>>> 查看ds的pod
$ kubectl get po -owide
执行结果:(发现每个节点都部署了一个Pod)
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-65zqs 1/1 Running 0 2m32s 172.25.244.226 k8s-master01 <none> <none>
nginx-ds77x 1/1 Running 0 2m32s 172.25.92.92 k8s-master02 <none> <none>
nginx-v4hxt 1/1 Running 0 2m32s 172.18.195.29 k8s-master03 <none> <none>
nginx-xbwl8 1/1 Running 0 2m32s 172.27.14.228 k8s-node02 <none> <none>
nginx-zzwrt 1/1 Running 0 2m33s 172.17.125.29 k8s-node01 <none> <none>

#>>> 查看ds的实例
$ kubectl get ds
执行结果:
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
nginx 5 5 5 5 5 <none> 3m32s

#>>> 查看其他命名空间下的ds
$ kubectl get ds -n kube-system
执行结果:
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
calico-node 5 5 5 5 5 kubernetes.io/os=linux 10d

3.3 DaemonSet指定节点部署Pod(只部署在ssd硬盘标签的节点上)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
$ vim nginx-ds.yaml
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
labels:
app: nginx
name: nginx
spec:
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
nodeSelector: # 标签选择器
cloud: study # 标签类型,指定节点标签
containers:
- image: registry.cn-zhangjiakou.aliyuncs.com/taosweet/nginx:1.24.0-alpine
name: nginx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#>>> 查看所有节点状态
$ kubectl get nodes
执行结果:
k8s-master01 Ready <none> 11d v1.23.14
k8s-master02 Ready <none> 11d v1.23.14
k8s-master03 Ready <none> 11d v1.23.14
k8s-node01 Ready <none> 11d v1.23.14
k8s-node02 Ready <none> 11d v1.23.14

#>>> 将node节点打上标签(打上ssd硬盘标签)
$ kubectl label nodes k8s-node01 k8s-node02 disktype=ssd
执行结果:
node/k8s-node01 labeled
node/k8s-node02 labeled

#>>> 更新DaemonSet
$ kubectl replace -f nginx-ds.yaml
执行结果:
daemonset.apps/nginx replaced

#>>> 查看Pod
$ kubectl get po
执行结果:(结果显示只在打了ssd标签的node节点上部署了Pod)
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-fd767 1/1 Running 0 2m5s 172.17.125.30 k8s-node01 <none> <none>
nginx-lgtvz 1/1 Running 0 2m7s 172.27.14.229 k8s-node02 <none> <none>

#>>> 查看集群默认的标签
$ kubectl get node --show-labels
执行结果:
NAME STATUS ROLES AGE VERSION LABELS
k8s-master01 Ready <none> 11d v1.23.14 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-master01,kubernetes.io/os=linux,node.kubernetes.io/node=
k8s-master02 Ready <none> 11d v1.23.14 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-master02,kubernetes.io/os=linux,node.kubernetes.io/node=
k8s-master03 Ready <none> 11d v1.23.14 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-master03,kubernetes.io/os=linux,node.kubernetes.io/node=
k8s-node01 Ready <none> 11d v1.23.14 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,disktype=ssd,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-node01,kubernetes.io/os=linux,node.kubernetes.io/node=
k8s-node02 Ready <none> 11d v1.23.14 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,disktype=ssd,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-node02,kubernetes.io/os=linux,node.kubernetes.io/node=