• Deployment


    Deployment

    RC是kubernetes中的一个核心概念,Deployment 是新一代的RC,除了拥有RC的功能外,还具备一下特性:

    • 支持事件和状态查看:可以查看Deployment升级的状态和详细过程
    • 回滚:升级Pod后出现问题,可以使用回滚功能回退到之前任一(总记录历史数以内)历史版本
    • 版本记录:每一次对Deployment的操作,都能记录下来,保证回滚的基础
    • 暂停和启动:对于每一次更新都能暂停和启动
    • 金丝雀发布

    Deployement 作为新一代的RC,不仅在功能上更丰富了,同时官方推荐使用,在一些官方组件上,也能看到是使用Deployment部署,比如kube-proxy,kube-dns。

    结构图层

    可以看出,Deployment管理一个或多个Replica Set,一个Replica Set管理一个或多个Pod。Deployment 管理多个rs的作用,主要是为了支持回滚机制,每次操作Deployment后,都会生成一个新的RS对象保存下来,也可以设置保留历史版本数量,当需要以前的版本时可以一键回滚。

    用例

    以下是部署的典型用例:

    创建部署

    官方模板 nginx-deployment.yaml

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

    这是部署示例。它创建一个ReplicaSet来调出三个nginx Pod。

    通过下载示例文件,然后运行以下命令来运行示例:

    kubectl apply -f https://k8s.io/examples/controllers/nginx-deployment.yaml
    

    将kubectl标志设置--recordtrue允许您将当前命令记录在正在创建或更新的资源的注释中。这对于将来的自省很有用:例如,查看每个Deployment版本中执行的命令。

    要查看“部署”推出状态,请运行:

    $ kubectl rollout status deployment/nginx-deployment
    Waiting for rollout to finish: 2 out of 3 new replicas have been updated...
    deployment "nginx-deployment" successfully rolled out
    

    创建的ReplicaSet确保始终有三个nginx Pod。

    注意:您必须在Deployment中指定适当的选择器和pod模板标签(在本例中为 app = nginx)。也就是说,请勿与其他控制器(包括其他Deployment,ReplicaSet,StatefulSet等)重叠。Kubernetes不会阻止您重叠,并且如果多个控制器具有重叠的选择器,那么这些控制器可能会相互竞争,并且无法正常运行。

    Pod模板哈希标签

    注意: Do not change this label.

    注意上面的pod标签中示例输出中的pod-template-hash标签。此标签由Deployment控制器添加到Deployment创建或采用的每个ReplicaSet中。其目的是确保部署的子副本集不重叠。它是通过对ReplicaSet的PodTemplate进行散列并使用所得的散列作为将添加到ReplicaSet选择器,吊舱模板标签以及ReplicaSet可能具有的任何现有吊舱中的标签值来计算的。

    更新部署

    注意:只有且仅当.spec.template更改了部署的pod模板(即)(例如,模板的标签或容器映像已更新)时,才会触发部署的推出。其他更新,例如扩展部署,不会触发部署。

    假设我们现在要更新nginx Pods以使用nginx:1.9.1图像而不是nginx:1.7.9图像。

    $ kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1
    deployment "nginx-deployment" image updated
    

    或者,我们可以edit部署和改变.spec.template.spec.containers[0].imagenginx:1.7.9nginx:1.9.1

    $ kubectl edit deployment/nginx-deployment
    deployment "nginx-deployment" edited
    

    要查看部署状态,请运行:

    $ kubectl rollout status deployment/nginx-deployment
    Waiting for rollout to finish: 2 out of 3 new replicas have been updated...
    deployment "nginx-deployment" successfully rolled out
    

    部署成功后,您可能需要get部署:

    $ kubectl get deployments
    NAME               DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
    nginx-deployment   3         3         3            3           36s
    

    最新副本数表明部署已将副本更新为最新配置。当前副本指示此Deployment管理的全部副本,可用副本指示可用的当前副本数。

    我们可以kubectl get rs通过创建新的ReplicaSet并将其缩放到3个副本,以及将旧的ReplicaSet缩小到0个副本来看到Deployment更新了Pod。

    过渡(又名进行中的多个更新)

    每次部署控制器观察到新的部署对象时,如果没有现有的ReplicaSet,则会创建一个ReplicaSet来调出所需的Pod。标签匹配.spec.selector但模板不匹配的现有ReplicaSet控制Pod .spec.template按比例缩小。最终,新的副本集将被缩放为.spec.replicas,所有旧的副本集将被缩放为0。

    如果在进行现有部署时更新部署,则部署将根据更新创建一个新的ReplicaSet并开始进行扩展,并将其先前扩展的ReplicaSet进行滚动-它将添加到其列表中旧的ReplicaSets,并将开始按比例缩小比例。

    例如,假设您创建了一个Deployment来创建5个的副本nginx:1.7.9,但是nginx:1.9.1当只创建了3个副本时,更新了Deployment来创建5个的副本nginx:1.7.9。在这种情况下,Deployment将立即开始杀死nginx:1.7.9它已经创建的3个Pod,并将开始创建 nginx:1.9.1Pod。nginx:1.7.9更改路线之前,它不会等待创建5个副本。

    标签选择器更新

    通常不建议更新标签选择器,建议您预先计划选择器。无论如何,如果您需要执行标签选择器更新,请格外小心,并确保您已掌握所有含义。

    • 添加选择器时,还需要使用新标签来更新Deployment规范中的pod模板标签,否则将返回验证错误。此更改是不重叠的更改,这意味着新选择器不会选择使用旧选择器创建的副本集和Pod,从而导致所有旧副本集孤立,并创建新的副本集。
    • 选择器更新(即更改选择器键中的现有值)会导致与添加操作相同的行为。
    • 选择器的删除(即从“部署”选择器中删除现有的密钥)不需要对窗格模板标签进行任何更改。没有孤立的现有ReplicaSet,也不会创建新的ReplicaSet,但是请注意,已删除的标签仍存在于任何现有Pod和ReplicaSet中。

    滚动升级

    现在我们将刚刚保存的yaml文件中的nginx镜像修改为nginx:1.13.3,然后在spec下面添加滚动升级策略:

    minReadySeconds: 5
    strategy:
      # indicate which strategy we want for rolling update
      type: RollingUpdate
      rollingUpdate:
        maxSurge: 1
        maxUnavailable: 1
    
    • 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 "nginx-deploy" configured
    

    回滚部署

    有时您可能想回滚部署;例如,当部署不稳定时(例如崩溃循环)。默认情况下,所有“部署”的推出历史记录都保留在系统中,以便您可以随时回滚(可以通过修改修订历史记录限制来更改它)。

    注意:触发展开部署时,将创建展开的修订版。这意味着只有且仅当.spec.template更改了部署的吊舱模板()(例如,更新模板的标签或容器映像)时,才创建新修订。其他更新(例如扩展Deployment)不会创建Deployment版本,因此我们可以促进同时进行手动或自动扩展。这意味着,当您回滚到较早的修订版时,只会回滚Deployment的pod模板部分。

    假设我们在更新Deployment时输入了图像名称,nginx:1.91而不是nginx:1.9.1

    $ kubectl set image deployment/nginx-deployment nginx=nginx:1.91
    deployment "nginx-deployment" image updated
    

    推出将被卡住。

    $ kubectl rollout status deployments nginx-deployment
    Waiting for rollout to finish: 2 out of 3 new replicas have been updated...
    

    按Ctrl-C停止上述推出状态监视。有关卡住的卷展栏的更多信息,参见 此处

    您还将看到旧副本(nginx-deployment-1564180365和nginx-deployment-2035384211)和新副本(nginx-deployment-3066724191)的数量均为2。

    $ kubectl get rs
    NAME                          DESIRED   CURRENT   READY   AGE
    nginx-deployment-1564180365   2         2         0       25s
    nginx-deployment-2035384211   0         0         0       36s
    nginx-deployment-3066724191   2         2         2       6s
    

    查看创建的Pod,您将看到由新的ReplicaSet创建的2个Pod陷入了图像提取循环中。

    $ kubectl get pods
    NAME                                READY     STATUS             RESTARTS   AGE
    nginx-deployment-1564180365-70iae   1/1       Running            0          25s
    nginx-deployment-1564180365-jbqqo   1/1       Running            0          25s
    nginx-deployment-3066724191-08mng   0/1       ImagePullBackOff   0          6s
    nginx-deployment-3066724191-eocby   0/1       ImagePullBackOff   0          6s
    

    注意: Deployment Controller将自动停止不良的部署,并将停止扩展新的ReplicaSet。这取决于maxUnavailable您指定的rollingUpdate参数(特别是)。Kubernetes默认情况下将值设置为1,spec.replicas设置为1,因此如果您不关心设置这些参数,则默认情况下您的Deployment可能不可用100%!将来的版本将在Kubernetes中修复此问题。

    $ kubectl describe deployment
    

    要解决此问题,我们需要回滚到稳定的Deployment的先前版本。

    检查部署的推出历史记录

    首先,检查此部署的修订:

    $ kubectl rollout history deployment/nginx-deployment
    deployments "nginx-deployment"
    REVISION    CHANGE-CAUSE
    1           kubectl apply -f https://k8s.io/examples/controllers/nginx-deployment.yaml
    2           kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1
    3           kubectl set image deployment/nginx-deployment nginx=nginx:1.91
    

    因为我们在使用创建此Deployment时记录了命令--record,所以我们可以轻松地看到我们在每个修订版中所做的更改。

    要进一步查看每个修订的详细信息,请运行:

    $ kubectl rollout history deployment/nginx-deployment --revision=2
    deployments "nginx-deployment" revision 2
      Labels:       app=nginx
              pod-template-hash=1159050644
      Annotations:  kubernetes.io/change-cause=kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1
      Containers:
       nginx:
        Image:      nginx:1.9.1
        Port:       80/TCP
         QoS Tier:
            cpu:      BestEffort
            memory:   BestEffort
        Environment Variables:      <none>
      No volumes.
    

    回滚到以前的修订

    现在,我们决定撤消当前的推出并回滚到以前的版本:

    $ kubectl rollout undo deployment/nginx-deployment
    deployment "nginx-deployment" rolled back
    

    另外,您可以通过以下方式回滚到特定修订--to-revision

    $ kubectl rollout undo deployment/nginx-deployment --to-revision=2
    deployment "nginx-deployment" rolled back
    

    有关与推出相关命令的更多详细信息,请阅读kubectl rollout

    现在,部署已回滚到以前的稳定版本。

    扩展部署

    您可以使用以下命令扩展部署:

    $ kubectl scale deployment nginx-deployment --replicas=10
    deployment "nginx-deployment" scaled
    

    假设在集群中启用了水平Pod自动缩放,则可以为Deployment设置一个自动缩放器,并根据现有Pod的CPU利用率选择要运行的Pod的最小和最大数量。

    $ kubectl autoscale deployment nginx-deployment --min=10 --max=15 --cpu-percent=80
    deployment "nginx-deployment" autoscaled
    

    比例缩放

    RollingUpdate部署支持同时运行一个应用程序的多个版本。当您或自动缩放器缩放在推出期间(正在进行或已暂停)的RollingUpdate部署时,部署控制器将平衡现有活动副本集(带有Pod的副本集)中的其他副本,以降低风险。这称为比例缩放

    例如,您正在运行具有10个副本,maxSurge = 3和maxUnavailable = 2 的Deployment 。

    通过按比例缩放,我们将其他副本分布在所有副本集中。较大比例的副本将进入具有最多副本的副本集,而较低比例的副本将进入具有较少副本的副本集。任何剩余的都将被添加到具有最多副本的ReplicaSet中。副本数为零的副本集不会按比例放大。

    在上面的示例中,将3个副本添加到旧的ReplicaSet中,将2个副本添加到新的ReplicaSet中。假设新副本运行状况良好,推出过程最终应将所有副本移至新的ReplicaSet。

    暂停和恢复部署

    您可以在触发一个或多个更新之前暂停部署,然后再恢复它。这样,您可以在暂停和恢复之间应用多个修复程序,而不会触发不必要的部署。

    通过运行以下命令来暂停:

    $ kubectl rollout pause deployment/nginx-deployment
    deployment "nginx-deployment" paused
    

    然后更新部署的映像:

    $ kubectl set image deploy/nginx-deployment nginx=nginx:1.9.1
    deployment "nginx-deployment" image updated
    

    请注意,没有新的部署开始:

    $ kubectl rollout history deploy/nginx-deployment
    deployments "nginx"
    REVISION  CHANGE-CAUSE
    1   <none>
    
    $ kubectl get rs
    NAME               DESIRED   CURRENT   READY     AGE
    nginx-2142116321   3         3         3         2m
    

    您可以根据需要进行任意数量的更新,例如,更新将使用的资源:

    $ kubectl set resources deployment nginx -c=nginx --limits=cpu=200m,memory=512Mi
    deployment "nginx" resource requirements updated
    

    部署在暂停之前的初始状态将继续其功能,但是只要暂停部署,对部署的新更新将不会有任何效果。

    最终,恢复部署并观察新的ReplicaSet以及所有新更新:

    $ kubectl rollout resume deploy/nginx-deployment
    deployment "nginx" resumed
    $ kubectl get rs -w
    NAME               DESIRED   CURRENT   READY     AGE
    nginx-2142116321   2         2         2         2m
    nginx-3926361531   2         2         0         6s
    nginx-3926361531   2         2         1         18s
    nginx-2142116321   1         2         2         2m
    nginx-2142116321   1         2         2         2m
    nginx-3926361531   3         2         1         18s
    nginx-3926361531   3         2         1         18s
    nginx-2142116321   1         1         1         2m
    nginx-3926361531   3         3         1         18s
    nginx-3926361531   3         3         2         19s
    nginx-2142116321   0         1         1         2m
    nginx-2142116321   0         1         1         2m
    nginx-2142116321   0         0         0         2m
    nginx-3926361531   3         3         3         20s
    ^C
    $ kubectl get rs
    NAME               DESIRED   CURRENT   READY     AGE
    nginx-2142116321   0         0         0         2m
    nginx-3926361531   3         3         3         28s
    

    注意:您不能回滚已暂停的部署,直到您将其恢复。

    部署状态

    部署在其生命周期中会进入各种状态。它可以前进,同时推出新ReplicaSet,也可以是完整的,也可以不取得进展

    进行中的部署

    Kubernetes标记的部署作为前进当执行下列任务之一:

    • 部署将创建一个新的ReplicaSet。
    • 部署正在扩展其最新的ReplicaSet。
    • 部署正在缩减其较旧的ReplicaSet。
    • Pod已准备就绪或可用(至少已准备好MinReadySeconds)。

    您可以使用监视部署的进度kubectl rollout status

    完成部署

    Kubernetes 具有以下特征时,将Deployment标记为完成

    • 与Deployment关联的所有副本均已更新为您指定的最新版本,这意味着您请求的所有更新均已完成。
    • 与部署关联的所有副本均可用。
    • 没有运行用于部署的旧副本。

    您可以使用来检查部署是否已完成kubectl rollout status。如果推出成功完成,则kubectl rollout status返回零退出代码。

    $ kubectl rollout status deploy/nginx-deployment
    Waiting for rollout to finish: 2 of 3 updated replicas are available...
    deployment "nginx" successfully rolled out
    $ echo $?
    0
    

    部署失败

    尝试部署其最新的ReplicaSet可能会遇到麻烦,而没有完成。这可能是由于以下因素引起的:

    • 配额不足
    • 准备就绪探针故障
    • 图像拉出错误
    • 权限不足
    • 极限范围
    • 应用程序运行时配置错误

    检测这种情况的一种方法是在“部署”规范中指定一个截止日期参数:(spec.progressDeadlineSeconds)。spec.progressDeadlineSeconds表示部署控制器在指示(处于部署状态)部署进度已停止之前等待的秒数。

    以下kubectl命令设置规范progressDeadlineSeconds以使控制器在10分钟后报告部署进度不足:

    $ kubectl patch deployment/nginx-deployment -p '{"spec":{"progressDeadlineSeconds":600}}'
    "nginx-deployment" patched
    

    一旦超过了最后期限,Deployment控制器就会将具有以下属性的DeploymentCondition添加到Deployment的status.conditions

    • Type=Progressing
    • Status=False
    • Reason=ProgressDeadlineExceeded
  • 相关阅读:
    HTTPS原理浅析
    Java8 HashMap源码分析
    Java8 ArrayList源码分析
    Java反射
    Java泛型
    Tensorflow卷积神经网络
    Java8 Stream简介
    java.io与网络通信
    Python实现RNN
    域名系统DNS简介
  • 原文地址:https://www.cnblogs.com/h-gallop/p/11817120.html
Copyright © 2020-2023  润新知