Kubernetes常用资源对象-Deployment

1、RC / RS 和 Deployment的区别

前面我们学习了Replication Controller 和 Replica Set 两种资源对象, RC 和 RS 的功能基本上是差不多的,唯⼀的区别就是 RS ⽀持集合的 selector 。我们也讲到了如何通过 RC / RS 来控制 Pod 副本的数量,也实现了滚动升级 Pod 的功能。现在看上去似乎⼀切都⽐较完美的运行着,但是为什么我们还是推荐使用 Deployment 这种控制器,而不是我们之前的 RC 或者 RS呢?

下面我们就来看看RC / RS 和 Deployment 之间的区别,⾸先 RC 是 Kubernetes 的⼀个核心概念,当我们把应⽤部署到集群之后,需要保证应⽤能够持续稳定的运行, RC 就是这个保证的关键,他的主要功能如下:

  • 确保 Pod 数量:它会确保 Kubernetes 中有指定数量的 Pod 在运⾏,如果少于指定数量的 Pod , RC 就会创建新的,反之这会删除多余的,保证 Pod 的副本数量不变。
  • 确保 Pod 健康:当 Pod 不健康,比如运⾏出错了,总之无法提供正常服务时, RC 也会杀死不健
    康的 Pod ,重新创建一个新的Pod。
  • 弹性伸缩:在业务⾼峰或者低峰的时候,可以通过 RC 来动态调整 Pod 数量来提供资源的利用率,当然我们也提到过如何使用 HPA 这种资源对象的话可以做到自动伸缩。
  • 滚动升级:滚动升级是⼀种平滑的升级⽅式,通过逐步替换的策略,保证整体系统的稳定性。

Deployment 同样也是 Kubernetes 系统的⼀个核心概念,主要职责和 RC ⼀样的都是保证 Pod 的数量
和健康,⼆者大部分功能都是完全⼀致的,我们可以看成是⼀个升级版的 RC 控制器,那 Deployment ⼜具备那些新特性呢?

  • RC 的全部功能: Deployment 具备上⾯描述的 RC 的全部功能;
  • 事件和状态查看:可以查看 Deployment 的升级详细进度和状态;
  • 回滚:当升级 Pod 的时候如果出现问题,可以使用回滚操作回滚到之前的任⼀版本;
  • 版本记录:每⼀次对 Deployment 的操作,都能够保存下来,这也是保证可以回滚到任⼀版本的基础;
  • 暂停和启动:对于每⼀次升级都能够随时暂停和启动。

2、创建Deployment

我们知道 Deployment 作为新⼀代的 RC ,不仅在功能上更为丰富了,同时官方也都是推荐使用 Deployment 来管理 Pod 的,比如⼀些官方组件 kube-dns 、 kube-proxy 也都是使用 Deployment 来管理的,所以当⼤家在使用的时候也最好通过 Deployment 来管理 Pod 。

img

从上图我们可以看出⼀个Deployment拥有多个Replica Set,而⼀个Replica Set拥有⼀个或多个Pod。一个Deployment控制多个RS主要是为了支持回滚机制,每当Deployment操作时,Kubernetes会重新生成⼀个Replica Set并保留,以后有需要的话就可以回滚⾄之前的状态。

话不多说、我们同样还是通过示例创建⼀个Deployment,而Deployment创建了⼀个Replica Set来启动3个nginx pod的方式来具体的看一看, Yaml文件如下:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deploy
  labels:
    k8s-app: nginx-demo
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80

img

将上⾯内容保存为: nginx-deployment.yaml,执行 kubectl apply -f nginx-deployment.yaml 命令创建 Deployment;执行完成以后我们可以通过 kubectl get deployments 命令查看刚才创建的Deployment;:

img

通过 kubectl get rs 命令我们可以看到Deployment已经创建了1个Replica Set,通过 kubectl get pod –show-labels 命令我们可以看到 Deployment 的运行状态,这里显示有3个Pod:

img

当然,这是因为我们在上⾯的Deployment Yaml⽂件中配置了 replicas:3 ,他将会保证我们始终有3个POD在运⾏。Deployment 和 RC 的功能⼤部分都⼀样的,上一篇文章我们已经和演示了大部分功能了,这里我们重点演示一下 Deployment 的滚动升级和回滚功能。

