理解Kubernetes中rc是什么

Kubernetes-rc

Kubernetes 滚动更新及回滚

当集群中的某个服务需要升级时,我们需要停止目前与该服务相关的所有Pod,然后重新拉取镜像并启动。如果集群规模比较大,则这个工作就变成了一个挑战,而且先全部停止然后逐步升级的方式会导致长时间的服务不可用。Kubernetes提供了rolling-update滚动升级功能来解决上述问题

滚动升级通过执行kubectl rolling-update命令一键完成,该命令创建了一个新的RC,然后自动控制旧的RC中的Pod副本数量逐渐减少到0,同时新的RC中的Pod副本的数量从0逐步增加到目标值,最终实现了Pod的升级。系统会要求新的RC和旧的RC在相同的命名空间下

创建演示文件

apiVersion: apps/v1beta2
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.13.0-alpine
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
        
创建
[root@kubernetes-m media]# kubectl create -f pod.yaml --record
deployment.apps/nginx created

已运行的Pod副本数量有3个
[root@kubernetes-m media]# kubectl get pod -A | grep nginx
default       nginx-74c749db5-2kjz6                  1/1     Running   0          52s
default       nginx-74c749db5-492fj                  1/1     Running   0          52s
default       nginx-74c749db5-qv27n                  1/1     Running   0          52s

Kubernetes 更新
更新实际上就是替换镜像版本,有以下几种方式进行更新
有一点需要说明,当我们执行Deployment更新的时候,会保留一个rs版本号,用于回滚
[root@kubernetes-m media]# kubectl get rs
NAME              DESIRED   CURRENT   READY   AGE
nginx-74c749db5   3         3         3       94s

同时也可以通过查看deployment describe中查看到
---
Events:
  Type    Reason             Age   From                   Message
  ----    ------             ----  ----                   -------
  Normal  ScalingReplicaSet  4m5s  deployment-controller  Scaled up replica set nginx-74c749db5 to 3
  
由于RS版本号会一直产生早上资源被占用的情况,可以在deployment中添加revisionHistoryLimit 保留近期多久的rs版本号,下面步骤有相关参数解释,这里不进行过多说明

修改deployment文件进行更新
[root@kubernetes-m media]# sed -i 's#1.13.0-alpine#1.10.0-alpine#g' pod.yaml
[root@kubernetes-m media]# kubectl apply -f pod.yaml   #apply才会触发滚动更新哦,create是不行的

default       nginx-74c749db5-2hgzc                  1/1     Running       0          6s
default       nginx-74c749db5-667q2                  1/1     Running       0          4s
default       nginx-74c749db5-qhft7                  1/1     Running       0          5s
default       nginx-79574b4d46-5x8kc                 0/1     Terminating   0          42s
default       nginx-79574b4d46-scksn                 0/1     Terminating   0          42s
--record的作用是将当前命令记录到 revision 记录中,这样我们就可以知道每个 revison 对应的是哪个配置文件。

② 直接修改deployment进行更新镜像
[root@kubernetes-m media]# kubectl edit deployments.apps nginx
...
    spec:
      containers:
      - image: nginx:1.13.0-alpine   #更改这个
        imagePullPolicy: IfNotPresent
        name: nginx
...

不太推荐使用edit进行编辑,退出即保存,同时也会在我们的rollout里面产生一个版本号

③ 接下来是使用kubectl set命令进行替换镜像
命令格式如下
kubectl set image deployment/SVC_NAME -n namespace_name container_name=images:v1 #注意后面是容器名称,并不是svc名称

[root@kubernetes-m media]# kubectl set image deployment/nginx nginx=nginx:1.13.0-alpine
deployment.apps/nginx image updated
[root@kubernetes-m media]# kubectl get pod -A
NAMESPACE     NAME                                   READY   STATUS        RESTARTS   AGE
default       nginx-74c749db5-f7vg5                  1/1     Running       0          2s
default       nginx-74c749db5-mfn94                  1/1     Running       0          4s
default       nginx-74c749db5-rc4v7                  1/1     Running       0          3s
default       nginx-79574b4d46-6jl69                 1/1     Terminating   0          6m44s
default       nginx-79574b4d46-9cgc4                 0/1     Terminating   0          6m43s

回滚
我们使用上面的更新应用时Kubernetes都会记录下当前的配置文件,保存为一个revision (版本),这样就可以通过这个版本回滚到特定的时间
我们可以通过rollout参数查看当前版本号

