首先我们要理解:一个应用跑在k8s集群上了,那么这个应用就是一个工作负载(workloads)。

在k8s中会用pod的来承载这个应用,那么负责管理这个pod的东西就叫工作负载资源(workload resources

我们可以简单理解为是这样的:

工作负载资源又支持jj自定义或使用第三方资源,这里我们先认识内置的,k8s内置工作负载资源包含如下:

  • deployment
  • replicaset
  • statefulset
  • daemonset
  • jobs
  • cronjob
  • TTL Controller for Finished Resources
  • ReplicationController (逐步被ReplicaSet替代)

那让我们从最常用的deployment开始吧。

一个 Deployment 为 Pods和 ReplicaSets提供声明式的更新能力,我们从下面几个方面开始上手:

  1. 创建 Deployment 将 ReplicaSet 上线。 ReplicaSet 在后台创建 Pods。 检查 ReplicaSet 的上线状态,查看其是否成功。
  2. **通过更新 Deployment 的 Pod模板(TemplateSpec),声明 Pod 的新状态 。 **新的 ReplicaSet 会被创建,Deployment 以受控速率将 Pod 从旧 ReplicaSet 迁移到新 ReplicaSet。 每个新的 ReplicaSet 都会更新到 Deployment 的修订版本。
  3. 如果 Deployment 与你的预期不符,可以回滚到较早的 Deployment 版本。 每次回滚都会更新到 Deployment 修订的新版本。
  4. 通过Deployment 扩大应用规模承担更多负载
  5. 暂停 Deployment ,对 PodTemplateSpec 做修改然后恢复执行,让pod更新到新版本。

deployment创建

说了这么多还不如手动写一个deployment的yml声明实在(如果你喜欢json也可以是json格式,本质上还是将yml转换为json格式请求的api)。

下面deployment创建了一个replicaset,这个replicaset将会启动三个nginx的pod:

nginx-deployment.yml

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

通过kubectl apply 将声明文件转换为api提交给apiserver

$ kubectl apply -f nginx-deployment.yml
deployment.apps/nginx-deployment created

查看deployment资源创建的对象nginx-deployment(这里的对象与编程语言中对象同义)

$ kubectl get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 3/3 3 3 67m

查看nginx-deplyment创建的replicat对象nginx-deployment-767cf44bff

$kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-deployment-767cf44bff 3 3 3 68m

最后是nginx-deployment-767cf44bff创建的三个pod对象

$ kubectl get pod 

NAMESPACE     NAME                                READY   STATUS    RESTARTS   AGE
default nginx-deployment-767cf44bff-9fj8q 1/1 Running 0 13m
default nginx-deployment-767cf44bff-f746l 1/1 Running 0 13m
default nginx-deployment-767cf44bff-ktbzl 1/1 Running 0 13m

也可以通过rollout status 查看 Deployment 上线状态。

$kubectl rollout status deployment/nginx-deployment
deployment "nginx-deployment" successfully rolled out

这就是deployment资源创建对象的关系图:

现在我们主要来看一下创建的这个nginx-deployment声明。

我们把yml文件分为两个大部分(红色):

  • 属性。

    • apiVersion - 创建该对象所使用的 Kubernetes API 的版本
    • kind - 想要创建的对象的类别
    • metadata - 帮助唯一性标识对象的一些数据,包括一个 name 字符串、UID 和可选的 namespace
  • 规格 spec(specification)

    • replicas - 期望的pod副本数量
    • selector - pod标签选择器
    • template - pod模板

    我们在selector中匹配包含app=nginx标签的pod,pod模板中又为新创建的pod打上app=nginx的标签,这样就形成了控制闭环。

我们通过可以show-labels查看pod的标签

$ kubectl get pod  --show-labels
NAME READY STATUS RESTARTS AGE LABELS
nginx-deployment-767cf44bff-9fj8q 1/1 Running 0 81m app=nginx,pod-template-hash=767cf44bff
nginx-deployment-767cf44bff-f746l 1/1 Running 0 81m app=nginx,pod-template-hash=767cf44bff
nginx-deployment-767cf44bff-ktbzl 1/1 Running 0 81m app=nginx,pod-template-hash=767cf44bff

为什么pod中又有一个pod-template-hash标签?

eployment 控制器将 pod-template-hash 标签添加到 Deployment 所创建的每一个 ReplicaSet 中。我们来看一下rs的selector描述:

$ kubectl describe rs
Name: nginx-deployment-767cf44bff
Namespace: default
Selector: app=nginx,pod-template-hash=767cf44bff

pod-template-hash 标签是通过对 ReplicaSet 的 PodTemplate 进行哈希处理,此标签可确保 Deployment 的子 ReplicaSets 不冲突,所生成的哈希值被添加到 ReplicaSet的selector、Pod 模板labels、以及 ReplicaSet 旗下的任何 Pod 中。这样deployment下的replicaset只能控制自己的pod。恩,妙哉。

不同工作负载资源所创建的对象,spec是不同的。比如在Deployment中spec可以包含如下字段,这个可以在Kubernetes API中找到。

大多数字段都包含了一个默认值,除非有特殊需求,大多数时候很难被用到。如果需要的时候你再谷歌一下也不迟。到这里deployment工作负载的第一个用例已经成了。


deployment更新

仅当 Deployment Pod 模板(即 .spec.template字段)发生改变时,例如模板的标签或容器镜像被更新, 才会触发 Deployment 上线。

其他更新(如对 Deployment 执行扩缩容的操作)不会触发上线动作。

  1. 我们可以通过kubectl set 命令更新现有工作负责资源
$ kubectl set image deployment/nginx-deployment nginx-web=nginx:1.17 --record
deployment.apps/nginx-deployment image updated

--record 用于记录kubectl对资源的操作。便于后期需要时回滚。下面会说到。

kubectl set -h 查询set支持更新的内容。

Available Commands:

  • env Update environment variables on a pod template
  • image Update image of a pod template

    resources Update resource requests/limits on objects with pod templates
  • selector Set the selector on a resource
  • serviceaccount Update ServiceAccount of a resource
  • subject Update User, Group or ServiceAccount in a RoleBinding/ClusterRoleBinding
  1. 使用kubectl edit编辑deployment后自动更新
$ kubectl edit deployment/nginx-deployment --record
deployment.apps/nginx-deployment edited
  1. 直接更新deployment yml文件

个人觉得最好的方式是更新yml声明文件,通过kubectl apply 应用即可,这样你只要管理好你的的nginx-deployment.yml做到心中有数

当我们更新后查看rs状态,此时deployment 创建了一个新的nginx-deployment replicaset并投入使用。

$ kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-deployment-64f9765d86 4 4 4 4h11m
nginx-deployment-6cf9cc9c9d 0 0 0 5h6m

这里顺便看一下deployment中pod滚动更新策略

我们可以通过kubectl describe deployment 查看RollingUpdateStrategy字段,即在滚动更新时最大不可用pod数为1/4,最大可用pod数为期望副本数1.25倍(多25%)。

RollingUpdateStrategy: 25% max unavailable, 25% max surge

假如我们将 deployment_A 中4个副本(pod)更新到deployment_B(也是4副本),其中的某个数据pod状态如下

$ kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx-deployment-64f9765d86-c9rlj 0/1 ContainerCreating 0 2s
nginx-deployment-64f9765d86-wngmx 0/1 ContainerCreating 0 2s
nginx-deployment-7fcdcb4b75-lmsmm 1/1 Running 0 4h6m
nginx-deployment-7fcdcb4b75-m99tx 1/1 Terminating 0 4h5m
nginx-deployment-7fcdcb4b75-tghb2 1/1 Running 0 4h5m
nginx-deployment-7fcdcb4b75-xfs2m 1/1 Running 0 4h6m

即只有1个在停止,正在创建2个新pod(即将有5个可用),详细滚动过程可通过kubectl descibe deployment中events查看。

尽量不要更新模板中labels,会造成pod孤立。在某些API版本已经被禁止了。


deployment回滚

deployment回滚和更新一样,Pod 模板部分会被回滚。

我们通过 rollout history 来查看某个deployment的历史版本。即之前通过--record所记录的。

$ kubectl  rollout history   deployment/nginx-deployment
deployment.apps/nginx-deployment
REVISION CHANGE-CAUSE
1 <none>
2 <none>
3 kubectl apply --filename=nginx-deployment.yml --record=true
4 kubectl apply --filename=nginx-deployment.yml --record=true
5 kubectl set image deployment/nginx-deployment nginx-web=nginx:1.17 --record=true
9 kubectl edit deployment/nginx-deployment --record=true
10 kubectl edit deployment/nginx-deployment --record=true

回滚到第5个版本。

$ kubectl rollout undo deployment/nginx-deployment --to-revision=5
deployment.apps/nginx-deployment rolled back

或者直接回滚到上一个版本。

$ kubectl rollout undo deployment/nginx-deployment

还是如前面所说,回滚只一种更工程化的说法,其实回滚也是一种更新,yml声明依然是核心。所以我们更应该关注的对deployment的yml文件的版本控制。


deployment缩放

缩放控制的是.spec.replicas,也可通过scale命令操作。

$ kubectl scale deployment/nginx-deployment --replicas=6
deployment.apps/nginx-deployment scaled

水平自动缩放本为暂不涉及,后面文章会详细讨论。可以参考:Horizontal Pod Autoscaler


deployment暂停与恢复

我们可以在触发更新之前暂停 Deployment,然后做多个修改之后再恢复,进行一次性上线。

还是我们之前的deployment

$ kubectl get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 4/4 4 4 30m $ kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-deployment-64f9765d86 4 4 4 30m

暂停deployment

$ kubectl rollout pause deployment/nginx-deployment
error: deployments.apps "nginx-deployment" is already paused

对nginx-deployment做一些更新

  1. 直接修改yml文件,更新镜像为nginx:1.17,并通过kubectl apply应用更改。
  2. 通过set做资源限制。
$ kubectl set resources deployment/nginx-deployment -c=nginx-web --limits=cpu=50m,memory=100Mi
deployment.apps/nginx-deployment resource requirements updated

此时我们查看rs副本状态,查看deployment版本信息

$ kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-deployment-64f9765d86 4 4 4 40m $ kubectl rollout history deployment/nginx-deployment
deployment.apps/nginx-deployment
REVISION CHANGE-CAUSE
1 <none>

可以看到还是之前的rs,deployment并没有将我们的修改应用到对象中。

现在我们将deployment通过Resume恢复

$ kubectl rollout resume deployment/nginx-deployment
deployment.apps/nginx-deployment resumed

查看rs状态

$ kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-deployment-64f9765d86 3 3 3 41m
nginx-deployment-7f4447656b 2 2 0 4s

这会deployment已恢复,并应用了对资源对象的更新。


参考:

k8s官方文档Deployment

k8s工作负载资源之deployment的更多相关文章

  1. Kubernetes K8S之资源控制器StatefulSets详解

    Kubernetes的资源控制器StatefulSet详解与示例 主机配置规划 服务器名称(hostname) 系统版本 配置 内网IP 外网IP(模拟) k8s-master CentOS7.7 2 ...

  2. k8s负载资源StatefulSet工作解析

    在k8s中工作负载资源StatefulSet用于管理有状态应用. 什么是无状态? 组成一个应用的pod是对等的,它们之前没有关联和依赖关系,不依赖外部存储. 即我们上篇小作文中deployment创建 ...

  3. 跟k8s工作负载Deployments的缘起缘灭

    跟k8s工作负载Deployments的缘起缘灭 考点之简单介绍一下什么是Deployments吧? 考点之怎么查看 Deployment 上线状态? 考点之集群中能不能设置多个Deployments ...

  4. k8s控制器资源(五)

    Pod pod在之前说过,pod是kubernetes集群中是最小的调度单元,pod中可以运行多个容器,而node又可以包含多个pod,关系如下图: 在对pod的用法进行说明之前,有必要先对docke ...

  5. K8s容器资源限制

    在K8s中定义Pod中运行容器有两个维度的限制: 1. 资源需求:即运行Pod的节点必须满足运行Pod的最基本需求才能运行Pod. 如: Pod运行至少需要2G内存,1核CPU    2. 资源限额: ...

  6. k8s系列---资源指标API及自定义指标API

    不得不说千万不要随意更改版本,我用的1.13的版本,然后学到这一步时,还因yaml文件不同,卡住了很久,然后各种google才找到解决办法  https://www.linuxea.com/2112. ...

  7. Kubernetes K8S之资源控制器Daemonset详解

    Kubernetes的资源控制器Daemonset详解与示例 主机配置规划 服务器名称(hostname) 系统版本 配置 内网IP 外网IP(模拟) k8s-master CentOS7.7 2C/ ...

  8. Kubernetes K8S之资源控制器Job和CronJob详解

    Kubernetes的资源控制器Job和CronJob详解与示例 主机配置规划 服务器名称(hostname) 系统版本 配置 内网IP 外网IP(模拟) k8s-master CentOS7.7 2 ...

  9. k8s控制器资源

    k8s控制器资源   Pod pod在之前说过,pod是kubernetes集群中是最小的调度单元,pod中可以运行多个容器,而node又可以包含多个pod,关系如下图: 在对pod的用法进行说明之前 ...

随机推荐

  1. Python--数据存储

    新建测试文档测试.txt内容如下: 张三:今天天气真好. 李四:是的,真的太好了. 张三:阳光明媚. 李四:鸟语花香. 王五:装逼现场:请带好安全帽 张三:难得好天气,今天就不偷懒了. 李四:能把乞讨 ...

  2. Shell-10-标准输入输出错误

    标准输入输出和错误 标准输入.输出和错误 重定向符号 示例 1 1 标准输出 2 错误输出 2 标准输出和错误输出同时定向到一个文件中 >share.txt 2>&1 3 > ...

  3. Redis-03-集群

    集群介绍 Redis Cluster 是 redis 的分布式解决方案, 在3.0版本正式推出,当遇到单机.内存.并发.流量等瓶颈时,可以采用Cluster架构方案达到负载均衡目的 Redis Clu ...

  4. Error running 'Tomcat 9.0.24': port out of range:-1

    修改tomcat安装目录下的conf--server.xml检查一下,端口不能是-1, 一般会选80,或者1-65535之间的任意一个整数

  5. 在ASP.NET Core调用WebService

    一.前言 现实生产中,有一些比较老的系统对外提供的接口都是WebService形式的,如果是使用.NET Framework创建的项目调用WebService非常方便,网上有很多代码示例,这里不在讲解 ...

  6. Json 文件 : 出现 Expected value at 1:0 问题的解决

    只要找一个json在线解析,验证你的json文件格式的正确性,错误可以忽略. 如要消除红叉,关闭Json Validation即可,如下操作:

  7. 链表LinkedList、堆栈Stack、集合Set

    链表LinkedList LinkedList 也像 ArrayList 一样实现了基本的 List 接口,但它在 List 中间执行插入和删除操作时比 ArrayList 更高效.然而,它在随机访问 ...

  8. Java程序设计学习笔记(六) — 网络编程

    时间:2016-5-8 02:03 --网络编程        网络传输实际上就是进行数据传输.    一.传输的步骤:        1.对对方IP地址进行定位.        2.将数据打包发送到 ...

  9. 刷题-力扣-168. Excel表列名称

    168. Excel表列名称 题目链接 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/excel-sheet-column-title 著作权 ...

  10. Learning ROS: Roslaunch tips for large projects

    Design tip: Top-level launch files should be short, and consist of include's to other files correspo ...