目录
1.2、Pod 是 Kubernetes 的基础单元,Pod 启动典型创建过程如下: 工作机制 ****
1.4、Predicate 有一系列的常见的算法可以使用: **
1.5、 优先级由一系列键值对组成,键是该优先级项的名称,值是它的权重(该项的重要性)。有一系列的常见的优先级选项包括:
Kubernetes 是通过 List-Watch **** 的机制进行每个组件的协作,保持数据同步的,每个组件之间的设计实现了解耦。
用户是通过 kubectl 根据配置文件,向 APIServer 发送命令,在 Node 节点上面建立 Pod 和 Container。
APIServer 经过 API 调用,权限控制,调用资源和存储资源的过程,实际上还没有真正开始部署应用。这里 需要 Controller Manager、Scheduler 和 kubelet 的协助才能完成整个部署过程。
在 Kubernetes 中,所有部署的信息都会写到 etcd 中保存。实际上 etcd 在存储部署信息的时候,会发送 Create 事件给 APIServer,而 APIServer 会通过监听(Watch)etcd 发过来的事件。其他组件也会监听(Watch)APIServer 发出来的事件。

#注意:在创建 Pod 的工作就已经完成了后,为什么 kubelet 还要一直监听呢?原因很简单,假设这个时候 kubectl 发命令,要扩充 Pod 副本数量,那么上面的流程又会触发一遍,kubelet 会根据最新的 Pod 的部署情况调整 Node 的资源。又或者 Pod 副本数量没有发生变化,但是其中的镜像文件升级了,kubelet 也会自动获取最新的镜像文件并且加载。
Scheduler 是 kubernetes 的调度器,主要的任务是把定义的 pod 分配到集群的节点上。其主要考虑的问题如下:
Sheduler 是作为单独的程序运行的,启动之后会一直监听 APIServer,获取 spec.nodeName 为空的 pod,对每个 pod 都会创建一个 binding,表明该 pod 应该放到哪个节点上。
调度分为几个部分:首先是过滤掉不满足条件的节点,这个过程称为预算策略(predicate);然后对通过的节点按照优先级排序,这个是优选策略(priorities);最后从中选择优先级最高的节点。如果中间任何一步骤有错误,就直接返回错误。
如果在 predicate 过程中没有合适的节点,pod 会一直在 pending 状态,不断重试调度,直到有节点满足条件。 经过这个步骤,如果有多个节点满足条件,就继续 priorities 过程:按照优先级大小对节点排序。
通过算法对所有的优先级项目和权重进行计算,得出最终的结果。

这些调度约束可以根据业务需求和集群配置进行灵活的设置,以实现对Pod调度的控制和优化。
pod.spec.nodeName 将 Pod 直接调度到指定的 Node 节点上,会跳过 Scheduler 的调度策略,该匹配规则是强制匹配
- apiVersion: apps/v1
- kind: Deployment
- metadata:
- name: myapp
- spec:
- replicas: 3
- selector:
- matchLabels:
- app: myapp
- template:
- metadata:
- labels:
- app: myapp
- spec:
- nodeName: node02
- containers:
- - name: myapp
- image: nginx
- ports:
- - containerPort: 80
- ~

创建完成


由上可看出全部都在节点node02
查看详细事件(发现未经过 scheduler 调度分配)

pod.spec.nodeSelector:通过 kubernetes 的 label-selector 机制选择节点,由调度器调度策略匹配 label,然后调度 Pod 到目标节点,该匹配规则属于强制约束
- kubectl label --help
- Usage:
- kubectl label [--overwrite] (-f FILENAME | TYPE NAME) KEY_1=VAL_1 ... KEY_N=VAL_N [--resource-version=version] [options]
kubectl get node
给对应的 node 设置标签分别为 kgc=a 和 kgc=b

- apiVersion: apps/v1
- kind: Deployment
- metadata:
- labels:
- app myapp1
- name: myapp1
-
- spec:
- replicas: 3
- selector:
- matchLabels:
- app: myapp1
- template:
- metadata:
- labels:
- app: myapp1
- spec:
- nodeSelector:
- kgc: a
- containers:
- - name: myapp1
- image: nginx
- ports:
- - containerPort: 80
-
- ~


创建

kubectl get pod -o wide

查看详细事件(通过事件可以发现要先经过 scheduler 调度分配)


修改一个 label 的值,需要加上 --overwrite 参数
kubectl label nodes node01 kgc=c --overwrite

删除一个 label,只需在命令行最后指定 label 的 key 名并与一个减号相连即可:
kubectl label nodes node02 kgc-

指定标签查询 node 节点
kubectl get node -l kgc=c

