zoukankan      html  css  js  c++  java
  • k8s 控制器(kube-controller-manager)-deployment

    k8s 控制器:controller-manager ,是部署、管理pod 的。常见的控制器类型有deployment、Job 、statefulset 、daemonset 等等。deployment 是最常见的控制器,它是部署静态服务用的控制器。控制器是通过标签来关联查找pod 的

     deployment 

    介绍

    Deployment 是一种更高阶资源, 相比于rc或rs 或其他控制器它的价值是不仅可以用来部署应用程序,还可以以声明的方式滚动升级应用。更强大的是它可以定制升级策略,记录升级所有版本,方便升级失败的回退等操作。
     
    当创建个 Deployment 时, ReplicaSet 资源也会随之创建,在使用 Deployment 时, 实际的 pod是由 Deployment 的 Replicaset 创建和管理的, 而不是由 Deployment 直接创建和管理的

    deployment  功能与应用场景

    关于版本迭代和升级

    1、下线旧的服务,上线新的服务,此方式适用于新旧应用不能同时提供服务,弊端就是可能造成服务短暂不可用。

    2、滚动更新,下线一个旧的再上一个新的,依次逐个更新,直至所有旧的下线新的上线,此过程新旧程序同时提供服务。

    针对滚动更新,k8s 中的两种方式

    方式一

    kubectl + rc 方式滚动升级,通过rc或rs 创建pod 应用,再通过kubectl  rolling-update 命令升级。整个过程如下:

    通过yaml新建资源rc和service,pod 模板绑定标签,rc和svc 通过标签选择器关联Pod ,kubectl 命令来新建一个rc并且制定新镜像版本,发送命令到api ,每次删除一个旧的pod ,就新建一个新的pod ,直至旧的pod 完全消失新pod全部建立,整个过程service 可以访问在线的新旧pod 提供服务。

    方式二

    deployment  声明式的方式实现滚动升级,而不是kubectl 命令式的方式,本文后面会有详细介绍。

    两者比较

    方式一  中整个过程一直是通过kubectl 客户端命令与api 通信,如果客户端与api 网络故障容易导致升级中断,而且此过程中还添加了新的标签。

    方式二  声明式的,而不是kubectl 命令式的方式;deployment 方式升级可以有两种方式(滚动升级,删除旧的上新的),而且升级出错可以回退。deployment 方式升级实现过程与kubectl rollling-update 过程相似也是新建一个副本控制器,整个过程是由deployment 协调维护两个副本控制器的状态的,但是旧的rs 不会删除,记录所有升级记录,可以回退。

    相关操作 

    部署应用程序 

    创建资源deployment

    kubectl create   deployment   --help
    
    kubectl  create  deployment  dep-name  --image=naginx  --dry-run  -o  yaml > a.yaml  # --dry-run不实际生效只是测试,-o yaml把此命令转换成yaml 格式
    
    vi a.yaml                           #再编辑配置此文件自定义要配置的pod 参数。
    
    kubectl   create  -f  a.yaml --record      #根据文件创建资源,record 参数为了记录历史版本号
    
    kubectl   get  deploy -n  namespace        #查看通过 deployment 部署的pod
    
    kubectl   describe  deploy,pods -n namespace  #查看详情
      kubectl   rollout   status deployment kubia  #查看部署状态
    
      kubectl  get pod                   #查看部署的pod,由Deployment创建的三个pod 名称中均包含一个额外的数字,这个数字实际上对应 Deployment 和 Repli                                                   caSet 中的 pod 模板的哈希值
    
      kubectl   get  replicasets  #查看创建的rc ,ReplicaSet的名称中也包含了其 pod 模板的哈希值。Deployment 会创建多个 ReplicaSet, 用来对应和管                                                 理一个版本的pod模板。像这样使用pod模板的哈希值,可以让 Deployment 始终对给定版本的pod模板创建相同的(或使用已有的) ReplicaSet。
    View Code

    创建service  发布应用

    kubectl  expose  --help
    
    kubectl  expose  --named=service-name deployment    dep-name --port=80    --target-port=8080    --type=NodePort  
    
                   代理的名称         为哪个dep创建代理         代理对外端口   pod 中内部端口         端口暴露类型
    
    kubectl get service  #查看创建的代理
    View Code

    升级/回滚/扩容

    升级 
    分为两种升级策略,默认是滚动更新(策略名为 RollingUpdate)升级过程中pod数量可以在期望副本数的一定区间内浮动, 并且其上限和下限是可配置的。 如果应用能够支持多个版本同时对外提供服务, 则推荐使用这个策略来升级应用;
    另一种策略为 Recreate, 它会一次性删除所有旧版本的 pod, 然后创建新的pod使用这种策略的话, 会导致应用程序出现短暂的不可用。
    在线更改deployment 的配置的命令一般都会引发升级(kubectl apply/kubectl edit /kubectl set image等)

    回滚
       回滚升级之所以可以这么快地完成,是因为 Deployment 始终保持着升级的版本历史记录。之后也会看到,历史版本号会被保存在 ReplicaSet 。滚动升级成功后,
      老版本的 ReplicaSet 不会被删掉,这使得回被操作可以回滚到任何一个历史版
    旧版本的 ReplicaSet 过多会导致 ReplicaS 列表过于混乱,可以通过指定
    Deployment re    visionHistoryLimit 属性来限制历史版本数量。默认值是
    所以正常情况下在版本列表里只有当前版本和上一个版本(以及只保留了当前和上
    ReplicaSet ),所有再早之前的    ReplicaSet 都会被删除。 
    注意 extensions/vlbetal 版本的 Depl oy nt revisi nHistoryLimit 没有值,在 apps/vlbeta2 版本中,这个默认值是 10
     
     升级
      kubectl patch deployment kubia-p '{"spec": {"minReadySeconds": 10}}'  #减慢升级速度
    kubectl  set image  deployment web  old-defined-image-name=image-name  #升级/更新(原理:通过指定原Pod 对应的镜像来实现更新pod。升级过程:滚动升级,先创建一个新镜像容器,运行成功后再删除旧的容器)
    
    kubectl edit svc/web  #如果新镜像里面服务端口有变化,此命令更新service 映射端口
      关于滚动升级有两个重要的策略属性:maxSurge和maxUnavailable ,具体查看官网根据实际情况设置
     
    回滚Deployment
      
     kubectl rollout undo deployment kubia    #会被回滚到上个版本。 
     
     kubectl rollout hist ry deployment kubia  #查看升级的历史版本
    
     kubectl rollout undo deployment kubia- -to-revision=l #会滚到特定一个版本
    
    暂停滚动升级/恢复暂停的滚动升级
      
      kubect1 rollout pause deployment  kubia 
      
      kubect1 rollout resume deployment kubia
     
     
    阻止出错版本的滚动升级策略配置(minReadySeconds + 就绪探针+progressDeadlineSeconds)
      升级部署第一个pod的时候通过就绪探针检测正常的时间达到minReadySeconds值后k8s 就认为此pod 可用,只有pod 可用以后才会继续升级下一个pod ,否则会停止升级错误的pod
      如果达到了progressDeadlineSeconds指定的时间, 则滚动升级过程会自动取消。
    
    vi a.yam. 
     apiVersion: apps/vlbetal
     kind: Deployment
     metadata:
      name: kubia
     spec:
     replicas: 3
      minReadySeconds: 10            #设置minReadySeconds的值为10
      strategy: 
        rollingUpdate: 
          maxSurge: 1 
          maxUnavailable: 0
        type: RollingUpdate 
      template: 
        metadata: 
          name: kubia 
          labels: 
            app: kubia
        spec: 
          containers: 
          -image: luksa/kubia:v3
          name: nodejs 
          readinessProbe:           #定义一个就绪探针每隔一秒执行一次,就绪探针发送http get请求
            periodSeconds: 1 
            httpGet:
              path:/ 
              port: 8080 
    
    kubectl apply -f a.yaml
    View Code

    扩/缩容

    升级相关的几个重要配置属性

    max Surge 
    决定了 Deployment 配置中期望的副本数之外,最多允许超出的 od 实例的数量。默认值为 25% ,所以 pod 实例最多可以比期望数量多 25 如果期望副本数被设置为 4.那么在滚动列级知 间,不会运行超 pod 实例。当把百分数转换成绝对值时将数字四舍五入 这个值也可以不是百分数 是绝对值 例如,可以允许最多多个成两个pod决定了在滚动升级
    View Code
    maxUnavailable 
    决定了在滚动升级期间 ,相对于期望副本数能够允许有多少 实例处于不可用状态。默认值也是 25% 所以可用 od 实例的数量不能低于期望副本数的 75 。百分数转换成绝对值时这个数字也会四舍五入 如果期望副本数设置为 ,并且百分比为 25 %.那么只能有 pod 于不可用状态。在整个发布过程中 ,总是保持至少有三个实例处于可用状态来提供服务 maxSurge 样,也可以 定绝对值而不是百分比
    View Code
    minReadySeconds
    minReadySeconds属性指定新创建的pod至少要成功运行多久之后 , 才能将其视为可用。 在pod可用之前, 滚动升级的过程不会继续(还记得 maxUnava辽- able属性吗?)。 当所有容器的就绪探针返回成功时 , pod 就被标记为就绪状态。如果一个新的pod运行出错, 就绪探针返回失败, 如果一个新的pod 运行出错, 并且在minReadySeconds时间内它的就绪探针出现了失败, 那么新版本的滚动升级将被阻止。
    View Code
    就绪探针
    类似于健康检查,设定一个检查频率,根据检查返回结果判定pod 是否处于就绪状态,例如每隔1s 发送一个get 请求,返回200则认为pod 是就绪状态,配合minReadySeconds使用,就绪状态达到 minReadySeconds值后认为pod 可以,可以就绪升级下一个。当pod 为非就绪状态那么service 也不会转发请求到该pod,然后也会停止部署升级下一个,直至返回就绪状态且达到设定时间才会继续部署
    View Code
    progressDeadlineSeconds
    如果达到了progressDeadlineSeconds指定的时间, 则滚动升级过程会自动取消。默认情况下, 在10分钟内不能完成滚动升级的话, 将被视为失败。注意extensions/vlbetal版本不会设置默认的deadline。
    View Code

     FAQ

    关于升级过程的镜像问题

    使用同样的Tag推送更新过后的镜像虽然在开发过程中经常推送修改后的应用到同一个镜像tag, 但是这种做法并不可取。 如果修改了latest的tag的话是可行的, 但如果使用一个不同的
    tag名(比如是vl而不是lastest), 等计算节点拉取过镜像之后, 便会将镜像存储在节点上 。 如果使用该镜像启动新的pod, 便不会重新拉取镜像(至少这是默认的拉取镜像策略)。
    这也意味着, 如果将对更改过后的镜像推到相同的tag, 会导致镜像不被重新拉取。 如果一个新的pod被调度到同一个节点上, Kubelet直接使用旧的镜像版本来启动pod。 另一方面, 没有运行过旧版本的节点将拉取并运行新镜像, 因此最后可能有两个不同版本的pod同时运行。 为了确保这种情况不会发生, 需要将容器的imagePullPo巨cy属性设置为Always
    
      另外默认的imagePullPo巨cy 策略也依赖于镜像的tag。如果容器使用latest的tag (显式指定或者不指定),则imagePullPolicy默认为Always,但是如果容器指定了其他标记,则策略   默认为IfNotPresent。当使用非latest的tag时,如果对镜像进行更改而不更改tag, 则需要正确设置imagePullPolicy。当然最好使用一个新的tag来更新镜像。 
    View Code

    修改 Deployment 或其他资源的不同方式

      kubectl edit    #使用默认编辑器在线打开资源配置。修改保存并退出编辑器,资源对象会被更新例子: kubectl edit deployment asdf 
    
      kubectl patch    #修改单个资源属性,例子: kubectl patch deployment kubia-p'{"spec":{"template": {"spec": {"containers": [ {"name":"nodejs","im                     age":"luksa/kubia:v2"}]}}}}'
      
      kubectl apply     #通过一个完整的YAML或JSON文件,应用其中新的值来修改对象。如果YAML/JSON中指定对象不存在,则会被创建。该文件需要包含资源的完整定义(不能像kube                     ctl patch那样只包含想要更新的字段)例子 : kubec七1 apply-f kubia-deployment-v2.yaml 
    
     
     kubectl replace  #将原有对象替换为YAML/JSON文件中定义的新对象。与apply命令相反,运行这个命令前要求对象必须存在,否则会打印错误例子: kubectl replace-f kubi                    a-deployment一v2.yaml。 
    
     
     kubectl setimage   #修改Pod、ReplicationController、Deployment、DernonSet、Job或ReplicaSet内镜像例子:kubectl set image deployment kubia nodejs=l                     uksa/kubia:v2
    View Code

     相关命令

    Tips:k8s 中所有的对象操作都需要指定命名空间,否则就是在默认的命名空间

    列出所有存在的命名空间
    
      kubectl get  ns
    
    新建的pod 查看
      kubectl  get  pods  -n  namespace                          #注意如果不指定命名空间,默认就是default命名空间。pod 状态异常,日志查看
    
    pod 状态异常,日志查看
      kubectl   logs   -f   pod-name     -n  namespace            #同样需要指定命名空间,否则在默认命名空间如果没有,会提示not found
    
    查看一个deployment 配置(如果通过deployment 部署了pod,想知道相关配置)
      kubectl get deployment -n kzf                       #先在控制器所在命名空间查看所有的deployment 
        NAME       READY     UP-TO-DATE AVAILABLE     AGE
        usercenter    2/2        2      2         6d5h
    
      kubectl describe deployment  app1  -n kzf                #指定控制器名称,查看该控制器的配置
    
      kubectl get deployment nginx -n kzf -o yaml                #获取控制器的yaml格式配置,可以使用此配置创建新的控制器
    
    当不知道一个pod 是通过哪种控制器部署的时候可以查看pod 信息获取控制器信息
      kubectl describe pod pay-c6f6fdd-mk6f2  -n kzf      #查看Controlled By:  xxxx/xxxx   项
    
      kubectl describe replicaset replicaset-name -n  kzf  #如果Controlled: 为ReplicaSet/xxx ,可以进一步查看replicaset信息得知replicaset 由谁创建的
    View Code
  • 相关阅读:
    指针总结与地址
    寻址方式
    为什么要有指针?
    指针与变量
    Wired Memory
    Memory Usage Performance Guidelines
    内存管理与运行时
    Java jvm 内存回收机制
    GC详解及Minor GC和Full GC触发条件总结
    Java的内存回收机制详解X
  • 原文地址:https://www.cnblogs.com/fanggege/p/11938320.html
Copyright © 2011-2022 走看看