凯发k8国际娱乐官网入口-k8凯发> 云容器引擎 cce> > > 无状态负载(deployment)
更新时间:2023-09-06 gmt 08:00

无状态负载(deployment)-凯发k8国际娱乐官网入口

无状态负载(deployment)

pod是kubernetes创建或部署的最小单位,但是pod是被设计为相对短暂的一次性实体,pod可以被驱逐(当节点资源不足时)、随着集群的节点崩溃而消失。kubernetes提供了controller(控制器)来管理pod,controller可以创建和管理多个pod,提供副本管理、滚动升级和自愈能力,其中最为常用的就是deployment。

图1 deployment

一个deployment可以包含一个或多个pod副本,每个pod副本的角色相同,所以系统会自动为deployment的多个pod副本分发请求。

deployment集成了上线部署、滚动升级、创建副本、恢复上线的功能,在某种程度上,deployment实现无人值守的上线,大大降低了上线过程的复杂性和操作风险。

创建deployment

以下示例为创建一个名为nginx的deployment负载,使用nginx:latest镜像创建两个pod,每个pod占用100m core cpu、200mi内存。

apiversion: apps/v1      # 注意这里与pod的区别,deployment是apps/v1而不是v1
kind: deployment         # 资源类型为deployment
metadata:
  name: nginx            # deployment的名称
spec:
  replicas: 2            # pod的数量,deployment会确保一直有2个pod运行         
  selector:              # label selector
    matchlabels:
      app: nginx
  template:              # pod的定义,用于创建pod,也称为pod template
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx:latest
        name: container-0
        resources:
          limits:
            cpu: 100m
            memory: 200mi
          requests:
            cpu: 100m
            memory: 200mi
      imagepullsecrets:
      - name: default-secret

从这个定义中可以看到deployment的名称为nginx,spec.replicas定义了pod的数量,即这个deployment控制2个pod;spec.selector是label selector(标签选择器),表示这个deployment会选择label为app=nginx的pod;spec.template是pod的定义,内容与pod中的定义完全一致。

将上面deployment的定义保存到deployment.yaml文件中,使用kubectl创建这个deployment。

使用kubectl get查看deployment和pod,可以看到ready值为2/2,前一个2表示当前有2个pod运行,后一个2表示期望有2个pod,available为2表示有2个pod是可用的。

$ kubectl create -f deployment.yaml
deployment.apps/nginx created
$ kubectl get deploy
name           ready     up-to-date   available   age
nginx          2/2       2            2           4m5s

deployment如何控制pod

继续查询pod,如下所示。

$ kubectl get pods
name                     ready     status    restarts   age
nginx-7f98958cdf-tdmqk   1/1       running   0          13s
nginx-7f98958cdf-txckx   1/1       running   0          13s

如果删掉一个pod,您会发现立马会有一个新的pod被创建出来,如下所示,这就是前面所说的deployment会确保有2个pod在运行,如果删掉一个,deployment会重新创建一个,如果某个pod故障或有其他问题,deployment会自动拉起这个pod。

$ kubectl delete pod nginx-7f98958cdf-txckx
$ kubectl get pods
name                     ready     status    restarts   age
nginx-7f98958cdf-tdmqk   1/1       running   0          21s
nginx-7f98958cdf-tesqr   1/1       running   0          1s

看到有如下两个名为nginx-7f98958cdf-tdmqk和nginx-7f98958cdf-tesqr的pod, 其中nginx是直接使用deployment的名称,-7f98958cdf-tdmqk和-7f98958cdf-tesqr是kubernetes随机生成的后缀。

您也许会发现这两个后缀中前面一部分是相同的,都是7f98958cdf,这是因为deployment不是直接控制pod的,deployment是通过一种名为replicaset的控制器控制pod,通过如下命令可以查询replicaset,其中rs是replicaset的缩写。

$ kubectl get rs
name               desired   current   ready     age
nginx-7f98958cdf   2         2         2         1m

这个replicaset的名称为nginx-7f98958cdf,后缀-7f98958cdf也是随机生成的。

