1、Deployment-无状态部署1、什么是Deployment2、Deployment创建Deployment:滚动更新: 10 2 - 8 4 , 2 4 0 - 10RS1 RS2 两个版本同时存在1、比例缩放,滚动更新2、HPA(动态扩缩容)3、Canary(金丝雀部署)4、Deployment状态与排错2、DaemonSet3、StatefulSet4、Job、CronJob1、Job默认这个任务需要成功执行一次。查看job情况修改下面参数设置再试试千万不要用阻塞容器。nginx。job由于Pod一直running状态。下一个永远得不到执行,而且超时了,当前running的Pod还会删掉2、CronJobkubectl explain cronjob.spec指定了 CronJob 应该保留多少个 completed 和 failed 的 Job 记录。将其设置为 0,则 CronJob 不会保留已经结束的 Job 的记录。 1、Deployment-无状态部署 1、什么是Deployment 一个 Deployment 为 Pods 和 ReplicaSets 提供声明式的更新能力。你负责描述 Deployment 中的 目标状态,而 Deployment 控制器(Controller) 以受控速率更改实际状态, 使其变为期望状态;控制循环。 for(){ xxx controller.spec()}不要管理 Deployment 所拥有的 ReplicaSet我们部署一个应用一般不直接写Pod,而是部署一个DeploymentDeploy编写规约 https://kubernetes.io/zh/docs/concepts/workloads/controllers/deployment/#writing-a-deployment-spec 2、Deployment创建 基本格式 .metadata.name指定deploy名字replicas 指定副本数量selector 指定匹配的Pod模板。template 声明一个Pod模板apiVersion: apps/v1 ### kind: Deployment ## metadata:name: mydeploy-03 ### 遵循域名编写规范namespace: defaultlabels:dep: test-02### 期望状态spec:paused: false ## 就是 kubectl rollout pause/resume 功能progressDeadlineSeconds: 600 ## revisionHistoryLimit: 15 ### 保留最近的15个版本。 /etcdselector: ### 选择器matchLabels: ### 匹配标签 pod-name: aaaa ### 和模板template里面的pod的标签必须一样#### template:metadata: ### pod的metadata labels: pod-name: aaaaspec: containers: - name: nginx-01 image: nginx ```bashDeployment:滚动更新: 10 2 - 8 4 , 2 4 0 - 10RS1 RS2 两个版本同时存在minReadySeconds: 10 这个Pod10s以后才认为是read状态,影响多久后杀死旧Pod paused : false 当前是否停止状态,暂停更新 progressDeadlineSeconds: 600 处理的最终期限,Deployment如果超过了这个指定的处理描述就会给集群汇报错误 replicas : Pod 期望的数量(副本数量),是 ReplicaSet 控制器实现的 revisionHistoryLimit : 旧副本集保留的数量,可回滚的数量,默认是10 selector -required-: 指定我们Deployment要控制的所有的Pod的共通标签 strategy : 指定新Pod替换旧Pod的策略 rollingUpdate : 指定滚动更新策略 maxSurge <string>【最大增量】: 2 一次最多新建几个Pod。 百分比和数字都可以 MaxUnavailable:为0 的时候, maxSurge不能为0 maxUnavailable【最大不可用量】: 4 最大不可用的Pod数量template -required-: 编写Pod - 在检查集群中的 Deployment 时,所显示的字段有: - `NAME` 列出了集群中 Deployment 的名称。 - `READY` 显示应用程序的可用的 _副本_ 数。显示的模式是“就绪个数/期望个数”。 - `UP-TO-DATE` 显示为了达到期望状态已经更新的副本数。 - `AVAILABLE` 显示应用可供用户使用的副本数。 - `AGE` 显示应用程序运行的时间。- ReplicaSet 输出中包含以下字段: - `NAME` 列出名字空间中 ReplicaSet 的名称; - `DESIRED` 显示应用的期望副本个数,即在创建 Deployment 时所定义的值。 此为期望状态; - `CURRENT` 显示当前运行状态中的副本个数; - `READY` 显示应用中有多少副本可以为用户提供服务; - `AGE` 显示应用已经运行的时间长度。 - 注意:ReplicaSet 的名称始终被格式化为`[Deployment名称]-[随机字符串]`。 其中的随机字符串是使用 pod-template-hash 作为种子随机生成的。> 一个Deploy产生三个> - Deployment资源> - replicaset资源> - Pod资源> Deployment控制RS,RS控制Pod的副本数> ReplicaSet: 只提供了副本数量的控制功能> Deployment: 每部署一个新版本就会创建一个新的副本集,利用他记录状态,回滚也是直接让指定的rs生效> --- rs1: 4 abc> --- rs2: 4 def> --- rsN: 4 eee> nginx=111 nginx:v1=2222 nginx:v2=3333<a name="aABln"></a>## 3、Deployment 更新机制- 仅当 Deployment Pod 模板(即 `.spec.template`)发生改变时,例如**模板的标签或容器镜像被更新, 才会触发 Deployment 上线**。 **其他更新(如对 Deployment 执行扩缩容的操作)不会触发上线动作。** - **上线动作 原理: 创建新的rs,准备就绪后,替换旧的rs(此时不会删除,因为**`**revisionHistoryLimit**`** 指定了保留几个版本)** ```bash################更新##################################kubectl set image deployment资源名 容器名=镜像名kubectl set image deployment.apps/nginx-deployment php-redis=tomcat:8 --record## yaml提取可更新的关键所有字段计算的hash。web---- /hellopostman aservice- /hello#或者直接修改定义也行kubectl edit deployment.v1.apps/nginx-deployment#查看状态kubectl rollout status deployment.v1.apps/nginx-deployment################查看历史并回滚#####################################查看更新历史-看看我们设置的历史总记录数是否生效了kubectl rollout history deployment.v1.apps/nginx-deployment#回滚kubectl rollout undo deployment.v1.apps/nginx-deployment --to-revision=2###############累计更新###############暂停记录版本kubectl rollout pause deployment.v1.apps/nginx-deployment#多次更新操作。##比如更新了资源限制kubectl set resources deployment.v1.apps/nginx-deployment -c=nginx --limits=cpu=200m,memory=512Mi##比如更新了镜像版本kubectl set image deployment.apps/nginx-deployment php-redis=tomcat:8##在继续操作多次##看看历史版本有没有记录变化kubectl rollout history deployment.v1.apps/nginx-deployment#让多次累计生效kubectl rollout resume deployment.v1.apps/nginx-deployment 1、比例缩放,滚动更新apiVersion: apps/v1 ### kind: Deployment ## metadata: name: mydeploy-05 ### 遵循域名编写规范 namespace: default labels: dep: test-04### 期望状态spec: strategy: # type: Recreate ### 把以前全部杀死,直接新建 #RollingUpdate 滚动更新 type: RollingUpdate #滚动更新策略 rollingUpdate: #可以使数字 可以使百分比 #每次更新的副本数量 maxUnavailable: 2 #当前部署的副本数不可用量 maxSurge: 20% replicas: 10 selector: ### 选择器 matchLabels: ### 匹配标签 pod-name: aaa55566 ### 和模板template里面的pod的标签必须一样 #### template: metadata: ### pod的metadata labels: pod-name: aaa55566 spec: containers: - name: nginx-01 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 apiVersion: autoscaling/v1kind: HorizontalPodAutoscalermetadata: creationTimestamp: null name: php-apachespec: maxReplicas: 10 #动态扩容最大副本集 minReplicas: 1 #保留最小副本集 scaleTargetRef: ### 将要扩展的目标引用 apiVersion: apps/v1 kind: Deployment name: php-apache ## Pod limit: 100m targetCPUUtilizationPercentage: 50 ### cpu使用超过50%就扩容,低于就缩容 ##hpa配置 hpa.yamlapiVersion: autoscaling/v1kind: HorizontalPodAutoscalermetadata: name: php-apachespec: maxReplicas: 10 minReplicas: 1 scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: php-apache 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 默认输出11111nginx: 默认输出 默认页; 4、Deployment状态与排错https://kubernetes.io/zh/docs/concepts/workloads/controllers/deployment/#deployment-status 2、DaemonSetDaemonSet 控制器确保所有(或一部分)的节点都运行了一个指定的 Pod 副本。 每当向集群中添加一个节点时,指定的 Pod 副本也将添加到该节点上当节点从集群中移除时,Pod 也就被垃圾回收了删除一个 DaemonSet 可以清理所有由其创建的 Pod DaemonSet 的典型使用场景有 在每个节点上运行集群的存储守护进程,例如 glusterd、ceph在每个节点上运行日志收集守护进程,例如 fluentd、logstash在每个节点上运行监控守护进程,例如 Prometheus Node Exporter、Sysdig Agent、collectd、Dynatrace OneAgent、APPDynamics Agent、Datadog agent、New Relic agent、Ganglia gmond、Instana Agent 等apiVersion: apps/v1kind: DaemonSetmetadata:name: logginglabels: app: loggingspec:selector: matchLabels: name: loggingtemplate: metadata: labels: name: logging spec: containers: - name: logging image: nginx resources: limits: memory: 200Mi requests: cpu: 100m memory: 200Mi tolerations: #设置容忍master的污点 - key: node-role.kubernetes.io/master effect: NoSchedule#查看效果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)的控制器 apiVersion: v1kind: Service #定义一个负载均衡网络metadata: name: stateful-tomcat labels: app: stateful-tomcatspec: ports: - port: 8123 name: web targetPort: 8080 clusterIP: None #NodePort:任意机器+NodePort都能访问,ClusterIP:集群内能用这个ip、service域名能访问,clusterIP: None;不要分配集群ip。headless;无头服务。稳定的域名 selector: app: stateful-tomcat---apiVersion: apps/v1kind: StatefulSet #控制器。metadata: name: stateful-tomcatspec: selector: matchLabels: app: stateful-tomcat # has to match .spec.template.metadata.labels serviceName: "stateful-tomcat" #这里一定注意,必须提前有个service名字叫这个的 replicas: 3 # by default is 1 template: metadata: labels: app: stateful-tomcat # has to match .spec.selector.matchLabels spec: terminationGracePeriodSeconds: 10 containers: - name: tomcat image: tomcat:7 ports: - containerPort: 8080 name: web #观察效果。删除一个,重启后名字,ip等都是一样的。保证了状态#细节kubectl explain StatefulSet.specpodManagementPolicy: OrderedReady(按序)、Parallel(并发)serviceName -required- 设置服务名,就可以用域名访问pod了。 pod-specific-string.serviceName.default.svc.cluster.local#测试kubectl run -i --tty --image busybox dns-test --restart=Never --rm /bin/shping stateful-tomcat-0.stateful-tomcat#我们在这里没有加存储卷。如果有的话 kubectl get pvc -l app=stateful-tomcat 我们就能看到即使Pod删了再拉起,卷还是同样的。 4、Job、CronJob 1、JobKubernetes中的 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 ```yaml#参数说明kubectl explain job.spec activeDeadlineSeconds:10 总共维持10s #该字段限定了 Job 对象在集群中的存活时长,一旦达到 .spec.activeDeadlineSeconds 指定的时长,该 Job 创建的所有的 Pod 都将被终止。但是Job不会删除,Job需要手动删除,或者使用ttl进行清理 backoffLimit: #设定 Job 最大的重试次数。该字段的默认值为 6;一旦重试次数达到了 backoffLimit 中的值,Job 将被标记为失败,且尤其创建的所有 Pod 将被终止; completions: #Job结束需要成功运行的Pods。默认为1 manualSelector: parallelism: #并行运行的Pod个数,默认为1 ttlSecondsAfterFinished: ttlSecondsAfterFinished: 0 #在job执行完时马上删除 ttlSecondsAfterFinished: 100 #在job执行完后,等待100s再删除 #除了 CronJob 之外,TTL 机制是另外一种自动清理已结束Job(Completed 或 Finished)的方式: #TTL 机制由 TTL 控制器 提供,ttlSecondsAfterFinished 字段可激活该特性 #当 TTL 控制器清理 Job 时,TTL 控制器将删除 Job 对象,以及由该 Job 创建的所有 Pod 对象。# job超时以后 已经完成的不删,正在运行的Pod就删除#单个Pod时,Pod成功运行,Job就结束了#如果Job中定义了多个容器,则Job的状态将根据所有容器的执行状态来变化。#Job任务不建议去运行nginx,tomcat,mysql等阻塞式的,否则这些任务永远完不了。##如果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、CronJobCronJob 按照预定的时间计划(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. ```yamlapiVersion: batch/v1beta1kind: CronJobmetadata: name: hellospec: schedule: "*/1 * * * *" #分、时、日、月、周 jobTemplate: spec: template: spec: containers: - name: hello image: busybox args: - /bin/sh - -c - date; echo Hello from the Kubernetes cluster restartPolicy: OnFailure