YAML介绍;API资源对象Pod;Pod原理和生命周期;Pod资源限制
1)认识YAML
官网(https://yaml.org/)
YAML 语言创建于 2001 年,比 XML 晚了三年。YAML虽然在名字上模仿了XML,但实质上与XML完全不同,更适合人类阅读,计算机解析起来也很容易。
JSON是YAML的子集,YAML支持整数、浮点数、布尔、字符串、数组和对象等数据类型。
也就是说,任何合法的JSON文档也都是YAML文档,如果你了解JSON,那么学习YAML会容易很多。
但和JSON比起来,YAML的语法更简单,形式也更清晰紧凑,主要有如下规则:
- 使用缩进表示层次,缩进不允许使用tab,只能用空格,缩进空格数多少不要求,只要保证同一层级空格数一样多即可
- 使用 # 书写注释
- 数组(列表)是使用 - 开头的清单形式
- 对象(字典)的格式与JSON基本相同,但Key不需要使用双引号。
- 表示对象的 : 和表示数组的 - 后面都必须要有空格。
- 可以使用 — 在一个文件里分隔多个YAML对象。
2)YAML示例
YAML数组(列表)
ProgrammingLanguages:- Python- Java- JavaScript
对应json是这样的:
{"ProgrammingLanguages": ["Python","Java","JavaScript"]
}
YAML对象(字典)
CloudResources:virtualMachines: 5storageAccounts: 2
对应json是这样:
{"CloudResources": {"virtualMachines": 5,"storageAccounts": 2}
}
复杂的例子,组合数组和对象
DataCenter:primary:- database: active- cache: activesecondary:- webserver: active- load-balancer: inactive- storage-drivers: [s3, ceph, glusterfs]
对应json为:
{"DataCenter": {"primary": [{"database": "active"},{"cache": "active"}],"secondary": [{"webserver": "active"},{"load-balancer": "inactive"},{"storage-drivers": ["s3", "ceph", "glusterfs"]}]}
}
用一张图来总结YAML
API资源对象Pod
在K8s里,YAML用来声明API对象的,那么API对象都有哪些?可以这样查看资源对象:
kubectl api-resources
Pod为K8s里最小、最简单的资源对象。
运行一个pod
kubectl run pod-demo --image=busybox
从已知Pod导出YAML文件:
kubectl get pod pod-demo -o yaml > pod-demo.yaml
Pod YAML示例:
四个核心部分:apiVersion、Kind、metadata、spec
vi ngx-pod.yaml
apiVersion: v1
kind: Pod
metadata:name: ngx-podnamespace: tang #命名空间要提前创建好labels: ## labels字段非常关键,它可以添加任意数量的Key-Value,目的是为了让pod的信息更加详细env: devspec: ##用来定义该pod更多的资源信息,比如containers, volume, storagecontainers: ##定义容器属性- image: nginx:1.23.2imagePullPolicy: IfNotPresent ##镜像拉取策略,三种:Always/Never/IfNotPresent,一般默认是IfNotPresent,也就是说只有本地不存在才会远程拉取镜像,可以减少网络消耗。name: ngxenv: ##定义变量,类似于Dockerfile里面的ENV指令- name: osvalue: "Rocky Linux"ports:- containerPort: 80
创建命名空间namespace:
kubectl create namespace tang
使用YAML创建pod:
kubectl apply -f testpod.yaml
查看这个pod:
kubectl get pod -n tang
删除pod:
kubectl delete -f testpod.yaml
Pod原理和生命周期
Pod生命周期包括以下几个阶段:
- Pending:在此阶段,Pod已被创建,但尚未调度到运行节点上。此时,Pod可能还在等待被调度,或者因为某些限制(如资源不足)而无法立即调度。
- Running:在此阶段,Pod已被调度到一个节点,并创建了所有的容器。至少有一个容器正在运行,或者正在启动或重启。
- Succeeded:在此阶段,Pod中的所有容器都已成功终止,并且不会再次重启。
- Failed:在此阶段,Pod中的至少一个容器已经失败(退出码非零)。这意味着容器已经崩溃或以其他方式出错。
- Unknown:在此阶段,Pod的状态无法由Kubernetes确定。这通常是因为与Pod所在节点的通信出现问题。
除了这些基本的生命周期阶段之外,还有一些更详细的容器状态,用于描述容器在Pod生命周期中的不同阶段:
- ContainerCreating:容器正在创建,但尚未启动。
- Terminating:容器正在终止,但尚未完成。
- Terminated:容器已终止。
- Waiting:容器处于等待状态,可能是因为它正在等待其他容器启动,或者因为它正在等待资源可用。
- Completed:有一种Pod是一次性的,不需要一直运行,只要执行完就会是此状态。
3)创建Pod流程
1. 用户通过kubectl或其他API客户端提交Pod对象给API server。
2. API server尝试将Pod对象的相关信息存入etcd中,写入操作完成后API server会返回确认信息至客户端。
3. API server开始反映etcd中的状态变化。
4. 所有的Kubernetes组件均使用watch机制来跟踪检查API server上的相关变化。
5. Kube-scheduler通过其watcher观察到API server创建了新的Pod对象但尚未绑定至任何节点。
6. Kube-scheduler为Pod对象挑选一个工作节点并将结果更新至API server。
7. 调度结果由API server更新至etcd,而且API server也开始反映此Pod对象的调度结果。
8. Pod 被调度的目标工作节点上的kubelet尝试在当前节点上调用Containerd启动容器,并将容器的结果状态返回至API server。
9. API server将Pod 状态信息存入etcd。
10. 在etcd确认写操作完成后,API server将确认信息发送至相关的kubelet。
4)删除Pod流程
1. 请求删除Pod。
2. API server将Pod标记为Terminating状态。
3. (与第 2 步同时进行)kubelet在监控到Pod对象转为Terminating状态的同时启动Pod关闭过程。
4. (与第 2 步同时进行)Service将Endpoint摘除。
5. 如果当前Pod对象定义了preStop hook,则在其标记为Terminating后会以同步的方式执行,宽限期开始计时。
6. Pod中的容器进程收到TERM信号。
7. 宽限期结束后,若进程仍在运行,会收到SIGKILL信号。
8. kubelet请求API server将此Pod对象的宽限期设置为0,从而完成删除操作。
Pod资源限制
1)Resource Quota
资源配额Resource Quotas(简称quota)是对namespace进行资源配额,限制资源使用的一种策略。
K8S是一个多用户架构,当多用户或者团队共享一个K8S系统时,SA使用quota防止用户(基于namespace的)的资源抢占,定义好资源分配策略。
Quota应用在Namespace上,默认情况下,没有Resource Quota的,需要另外创建Quota,并且每个Namespace最多只能有一个Quota对象。
可限定资源类型:
计算资源:limits.cpu、requests.cpu、limits.memory、requests.memory
存储资源,包括存储资源的总量以及指定storage class的总量
requests.storage:存储资源总量,如500Gi
persistentvolumeclaims:pvc的个数
对象数,即可创建的对象的个数
pods, replicationcontrollers, configmaps, secrets,persistentvolumeclaims,services, services.loadbalancers,services.nodeports
注意:
Quota依赖于资源管理器,可以使用资源对象limits或者在创建资源对象时为pod设置资源限制(resources),如果不设置,资源对象无法创建。
当该namespace中的任意个额度达到预设Quota时,将无法创建资源对象。
Resource Quota示例:
cat > quota.yaml <<EOF
apiVersion: v1
kind: ResourceQuota
metadata:namespace: tangname: tang-quotaspec:hard:pods: 50 ## 该命名空间里最多支持启动50个Podsrequests.cpu: 0.5 ##最低保证0.5个CPU资源requests.memory: 512Mi ##最低保证512M内存limits.cpu: 5 ##最多使用5核CPUlimits.memory: 16Gi ##最多使用16G内存configmaps: 20 ##最多支持20个configMapspersistentvolumeclaims: 20 ##最多支持20个pvcreplicationcontrollers: 20 ##最多支持20个replicationControllerssecrets: 20 ##最多支持20个secretsservices: 50 ##最多支持50个services
EOF
生效
kubectl apply -f quota.yaml
查看
kubectl get quota -n aming
测试:
为了显示限额效果,修改quota.yaml,将pod限制数改为5,其它先删除掉
命令行创建deployment,指定Pod副本为7
kubectl create deployment testdp --image=nginx:1.23.2 -n aming --replicas=7
查看deployment和pod
kubectl get deploy,po -n aming
2)Pod的limits和requests
Resource Quota是针对namespace下面所有的Pod的限制,而Pod自身也有限制。
示例:
cat > quota-pod.yaml <<EOF
apiVersion: v1
kind: Pod
metadata:name: quota-podnamespace: amingspec:containers:- image: nginx:1.23.2name: ngximagePullPolicy: IfNotPresentports:- containerPort: 80resources:limits:cpu: 0.5 ##限制Pod CPU资源最多使用500m,这里的0.5=500m,1=1000mmemory: 2Gi ##限制内存资源最多使用2Grequests:cpu: 200m ##K8s要保证Pod使用的最小cpu资源为200m,如果node上资源满足不了,则不会调度到该node上memory: 512Mi ##K8s要保证Pod使用最小内存为512M,如果node上资源满足不了,则不会调度到该node上
EOF