3.1 控制器——ReplicaSet

3. 控制器(Controller)

3.1 副本集(ReplicaSet)

定义:副本集(ReplicaSet)的目的是为了保证一组稳定的Pod副本在任意给定时刻都在运行。因此,它通常用于保证特定数量的相同Pod的可用性。

 副本集使用一些字段进行定义,这些字段包含了一个选择器(指定如何识别可以获取的pods)、一个数字(表示应该维持多少个副本)、一个Pod模板(pod template,指定了新的Pod的创建标准)。然后,复副本集将根据需要进行创建或删除pods以达到所需的数量,从而实现其目的。当副本集需要创建新的Pod时,就会使用Pod模板。

 副本集和Pod之间的链接是通过Pod的metadata.ownerReferences字段,该字段指定了当前对象是属于哪个资源的,正是通过这个链接,副本集才知道它所维护的pods的状态,并据此进行计划。一个副本集主要是通过使用选择器辨识新的Pod,如果一个Pod没有OwnerReference(所属资源)或者OwnerReference(所属资源)不是一个控制器,它一旦和副本集的选择器匹配上了,它将会被副本集立即获取。

 副本集(ReplicaSet)保证了特定数量的Pod副本在任意状态都是处于运行状态。然而,Deployment是一个相对比较高层次的概念,它负责管理副本集(ReplicaSet)以及提供对pods的声明性更新以及许多其他有用的功能。相对于直接使用副本集(ReplicaSets),更加推荐使用Deployments来操作,除非需要自定义更新业务流程、或者根本不需要更新。因为实际上可能从不需要操作副本集对象,所以从这个角度也是推荐使用Deployments来替换,在spec部分来定义应用。下面是直接创建副本集的一个实例:

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
        image: gcr.io/google_samples/gb-frontend:v3

下面的命令将上述的清单保存到frontend.yaml并将其提交给K8S集群,它会创建定义的副本集(ReplicaSet)和它所管理的Pod:

kubectl apply -f http://k8s.io/examples/controllers/frontend.yaml

注意yaml文件的缩进,很容易出错的,将上述的镜像改成我自己打包的镜像,或者在worker node上拉镜像再改名(我这里是后者):

docker pull registry.cn-shanghai.aliyuncs.com/hhu/gb-frontend:v3
docker tag registry.cn-shanghai.aliyuncs.com/hhu/gb-frontend:v3 gcr.io/google_samples/gb-frontend:v3
docker rmi registry.cn-shanghai.aliyuncs.com/hhu/gb-frontend:v3

查看当前部署的副本集(ReplicaSets):

kubectl get rs
# 本地结果
NAME                  DESIRED   CURRENT   READY   AGE
frontend              3         3         3       5m24s
curl-66959f6557       1         1         1       15d
jenkins-7958858b5d    1         1         1       11d
my-nginx-64fc468bd4   0         0         0       15d

可以看到刚刚创建的frontend(上述的镜像和配置文件国内是拉不下来的),也可以检查副本集(Replicaset)的状态:

# 查看frontend的状态
kubectl describe rs/frontend

# 结果
Name:         frontend
Namespace:    default
Selector:     tier=frontend
Labels:       app=guestbook
              tier=frontend
