首先我们要理解:一个应用跑在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. Java 多线程与并发【知识点笔记】

    Java 多线程与并发[知识点笔记] Java多线程与并发 先说一下线程与进程的由来: 在初期的计算机,计算机只能串行执行任务,并且需要长时间的等待用户的输入才行 到了后来,出现了批处理,可以预先将用 ...

  2. Ubuntu本地提权适配不同小版本内核(CVE-2017-16995)

    朋友在执行的时候说有的会出现提权不成功,内核crash掉的现象.因为cred结构体的偏移量可能因为内核版本不同.内核编译选项不同而出现差异,作者给的exp偏移量是写死的,所以exp里面对应的偏移地址也 ...

  3. pikachu CSRF

    CSRF简介 CSRF 是 Cross Site Request Forgery 的 简称,中文名为跨域请求伪造在CSRF的攻击场景中,攻击者会伪造一个请求(一般是一个链接)然后欺骗目标用户进行点击, ...

  4. HTTP头参数详解及其中的危险

    一.重要的头参数 user_agent 发出请求的用户信息 X-Forwarded-For 表示 HTTP 请求端真实 IP(格式:X-Forwarded-For: client, proxy1, p ...

  5. Redis应用场景及缓存问题

    1.应用场景 (1)   缓存 缓存机制几乎在所有的大型网站都有使用,合理地使用缓存不仅可以加快数据的访问速度,而且能够有效地降低后端数据源的压力.Redis 提供了键值过期时间设置,并且也提供了灵活 ...

  6. AECC2018同时中英文切换多开使用,加倍提高你的工作效率

    最近相信不少人已经更新了AECC2018,升级之后第一件重要的事当然是中英文的切换了,要不然工作中很麻烦.对于一直习惯用中文的人来说,在用模板过程中会出现各种表达式报错极其不方便,而对于习惯英文操作朋 ...

  7. 【springcloud】Eureka 常用配置解析

    转自:https://www.cnblogs.com/zyon/p/11023750.html 1. 配置项解析 1.1 通用配置 # 应用名称,将会显示在Eureka界面的应用名称列 spring. ...

  8. 在EXCEL中,判断同列数据重复,并标识出来

    推荐方法:建立辅助列,查找B列数据是否重复.=IF(COUNTIF(B:B,B1)>1,"重复","")按住公式单元格右下角实心十字,向下拖拽复制公式.= ...

  9. k8s笔记0528-基于KUBERNETES构建企业容器云手动部署集群记录-4

    部署kubelet 1.二进制包准备 将软件包从linux-node1复制到linux-node2中去. [root@linux-node1 ~]# cd /usr/local/src/kuberne ...

  10. C#多线程开发-线程池03

    你好,我是阿辉. 前面2篇文章介绍了线程的基础知识和线程同步,下面我们来一起认识学习下,线程池的使用. 线程池 创建线程是昂贵的操作,所以为每个短暂的异步操作创建线程会产生显著的开销.一般情况下,都会 ...