deployment控制pod的方式如图2所示,deployment控制replicaset,replicaset控制pod。

图2 deployment通过replicaset控制pod

如果使用kubectl describe命令查看deployment的详情,您就可以看到replicaset,如下所示,可以看到有一行newreplicaset: nginx-7f98958cdf (2/2 replicas created),而且events里面事件确是把replicaset的实例扩容到2个。在实际使用中您也许不会直接操作replicaset,但了解deployment通过控制replicaset来控制pod会有助于您定位问题。

$ kubectl describe deploy nginx
name:                   nginx
namespace:              default
creationtimestamp:      sun, 16 dec 2018 19:21:58  0800
labels:                 app=nginx
...
newreplicaset:   nginx-7f98958cdf (2/2 replicas created)
events:
  type    reason             age   from                   message
  ----    ------             ----  ----                   -------
  normal  scalingreplicaset  5m    deployment-controller  scaled up replica set nginx-7f98958cdf to 2

升级

在实际应用中,升级是一个常见的场景,deployment能够很方便的支撑应用升级。

deployment可以设置不同的升级策略,有如下两种。

  • rollingupdate:滚动升级,即逐步创建新pod再删除旧pod,为默认策略。
  • recreate:替换升级,即先把当前pod删掉再重新创建pod。

deployment的升级可以是声明式的,也就是说只需要修改deployment的yaml定义即可,比如使用kubectl edit命令将上面deployment中的镜像修改为nginx:alpine。修改完成后再查询replicaset和pod,发现创建了一个新的replicaset,pod也重新创建了。

$ kubectl edit deploy nginx
$ kubectl get rs
name               desired   current   ready     age
nginx-6f9f58dffd   2         2         2         1m
nginx-7f98958cdf   0         0         0         48m
$ kubectl get pods
name                     ready     status    restarts   age
nginx-6f9f58dffd-tdmqk   1/1       running   0          1m
nginx-6f9f58dffd-tesqr   1/1       running   0          1m

deployment可以通过maxsurge和maxunavailable两个参数控制升级过程中同时重新创建pod的比例,这在很多时候是非常有用,配置如下所示。

spec:
  strategy:
    rollingupdate:
      maxsurge: 1
      maxunavailable: 0
    type: rollingupdate
  • maxsurge:与deployment中spec.replicas相比,可以有多少个pod存在,默认值是25%,比如spec.replicas为 4,那升级过程中就不能超过5个pod存在,即按1个的步伐升级,实际升级过程中会换算成数字,且换算会向上取整。这个值也可以直接设置成数字。
  • maxunavailable:与deployment中spec.replicas相比,可以有多少个pod失效,也就是删除的比例,默认值是25%,比如spec.replicas为4,那升级过程中就至少有3个pod存在,即删除pod的步伐是1。同样这个值也可以设置成数字。

在前面的例子中,由于spec.replicas是2,如果maxsurge和maxunavailable都为默认值25%,那实际升级过程中,maxsurge允许最多3个pod存在(向上取整,2*1.25=2.5,取整为3),而maxunavailable则不允许有pod unavailable(向上取整,2*0.75=1.5,取整为2),也就是说在升级过程中,一直会有2个pod处于运行状态,每次新建一个pod,等这个pod创建成功后再删掉一个旧pod,直至pod全部为新pod。

回滚

回滚也称为回退,即当发现升级出现问题时,让应用回到老的版本。deployment可以非常方便的回滚到老版本。

例如上面升级的新版镜像有问题,可以执行kubectl rollout undo命令进行回滚。

$ kubectl rollout undo deployment nginx
deployment.apps/nginx rolled back

deployment之所以能如此容易的做到回滚,是因为deployment是通过replicaset控制pod的,升级后之前replicaset都一直存在,deployment回滚做的就是使用之前的replicaset再次把pod创建出来。deployment中保存replicaset的数量可以使用revisionhistorylimit参数限制,默认值为10。

分享:
网站地图