在Kubernetes上,很少会直接创建一个Pod,在大多数情况下,会通过RC、Deployment、DaemonSet、Job等控制器完成对一组Pod副本的创建、调度和整个生命周期的自动化控制。
在最早的Kubernetes版本里没有这么多Pod副本控制器的,只有一 个Pod副本控制器RC(Replication Controller),这个控制器是这样设计 实现的:RC独立于所控制的Pod,并通过Label标签这个松耦合关联关系 控制目标Pod实例的创建和销毁,随着Kubernetes的发展,RC也出现了新的继任者Deployment,用于更加自动地完成Pod副本的部署、版 本更新、回滚等功能。
严谨地说,RC的继任者其实并不是Deployment,而是ReplicaSet, 因为ReplicaSet进一步增强了RC标签选择器的灵活性。之前RC的标签选择器只能选择一个标签,而ReplicaSet拥有集合式的标签选择器,可以选择多个Pod标签,如下所示
selector:
matchLables:
tier: frontend
matchExpressions:
- {key: tier, operator: In, values: [frontend]}
与RC不同,ReplicaSet被设计成能控制多个不同标签的Pod副本。 一种常见的应用场景是,应用MyApp目前发布了v1与v2两个版本,用户 希望MyApp的Pod副本数保持为3个,可以同时包含v1和v2版本的Pod, 就可以用ReplicaSet来实现这种控制,写法如下
selector:
matchLables:
version: v2
matchExpressions:
- {key: version, operator: In, values: [v1,v2]}
Kubernetes的滚动升级就是巧妙运用ReplicaSet的这个特性来实现的,同时,Deployment也是通过ReplicaSet来实现Pod副本自动控制功能的。我们不应该直接使用底层的ReplicaSet来控制Pod副本,而应该 使用管理ReplicaSet的Deployment对象来控制副本,这是来自官方的建议。
全自动调度的控制器是Deployment或RC,Deployment或RC的主要功能之一就是自动部署一个容器应用的 份副本,以及持续监控副本的数量,在集群内始终维持用户指定的副本数量。
下面是一个Deployment配置的例子,使用这个配置文件可以创建一个ReplicaSet,这个ReplicaSet会创建3个Nginx应用的Pod
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
运行kubectl create命令创建这个Deployment
# kubectl apply -f nginx-deployment.yaml
deployment.apps/nginx-deployment created
查看Deployment、RS、Pod的状态
# kubectl get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 3/3 3 3 58s
# kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-deployment-7bffc778db 3 3 3 85s
# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-deployment-7bffc778db-j5czg 1/1 Running 0 1m34s
nginx-deployment-7bffc778db-lbpjg 1/1 Running 0 1m34s
nginx-deployment-7bffc778db-zcn6m 1/1 Running 0 1m34s
从调度策略上来说,这3个Nginx Pod由系统全自动完成调度。它们各自最终运行在哪个节点上,完全由Master的Scheduler经过一系列算法计算得出,用户无法干预调度过程和结果。
# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-deployment-7bffc778db-j5czg 1/1 Running 0 3m36s 172.20.3.229 k8s-node-1 <none> <none>
nginx-deployment-7bffc778db-lbpjg 1/1 Running 0 3m36s 172.20.4.27 k8s-node-2 <none> <none>
nginx-deployment-7bffc778db-zcn6m 1/1 Running 0 3m36s 172.20.5.203 k8s-node-3 <none> <none>
定向调度通过NodeSelector标签实现, Master上的Scheduler服务(kube-scheduler进程)负责实现Pod的调度,整个调度过程通过执行一系列复杂的算法,最终为每个Pod都计算出一个最佳的目标节点,这一过程是自动完成的,通常我们 无法知道Pod最终会被调度到哪个节点上。在实际情况下,也可能需要将Pod调度到指定的一些Node上,可以通过Node的标签(Label)和Pod的nodeSelector属性相匹配,来达到上述目的。
首先通过kubectl label命令给目标Node打上一些标签
# kubectl label nodes k8s-node-1 zone=north
然后,在Pod的定义中加上nodeSelector的设置,以redismaster-controller.yaml为例
apiVersion: v1
kind: ReplicationController
metadata:
name: redis-master
labels:
name: redis-master
spec:
replicas: 1
selector:
name: redis-master
template:
metadata:
labels:
name: redis-master
spec:
containers:
- name: master
image: redis
ports:
- containerPort: 6379
nodeSelector:
zone: north
创建Pod,scheduler就会将该Pod调度到拥有zone=north标签的Node上
如果我们给多个Node都定义了相同的标签(例如zone=north),则scheduler会根据调度算法从这组Node中挑选一个可用的Node进行Pod调度。
通过基于Node标签的调度方式,我们可以把集群中具有不同特点的Node都贴上不同的标签,例 如role=frontend、role=backend``、role=database等标签,在部署应用时就可以根据应用的需求设置NodeSelector来进行指定Node范围的调度。
如果我们指定了Pod的nodeSelector条件,且在集群中不存在包含相应标签的Node,则即使在集群中还有其他可供使用的Node,这个Pod也无法被成功调度。
除了用户可以自行给Node添加标签,Kubernetes也会给Node预定义 一些标签,包括
也可以使用这些系统标签进行Pod的定向调度。
NodeSelector通过标签的方式,简单实现了限制Pod所在节点的方法。亲和性调度机制则极大扩展了Pod的调度能力,主要的增强功能如 下。
PodPod的标签来进行限制,而非节点本身的标签。这样就可以定义一种规则来描述Pod之间的亲和或互斥关系亲和性调度功能包括节点亲和性NodeAffinity和Pod亲和性PodAffinity两个维度的设置。节点亲和性与NodeSelector类似,增 强了上述前两点优势;Pod的亲和与互斥限制则通过Pod标签而不是节点标签来实现,也就是上面所陈述的方式,同时具有前两点提到的优点。
NodeSelector将会继续使用,随着节点亲和性越来越能够表达nodeSelector的功能,最终NodeSelector会被废弃。
文章参考来源:《kubernetes权威指南-第4版》
原文:https://www.cnblogs.com/ssgeek/p/12731621.html