k8s工作负载资源之deployment
首先我们要理解:一个应用跑在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提供声明式的更新能力,我们从下面几个方面开始上手:
- 创建 Deployment 将 ReplicaSet 上线。 ReplicaSet 在后台创建 Pods。 检查 ReplicaSet 的上线状态,查看其是否成功。
- **通过更新 Deployment 的 Pod模板(TemplateSpec),声明 Pod 的新状态 。 **新的 ReplicaSet 会被创建,Deployment 以受控速率将 Pod 从旧 ReplicaSet 迁移到新 ReplicaSet。 每个新的 ReplicaSet 都会更新到 Deployment 的修订版本。
- 如果 Deployment 与你的预期不符,可以回滚到较早的 Deployment 版本。 每次回滚都会更新到 Deployment 修订的新版本。
- 通过Deployment 扩大应用规模承担更多负载。
- 暂停 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 执行扩缩容的操作)不会触发上线动作。

- 我们可以通过
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
- 使用
kubectl edit编辑deployment后自动更新
$ kubectl edit deployment/nginx-deployment --record
deployment.apps/nginx-deployment edited
- 直接更新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做一些更新
- 直接修改yml文件,更新镜像为nginx:1.17,并通过kubectl apply应用更改。
- 通过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的更多相关文章
- Kubernetes K8S之资源控制器StatefulSets详解
Kubernetes的资源控制器StatefulSet详解与示例 主机配置规划 服务器名称(hostname) 系统版本 配置 内网IP 外网IP(模拟) k8s-master CentOS7.7 2 ...
- k8s负载资源StatefulSet工作解析
在k8s中工作负载资源StatefulSet用于管理有状态应用. 什么是无状态? 组成一个应用的pod是对等的,它们之前没有关联和依赖关系,不依赖外部存储. 即我们上篇小作文中deployment创建 ...
- 跟k8s工作负载Deployments的缘起缘灭
跟k8s工作负载Deployments的缘起缘灭 考点之简单介绍一下什么是Deployments吧? 考点之怎么查看 Deployment 上线状态? 考点之集群中能不能设置多个Deployments ...
- k8s控制器资源(五)
Pod pod在之前说过,pod是kubernetes集群中是最小的调度单元,pod中可以运行多个容器,而node又可以包含多个pod,关系如下图: 在对pod的用法进行说明之前,有必要先对docke ...
- K8s容器资源限制
在K8s中定义Pod中运行容器有两个维度的限制: 1. 资源需求:即运行Pod的节点必须满足运行Pod的最基本需求才能运行Pod. 如: Pod运行至少需要2G内存,1核CPU 2. 资源限额: ...
- k8s系列---资源指标API及自定义指标API
不得不说千万不要随意更改版本,我用的1.13的版本,然后学到这一步时,还因yaml文件不同,卡住了很久,然后各种google才找到解决办法 https://www.linuxea.com/2112. ...
- Kubernetes K8S之资源控制器Daemonset详解
Kubernetes的资源控制器Daemonset详解与示例 主机配置规划 服务器名称(hostname) 系统版本 配置 内网IP 外网IP(模拟) k8s-master CentOS7.7 2C/ ...
- Kubernetes K8S之资源控制器Job和CronJob详解
Kubernetes的资源控制器Job和CronJob详解与示例 主机配置规划 服务器名称(hostname) 系统版本 配置 内网IP 外网IP(模拟) k8s-master CentOS7.7 2 ...
- k8s控制器资源
k8s控制器资源 Pod pod在之前说过,pod是kubernetes集群中是最小的调度单元,pod中可以运行多个容器,而node又可以包含多个pod,关系如下图: 在对pod的用法进行说明之前 ...
随机推荐
- 解决微信官方SDK给出1.4.0等版本没有预览文件(previewFile)等接口
使用苹果手机测试 调用微信的js-sdk在系统中实现上传.预览附件的功能.在自己的手机测试通过后,直接丢给QA测试了 本以为相安无事了,没想到QA用安卓手机测的时候居然不得,使用的是下载下来的jwei ...
- Java之JSP
JSP JSP简介 JSP指的是 JavaServerPages ,Java服务器端页面,也和Servlet一样,用来开发动态web JSP页面中可以嵌入java代码为用户提供动态数据 JSP原理 J ...
- 浅谈 SQL 注入(注入篇)
一.SQL注入简介 1.1 什么是SQL注入 在用户可控制的参数上过滤不严或没有任何限制,使得用户将传入的参数(如URL,表单,http header)与SQL语句合并构成一条 SQL语句传递给web ...
- 浅看spa单页应用路由
路由观察浏览器的URL的变更.当URL 变更时,路由会解析它并生成一个新的路由实例. 一个基本的路由是这样的: class Router { private _defaultController: s ...
- .net core2.1 迁移.net core 3.1
1.解决方案->属性-->目标框架 .net core3.1 2.删除旧的Nuget包添加新的NuGet包 3.修改Startup.cs 修改ConfigureServices 修改Con ...
- C#基础知识---迭代器与Foreach语句
一.Foreach语句简介 在C# 1.0中我们经常使用foreach来遍历一个集合中的元素,然而如果一个集合要支持使用foreach语句来进行遍历,这个集合一般需要IEnumerable或IEnum ...
- 判断N是否是质数,为什么判断到根号N就可以了
N=根号N*根号NN的因数除了根号N,其他都是成对存在的, 且必定一个大于根号N一个小于根号N假设N不是质数,有个因数大于根号N(不是N本身) 则N必定有一个与之对应的小于根号N的因数也就是说,如果2 ...
- WPF设计自定义控件
在实际工作中,WPF提供的控件并不能完全满足不同的设计需求.这时,需要我们设计自定义控件. 这里LZ总结一些自己的思路,特性如下: Coupling UITemplate Behaviour Func ...
- 关于struts中Ognl和iterator配合再次理解
Person.jsp (struts.xml中省略) package com.mzy.entity; public class Person { private String name; privat ...
- 对集合使用Comparator
1 import java.util.Comparator; 2 import java.util.PriorityQueue; 3 4 /** 5 * 对集合使用Comparator,不改变对象的自 ...