# 一、Kubernetes

Kubernetes 是 Google 基于 go语言 开源的容器编排调度，用于管理容器集群自动化部署、扩容以及运维的开源平台。作为云原生计算基金会 CNCF（Cloud Native Computing Foundation）最重要的组件之一（CNCF 另一个毕业项目 Prometheus ），它的目标不仅仅是一个编排系统，而是提供一个规范，可以让你来描述集群的架构，定义服务的最终状态，Kubernetes 可以帮你将系统自动地达到和维持在这个状态，Kubernetes 也可以对容器(Docker)进行集群管理和服务编排（Docker compose类似的功能）,对于大多开发者来说，以容器的方式运行一个程序是一个最基本的需求，跟多的是 Kubernetes 能够提供路由网关、水平扩展、监控、备份、灾难恢复等一系列运维能力。



# 二、特性

kubernetes具有以下特性：

- **服务发现和负载均衡**
  Kubernetes 可以使用 DNS 名称或自己的 IP 地址公开容器，如果进入容器的流量很大， Kubernetes 可以负载均衡并分配网络流量，从而使部署稳定。
- **存储编排**
  Kubernetes 允许你自动挂载你选择的存储系统，例如本地存储、公共云提供商等。
- **自动部署和回滚**
  你可以使用 Kubernetes 描述已部署容器的所需状态，它可以以受控的速率将实际状态 更改为期望状态。例如，你可以自动化 Kubernetes 来为你的部署创建新容器， 删除现有容器并将它们的所有资源用于新容器。
- **自动完成装箱计算**
  Kubernetes 允许你指定每个容器所需 CPU 和内存（RAM）。 当容器指定了资源请求时，Kubernetes 可以做出更好的决策来管理容器的资源。
- **自我修复**
  Kubernetes 重新启动失败的容器、替换容器、杀死不响应用户定义的 运行状况检查的容器，并且在准备好服务之前不将其通告给客户端。
- **密钥与配置管理**
  Kubernetes 允许你存储和管理敏感信息，例如密码、OAuth 令牌和 ssh 密钥。 你可以在不重建容器镜像的情况下部署和更新密钥和应用程序配置，也无需在堆栈配置中暴露密钥。



**Kubernetes 提供了一个可弹性运行分布式系统的框架。 Kubernetes 会满足你的扩展要求、故障转移、部署模式等。 例如，Kubernetes 可以轻松管理系统的 Canary 部署。**



