[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 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: registry.cn-hangzhou.aliyuncs.com/hujiaming/nginx:1.24.0 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 简介
Deployment 是一种用于管理和部署容器化应用程序的资源。它提供了一种声明式的方法来管理应用程序的副本,支持滚动更新 、回滚 、扩展 和自动修复 等功能。
一般用于部署公司的无状态服务 ,也是最常用的控制器,企业内部现在以微服务为主,而微服务实现无状态化也是最佳实践 ,可以利用Deployment 的高级功能做到无缝迁移、自动扩容缩容、自动灾难恢复、一键回滚等功能。通过定义Deployment ,你可以描述应用的期望状态,Kubernetes会负责将实际状态调整为期望状态。
1.2 Deployment部署方式: 首先在控制端定义了一个3副本的kind为Deployment 的yaml文件时,在执行kubectl create 是会提交给apiserver;然后持久化实例到etcd,在yaml中指定的命名空间下,可以看到有个nginx Deployment资源,然后会先创建一个名为nginx-xxx(随机字符串)的RS复制集,然后由复制集会选出最优节点部署Pod(有可能一台节点,有可能多台节点;没有固定的节点)。
kubectl向apiserver发送创建请求;
apiserver将 Deployment 持久化到etcd,etcd与apiserver进行一次http通信。
controller manager通过watch api监听 apiserver ,deployment controller看到了一个新创建的deplayment对象更后,将其从队列中拉出,根据deployment的描述创建一个ReplicaSet并将 ReplicaSet 对象返回apiserver并持久化回etcd。以此类推,当replicaset控制器看到新创建的replicaset对象,将其从队列中拉出,根据描述创建pod对象。
接着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 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 -------------------------------------------------------------------------------------------------------- --- 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 $ kubectl create -f nginx-deploy.yaml deployment.apps/nginx created $ kubectl get rs
提示: NAME :RS名称 DESIRED:期望的 Pod 副本数。 CURRENT:当前实际的 Pod 副本数 READY:就绪的 Pod 副本数。 AGE:存在时长
1 2 $ kubectl get po -owide
提示: 可以看到pod的前缀和RS的前缀一致。
1 2 $ kubectl get deploy -owide
NAME: Deployment名称READY:Pod的状态,已经Ready的个数UP-TO-DATE:已经达到期望状态的被更新的副本数AVAILABLE:已经可以用的副本数AGE:显示应用程序运行的时间CONTAINERS:容器名称IMAGES:容器的镜像SELECTOR:管理的Pod的标签
测试删除某个Pod
1 2 3 4 5 6 $ kubectl delete po nginx-deployment-7bcc989f8f-97gsf pod "nginx-deployment-7bcc989f8f-97gsf" deleted $ kubectl get po
解释: 自愈机制。期望状态 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 set image deploy nginx-deployment nginx=registry.cn-hangzhou.aliyuncs.com/hujiaming/nginx:1.24.0 --record $ kubectl rollout status deploy nginx-deployment kubectl replace -f $ kubectl get deploy nginx-deployment $ kubectl edit deploy nginx-deployment 找到images修改镜像Tag $ kubectl describe deploy nginx-deployment
解释: 在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更新过程
创建新的 ReplicaSet :当 Deployment 检测到 Pod 模板发生变化(例如镜像版本更新)时,会创建一个新的 ReplicaSet 来管理新的 Pod。
生成新 ReplicaSet :新 ReplicaSet 的名称类似 nginx-deployment-xxxxxx,包含新的镜像版本信息。
逐步更新 :Deployment Controller 会逐步替换旧的 Pod,而不是一次性删除所有旧 Pod 并创建新 Pod。
更新策略 :默认情况下,Kubernetes 使用滚动更新策略,即每次终止一部分旧的 Pod 并创建一部分新的 Pod。
新旧 Pod 共存 :在更新过程中,新旧版本的 Pod 会共存一段时间,确保在任何时间点都有足够的 Pod 提供服务。
健康检查 :新的 Pod 在替换旧的 Pod 之前,必须通过健康检查,确保其能够正常运行。
终止旧 Pod :当新的 Pod 通过健康检查后,Deployment Controller 会逐步终止旧的 Pod。
创建新 Pod :与此同时,创建新的 Pod,直到新的 ReplicaSet 中的 Pod 数量达到期望值。
更新完成 :当所有新的 Pod 都被创建并通过健康检查,且旧的 Pod 被终止后,滚动更新过程完成。
1.4 Deployment回滚(生产环境用的较多) 使用场景:当新发的版本出现BUG或者因为某些原因无法正常使用时,就需要进行版本回退。一般情况都是回滚到上一个版本(deploy回滚不推荐使用修改yaml的方式,有可能历代版本有其他修改的参数)
1 2 $ kubectl rollout history deploy nginx-deployment
1 2 3 $ kubectl rollout history deploy nginx-deployment --revision=2
1 2 3 4 5 6 7 $ kubectl rollout undo deploy nginx-deployment deployment.apps/nginx-deployment rolled back $ 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 scale deploy nginx-deployment --replicas=5 $ kubectl get po $ 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 maxUnavailable: 1 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 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" 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 $ kubectl create -f nginx-sts.yaml $ kubectl get po 执行结果: NAME READY STATUS RESTARTS AGE web-0 1/1 Running 0 4m7s web-1 1/1 Running 0 4m6s $ 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 $ 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
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 $ kubectl apply -f nginx-ds.yaml $ 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> $ kubectl get ds 执行结果: NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE nginx 5 5 5 5 5 <none> 3m32s $ 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 $ kubectl label nodes k8s-node01 k8s-node02 disktype=ssd 执行结果: node/k8s-node01 labeled node/k8s-node02 labeled $ kubectl replace -f nginx-ds.yaml 执行结果: daemonset.apps/nginx replaced $ 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=