ReplicaSet
ReplicaSet
ReplicaSet简称RS,随着Kubernetes的高速发展,官方已经推荐我们使用RS和Deployment来代替RC了,实际上RS和RC的功能基本一致,目前唯一的一个区别就是RC只支持基于等式的selector(env=dev或environment!=qa),但RS还支持基于集合的selector,这对复杂的运维管理就非常方便了。
kubectl命令行工具中关于RC的大部分命令同样适用于我们的RS资源对象。不过我们也很少会去单独使用RS,它主要被Deployment这个更加高层的资源对象使用,除非用户需要自定义升级功能或根本不需要升级Pod,在一般情况下,我们推荐使用Deployment而不直接使用Replica Set。
下面我们简单定义一个ReplicaSet的YAML文件:
apiVersion: apps/v1 kind: ReplicaSet metadata: name: nginx-set labels: app: nginx spec: replicas: 2 selector: matchLabels: app: nginx template: metadata: name: nginx labels: app: nginx spec: containers: - name: nginx image: nginx:1.7.9
从这个YAML文件中,我们可以看到其定义了一个Pod标签为app:nginx的Pod的副本数为2。
然后创建一个YAML文件:
kubectl apply -f rs-myapp.yaml
然后查看ReplicaSet的状态:
[root@master rs]# kubectl get rs NAME DESIRED CURRENT READY AGE nginx-set 2 2 2 26s
然后看Pod的状态:
[root@master rs]# kubectl get pods NAME READY STATUS RESTARTS AGE nginx-set-n6dxl 1/1 Running 0 2m37s nginx-set-p2lxb 1/1 Running 0 2m37s
从上面可以看到,我们在YAML文件中定义了Pod template中定义了Pod的名字,但是我们在查看Pod的时候发现其并不是我们定义的Pod名,而是RS的名字加随机字符串。
除了以上,RS还支持水平扩缩和版本更新,对于水平扩缩,我们可以用kubectl scale和kubectl edit来直接修改,也可以修改上面定义的YAML文件再使用kubectl apply来使其生效。
我们使用kubectl edit来修改,使用这个修改会立即生效,如下:
kubectl edit rs nginx-set kind: ReplicaSet .... spec: replicas: 3 selector: ....
保存退出就会立即生效replicaset.extensions/nginx-set edited。然后我们查看Pod的数量:
replicaset.extensions/nginx-set edited [root@master rs]# kubectl get pods NAME READY STATUS RESTARTS AGE nginx-set-n6dxl 1/1 Running 0 10m nginx-set-p2lxb 1/1 Running 0 10m nginx-set-pz2mc 1/1 Running 0 33s
缩容的做法一样。我们也可以对镜像版本进行升级,修改方法同上,我们还是用kubectl edit来修改:
kubectl edit rs nginx-set .... spec: containers: - image: nginx:1.8 imagePullPolicy: IfNotPresent
如上我们将nginx的版本从1.7.9升级到1.8,我们这时查看RS的信息如下:
[root@master rs]# kubectl get rs nginx-set -o wide NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR nginx-set 3 3 3 14m nginx nginx:1.8 app=nginx
我们发现在RS层,nginx的版本已经更新了,但是正在运行的Pod里也已经更新了吗?我们kubectl describe一下pod,如下:
[root@master rs]# kubectl describe pod nginx-set-n6dxl ...... Controlled By: ReplicaSet/nginx-set Containers: nginx: Container ID: docker://68e20a9c102fa4385cf5fc082e9767dc5a6011020bc19a759f3f0a853389f7dc Image: nginx:1.7.9 ......
我们发现Pod的镜像版本还是1.7.9,并没有随着我们更新RS而立即更新Pod。这是因为在RS控制器下,Pod不会自己去创建删除,也就是不会滚动更新,要实现滚动更新就要用Kubernetes的另外一个控制器:Deployment。那么对于RS控制器来说,我们想升级Pod的镜像应该怎么做呢?
我们可以删除Pod,然后通过RS控制器再新创建一个Pod,这时候的Pod版本就会更新,如下:
[root@master rs]# kubectl delete pod nginx-set-n6dxl pod "nginx-set-n6dxl" deleted
然后我们查看通过RS控制器新创建的Pod的nginx版本信息,如下:
[root@master rs]# kubectl describe pod nginx-set-znlcl ...... Containers: nginx: Container ID: docker://2005822f90324cc33478002fcf2bec82d1f1efc5671d688d5913d04e17df6811 Image: nginx:1.8 .......
我们看到nginx的版本已经更新了,其他的Pod版本还是1.7.9。
这种版本更新需要大量的人为干预,这不符合我们期望,所以Kubernetes就推出了另外一个控制器Deployment,它是工作在RS之上的,除了有RS的功能之外,还有滚动更新等功能。
最后我们总结下关于RC/RS的一些特性和作用:
- 大部分情况下,我们可以通过定义一个RC实现的Pod的创建和副本数量的控制
- RC中包含一个完整的Pod定义模块(不包含apiversion和kind)
- RC是通过label selector机制来实现对Pod副本的控制的
- 通过改变RC里面的Pod副本数量,可以实现Pod的扩缩容功能
- 通过改变RC里面的Pod模板中镜像版本,可以实现Pod的滚动升级功能(但是不支持一键回滚,需要用相同的方法去修改镜像地址)