ReplicationController确保在任何时候都有特定数量的Pod副本处于运行状态,也叫作期望值,换句话说,ReplicationController确保一个Pod或一组同类的Pod总是可用的。ReplicationController的功能已经被ReplicaSet接管
现在推荐使用配置 ReplicaSet
的 Deployment
来建立副本管理机制。
ReplicationController如何工作
当Pod数量过多是,ReplicationController 会终止多余的 pod。当 pod 数量太少时,ReplicationController 将会启动新的 pod。 与手动创建的 pod 不同,由 ReplicationController 创建的 pod 在失败、被删除或被终止时会被自动替换。例如:在中断性维护(也就是当前Pod运行所在的服务器需要关机停止服务等操作)之后,Pod会在其他节点上重新创建。即使只需要一个Pod的时候,也应该使用ReplicationController来创建Pod。ReplicationController 类似于进程管理器,但是 ReplicationController 不是监控单个节点上的单个进程,而是监控跨多个节点的多个 pod。
ReplicationController 通常缩写为 “rc”,并作为 kubectl 命令的快捷方式。
简单的例子就是创建一个 ReplicationController 对象来可靠地无限期地运行 Pod 的一个实例。 复杂一点是运行一个多副本服务(如 web 服务器)的若干相同副本。
运行一个ReplicationController的实例
编写yaml文件
[root@node1 ~]# vim test.yml
apiVersion: v1
kind: ReplicationController
metadata:
name: nginx
spec:
replicas: 3
selector:
app: nginx
template:
metadata:
name: nginx
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.8
ports:
- containerPort: 80
运行模板
[root@node1 ~]# kubectl apply -f test.yml
replicationcontroller/nginx created
查看创建好的ReplicationController
这里查看Deployment是看不到的,因为是在不依赖与Deployment的情况下创建的
[root@node1 ~]# kubectl get rc
NAME DESIRED CURRENT READY AGE
nginx 3 3 3 99s
查看ReplicationController运行的Pod
[root@node1 ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx-9dtqf 1/1 Running 0 3m31s
nginx-mjnxc 1/1 Running 0 3m31s
nginx-t6sdn 1/1 Running 0 3m31s
查看详细信息,运行状态是没有问题的
[root@node1 ~]# kubectl describe rc nginx
Name: nginx
Namespace: default
Selector: app=nginx
Labels: app=nginx
Annotations: Replicas: 3 current / 3 desired
Pods Status: 3 Running / 0 Waiting / 0 Succeeded / 0 Failed
Pod Template:
Labels: app=nginx
Containers:
nginx:
Image: nginx:1.8
Port: 80/TCP
Host Port: 0/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal SuccessfulCreate 2m48s replication-controller Created pod: nginx-t6sdn
Normal SuccessfulCreate 2m48s replication-controller Created pod: nginx-mjnxc
Normal SuccessfulCreate 2m48s replication-controller Created pod: nginx-9dtqf
以机器可读的形式列出属于ReplicationController的所有pod,可以使用以下的命令
[root@node1 ~]# pods=$(kubectl get pods --selector=app=nginx --output=jsonpath={.items..metadata.name})
[root@node1 ~]# echo $pods
nginx-9dtqf nginx-mjnxc nginx-t6sdn
目前测试完成之后,可以将该ReplicationController删除
[root@node1 ~]# kubectl delete -f test.yml
ReplicationController的职责
ReplicationController 只需确保所需的 pod 数量与其标签选择器匹配,并且是可操作的。 目前,它的计数中只排除终止的 pod。有官方文档显示在未来,可能会考虑系统提供的就绪状态和其他信息,可能会对替换策略添加更多控制,计划发出事件,这些事件可以被外部客户端用来实现任意复杂的替换和/或缩减策略。
ReplicationController 永远被限制在这个狭隘的职责范围内。 它本身既不执行就绪态探测,也不执行活跃性探测。 它不负责执行自动缩放,而是由外部自动缩放器控制,后者负责更改其 replicas
字段值。不会向 ReplicationController 添加调度策略(例如,spreading)。 它也不应该验证所控制的 pod 是否与当前指定的模板匹配,因为这会阻碍自动调整大小和其他自动化过程。 类似地,完成期限、整理依赖关系、配置扩展和其他特性也属于其他地方。 甚至计划考虑批量创建 pod 的机制。
ReplicaSet
ReplicaSet是下一代的ReplicationController。二者的唯一区别就是选择器的支持,ReplicaSet支持新的基于集合的选择器需求,而ReplicationController仅支持基于相等选择器的需求。
怎样使用ReplicaSet
大多数支持ReplicationController的kubectl
命令也支持ReplicaSet。但rolling-update
命令例外。如果想要滚动更新在新版本中需要使用Deployment来调用。rolling-update
在现在的生产环境中是必须的,而Deployment是声明性的,所以建议使用rollout
或者rolling-update
来使用Deployment
虽然ReplicaSet可以独立使用,但现在它主要被Deployments用作协调Pod创建、删除和更新的机制。当使用Deployment时,不需要担心还要去管理Pod所创建的ReplicaSet。Deployment会去自动的管理各自的ReplicaSet。
什么时候使用ReplicaSet
ReplicaSet确保任何时间都有指定数量的Pod副本在运行。而Deployment是一个更高级的概念,他管理ReplicaSet,并向Pod提供声明式的更新以及许多其他有用的功能。所以建议在新版本使用Deployment,而不是直接使用ReplicaSet,除非需要自定义更新业务流程或者根本不需要更新。
也就是可能永远不需要操作ReplicaSet对象,而是使用Deployment。
ReplicaSet示例
编写yaml文件
[root@node1 ~]# vim frontend.yml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: frontend
labels:
app: guestbook # 可以定义多个标签
tier: frontend
spec:
replicas: 3
selector:
matchLabels:
tier: frontend # 标签选择器选择一个即可
template:
metadata:
labels:
tier: frontend
spec:
containers:
- name: php-redis # redis属于后端服务所以不暴露端口
image: redis
运行文件
[root@node1 ~]# kubectl apply -f frontend.yml
replicaset.apps/frontend created
运行完成后,与ReplicationController一样,同样不会运行Deployment,可以单独查看ReplicaSet
[root@node1 ~]# kubectl get rs
NAME DESIRED CURRENT READY AGE
frontend 3 3 2 58s
查看ReplicaSet的详细信息
[root@node1 ~]# kubectl describe rs frontend
Name: frontend
Namespace: default
Selector: tier=frontend
Labels: app=guestbook
tier=frontend
Annotations: Replicas: 3 current / 3 desired
Pods Status: 3 Running / 0 Waiting / 0 Succeeded / 0 Failed
Pod Template:
Labels: tier=frontend
Containers:
php-redis:
Image: redis
Port: <none>
Host Port: <none>
Environment: <none>
Mounts: <none>
Volumes: <none>
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal SuccessfulCreate 61m replicaset-controller Created pod: frontend-46lp8
Normal SuccessfulCreate 61m replicaset-controller Created pod: frontend-ng8n5
Normal SuccessfulCreate 61m replicaset-controller Created pod: frontend-zjjjm
其实和ReplicationController的详细信息没有多大的区别。唯一的区别是ReplicationController不支持多标签,而ReplicaSet支持多标签的选择
查看运行的Pod
[root@node1 ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
frontend-46lp8 1/1 Running 0 9h
frontend-ng8n5 1/1 Running 0 9h
frontend-zjjjm 1/1 Running 0 9h
删除ReplicaSet和它的Pod
要删除ReplicaSet和它的所有Pod,使用kubectl delete命令。默认情况下,会自动删除所有由这个ReplicaSet创建的所有Pod
[root@node1 ~]# kubectl delete rs frontend
replicaset.apps "frontend" deleted
只删除ReplicaSet
也可以指删除ReplicaSet,而保留它所拥有的Pod,方法是kubectl delete --cascade=false
一旦只删除ReplicaSet,而不删除Pod,就需要创建一个新的ReplicaSet来接替剩下的Pod。由于新旧ReplicaSet的标签选择器(spec.selector)是相同的,但是它不会努力使现有的Pod与新的、不同的模板匹配。想要以可控的方式将Pod更新到新的spec,就要使用滚动更新的方式。
Pod与ReplicaSet的隔离
可以通过改变标签来从 ReplicaSet 的目标集中移除 Pod。这种技术可以用来从服务中去除 Pod,以便进行排错、数据恢复等。 以这种方式移除的 Pod 将被自动替换(假设副本的数量没有改变)。