3、滚动升级Deployment

还是上面那个示例我们将刚刚保存的Yaml文件中的nginx镜像修改为 nginx:1.13.3 ,然后在spec下⾯添加滚动升级策略:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deploy
  labels:
    k8s-app: nginx-demo
spec:
  replicas: 3
  minReadySeconds: 5
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.13.3
        ports:
        - containerPort: 80

img

参数解析

  • minReadySeconds:

Kubernetes在等待设置的时间后才进⾏升级;

如果没有设置该值,Kubernetes会假设该容器启动起来后就提供服务了;

如果没有设置该值,在某些极端情况下可能会造成服务服务正常运行。

  • maxSurge:

升级过程中最多可以比原先设置多出的POD数量;

例如:maxSurage=1,replicas=5,则表示Kubernetes会先启动1⼀个新的Pod后才删掉⼀个旧
的POD,整个升级过程中最多会有5+1个POD。

  • maxUnavaible:

升级过程中最多有多少个POD处于⽆法提供服务的状态;

当 maxSurge 不为0时,该值也不能为0;

例如:maxUnavaible=1,则表示Kubernetes整个升级过程中最多会有1个POD处于⽆法服务
的状态。

然后我们执行 kubectl apply -f nginx-deployment.yaml 命令更新 Deployment :

img

当然我们也可以通过下面的命令查看状态、暂停升级、继续升级等操作:

查看状态:

kubectl rollout status deployment/nginx-deploy

暂停升级:

kubectl rollout pause deployment nginx-deploy

继续升级:

kubectl rollout resume deployment nginx-deploy

升级结束后,我们也可以通过 kubectl get rs 查看rs的状态:

img

根据AGE我们可以看到离我们最近的当前状态是:3,和我们的Yaml⽂件是⼀致的,证明升级成功了。
用 kubectl describe deployment nginx-deploy 命令可以查看升级的全部信息:

img

4、回滚Deployment

我们已经能够滚动平滑的升级 Deployment 了,但是如果升级以后的Pod出现问题该怎么办呢?我们
能够想到的最好最快的⽅式当然是回退到上⼀次能够提供正常⼯作的版本,Deployment就为我们提供了回滚机制。

⾸先,我们通过 kubectl rollout history deployment nginx-deploy 命令查看Deployment的升级历史:

img

从上⾯的结果可以看出在我们在执行 Deployment 升级的时候最好带上–record=true参数,便于我们后期查看历史版本信息。

为什么呢?

默认情况下,所有通过 kubectl xxxx –record 都会被 kubernetes 记录到 etcd 进行持久化,这无疑会占用资源,最重要的是,时间久了,当你 kubectl get rs 时,会有成百上千的垃圾 RS 返回给你,那时你可能就眼花缭乱了。

在生产环境中,我们最好通过设置Deployment的 .spec.revisionHistoryLimit 来限制最大保留的 revisionnumber ,比如15个版本,回滚的时候⼀般只会回滚到最近的几个版本就⾜够了。其实 rollouthistory 中记录的 revision 都和 ReplicaSets ⼀⼀对应。如果手动 delete 某个ReplicaSet,对应的 rollout history 就会被删除,也就是还说你无法回滚到这个 revison 了。rollout history 和 ReplicaSet 的对应关系,可以在 kubectl describe rs $RSNAME 返回的 revision 字段中得到,这里的 revision 就对应着 rollout history 返回的 revison 。

同样我们可以执行 kubectl rollout history deployment nginx-deploy –revision=3
deployments ” 命令查看单个 revison 的信息:

img

假如现在要直接回退到当前版本的前⼀个版本,我们可以执行 kubectl rollout undo deployment nginx-deploy 命令:

img

当然也可以⽤ revision 回退到指定的版本:

kubectl rollout undo deployment nginx-deploy --to-revision=2

注:回滚到执行版本这里就不再演示了,感兴趣的小伙伴可以自行操作。

现在可以用 kubectl describe rs nginx-deploy 命令查看Deployment现在的状态了,我们可以看到deployment的回滚过程:

img

img

推荐文章