赞
踩
我们在定义pod资源时,可以直接创建一个kind:Pod类型的自主式pod,但是这存在一个问题,假如pod被删除了,那这个pod就不能自我恢复,就会彻底被删除,线上这种情况非常危险,所以今天就给大家讲解下pod的控制器,所谓控制器就是能够管理pod,监测pod运行状况,当pod发生故障,可以自动恢复pod。也就是说能够代我们去管理pod中间层,并帮助我们确保每一个pod资源始终处于我们所定义或者我们所期望的目标状态,一旦pod资源出现故障,那么控制器会尝试重启pod或者里面的容器,如果一直重启有问题的话那么它可能会基于某种策略来进行重新布派或者重新编排;如果pod副本数量低于用户所定义的目标数量,它也会自动补全;如果多余,也会自动终止pod资源。
ReplicaSet是kubernetes中的一种副本控制器,简称rs,主要作用是控制由其管理的pod,使pod副本的数量始终维持在预设的个数。它的主要作用就是保证一定数量的Pod能够在集群中正常运行,它会持续监听这些Pod的运行状态,在Pod发生故障时重启pod,pod数量减少时重新运行新的 Pod副本。官方推荐不要直接使用ReplicaSet,用Deployments取而代之,Deployments是比ReplicaSet更高级的概念,它会管理ReplicaSet并提供很多其它有用的特性,最重要的是Deployments支持声明式更新,声明式更新的好处是不会丢失历史变更。所以Deployment控制器不直接管理Pod对象,而是由 Deployment 管理ReplicaSet,再由ReplicaSet负责管理Pod对象。
Replicaset核心作用在于代用户创建指定数量的pod副本,并确保pod副本一直处于满足用户期望的数量, 起到多退少补的作用,并且还具有自动扩容缩容等机制。
Replicaset控制器主要由三个部分组成:
1、用户期望的pod副本数:用来定义由这个控制器管控的pod副本有几个
2、标签选择器:选定哪些pod是自己管理的,如果通过标签选择器选到的pod副本数量少于我们指定的数量,需要用到下面的组件
3、pod资源模板:如果集群中现存的pod数量不够我们定义的副本中期望的数量怎么办,需要新建pod,这就需要pod模板,新建的pod是基于模板来创建的。
2、 Replicaset资源清单文件编写技巧
#查看定义Replicaset资源需要的字段有哪些?
[root@master1 ~]# kubectl explain rs
KIND: ReplicaSet
VERSION: apps/v1
DESCRIPTION:
ReplicaSet ensures that a specified number of pod replicas are running at
any given time.
FIELDS:
apiVersion <string> #当前资源使用的api版本,跟VERSION: apps/v1保持一致
kind <string> #资源类型,跟KIND: ReplicaSet保持一致
metadata <Object> #元数据,定义Replicaset名字的
spec <Object> ##定义副本数、定义标签选择器、定义Pod模板
status <Object> #状态信息,不能改
查看replicaset的spec字段如何定义?
[root@master1 ~]# kubectl explain rs.spec
KIND: ReplicaSet
VERSION: apps/v1
RESOURCE: spec <Object>
DESCRIPTION:
Spec defines the specification of the desired behavior of the ReplicaSet.
More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
ReplicaSetSpec is the specification of a ReplicaSet.
FIELDS:
minReadySeconds <integer>
replicas <integer> #定义的pod副本数,根据我们指定的值创建对应数量的pod
selector <Object> -required- #用于匹配pod的标签选择器
template <Object> #定义Pod的模板,基于这个模板定义的所有pod是一样的
查看replicaset的spec.template字段如何定义?
对于template而言,其内部定义的就是pod,pod模板是一个独立的对象
[root@master1 ~]# kubectl explain rs.spec.template
KIND: ReplicaSet
VERSION: apps/v1
RESOURCE: template <Object>
DESCRIPTION:
Template is the object that describes the pod that will be created if
insufficient replicas are detected。PodTemplateSpec describes the data a pod should have when created from a
template
FIELDS:
metadata <Object>
spec <Object>
[root@master1 ~]# kubectl explain rs.spec.template.spec
上面可以看到,ReplicaSet资源中有两个spec字段。第一个spec声明的是ReplicaSet定义多少个Pod副本(默认将仅部署1个Pod)、匹配Pod标签的选择器、创建pod的模板。第二个spec是spec.template.spec:主要用于Pod里的容器属性等配置。
.spec.template里的内容是声明Pod对象时要定义的各种属性,所以这部分也叫做PodTemplate(Pod模板)。还有一个值得注意的地方是:在.spec.selector中定义的标签选择器必须能够匹配到spec.template.metadata.labels里定义的Pod标签,否则Kubernetes将不允许创建ReplicaSet。
3、Replicaset使用案例:部署Guestbook留言板
[root@master1 replicaset]# vim replicaset.yaml [root@master1 replicaset]# cat replicaset.yaml apiVersion: apps/v1 kind: ReplicaSet metadata: name: forntend labels: app: guestbook tier: frontend spec: replicas: 3 selector: matchLabels: tier: frontend template: metadata: labels: tier: frontend spec: containers: - name: php-redis image: yecc/gcr.io-google_samples-gb-frontend:v3 imagePullPolicy: IfNotPresent [root@master1 replicaset]# kubectl apply -f replicaset.yaml replicaset.apps/forntend created #pod的名字是由控制器的名字-随机数组成的 [root@master1 replicaset]# kubectl get pods NAME READY STATUS RESTARTS AGE forntend-4vtcp 1/1 Running 0 73s forntend-8jqtt 1/1 Running 0 73s forntend-bpfck 1/1 Running 0 73s [root@master1 replicaset]# kubectl get rs NAME DESIRED CURRENT READY AGE forntend 3 3 3 84s
#资源清单详细说明
apiVersion: apps/v1 #ReplicaSet 这个控制器属于的核心群组 kind: ReplicaSet #创建的资源类型 metadata: name: frontend #控制器的名字 labels: app: guestbook tier: frontend spec: replicas: 3 #管理的pod副本数量 selector: matchLabels: tier: frontend #管理带有tier=frontend标签的pod template: #定义pod的模板 metadata: labels: tier: frontend #pod标签,一定要有,这样上面控制器就能找到它要管理的pod是哪些了 spec: containers: #定义pod里运行的容器 - name: php-redis #定义容器的名字 image: yecc/gcr.io-google_samples-gb-frontend:v3 ports: #定义端口 - name: http #定义容器的名字 containerPort: 80 #定义容器暴露的端口
4、Replicaset管理pod:扩容、缩容、更新
Replicaset实现pod的动态扩容
ReplicaSet最核心的功能是可以动态扩容和回缩,如果我们觉得两个副本太少了,想要增加,只需要修改配置文件replicaset.yaml里的replicas的值即可,原来replicas: 3,现在变成replicaset: 4,修改之后,执行如下命令更新:
[root@master1 replicaset]# vim replicaset.yaml
[root@master1 replicaset]# cat replicaset.yaml | grep replicas
replicas: 4
[root@master1 replicaset]# vim replicaset.yaml
[root@master1 replicaset]# kubectl apply -f replicaset.yaml
replicaset.apps/forntend configured
[root@master1 replicaset]# kubectl get rs
NAME DESIRED CURRENT READY AGE
forntend 4 4 4 5m2s
[root@master1 replicaset]# kubectl get pods
NAME READY STATUS RESTARTS AGE
forntend-4vtcp 1/1 Running 0 5m6s
forntend-8jqtt 1/1 Running 0 5m6s
forntend-bpfck 1/1 Running 0 5m6s
forntend-zt2jn 1/1 Running 0 10s
也可以直接编辑控制器实现扩容
kubectl edit rs frontend #这个是我们把请求提交给了apiserver,实时修改
[root@master1 replicaset]# kubectl edit rs forntend
replicaset.apps/forntend edited
把上面的spec下的replicas 后面的值改成5,保存退出
[root@master1 replicaset]# kubectl get rs
NAME DESIRED CURRENT READY AGE
forntend 5 5 5 8m4s
[root@master1 replicaset]# kubectl get pods
NAME READY STATUS RESTARTS AGE
forntend-4vtcp 1/1 Running 0 8m7s
forntend-8jqtt 1/1 Running 0 8m7s
forntend-bpfck 1/1 Running 0 8m7s
forntend-glhdg 1/1 Running 0 34s
forntend-zt2jn 1/1 Running 0 3m11s
Replicaset实现pod的动态缩容
如果我们觉得5个Pod副本太多了,想要减少,只需要修改配置文件replicaset.yaml里的replicas的值即可,把replicaset:4变成replicas: 2,修改之后,执行如下命令更新:
[root@master1 replicaset]# vim replicaset.yaml [root@master1 replicaset]# cat replicaset.yaml | grep replicas replicas: 2 [root@master1 replicaset]# kubectl apply -f replicaset.yaml replicaset.apps/forntend configured [root@master1 replicaset]# kubectl get rs NAME DESIRED CURRENT READY AGE forntend 2 2 2 9m52s [root@master1 replicaset]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES forntend-8jqtt 1/1 Running 0 13m 10.1.104.36 node2 <none> <none> forntend-bpfck 1/1 Running 0 13m 10.1.166.174 node1 <none> <none> [root@master1 replicaset]# kubectl get rs -o wide NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR forntend 2 2 2 13m php-redis yecc/gcr.io-google_samples-gb-frontend:v2 tier=frontend [root@master1 replicaset]# curl 10.1.104.36 <html ng-app="redis"> <head> <title>Guestbook</title> <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css"> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.12/angular.min.js"></script> <script src="controllers.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.13.0/ui-bootstrap-tpls.js"></script> </head> <body ng-controller="RedisCtrl"> <div style="width: 50%; margin-left: 20px"> <h2>Guestbook</h2> <form> <fieldset> <input ng-model="msg" placeholder="Messages" class="form-control" type="text" name="input"><br> <button type="button" class="btn btn-primary" ng-click="controller.onRedis()">Submit</button> </fieldset> </form> <div> <div ng-repeat="msg in messages track by $index"> {{msg}} </div> </div> </div> </body> </html>
Replicaset实现pod的更新
修改镜像image: yecc/gcr.io-google_samples-gb-frontend:v3变成- image: ikubernetes/myapp:v2,修改之后保存退出
[root@master1 replicaset]# kubectl edit rs forntend
replicaset.apps/forntend edited
[root@master1 replicaset]# kubectl get rs -o wide
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR
forntend 2 2 1 27m php-redis ikubernetes/myapp:v2 tier=frontend
#上面可以看到镜像变成了ikubernetes/myapp:v2,说明滚动升级成功了
[root@master1 replicaset]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
forntend-8jqtt 1/1 Running 0 18m 10.1.104.36 node2 <none> <none>
forntend-bpfck 1/1 Running 0 18m 10.1.166.174 node1 <none> <none>
[root@master1 replicaset]# curl 10.1.104.36 <html ng-app="redis"> <head> <title>Guestbook</title> <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css"> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.12/angular.min.js"></script> <script src="controllers.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.13.0/ui-bootstrap-tpls.js"></script> </head> <body ng-controller="RedisCtrl"> <div style="width: 50%; margin-left: 20px"> <h2>Guestbook</h2> <form> <fieldset> <input ng-model="msg" placeholder="Messages" class="form-control" type="text" name="input"><br> <button type="button" class="btn btn-primary" ng-click="controller.onRedis()">Submit</button> </fieldset> </form> <div> <div ng-repeat="msg in messages track by $index"> {{msg}} </div> </div> </div> </body> </html>
#上面可以看到虽然镜像已经更新了,但是原来的pod使用的还是之前的镜像,新创建的pod才会使用最新的镜像
删除一个pod,让replicaset新建一个pod资源
[root@master1 replicaset]# kubectl delete pods forntend-8jqtt
pod "forntend-8jqtt" deleted
[root@master1 replicaset]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
forntend-75cg6 1/1 Running 0 26s 10.1.104.39 node2 <none> <none>
forntend-bpfck 1/1 Running 0 28m 10.1.166.174 node1 <none>
#新生成的pod的镜像已经变成了myapp的,说明更新完成了
[root@master1 replicaset]# curl 10.1.104.39
Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a>
如果我们直接修改replicaset.yaml文件,把image: yecc/gcr.io-google_samples-gb-frontend:v3变成- image: ikubernetes/myapp:v2
kubectl apply -f replicaset.yaml
发现原来的pod还是用的frontend:v3这个镜像,没有实现自动更新
生产环境如果升级,可以删除一个pod,观察一段时间之后没问题再删除另一个pod,但是这样需要人工干预多次;实际生产环境一般采用蓝绿发布,原来有一个rs1,再创建一个rs2(控制器),通过修改service标签,修改service可以匹配到rs2的控制器,这样才是蓝绿发布,这个也需要我们精心的部署规划,我们有一个控制器就是建立在rs之上完成的,叫做Deployment
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。