[root@kubernetes-m media]# kubectl rollout history deployment nginx
deployment.apps/nginx 
REVISION  CHANGE-CAUSE
3         <none>
4         <none>

我们可以通过kubectl rollout undo 将deployment回滚到指定的版本,这里模拟回滚到第一个版本
默认情况下,如果不加--to-revision=版本号,默认回退到上一个版本
[root@kubernetes-m media]# kubectl describe deployments.apps nginx | grep Image
    Image:        nginx:1.13.0-alpine

[root@kubernetes-m media]# kubectl rollout undo deployment nginx
deployment.apps/nginx rolled back

[root@kubernetes-m media]# kubectl describe deployments.apps nginx | grep Image
    Image:        nginx:1.10.0-alpine

如果我们使用kubectl apply -f xx.yaml不加任何参数,那么在rollout将不会记录任何描述

如果我们想让rollout里面记录的文件带有版本号,只需要将文件修改一个名称更新时加上--record参数就可以,下面就会显示版本号
[root@kubernetes-m media]# kubectl apply -f pod.yaml 
deployment.apps/nginx created
[root@kubernetes-m media]# vim pod.yaml 
[root@kubernetes-m media]# kubectl get rs
NAME              DESIRED   CURRENT   READY   AGE
nginx-74c749db5   3         3         3       11s
[root@kubernetes-m media]# mv pod.yaml pod_v1.yaml
#修改镜像名称
[root@kubernetes-m media]# kubectl apply -f pod_v1.yaml 
deployment.apps/nginx configured
[root@kubernetes-m media]# kubectl get pod -A
NAMESPACE     NAME                                   READY   STATUS              RESTARTS   AGE
default       nginx-74c749db5-b2gjp                  0/1     Terminating         0          79s
default       nginx-74c749db5-drscp                  1/1     Running             0          79s
default       nginx-74c749db5-m4hwl                  1/1     Terminating         0          79s
default       nginx-79574b4d46-jf5fh                 1/1     Running             0          3s
default       nginx-79574b4d46-jwq72                 0/1     ContainerCreating   0          0s
default       nginx-79574b4d46-x878w                 1/1     Running             0          1s

然后我们从1.10.0再次回滚到1.13.0
[root@kubernetes-m media]# kubectl get rs
NAME               DESIRED   CURRENT   READY   AGE
nginx-74c749db5    0         0         0       99s
nginx-79574b4d46   3         3         3       23s

[root@kubernetes-m media]# kubectl rollout undo deployment nginx --to-revision=1
deployment.apps/nginx rolled back

[root@kubernetes-m media]# kubectl describe deployments.apps nginx | grep Image
    Image:        nginx:1.13.0-alpine
rollout命令参数如下

kubectl rollout -h
Manage the rollout of a resource.
 
 Valid resource types include:    #支持的资源格式
 
  *  deployments
  *  daemonsets
  *  statefulsets
 
Examples:
  # Rollback to the previous deployment
  kubectl rollout undo deployment/abc
 
  # Check the rollout status of a daemonset
  kubectl rollout status daemonset/foo
 
Available Commands:
  history     显示 rollout 历史
  pause       标记提供的 resource 为中止状态
  resume      继续一个停止的 resource
  status      显示 rollout 的状态
  undo        撤销上一次的 rollout
 
参数使用格式kubectl rollout [XXXX] deployment nginx-deployment


默认配置下,Kubernetes 只会保留最近的几个 revision,可以在 Deployment 配置文件中通过 revisionHistoryLimit 属性增加 revision 数量。(同时rs和我们rollout中记录的版本号相同,可以理解为rollout中显示的REVISION版本号实际上就是rs中的版本)

revisionHistoryLimit(历史版本记录):
Deployment revision history存储在它控制的ReplicaSets中。默认保存记录5个  
 
  .spec.revisionHistoryLimit 是一个可选配置项,用来指定可以保留的旧的ReplicaSet数量。该理想值取决于心Deployment的频率和稳定性。如果该值没有设置的话,默认所有旧的Replicaset或会被保留,将资源存储在etcd中,是用kubectl get rs查看输出。每个Deployment的该配置都保存在ReplicaSet中,然而,一旦删除的旧的RepelicaSet,Deployment就无法再回退到那个revison了。
 
  如果将该值设置为0,所有具有0个replica的ReplicaSet都会被删除。在这种情况下,新的Deployment rollout无法撤销,因为revision history都被清理掉了。
 