Annotations:  kubectl.kubernetes.io/last-applied-configuration:
                {"apiVersion":"apps/v1","kind":"ReplicaSet","metadata":{"annotations":{},"labels":{"app":"guestbook","tier":"frontend"},"name":"frontend",...
Replicas:     3 current / 3 desired
Pods Status:  3 Running / 0 Waiting / 0 Succeeded / 0 Failed
Pod Template:
  Labels:  tier=frontend
  Containers:
   php-redis:
    Image:        gcr.io/google_samples/gb-frontend:v3
    Port:         <none>
    Host Port:    <none>
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Events:
  Type    Reason            Age    From                   Message
  ----    ------            ----   ----                   -------
  Normal  SuccessfulCreate  4m26s  replicaset-controller  Created pod: frontend-chgz5
  Normal  SuccessfulCreate  4m26s  replicaset-controller  Created pod: frontend-lmqv7
  Normal  SuccessfulCreate  4m26s  replicaset-controller  Created pod: frontend-4mklc

查看Pod(有3个frontend的Pod):

# 查看Pod
kubectl get Pods

# 结果
NAME                       READY   STATUS    RESTARTS   AGE
curl-66959f6557-pn49b      1/1     Running   2          15d
frontend-4mklc             1/1     Running   0          5m4s
frontend-chgz5             1/1     Running   0          5m4s
frontend-lmqv7             1/1     Running   0          5m4s
jenkins-7958858b5d-27qlx   1/1     Running   1          11d

当然还可以验证这些Pod的owner reference是设置到了frontend副本集(ReplicaSet),可以通过获取某个运行的Pod的yaml文件查看:

# 查看frontend-4mklc的pod的yaml文件
kubectl get pods frontend-4mklc -o yaml

# 部分输出
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: "2019-04-28T06:27:56Z"
  generateName: frontend-
  labels:
    tier: frontend
  name: frontend-4mklc
  namespace: default
  ownerReferences:
  - apiVersion: apps/v1
    blockOwnerDeletion: true
    controller: true
    kind: ReplicaSet
    name: frontend
    uid: c2d0bc7c-697e-11e9-a84a-000c292a92cd
  resourceVersion: "3146592"
  selfLink: /api/v1/namespaces/default/pods/frontend-4mklc
  uid: c2e03103-697e-11e9-a84a-000c292a92cd
spec:
  containers:
  - image: gcr.io/google_samples/gb-frontend:v3
    imagePullPolicy: IfNotPresent
    name: php-redis
    resources: {}
    terminationMessagePath: /dev/termination-log
    terminationMessagePolicy: File
    volumeMounts:
    - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
      name: default-token-gb6cw
      readOnly: true
...

【采集非模板Pod】

 当创建裸仓(bare Pod)并没有问题,强烈推荐确保裸仓不要有和任何副本集(ReplicaSet)标签选择器匹配的,因为副本集(ReplicaSet)不限制模板指定哪些Pod属于该副本集——它可以以规定的方式获取其他的Pod,以之前的前端副本集为例,Pod在下面的清单中指定:

apiVersion: v1
kind: Pod
metadata:
  name: pod1
  labels:
    tier: frontend
spec:
  containers:
  - name: hello1
    image: registry.cn-shanghai.aliyuncs.com/hhu/hello-app:2.0

---

apiVersion: v1
kind: Pod
metadata:
  name: pod2
  labels:
    tier: frontend
spec:
  containers:
  - name: hello2
    image: registry.cn-shanghai.aliyuncs.com/hhu/hello-app:1.0

上述的Pod没有控制器作为它们的owner reference、没有匹配的前端副本集,假设在前端副本集已经部署了、并这个副本集已经被设置为它的初始化Pod的副本,然后创建了Pod,已经将这个Pod设置为初始Pod副本去填充必要的副本数量:kubectl apply -f http://k8s.io/examples/pods/pod-rs.yaml,新的Pod将会通过副本集(ReplicaSet)获取,然后然后立即终止,因为副本集会超过其所需的计数。注意这里的顺序是创建副本集–>再通过副本集创建Pod,如果先创建Pod(kubectl apply -f http://k8s.io/examples/pods/pod-rs.yaml),再创建副本集(kubectl apply -f http://k8s.io/examples/controllers/frontend.yaml),此时通过kubectl get Pods只会发现只有一个Pod。

【副本集RepicaSet清单】

 副本集也是K8S中的API对象,一个ReplicaSet需要apiVersionkind以及metadata字段,对于ReplicaSet,kind永远都仅仅是ReplicaSet,副本集也需要.spec

 Pod模板,.spec.template字段是Pod模板,它也需要标签,在之前的frontend.yaml栗子中,有一个标签tier: frontend,注意不要和其他控制器的标签选择器重叠,以免它们使用这个Pod,对于Pod模板的重启策略(restart policy字段.spec.template.spec.restartPolicy)只能指定为Always(这也是默认值)。

 Pod 标签选择器,即.spec.selector,用于辨识Pod,在之前的frontend.yaml栗子中,选择器位:

matchLabels:
	tier: frontend

在副本集(ReplicaSet)中,.spec.template.metadata.labels必须和spec.selector,否则会直接被API拒绝请求。注意:2个ReplicaSet指定相同的.spec.selector、但指定的.spec.template.metadata.labels.spec.template.spec字段不同,每个ReplicaSet会忽略其他ReplicaSet创建的pod。

副本:可以通过.spec.replicas设置多少个Pod应该并行运行,然后由副本集控制添加、删除Pod以满足这个数字,如果不指定,默认为1

【副本集的操作】

 ReplicaSet常见的行为有:

1.删除副本集以及由其创建的Pod

必须将下面的-d选项中的propagationPolicy设置为Background或者Foreground

kubectl proxy --port=8080
curl -X DELETE  'localhost:8080/apis/extensions/v1beta1/namespaces/default/replicasets/frontend' \
> -d '{"kind":"DeleteOptions","apiVersion":"v1","propagationPolicy":"Foreground"}' \
> -H "Content-Type: application/json"

2.仅仅删除副本集

必须将下面的propagationPolicy设置为Orphan

kubectl proxy --port=8080
curl -X DELETE  'localhost:8080/apis/extensions/v1beta1/namespaces/default/replicasets/frontend' \
> -d '{"kind":"DeleteOptions","apiVersion":"v1","propagationPolicy":"Orphan"}' \
> -H "Content-Type: application/json"

原始的副本集删除后,可以创建新的副本替换它并接管它之前创建的Pod,只要新的副本集中的.spec.selector和之前的一样就行,但新的副本集不会做出任何努力使现有的pod匹配新的、不同的pod模板。如果要升级Pod到新的,需要使用 rolling update。

3.将Pod从副本集中隔离

这里是需要修改Pod上的标签即可,以这种方式从副本集中隔离开来的Pod会自动被新的Pod替换。

4.对副本集进行伸缩

通过更新.spec.replicas可以轻松对副本集进行伸缩,ReplicaSet Controller将确保这个数量的Pod副本。

5.作为水平Pod自动定标器目标的副本集

副本集也可以是水平Pod自动分频器( Horizontal Pod Autoscalers-HPA)的目标,即副本集可以由hpa自动缩放,下面是栗子:

apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
  name: frontend-scaler
spec:
  scaleTargetRef:
    kind: ReplicaSet
    name: frontend
  minReplicas: 3
  maxReplicas: 10
  targetCPUUtilizationPercentage: 50

保存上述清单到hpa-rs.yaml并提交到K8S集群就会创建定义的HPA,它将根据复制的Pod的CPU使用情况自动缩放目标副本集kubectl apply -f https://k8s.io/examples/controllers/hpa-rs.yaml,还可以使用kubectl autoscale完成同样的事:kubectl autoscale rs frontend --max=10(这种方式更简单)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值