亲和性
官网:
https://kubernetes.io/zh/docs/concepts/scheduling-eviction/assign-pod-node/
节点亲和性
- pod.spec.nodeAffinity
- ●preferredDuringSchedulingIgnoredDuringExecution:软策略
- ●requiredDuringSchedulingIgnoredDuringExecution:硬策略
Pod 亲和性
pod.spec.affinity.podAffinity/podAntiAffinity
●preferredDuringSchedulingIgnoredDuringExecution:软策略
●requiredDuringSchedulingIgnoredDuringExecution:硬策略
可以把自己理解成一个Pod,当你报名来学云计算,如果你更倾向去zhangsan老师带的班级,把不同老师带的班级当作一个node的话,这个就是节点亲和性。如果你是必须要去zhangsan老师带的班级,这就是硬策略;而你说你想去并且最好能去zhangsan老师带的班级,这就是软策略。
如果你有一个很好的朋友叫lisi,你倾向和lisi同学在同一个班级,这个就是Pod亲和性。如果你一定要去lisi同学在的班级,这就是硬策略;而你说你想去并且最好能去lisi同学在的班级,这就是软策略。软策略是不去也可以,硬策略则是不去就不行。
/键值运算关系
实验:
硬策略:
requiredDuringSchedulingIgnoredDuringExecution
- mkdir /opt/affinity
- cd /opt/affinity
-
- vim pod1.yaml
- apiVersion: v1
- kind: Pod
- metadata:
- name: affinity
- labels:
- app: node-affinity-pod
- spec:
- containers:
- - name: with-node-affinity
- image: soscscs/myapp:v1
- affinity:
- nodeAffinity:
- requiredDuringSchedulingIgnoredDuringExecution:
- nodeSelectorTerms:
- - matchExpressions:
- - key: kubernetes.io/hostname #指定node的标签
- operator: NotIn #设置Pod安装到kubernetes.io/hostname的标签值不在values列表中的node上
- values::
- - node02
-

可以通过该命令进行命令以及格式的查询

创建完成


一共两个节点,不能在node02上只有在node01上

如果硬策略不满足条件,Pod 状态一直会处于 Pending 状态。
kubectl delete pod --all && kubectl apply -f pod1.yaml && kubectl get pods -o wide
软策略
preferredDuringSchedulingIgnoredDuringExecution
- apiVersion: v1
- kind: Pod
- metadata:
- name: affinity01
- labels:
- app: node-affinity-pod
- spec:
- containers:
- - name: with-node-affinity
- image: nginx
- affinity:
- nodeAffinity:
- preferredDuringSchedulingIgnoredDuringExecution:
- - weight: 1 #如果有多个软策略选项的话,权重越大,优先级越高
- preference:
- matchExpressions:
- - key: kubernetes.io/hostname
- operator: In
- values:
- - node03
软策略创建在node03节点上,但因为没有node03节点,也可以在其他节点创建
由下面可以看出来在node02节点创建,

把values:的值改成node01,则会优先在node01上创建Pod
kubectl delete pod --all && kubectl apply -f pod2.yaml && kubectl get pods -o wide


也可以通过标签来选择在那个节点上创建
如果把硬策略和软策略合在一起使用,则要先满足硬策略之后才会满足软策略
- apiVersion: v1
- kind: Pod
- metadata:
- name: affinity04
- labels:
- app: node-affinity-pod
- spec:
- containers:
- - name: with-node-affinity
- image: nginx
- ports:
- - name: http
- containerPort: 80
- affinity:
- nodeAffinity:
- requiredDuringSchedulingIgnoredDuringExecution: #先满足硬策略,排除有kubernetes.io/hostname=node02标签的节点
- nodeSelectorTerms:
- - matchExpressions:
- - key: kubernetes.io/hostname
- operator: In
- values:
- - node02
- preferredDuringSchedulingIgnoredDuringExecution: #再满足软策略,优先选择有kgc=a标签的节点
- - weight: 100
- preference:
- matchExpressions:
- - key: kgc
- operator: In
- values:
- - c
- ~
node01标签为kgc=c

创建成功

硬策略与软策略(优先级设最高),但该是硬策略优先

Pod亲和性与反亲和性
| 调度策略 | 匹配标签 | 操作符 | 拓扑域支持 | 调度目标 |
| nodeAffinity | 主机 | In, NotIn, Exists,DoesNotExist, Gt, Lt | 否 | 指定主机 |
| podAffinity | Pod | In, NotIn, Exists,DoesNotExist | 是 | Pod与指定Pod同一拓扑域 |
| podAntiAffinity | Pod | In, NotIn, Exists,DoesNotExist | 是 | Pod与指定Pod不在同一拓扑域 |

创建一个标签为 app=myapp01 的 Pod
- apiVersion: v1
- kind: Pod
- metadata:
- name: myapp01
- labels:
- app: myapp01
- spec:
- containers:
- - name: with-node-affinity
- image: nginx
-
创建


myapp01在node01节点上
使用 Pod 亲和性调度,创建多个 Pod 资源
- apiVersion: v1
- kind: Pod
- metadata:
- name: myapp02
- labels:
- app: myapp02
- spec:
- containers:
- - name: myapp02
- image: nginx
- affinity:
- podAffinity:
- requiredDuringSchedulingIgnoredDuringExecution:
- - namespaces:
- - default
- topologyKey: kgc
- labelSelector:
- matchExpressions:
- - key: app
- operator: In
- values:
- - myapp01
创建完成:

由下可知,node01和node02不是同一个域,所以不能通过调度算法 进行创建,只能在node01节点上创建,

若件变迁切换为一样的,

由于node02节点资源创建的东西多,通过调度算法会有现在node01上创建

调度算法随机分配