PS:为了保存版本升级的历史,需要再创建Deployment对象时,在命令中使用"--record"选项



一般配合revisionHistoryLimit使用的strategy (更新策略)

strategy(更新策略):
  .spec.strategy 指定新的Pod替换旧的Pod的策略。 .spec.strategy.type 可以是"Recreate"或者是 "RollingUpdate"。"RollingUpdate"是默认值。
 
  Recreate: 重建式更新,就是删一个建一个。类似于ReplicaSet的更新方式,即首先删除现有的Pod对象,然后由控制器基于新模板重新创建新版本资源对象。
 
  rollingUpdate:滚动更新,简单定义 更新期间pod最多有几个等。可以指定maxUnavailable 和 maxSurge 来控制 rolling update 进程。
 
  maxSurge:.spec.strategy.rollingUpdate.maxSurge 是可选配置项,用来指定可以超过期望的Pod数量的最大个数。该值可以是一个绝对值(例如5)或者是期望的Pod数量的百分比(例如10%)。当MaxUnavailable为0时该值不可以为0。通过百分比计算的绝对值向上取整。默认值是1。
 
  例如,该值设置成30%,启动rolling update后新的ReplicatSet将会立即扩容,新老Pod的总数不能超过期望的Pod数量的130%。旧的Pod被杀掉后,新的ReplicaSet将继续扩容,旧的ReplicaSet会进一步缩容,确保在升级的所有时刻所有的Pod数量和不会超过期望Pod数量的130%。
 
  maxUnavailable:.spec.strategy.rollingUpdate.maxUnavailable 是可选配置项,用来指定在升级过程中不可用Pod的最大数量。该值可以是一个绝对值(例如5),也可以是期望Pod数量的百分比(例如10%)。通过计算百分比的绝对值向下取整。  如果.spec.strategy.rollingUpdate.maxSurge 为0时,这个值不可以为0。默认值是1。
 
  例如,该值设置成30%,启动rolling update后旧的ReplicatSet将会立即缩容到期望的Pod数量的70%。新的Pod ready后,随着新的ReplicaSet的扩容,旧的ReplicaSet会进一步缩容确保在升级的所有时刻可以用的Pod数量至少是期望Pod数量的70%。
 
PS:maxSurge和maxUnavailable的属性值不可同时为0,否则Pod对象的副本数量在符合用户期望的数量后无法做出合理变动以进行更新操作。
 
  在配置时,用户还可以使用Deployment控制器的spec.minReadySeconds属性来控制应用升级的速度。新旧更替过程中,新创建的Pod对象一旦成功响应就绪探测即被认为是可用状态,然后进行下一轮的替换。而spec.minReadySeconds能够定义在新的Pod对象创建后至少需要等待多长的时间才能会被认为其就绪,在该段时间内,更新操作会被阻塞。
  
这里我提供revisionHistoryLimit和rollingUpdate的yaml文件 (完整yaml如下)

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 3
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: nginx
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.13.0
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80

具体参数可以查看上面解释!

RC介绍

Replication Controller (简称RC),RC是Kubernetes系统中的核心概念之一,简单来说,它定义了一个期望的场景,即声明某种Pod的副本数量在任意时刻都符合某个预期值

RC定义了如下

1.Pod期待的副本数(replicas) 2.用于筛选目标Pod的Label Seletcor(标签选择器) 3.当Pod的副本小于预期(replicas)时,用于创建新Pod的Pod模板(template)

RC主要功能

   --- 确保Pod数量: 它会确保Kubernetes中有指定数量的Pod在运行,如果少于指定数量的Pod,RC就会创建新的,反之会删除多余的,保证Pod的副本数量不变
   --- 确保Pod健康: 当Pod不健康,RC会杀死不健康的Pod,重新创建新的
   --- 弹性伸缩: 在业务高峰或者低峰的时候,可以用RC来动态调整Pod数量来提供资源的利用率吧,当然也可以使用HPA来实现
   --- 滚动升级: 滚动升级是一种平滑的升级方式,通过逐步替换的策略,保证整体系统的稳定性
   
RC例子演示

当我们定义了一个RC并提交到Kubernetes集群中以后,Master节点上的Controller Manager组件就得到通知,定期巡检系统中当前存活的目标Pod,并确保目标Pod实力的数量刚好等于此RC的期望值,如果有过多的Pod副本在运行,系统就会停掉一些Pod,否则系统就会再自动创建一些Pod。 可以说,通过RC,Kubernetes实现了用户应用集群的高可用性,并大大减少了传统IT需要手动的工作

