首先我们要理解:一个应用跑在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.ym
apiVersion: apps/v1
kind: Deployment
metadata:name: nginx-deployment
spec:replicas: 3selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:containers:- name: nginx-webimage: nginx:latestports:- 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-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) 我们在selector中匹配包含
app=nginx
标签的pod,pod模板中又为新创建的pod打上app=nginx
的标签,这样就形成了控制闭环。replicas
- 期望的pod副本数量selector
- pod标签选择器template
- pod模板
我们通过可以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中找到。