1、Deployment-无状态部署

1、什么是Deployment

2、Deployment创建

  • 基本格式
    • .metadata.name指定deploy名字
    • replicas 指定副本数量
    • selector 指定匹配的Pod模板。
    • template 声明一个Pod模板
      1. apiVersion: apps/v1 ###
      2. kind: Deployment ##
      3. metadata:
      4. name: mydeploy-03 ### 遵循域名编写规范
      5. namespace: default
      6. labels:
      7. dep: test-02
      8. ### 期望状态
      9. spec:
      10. paused: false ## 就是 kubectl rollout pause/resume 功能
      11. progressDeadlineSeconds: 600 ##
      12. revisionHistoryLimit: 15 ### 保留最近的15个版本。 /etcd
      13. selector: ### 选择器
      14. matchLabels: ### 匹配标签
      15. pod-name: aaaa ### 和模板template里面的pod的标签必须一样
      16. ####
      17. template:
      18. metadata: ### pod的metadata
      19. labels:
      20. pod-name: aaaa
      21. spec:
      22. containers:
      23. - name: nginx-01
      24. image: nginx
      ```bash

      Deployment:

      滚动更新: 10 2 - 8 4 , 2 4 0 - 10

      RS1 RS2 两个版本同时存在

      minReadySeconds: 10 这个Pod10s以后才认为是read状态,影响多久后杀死旧Pod paused : false 当前是否停止状态,暂停更新 progressDeadlineSeconds: 600 处理的最终期限,Deployment如果超过了这个指定的处理描述就会给集群汇报错误 replicas : Pod 期望的数量(副本数量),是 ReplicaSet 控制器实现的 revisionHistoryLimit : 旧副本集保留的数量,可回滚的数量,默认是10 selector -required-: 指定我们Deployment要控制的所有的Pod的共通标签 strategy : 指定新Pod替换旧Pod的策略 rollingUpdate : 指定滚动更新策略
      1. maxSurge <string>【最大增量】: 2 一次最多新建几个Pod 百分比和数字都可以
      2. MaxUnavailable:为0 的时候, maxSurge不能为0
      3. maxUnavailable【最大不可用量】: 4 最大不可用的Pod数量
      template -required-: 编写Pod
      1. - 在检查集群中的 Deployment 时,所显示的字段有:
      2. - `NAME` 列出了集群中 Deployment 的名称。
      3. - `READY` 显示应用程序的可用的 _副本_ 数。显示的模式是“就绪个数/期望个数”。
      4. - `UP-TO-DATE` 显示为了达到期望状态已经更新的副本数。
      5. - `AVAILABLE` 显示应用可供用户使用的副本数。
      6. - `AGE` 显示应用程序运行的时间。
      7. ![image.png](https://cdn.nlark.com/yuque/0/2022/png/12766423/1661827245249-f7fd0fd1-93bd-42dc-9241-9c9412a4040a.png#clientId=u86b710c5-717c-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=100&id=uf2008b9f&margin=%5Bobject%20Object%5D&name=image.png&originHeight=100&originWidth=625&originalType=binary&ratio=1&rotation=0&showTitle=false&size=9103&status=done&style=none&taskId=u2a197ffb-013e-4118-88d4-3c10dc386ce&title=&width=625)
      8. - ReplicaSet 输出中包含以下字段:
      9. - `NAME` 列出名字空间中 ReplicaSet 的名称;
      10. - `DESIRED` 显示应用的期望副本个数,即在创建 Deployment 时所定义的值。 此为期望状态;
      11. - `CURRENT` 显示当前运行状态中的副本个数;
      12. - `READY` 显示应用中有多少副本可以为用户提供服务;
      13. - `AGE` 显示应用已经运行的时间长度。
      14. - 注意:ReplicaSet 的名称始终被格式化为`[Deployment名称]-[随机字符串]` 其中的随机字符串是使用 pod-template-hash 作为种子随机生成的。
      15. ![image.png](https://cdn.nlark.com/yuque/0/2022/png/12766423/1661827506403-9b222da7-8345-40ed-b01c-10dc24f6e9b7.png#clientId=u86b710c5-717c-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=116&id=ud579d38f&margin=%5Bobject%20Object%5D&name=image.png&originHeight=116&originWidth=1617&originalType=binary&ratio=1&rotation=0&showTitle=false&size=19771&status=done&style=none&taskId=u7c5543a3-28ef-4223-a209-7ec654f7ab5&title=&width=1617)
      16. > 一个Deploy产生三个
      17. > - Deployment资源
      18. > - replicaset资源
      19. > - Pod资源
      20. >
      21. Deployment控制RSRS控制Pod的副本数
      22. > ReplicaSet 只提供了副本数量的控制功能
      23. > Deployment 每部署一个新版本就会创建一个新的副本集,利用他记录状态,回滚也是直接让指定的rs生效
      24. > --- rs1 4 abc
      25. > --- rs2: 4 def
      26. > --- rsN: 4 eee
      27. > nginx=111 nginx:v1=2222 nginx:v2=3333
      28. <a name="aABln"></a>
      29. ## 3、Deployment 更新机制
      30. - 仅当 Deployment Pod 模板(即 `.spec.template`)发生改变时,例如**模板的标签或容器镜像被更新, 才会触发 Deployment 上线**。 **其他更新(如对 Deployment 执行扩缩容的操作)不会触发上线动作。**
      31. - **上线动作 原理: 创建新的rs,准备就绪后,替换旧的rs(此时不会删除,因为**`**revisionHistoryLimit**`** 指定了保留几个版本)**
      32. ```bash
      33. ################更新#################################
      34. #kubectl set image deployment资源名 容器名=镜像名
      35. kubectl set image deployment.apps/nginx-deployment php-redis=tomcat:8 --record
      36. ## yaml提取可更新的关键所有字段计算的hash。
      37. web---- /hello
      38. postman aservice- /hello
      39. #或者直接修改定义也行
      40. kubectl edit deployment.v1.apps/nginx-deployment
      41. #查看状态
      42. kubectl rollout status deployment.v1.apps/nginx-deployment
      43. ################查看历史并回滚####################################
      44. #查看更新历史-看看我们设置的历史总记录数是否生效了
      45. kubectl rollout history deployment.v1.apps/nginx-deployment
      46. #回滚
      47. kubectl rollout undo deployment.v1.apps/nginx-deployment --to-revision=2
      48. ###############累计更新##############
      49. #暂停记录版本
      50. kubectl rollout pause deployment.v1.apps/nginx-deployment
      51. #多次更新操作。
      52. ##比如更新了资源限制
      53. kubectl set resources deployment.v1.apps/nginx-deployment -c=nginx --limits=cpu=200m,memory=512Mi
      54. ##比如更新了镜像版本
      55. kubectl set image deployment.apps/nginx-deployment php-redis=tomcat:8
      56. ##在继续操作多次
      57. ##看看历史版本有没有记录变化
      58. kubectl rollout history deployment.v1.apps/nginx-deployment
      59. #让多次累计生效
      60. kubectl rollout resume deployment.v1.apps/nginx-deployment

      1、比例缩放,滚动更新

      1. apiVersion: apps/v1 ###
      2. kind: Deployment ##
      3. metadata:
      4. name: mydeploy-05 ### 遵循域名编写规范
      5. namespace: default
      6. labels:
      7. dep: test-04
      8. ### 期望状态
      9. spec:
      10. strategy:
      11. # type: Recreate ### 把以前全部杀死,直接新建
      12. #RollingUpdate 滚动更新
      13. type: RollingUpdate
      14. #滚动更新策略
      15. rollingUpdate:
      16. #可以使数字 可以使百分比
      17. #每次更新的副本数量
      18. maxUnavailable: 2
      19. #当前部署的副本数不可用量
      20. maxSurge: 20%
      21. replicas: 10
      22. selector: ### 选择器
      23. matchLabels: ### 匹配标签
      24. pod-name: aaa55566 ### 和模板template里面的pod的标签必须一样
      25. ####
      26. template:
      27. metadata: ### pod的metadata
      28. labels:
      29. pod-name: aaa55566
      30. spec:
      31. containers:
      32. - name: nginx-01
      33. image: nginx

      2、HPA(动态扩缩容)

      概念:https://kubernetes.io/zh/docs/tasks/run-application/horizontal-pod-autoscale/#scaling-policies
      实战:https://kubernetes.io/zh/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/

      前置条件,需要先安装metrics-server

      https://github.com/kubernetes-sigs/metrics-server

      1. apiVersion: autoscaling/v1
      2. kind: HorizontalPodAutoscaler
      3. metadata:
      4. creationTimestamp: null
      5. name: php-apache
      6. spec:
      7. maxReplicas: 10 #动态扩容最大副本集
      8. minReplicas: 1 #保留最小副本集
      9. scaleTargetRef: ### 将要扩展的目标引用
      10. apiVersion: apps/v1
      11. kind: Deployment
      12. name: php-apache ## Pod limit: 100m
      13. targetCPUUtilizationPercentage: 50 ### cpu使用超过50%就扩容,低于就缩容
      1. ##hpa配置 hpa.yaml
      2. apiVersion: autoscaling/v1
      3. kind: HorizontalPodAutoscaler
      4. metadata:
      5. name: php-apache
      6. spec:
      7. maxReplicas: 10
      8. minReplicas: 1
      9. scaleTargetRef:
      10. apiVersion: apps/v1
      11. kind: Deployment
      12. name: php-apache
      13. targetCPUUtilizationPercentage: 50

      3、Canary(金丝雀部署)

      步骤原理

      • 准备一个Service,负载均衡Pod
      • 准备版本v1的deploy,准备版本v2的deploy

      滚动发布的缺点?(同时存在两个版本都能接受流量)

      • 没法控制流量 ; 6 4, 8 2 ,3 7
      • 滚动发布短时间就直接结束,不能直接控制新老版本的存活时间。

      用两个镜像:

      • registry.cn-hangzhou.aliyuncs.com/lfy_k8s_images/nginx-test:env-msg 默认输出11111
      • nginx: 默认输出 默认页;

      4、Deployment状态与排错

      https://kubernetes.io/zh/docs/concepts/workloads/controllers/deployment/#deployment-status

      2、DaemonSet

      DaemonSet 控制器确保所有(或一部分)的节点都运行了一个指定的 Pod 副本。

      • 每当向集群中添加一个节点时,指定的 Pod 副本也将添加到该节点上
      • 当节点从集群中移除时,Pod 也就被垃圾回收了
      • 删除一个 DaemonSet 可以清理所有由其创建的 Pod

      DaemonSet 的典型使用场景有

      • 在每个节点上运行集群的存储守护进程,例如 glusterd、ceph
      • 在每个节点上运行日志收集守护进程,例如 fluentd、logstash
      • 在每个节点上运行监控守护进程,例如 Prometheus Node ExporterSysdig Agent、collectd、Dynatrace OneAgentAPPDynamics AgentDatadog agentNew Relic agent、Ganglia gmond、Instana Agent
        1. apiVersion: apps/v1
        2. kind: DaemonSet
        3. metadata:
        4. name: logging
        5. labels:
        6. app: logging
        7. spec:
        8. selector:
        9. matchLabels:
        10. name: logging
        11. template:
        12. metadata:
        13. labels:
        14. name: logging
        15. spec:
        16. containers:
        17. - name: logging
        18. image: nginx
        19. resources:
        20. limits:
        21. memory: 200Mi
        22. requests:
        23. cpu: 100m
        24. memory: 200Mi
        25. tolerations: #设置容忍master的污点
        26. - key: node-role.kubernetes.io/master
        27. effect: NoSchedule
        28. #查看效果
        29. kubectl get pod -l name=logging -o wide

      3、StatefulSet

      有状态副本集;Deployment等属于无状态的应用部署(stateless

      • StatefulSet 使用场景;对于有如下要求的应用程序,StatefulSet 非常适用:
        • 稳定、唯一的网络标识(dnsname)
          • StatefulSet通过与其相关的无头服务为每个pod提供DNS解析条目。假如无头服务的DNS条目为:
            “(service name).(namespace).svc.cluster.local”,
            那么pod的解析条目就是”(pod name).(service name).$(namespace).svc.cluster.local”,每个pod name也是唯一的。
        • 稳定的、持久的存储;【每个Pod始终对应各自的存储路径(PersistantVolumeClaimTemplate)】
        • 有序的、优雅的部署和缩放。【按顺序地增加副本、减少副本,并在减少副本时执行清理】
        • 有序的、自动的滚动更新。【按顺序自动地执行滚动更新】
      • 限制
        • 给定 Pod 的存储必须由 PersistentVolume 驱动 基于所请求的 storage class 来提供,或者由管理员预先提供。
        • 删除或者收缩 StatefulSet 并不会删除它关联的存储卷。 这样做是为了保证数据安全,它通常比自动清除 StatefulSet 所有相关的资源更有价值。
        • StatefulSet 当前需要无头服务 来负责 Pod 的网络标识。你需要负责创建此服务。
        • 当删除 StatefulSets 时,StatefulSet 不提供任何终止 Pod 的保证。 为了实现 StatefulSet 中的 Pod 可以有序地且体面地终止,可以在删除之前将 StatefulSet 缩放为 0。
        • 在默认 Pod 管理策略(OrderedReady) 时使用 滚动更新,可能进入需要人工干预 才能修复的损坏状态。

      如果一个应用程序不需要稳定的网络标识,或者不需要按顺序部署、删除、增加副本,就应该考虑使用 Deployment 这类无状态(stateless)的控制器

      1. apiVersion: v1
      2. kind: Service #定义一个负载均衡网络
      3. metadata:
      4. name: stateful-tomcat
      5. labels:
      6. app: stateful-tomcat
      7. spec:
      8. ports:
      9. - port: 8123
      10. name: web
      11. targetPort: 8080
      12. clusterIP: None #NodePort:任意机器+NodePort都能访问,ClusterIP:集群内能用这个ip、service域名能访问,clusterIP: None;不要分配集群ip。headless;无头服务。稳定的域名
      13. selector:
      14. app: stateful-tomcat
      15. ---
      16. apiVersion: apps/v1
      17. kind: StatefulSet #控制器。
      18. metadata:
      19. name: stateful-tomcat
      20. spec:
      21. selector:
      22. matchLabels:
      23. app: stateful-tomcat # has to match .spec.template.metadata.labels
      24. serviceName: "stateful-tomcat" #这里一定注意,必须提前有个service名字叫这个的
      25. replicas: 3 # by default is 1
      26. template:
      27. metadata:
      28. labels:
      29. app: stateful-tomcat # has to match .spec.selector.matchLabels
      30. spec:
      31. terminationGracePeriodSeconds: 10
      32. containers:
      33. - name: tomcat
      34. image: tomcat:7
      35. ports:
      36. - containerPort: 8080
      37. name: web
      1. #观察效果。
      2. 删除一个,重启后名字,ip等都是一样的。保证了状态
      3. #细节
      4. kubectl explain StatefulSet.spec
      5. podManagementPolicy
      6. OrderedReady(按序)、Parallel(并发)
      7. serviceName -required-
      8. 设置服务名,就可以用域名访问pod了。
      9. pod-specific-string.serviceName.default.svc.cluster.local
      10. #测试
      11. kubectl run -i --tty --image busybox dns-test --restart=Never --rm /bin/sh
      12. ping stateful-tomcat-0.stateful-tomcat
      13. #我们在这里没有加存储卷。如果有的话 kubectl get pvc -l app=stateful-tomcat 我们就能看到即使Pod删了再拉起,卷还是同样的。

      4、Job、CronJob

      1、Job

      Kubernetes中的 Job 对象将创建一个或多个 Pod,并确保指定数量的 Pod 可以成功执行到进程正常结束:

      • 当 Job 创建的 Pod 执行成功并正常结束时,Job 将记录成功结束的 Pod 数量
      • 当成功结束的 Pod 达到指定的数量时,Job 将完成执行
      • 删除 Job 对象时,将清理掉由 Job 创建的 Pod ```yaml apiVersion: batch/v1 kind: Job metadata: name: pi spec: template: spec: containers:
      • name: pi image: perl command: [“perl”, “-Mbignum=bpi”, “-wle”, “print bpi(2000)”] restartPolicy: Never #Job情况下,不支持Always backoffLimit: 4 #任务4次都没成,认为失败 activeDeadlineSeconds: 10

        默认这个任务需要成功执行一次。

      查看job情况

      kubectl get job

      修改下面参数设置再试试

      千万不要用阻塞容器。nginx。job由于Pod一直running状态。下一个永远得不到执行,而且超时了,当前running的Pod还会删掉

      kubectl api-resources

      1. ```yaml
      2. #参数说明
      3. kubectl explain job.spec
      4. activeDeadlineSeconds:10 总共维持10s
      5. #该字段限定了 Job 对象在集群中的存活时长,一旦达到 .spec.activeDeadlineSeconds 指定的时长,该 Job 创建的所有的 Pod 都将被终止。但是Job不会删除,Job需要手动删除,或者使用ttl进行清理
      6. backoffLimit:
      7. #设定 Job 最大的重试次数。该字段的默认值为 6;一旦重试次数达到了 backoffLimit 中的值,Job 将被标记为失败,且尤其创建的所有 Pod 将被终止;
      8. completions: #Job结束需要成功运行的Pods。默认为1
      9. manualSelector:
      10. parallelism: #并行运行的Pod个数,默认为1
      11. ttlSecondsAfterFinished:
      12. ttlSecondsAfterFinished: 0 #在job执行完时马上删除
      13. ttlSecondsAfterFinished: 100 #在job执行完后,等待100s再删除
      14. #除了 CronJob 之外,TTL 机制是另外一种自动清理已结束Job(Completed 或 Finished)的方式:
      15. #TTL 机制由 TTL 控制器 提供,ttlSecondsAfterFinished 字段可激活该特性
      16. #当 TTL 控制器清理 Job 时,TTL 控制器将删除 Job 对象,以及由该 Job 创建的所有 Pod 对象。
      17. # job超时以后 已经完成的不删,正在运行的Pod就删除
      18. #单个Pod时,Pod成功运行,Job就结束了
      19. #如果Job中定义了多个容器,则Job的状态将根据所有容器的执行状态来变化。
      20. #Job任务不建议去运行nginx,tomcat,mysql等阻塞式的,否则这些任务永远完不了。
      21. ##如果Job定义的容器中存在http server、mysql等长期的容器和一些批处理容器,则Job状态不会发生变化(因为长期运行的容器不会主动结束)。此时可以通过Pod的.status.containerStatuses获取指定容器的运行状态。

      manualSelector:

      • job同样可以指定selector来关联pod。需要注意的是job目前可以使用两个API组来操作,batch/v1和extensions/v1beta1。当用户需要自定义selector时,使用两种API组时定义的参数有所差异。
      • 使用batch/v1时,用户需要将jod的spec.manualSelector设置为true,才可以定制selector。默认为false。
      • 使用extensions/v1beta1时,用户不需要额外的操作。因为extensions/v1beta1的spec.autoSelector默认为false,该项与batch/v1的spec.manualSelector含义正好相反。换句话说,使用extensions/v1beta1时,用户不想定制selector时,需要手动将spec.autoSelector设置为true。

      2、CronJob

      CronJob 按照预定的时间计划(schedule)创建 Job(注意:启动的是Job不是Deploy,rs)。一个 CronJob 对象类似于 crontab (cron table) 文件中的一行记录。该对象根据 Cron 格式定义的时间计划,周期性地创建 Job 对象。

      Schedule 所有 CronJob 的 schedule 中所定义的时间,都是基于 master 所在时区来进行计算的。

      一个 CronJob 在时间计划中的每次执行时刻,都创建 大约 一个 Job 对象。这里用到了 大约 ,是因为在少数情况下会创建两个 Job 对象,或者不创建 Job 对象。尽管 K8S 尽最大的可能性避免这种情况的出现,但是并不能完全杜绝此现象的发生。因此,Job 程序必须是 幂等的

      当以下两个条件都满足时,Job 将至少运行一次:

      • startingDeadlineSeconds 被设置为一个较大的值,或者不设置该值(默认值将被采纳)
      • concurrencyPolicy 被设置为 Allow ```

        kubectl explain cronjob.spec

        concurrencyPolicy:并发策略 “Allow” (允许,default): “Forbid”(禁止): forbids;前个任务没执行完,要并发下一个的话,下一个会被跳过 “Replace”(替换): 新任务,替换当前运行的任务

        failedJobsHistoryLimit:记录失败数的上限,Defaults to 1. successfulJobsHistoryLimit: 记录成功任务的上限。 Defaults to 3.

        指定了 CronJob 应该保留多少个 completed 和 failed 的 Job 记录。将其设置为 0,则 CronJob 不会保留已经结束的 Job 的记录。

        jobTemplate: job怎么定义(与前面我们说的job一样定义法)

        schedule: cron 表达式;

        startingDeadlineSeconds: 表示如果Job因为某种原因无法按调度准时启动,在spec.startingDeadlineSeconds时间段之内,CronJob仍然试图重新启动Job,如果在.spec.startingDeadlineSeconds时间之内没有启动成功,则不再试图重新启动。如果spec.startingDeadlineSeconds的值没有设置,则没有按时启动的任务不会被尝试重新启动。

      suspend 暂停定时任务,对已经执行了的任务,不会生效; Defaults to false.

      1. ```yaml
      2. apiVersion: batch/v1beta1
      3. kind: CronJob
      4. metadata:
      5. name: hello
      6. spec:
      7. schedule: "*/1 * * * *" #分、时、日、月、周
      8. jobTemplate:
      9. spec:
      10. template:
      11. spec:
      12. containers:
      13. - name: hello
      14. image: busybox
      15. args:
      16. - /bin/sh
      17. - -c
      18. - date; echo Hello from the Kubernetes cluster
      19. restartPolicy: OnFailure