---
apiVersion: v1
kind: ReplicationController
metadata:
  name: rc
  labels:
     app: rc
spec:
  replicas: 3   # 配置Pod数量
  selector:
    app: rc
  template:
    metadata:
      labels: 
        app: rc
    spec:
      containers:
        - name: nginx-demo
          image: nginx:1.13.0-alpine
          ports:
          - containerPort: 80

[root@kubernetes-m media]# kubectl apply -f rc.yaml 
replicationcontroller/rc created
[root@kubernetes-m media]# kubectl get rc
NAME   DESIRED   CURRENT   READY   AGE
rc     3         3         3       6s

	
DESIRED   #rc设置的数量
CURRENT   #已经创建的数量
READY     #准备好的数量

查看Pod数量及状态

[root@kubernetes-m media]# kubectl get po | grep rc
rc-bmtfq   1/1     Running   0          74s
rc-mltl2   1/1     Running   0          74s
rc-tsq4j   1/1     Running   0          74s

同时可以使用kubectl describe rc [rc-name]查看rc创建详情

[root@kubernetes-m media]# kubectl describe rc rc 
Name:         rc
Namespace:    default
Selector:     app=rc
Labels:       app=rc
Annotations:  Replicas:  3 current / 3 desired
Pods Status:  3 Running / 0 Waiting / 0 Succeeded / 0 Failed
Pod Template:
  Labels:  app=rc
  Containers:
   nginx-demo:
    Image:        nginx:1.13.0-alpine
    Port:         80/TCP
    Host Port:    0/TCP
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Events:
  Type    Reason            Age   From                    Message
  ----    ------            ----  ----                    -------
  Normal  SuccessfulCreate  12m   replication-controller  Created pod: rc-tsq4j
  Normal  SuccessfulCreate  12m   replication-controller  Created pod: rc-bmtfq
  Normal  SuccessfulCreate  12m   replication-controller  Created pod: rc-mltl2


例子:我们以2个Node节点为例,演示Pod副本数量自动控制的机制,加入我们的RC里定义rc这个Pod需要保持3个副本,系统可能在两台上创建Pod
假如Node2 上的Pod 2意外终止,根据RC定义的replicas数量2,Kubernetes将会自动创建并启动一个新的Pod,以保证集群中有2个服务可用
RC动态缩放
在Pod运行时,我们可以通过修改RC的副本数量,来实现Pod动态缩放Scaling功能,这也可以通过过kubectl scale命令来一键完成

扩展Pod副本到3
kubectl scale rc [rc名称] --replicas=3 

缩减副本到1
kubectl scale rc [rc名称] --replicas=1

演示1: 我们将tomcat的Pod数量由原来的3个更改为7个
[root@kubernetes-m media]# kubectl scale rc rc --replicas=7
replicationcontroller/rc scaled
[root@kubernetes-m media]# kubectl get pod -A
NAMESPACE     NAME                                   READY   STATUS    RESTARTS   AGE
default       rc-bmtfq                               1/1     Running   0          14m
default       rc-gwl6s                               1/1     Running   0          5s
default       rc-mltl2                               1/1     Running   0          14m
default       rc-p42d6                               1/1     Running   0          5s
default       rc-tsq4j                               1/1     Running   0          14m
default       rc-vkwb9                               1/1     Running   0          5s
default       rc-zrlht                               1/1     Running   0          5s

演示2:我们将tomcat的Pod输了由原来的7个修改为1个
[root@kubernetes-m media]# kubectl scale rc rc --replicas=1
replicationcontroller/rc scaled
[root@kubernetes-m media]# kubectl get pod -A
NAMESPACE     NAME                                   READY   STATUS        RESTARTS   AGE
default       rc-bmtfq                               0/1     Terminating   0          15m
default       rc-gwl6s                               0/1     Terminating   0          29s
default       rc-mltl2                               1/1     Running       0          15m
default       rc-p42d6                               0/1     Terminating   0          29s
default       rc-tsq4j                               0/1     Terminating   0          15m
default       rc-vkwb9                               0/1     Terminating   0          29s
default       rc-zrlht                               0/1     Terminating   0          29s

提示:deployment 后面的tomcat是我们在yaml文件中定义的 url:什么是yaml文件

除了通过命令的方式修改,我们还可以通过yaml文件的方式进行调试
posted @ 2021-12-17 11:07  Layzer  阅读(175)  评论(0)    收藏  举报