[认识rancher](https://www.cnblogs.com/zhangxingeng/p/11753959.html#toc_7)



# 三、Kubernetes架构

Kubernetes 遵循非常传统的客户端服务端架构，**客户端通过 RESTful 接口或者直接使用 kubectl 与 Kubernetes集群进行通信**，这两者在实际上并没有太多的区别，后者也只是对 Kubernetes 提供的 RESTful API 进行封装并提供出来。每一个 Kubernetes 集群都由一组 Master 节点和一系列的 Worker 节点组成，其中 Master 节点主要负责存储集群的状态并为 Kubernetes 对象分配和调度资源。

![components-of-kubernetes.svg](https://figure-bed-1304788733.cos.ap-guangzhou.myqcloud.com/typora/202206161146091.svg)



![img](https://figure-bed-1304788733.cos.ap-guangzhou.myqcloud.com/typora/202206161146112.png)





## 3.1、Master节点

Master功能：

（1）接收客户端的请求；

（2）安排容器的执行并且运行控制循环；

（3）将集群的状态向目标状态进行迁移.

Master 节点内部由三个组件构成:



### 3.1.1 API Server

负责处理来自用户的请求，其主要作用就是对外提供 RESTful 的接口，包括**用于查看集群状态的读请求以及改变集群状态的写请求**，也是**唯一一个与 etcd 集群通信的组件**。



### 3.1.2 Controller

管理器运行了一系列的控制器进程，这些进程会**按照用户的期望状态在后台不断地调节整个集群中的对象**，当**服务的状态发生了改变，控制器就会发现这个改变并且开始向目标状态迁移**。



### 3.1.3 Scheduler

调度器其实为 Kubernetes 中**运行的 Pod 选择部署的 Worker 节点**，它会**根据用户的需要选择最能满足请求的节点来运行 Pod，它会在每次需要调度 Pod 时执行**。



## 3.2 Node节点

Node 节点实现相对简单一点，主要是由 **kubelet 和 kube-proxy** 两部分组成：



### 3.2.1 kubelet

kubelet 是一个节点上的主要服务，它周**期性地从 API Server 接受新的或者修改的 Pod 规范**并且**保证节点上的 Pod 和其中容器的正常运行**，还会**保证节点会向目标状态迁移**，该节点仍然会**向 Master 节点发送宿主机的健康状况**。



### 3.2.2 kube-proxy

Kube-proxy  维护节点上的网络规则，实现了Kubernetes Service 概念的一部分。它的作用是使发往 Service 的流量（通过ClusterIP和端口）负载均衡到正确的后端Pod。



## 3.3 注意

1. **master节点为奇数个，但是一般不超过9个；而node节点可以有很多个，但是当多到一定程度的时候，我们不应该再去考虑扩容，而是增加集群，实行连级管理；**

2. **整个集群在外部是看不见的，只能看见ing，集群内部是一个rpc网络，通过dns来通信。当外部访问的时候是通过ing，然后ing通过dns解析来访问到内部，所以ing相当于一个代理；**

3. **我们也会在master节点上开一个接口来连接，用来管理node节点；**

4. **node节点相当于一个资源池，只是提供资源，而master是通过计算来调度这些资源的，这样资源就会比较平衡；**

5. **k8s的存储在etcd数据库上面，只有master的api-server能连接上，并且写入数据；**

6. **根据生产经验，一个节点上跑40个pod以下较为安全；**

7. **k8s底层的CRI用的是docker，containerd,CRI-O;**

8. **由于k8s集群中是通过服务名来通信的，那这样就需要coredns来解析，所以所有的k8s集群中都应该有集群dns。**





# 四、Kubernetes 基本对象与术语

### Pod

- Pod 是一组紧密关联的容器集合，它们共享 `PID`、`IPC`、`Network` 和 `UTS namespace`，是 Kubernetes 调度的基本单位。Pod 的设计理念是支持多个容器在一个 Pod 中共享网络和文件系统，可以通过进程间通信和文件共享这种简单高效的方式组合完成服务。



### Label

- Label 是识别 Kubernetes 对象的标签，以`key/value`的方式附加到对象上（key最长不能超过63字节，value 可以为空，也可以是不超过253字节的字符串）。 Label 不提供唯一性，并且实际上经常是很多对象（如 Pods）都使用相同的 label 来标志具体的应用。 Label 定义好后其他对象可以使用 Label Selector 来选择一组相同 label 的对象（比如 Service 用 label 来选择一组 Pod）。Label Selector 支持以下几种方式:

  - 等于和不等于, 如app=nginx和env!=production
  - 集合，如env in (production, test)
  - 多个label（它们之间是AND关系），如app=nginx, env=test



### Namespace

- Namespace 是对一组资源和对象的抽象集合，比如可以用来将系统内部的对象划分为不同的项目组或用户组。常见的 pods, services, deployments 等都是属于某一个 namespace 的（默认是default），而 Node, PersistentVolumes 等则不属于任何 namespace。



### ReplicaSet

- ReplicaSet 它的主要作用是确保 `Pod` 以你指定的副本数运行, 如果有容器异常退出, 会自动创建新的 `Pod` 来替代, 而异常多出来的容器也会自动回收。 支持集合式的 `selector`。ReplicaSet 可以独立使用, 但建议使用 `Deployment` 来自动管理 ReplicaSet, 这样就无需担心跟其他机制的不兼容问题（比如 ReplicaSet 不支持 rolling-update 但 Deployment 支持）, 并且 `Deployment` 还支持版本记录、回滚、暂停升级等高级特性。



### Deployment

- Deployment 确保任意时间都有指定数量的 `Pod` 在运行。如果为某个 `Pod` 创建了 Deployment 并且指定3个副本，它会创建3个 Pod，并且持续监控它们。如果某个 Pod 不响应，那么 Deployment 会替换它，保持总数为3。如果之前不响应的 Pod 恢复了，现在就有4个 Pod 了，那么 Deployment 会将其中一个终止保持总数为3。如果在运行中将副本总数改为5，Deployment 会立刻启动2个新 Pod，保证总数为5。Deployment 还支持回滚和滚动升级。
- 创建 Deployment 需要指定:

  - Pod 模板 用于配置 pod 生成的属性和副本。
  - Label 标签 Deployment 需要监控的 Pod 的标签。



### StatefulSet

- StatefulSet 是为了解决有状态服务的问题 (对应 Deployments 和 ReplicaSets是为无状态服务而设计), 其应用场景包括

  - 稳定的持久化存储，即 Pod 重新调度后还是能访问到相同的持久化数据，基于 PVC 来实现。
  - 稳定的网络标志，即 Pod 重新调度后其 `PodName` 和 `HostName` 不变，基于 Headless Service（即没有Cluster IP的Service）来实现
  - 有序部署，有序扩展，即 Pod 是有顺序的，在部署或者扩展的时候要依据定义的顺序依次依次进行（即从0到N-1，在下一个Pod运行之前所有之前的 Pod 必须都是 Running 和 Ready 状态），基于 init containers来实现。
  - 有序收缩，有序删除（即从N-1到0）



### DaemonSet

- DaemonSet 保证在每个Node上都运行一个容器副本，常用来部署一些集群的日志、监控或者其他系统管理应用。



### Service(SVC)

- Service 是应用服务的抽象体现，通过 labels 为应用提供负载均衡和服务发现。匹配 labels 的Pod IP 和端口列表组成 endpoints，由 kube-proxy 负责将服务 IP 负载均衡到这些endpoints 上。每个 Service 都会自动分配一个 cluster IP（仅在集群内部可访问的虚拟地址）和 DNS 名，其他容器可以通过该地址或 DNS 来访问服务，而不需要了解后端容器的运行。
- <font color='red'>只提供4层负载均衡能力【只能基于ip地址和端口进行转发】，而没有7层功能【不能通过主机名及域名的方案去进行负载均衡】，但有时我们可能需要更多的匹配规则来转发请求，这点上4层负载均衡是不支持的</font>



### Job

- Job 负责批量处理短暂的一次性任务 (short lived one-off tasks)，即仅执行一次的任务，它保证批处理任务的一个或多个Pod成功结束。
- Kubernetes 支持以下几种 Job
  - 非并行 Job：通常创建一个 Pod 直至其成功结束
  - 固定结束次数的 Job：设置 `.spec.completions`, 创建多个 Pod，直到 `.spec.completions` 个 Pod 成功结束
  - 带有工作队列的并行 Job：设置 `.spec.Parallelism` 但不设置 `.spec.completions`，当所有Pod结束并且至少一个成功时，Job 就认为是成功



### CronJob

- CronJob 即定时任务，就类似于 Linux 系统的 crontab，在指定的时间周期运行指定的任务。



### Horizontal Pod Autoscaler（HPA）

- Horizontal Pod Autoscaling 可以根据 CPU 使用率或应用自定义 metrics 自动扩展 Pod 数量（支持replication controller、deployment和replica set）, 从而合理的扩展性能与使用资源。



### PersistentVolume (PV)

- PersistentVolume（PV）是集群中由管理员配置的一段网络存储。 它是集群中的资源，就像节点是集群资源一样。 PV是容量插件，如Volumes，但其生命周期独立于使用PV的任何单个pod。 此API对象捕获存储实现的详细信息，包括NFS，iSCSI或特定于云提供程序的存储系统。
- PersistentVolume 支持的类型:

  - GCEPersistentDisk
  - AWSElasticBlockStore
  - AzureFile
  - AzureDisk
  - FC (Fibre Channel)
  - Flexvolume
  - Flocker
  - NFS
  - iSCSI
  - RBD (Ceph Block Device)
  - CephFS
  - Cinder (OpenStack block storage)
  - Glusterfs
  - VsphereVolume
  - Quobyte Volumes
  - HostPath
  - Portworx Volumes
  - ScaleIO Volumes
  - StorageOS

- PersistentVolume 服务状态

  - `Available` 资源尚未被claim使用
  - `Bound` 卷已经被绑定到claim了
  - `Released` claim被删除，卷处于释放状态，但未被集群回收。
  - `Failed` 卷自动回收失败



### PersistentVolumeClaim（PVC）

- PersistentVolumeClaim（PVC）是由用户进行存储的请求。 它类似于pod。 Pod消耗节点资源，PVC消耗PV资源。Pod可以请求特定级别的资源（CPU和内存）。声明可以请求特定的大小和访问模式（例如，可以一次读/写或多次只读）。
- PVC和PV是一一对应的。
- PVC 与 PV 的生命周期

  - PV是群集中的资源。PVC是对这些资源的请求，并且还充当对资源的检查。
  - PV和PVC之间的相互作用遵循生命周期：`Provisioning` ——-> `Binding` ——–> `Using` -——> `Releasing` -——> `Recycling`

- Provisioning (准备) 通过集群外的存储系统或者云平台来提供存储持久化支持。

  - 静态提供Static：集群管理员创建多个PV。 它们携带可供集群用户使用的真实存储的详细信息。 它们存在于Kubernetes API中，可用于消费。
  - 动态提供Dynamic：当管理员创建的静态PV都不匹配用户的PersistentVolumeClaim时，集群可能会尝试为PVC动态配置卷。 此配置基于StorageClasses：PVC必须请求一个类，并且管理员必须已创建并配置该类才能进行动态配置。 要求该类的声明有效地为自己禁用动态配置。

- Binding (绑定) 用户创建pvc并指定需要的资源和访问模式。在找到可用pv之前，pvc会保持未绑定状态。
- Using (使用) 用户可在pod中像volume一样使用pvc。
- Releasing (释放) 用户删除pvc来回收存储资源，pv将变成”released”状态。由于还保留着之前的数据，这些数据需要根据不同的策略来处理，否则这些存储资源无法被其他pvc使用。
- Recycling (回收) pv 可以设置三种回收策略：保留（Retain），回收（Recycle）和删除（Delete）。

  - 保留策略 - 允许人工处理保留的数据。
  - 删除策略 - 将删除pv和外部关联的存储资源，需要插件支持。
  - 回收策略 - 将执行清除操作，之后可以被新的pvc使用，需要插件支持。



### StorageClass

- StorageClass为管理员提供了一种描述他们提供的存储的”类”的方法。 不同的类可能映射到服务质量级别，或备份策略，或者由群集管理员确定的任意策略。 Kubernetes本身对于什么类别代表是不言而喻的。 这个概念有时在其他存储系统中称为”配置文件”。





# 五、pod

## 5.1 pod简介

在node上k8s管理的最小运行单位为pod！pod一定是个容器组，即可以跑多个容器。



## 5.2 pod状态



### 5.2.1 pending

悬决状态：pod已经被k8s接受，但是容器未创建未运行。这个阶段包括等待pod被调度的时间和下载镜像的时间。



### 5.2.2 running

运行中：pod已经绑定到某一个节点上，pod中所有的容器都已经被创建了；至少有一个容器在运行/正在启动/重启中。



### 5.2.3 succeeded

成功状态：pod中所有的容器都已经成功终止，而且不会重启。



### 5.2.4 failed

失败状态：pod中所有的容器都已经成功终止，但是至少有一个容器是非正常退出的。



### 5.2.5 unknow

未知状态：无法获取pod的状态，一般是因为与pod所在主机通信失败



### 5.2.6 CrashLoopBackoff

回收状态：当Pod一直重启不成功，k8s就会去回收这个pod，然后再去重新生成一个新的pod。这里需要注意的是，当出现大量的CrashLoopBackoff状态时，就要去考虑pod内部是不是出问题了。还有就是当你有大量的pod时，它偶尔也会出现这种状态。





# 六、pod的控制器类型(5种)



## 6.1.1 Deployments无状态pod控制器

Deployment是我们生产当中最常用的，就是我们所说的无状态pod，一般给web服务器使用。Deployment为Pod和ReplicaSet提供声明式的更新能力。Deployment是ReplicaSet的更高级。

其生成的pod叫：xxx-dahfjdfjsbfs



## 6.1.2 StatefulSets有状态pod控制器

StatefulSets 是用来管理有状态应用的工作负载 API 对象。StatefulSets 用来管理某 Pod 集合的部署和扩缩， 并为这些 Pod 提供持久存储和持久标识符。

（1）其生成的pod叫：xxx-01

（2）需要指定servername



## 6.1.3 DaemonSet守护pod控制器

DaemonSet 确保全部（或者某些）节点上运行一个 Pod 的副本。

特点：

（1）当某个节点上运行了一个daemonset守护pod，它会自己在每个节点上都部署一个daemonset守护pod；

（2）当集群扩容，加入新的节点时，daemonset会继续在新的节点上部署daemonset守护pod；

（3）当集群缩容时，节点上的daemonset守护pod会默认回收；

（4）当整个集群删除时，所有节点上的daemonset守护pod都会回收。



daemonset守护pod运用场景：

（1）在每个节点上运行集群守护进程；

（2）在每个节点上运行日志收集守护进程（后面建立efk时，Fluentd就要用daemonset去建立）

（3）在每个节点上运行监控守护进程



## 6.1.4 jobs控制器

jobs控制器我们可以理解为功能性控制器。我们更多的用来写一些一次性的服务，比如一次性定时任务，当定时任务执行结束后，pod就会终止，不会再重启。



## 6.1.5 cronjob控制器

（1）周期性任务，像Linux的Crontab一样。

（2）应用场景：如通知，备份等





## 6.2 特点

### 6.2.1.Deployment控制器

适合部署无状态的应用服务，用来管理pod和replicaset，具有上线部署、副本设定、滚动更新、回滚等功能，还可提供声明式更新，例如只更新一个新的Image



### 6.2.2.StatefulSets控制器

```
1、适合部署有状态应用

2、解决Pod的独立生命周期，保持Pod启动顺序和唯一性

3、稳定，唯一的网络标识符，持久存储（例如：etcd配置文件，节点地址发生变化，将无法使用）

4、有序，优雅的部署和扩展、删除和终止（例如：mysql主从关系，先启动主，再启动从）

5、有序，滚动更新

6、应用场景：例如数据库
```



#### 无状态服务的特点：

```
1）deployment 认为所有的pod都是一样的
2）不用考虑顺序的要求
3）不用考虑在哪个node节点上运行
4）可以随意扩容和缩容
```



#### 有状态服务的特点：

```
1）实例之间有差别，每个实例都有自己的独特性，元数据不同，例如etcd，zookeeper
2）实例之间不对等的关系，以及依靠外部存储的应用。
```



#### 常规的service服务和无头服务的区别

```
service：一组Pod访问策略，提供cluster-IP群集之间通讯，还提供负载均衡和服务发现。

Headless service 无头服务，不需要cluster-IP，直接绑定具体的Pod的IP，无头服务经常用于statefulset的有状态部署
```



#### 相比于Deployment而言，StatefulSets是有身份的！（序列编号区分唯一身份）

```
身份三要素：
1、域名 nginx-statefulset-0.nginx
2、主机名 nginx-statefulset-0
3、存储(PVC)
```



#### StatefulSet的有序部署和有序伸缩

```
部署（即0到N-1）
有序收缩，有序删除（即从N-1到0）
无论是部署还是删除，更新下一个 Pod 前，StatefulSet 控制器终止每个 Pod 并等待它们变成 Running 和 Ready
```



### 6.2.3.DaemonSet控制器

- 在每一个Node上运行一个Pod
  新加入的Node也同样会自动运行一个Pod
- 应用场景：监控，分布式存储，日志收集等



### 6.2.4.job控制器

- 一次性执行任务，类似Linux中的job
- 应用场景：如离线数据处理，视频解码等业务



### 6.2.5.cronjob控制器

- 周期性任务，像Linux的Crontab一样。
- 应用场景：如通知，备份等





# 七、Service(三种通信模式，四种类型)

对于kubernetes整个集群来说，Pod的地址也可变的，也就是说如果一个Pod因为某些原因退出了，而由于其设置了副本数replicas大于1，那么该Pod就会在集群的任意节点重新启动，这个重新启动的Pod的IP地址与原IP地址不同，这对于业务来说，就不能根据Pod的IP作为业务调度。kubernetes就引入了Service的概念，它为Pod提供一个入口，主要通过Labels标签来选择后端Pod，这时候不论后端Pod的IP地址如何变更，只要Pod的Labels标签没变，那么 业务通过service调度就不会存在问题。



当声明Service的时候，会自动生成一个cluster IP，这个IP是虚拟IP。我们就可以通过这个IP来访问后端的Pod，当然，如果集群配置了DNS服务，比如现在的CoreDNS，那么也可以通过Service的名字来访问，它会通过DNS自动解析Service的IP地址。



**Service的通信模式有三种，user space，iptables，ipvs。**



**Service的类型有四种，Cluster IP，LoadBalance，NodePort，ExternalName。其中Cluster IP是默认的类型。**

（1）、Cluster IP：通过 集群内部IP暴露服务，默认是这个类型，选择该值，这个Service服务只能通过集群内部访问；

（2）、LoadBalance：使用云提供商的负载均衡器，可以向外部暴露服务，选择该值，外部的负载均衡器可以路由到NodePort服务和Cluster IP服务；

（3）、NodePort：顾名思义是Node基本的Port，如果选择该值，这个Service可以通过NodeIP:NodePort访问这个Service服务，NodePort会路由到Cluster IP服务，这个Cluster IP会通过请求自动创建；

（4）、ExternalName：通过返回 CNAME 和它的值，可以将服务映射到 externalName 字段的内容，没有任何类型代理被创建，可以用于访问集群内其他没有Labels的Pod，也可以访问其他NameSpace里的Service（通过域名解析的方式直接访问到服务上）。



# 八、代码热更新情况

**当两个nginxpod需要更新代码，比如更新版本，这时，你执行了更新命令apply，service是不会马上停止pod来更新，它是会等待进入nginxpod的访问流量到0，才会去更新，只要哪个到0了就会去更新哪一个，然后后续流量会到更新完的pod上，然后等待旧的pod流量到0，也将它更新，更新后，就又恢复到之前的状况，实现热更新。**





# 九、存活探针/就绪探针

在docker/k8s中只要容器主进程还在运行，他们会认为容器是健康的(Always)，所以在生产环境中我们有必要增加存活探针。默认没有增加就绪探针时k8s会立即把创建的pod加入endpoints，如果pod启动时间久(可提供服务)这时客户端会被拒绝访问，所以在生产环境中增加就绪探针是必须的。



探针技术是kubelet对容器执行的定期诊断。kubelet调用容器实现的处理器有三种类型：ExecAction、TCPSocketAction、HTTPGetAction。

- ExecAction：在容器内执行指定的命令，如果命令退出的时候返回码为0，就会认为是成功的。
- TCPSocketAction：对指定的端口上的容器的IP地址进行TCP检查。如果端口打开，则会认为是成功的。
- HTTPGetAction：对指定的端口和路径上的容器的IP地址执行GET请求，如果响应码大于等于200并且小于400，则会认为是成功的。

对于每次探测，都会出现三种结果：成功、失败和未知。

探测方案存在两种形式：

- LivenessProbe：指示容器是否在运行。如果探测失败，kubelet将会杀死容器。如果容器不提供探针，默认状态是Success。
- ReadinessProbe：指示容器是否准备好服务请求。如果探测失败，端点控制器将会从与Pod匹配的所有Service的端点中删除该Pod的IP地址。初始延迟之前的就绪状态默认为Failure。如果容器不提供探针，默认状态为Success。





# 十、Kubernetes创建一个Pod的主要流程

Kubernetes中创建一个Pod涉及多个组件之间联动，主要流程如下：

1. 客户端提交Pod的配置信息（可以是yaml文件定义的信息）到kube-apiserver。

2. Apiserver收到指令后，通知给controller-manager创建一个资源对象。

3. Controller-manager通过api-server将pod的配置信息存储到ETCD数据中心中。

4. Kube-scheduler检测到pod信息会开始调度预选，会先过滤掉不符合Pod资源配置要求的节
   点，然后开始调度调优，主要是挑选出更适合运行pod的节点，然后将pod的资源配置单发送到
   node节点上的kubelet组件上。

5. Kubelet根据scheduler发来的资源配置单运行pod，运行成功后，将pod的运行信息返回给
   scheduler，scheduler将返回的pod运行状况的信息存储到etcd数据中心。



# 十一、Kubernetes Pod的常见调度方式

Kubernetes中，Pod通常是容器的载体，主要有如下常见调度方式：

- Deployment或RC：该调度策略主要功能就是自动部署一个容器应用的多份副本，以及持续监控副
  本的数量，在集群内始终维持用户指定的副本数量。

- NodeSelector：定向调度，当需要手动指定将Pod调度到特定Node上，可以通过Node的标签
  （Label）和Pod的nodeSelector属性相匹配。

- NodeAffinity亲和性调度：亲和性调度机制极大的扩展了Pod的调度能力，目前有两种节点亲和力
  表达：

- requiredDuringSchedulingIgnoredDuringExecution：硬规则，必须满足指定的规则，调度器才
  可以调度Pod至Node上（类似nodeSelector，语法不同）。

- preferredDuringSchedulingIgnoredDuringExecution：软规则，优先调度至满足的Node的节
  点，但不强求，多个优先级规则还可以设置权重值。



Taints和Tolerations（污点和容忍）：

- Taint：使Node拒绝特定Pod运行；

- Toleration：为Pod的属性，表示Pod能容忍（运行）标注了Taint的Node。



# 十二、常用命令

![0](https://figure-bed-1304788733.cos.ap-guangzhou.myqcloud.com/typora/202207051213708.png)
