乔克叔叔的博客,公众号:运维开发故事

kubernetes控制器之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的滚动升级功能(但是不支持一键回滚,需要用相同的方法去修改镜像地址)
posted @ 2020-05-29 10:42  乔克爱运维  阅读(849)  评论(0编辑  收藏  举报