文章目录
Pod生命周期
Pod生命周期概述
- 什么是Pod生命周期?
- Pod对象自从其创建开始至终止的时间范围称为生命周期
- 在这段时间中Pod处在不同的状态并可以执行相关操作
- 生命周期有什么用途
- 复杂服务运行时有启动顺序、依赖关系等,我们可以在声明周期中配置相关性,解决启动关系依赖等问题
- 容器服务在启动前或运行过程中需要做的相关操作,例如:配置文件生成、数据预加载、依赖服务的检测、安装等
- 生命周期中能做什么
- 必须操作:启动运行main容器
- 可选操作:设置容器的初始化方法:(InitContainer)
- 可选操作:配置容器探针:生命探测(IivenessProbe)、就绪探测(readinessProbe)、启动探测(startupProbe)
- 可选操作:添加事件处理函数:启动后回调(PostStart)、结束前回调(PreStop)
- Pod生命周期
Init容器
- Init容器(可选配置)
- init容器是一种特殊容器,在Pod内主容器启动之前执行,可以依据需求的不同定义多个
- init容器可以使用其他镜像,也可以包括一些主容器镜像中不存在的实用工具和安装脚本
- init容器的生命是有限的,不能无休止的运行下去,只有在初始化容器执行完成以后才会启动主容器,即只要初始化容器的退出状态代码不为0,则不会启动主容器
- init容器示例
[root@master ~] vim web1.yml
---
kind: Pod
apiVersion: v1
metadata:
name: web
spec:
restartPolicy: OnFailure #只有Always不生效,不然主容器永远无法启动
initContainers: #初始化容参数
- name: task1
image: myos:latest
command: ["sh"]
args:
- -c
- |
ID=${RANDOM}
echo "ID is ${ID}"
sleep 5
exit $((ID%2))
containers:
- name: apache
image: myos:httpd
[root@master ~] kubectl apply -f webl.yaml
pod/web1 created
[root@master ~] kubectl get pods -w
NAME READY STATUS RESTARTS AGE
web1 0/1 Init:0/1 0 1s
# 如果初始化任务失败就重复执行,直到成功为止
web1 0/1 Init:Error 0 6s
web1 0/1 Init:0/1 1 (1s ago) 7s
web1 0/1 PodInitializing 1 12s
# 初始化容器执行成功之前,主容器不会启动
web1 1/1 Running 1 13s
- init容器和普通容器非常像,除了以下三点
- 顺序执行,每个容器都必须等待上一个容器成功完成执行,如果init容器失败,kubectl会不断地重启该init容器,直到该容器成功为止
- 如果Pod对应的restartPolicy值为Never,并且Pod的init容器失败,则k8s会将整个Pod状态设置为失败,主容器将无法执行。
- 它们必须全部运行到生命周期结束
- init容器保护策略
[root@master ~] vim web1.yml
---
kind: Pod
apiVersion: v1
metadata:
name: web
spec:
restartPolicy: Never #设置失败后不重复执行
initContainers:
- name: task1
image: myos:latest
command: ["sh"]
args:
- -c
- |
ID=${RANDOM}
echo "ID is ${ID}"
sleep 5
exit $((ID%2))
- name: task2
image: myos:latest
command: ["sh"]
args:
- -c
- |
ID=${RANDOM}
echo "ID is ${ID}"
sleep 5
exit $((ID%2))
containers:
- name: apache
image: myos:httpd
# 重新创建 Pod
[root@master ~] kubectl replace --force -f webl.yaml
pod "web1" deleted
pod/web1 created
# 必须所有任务都成功,否则 Pod 创建失败
[root@master ~] kubectl get pods -w
NAME READY STATUS RESTARTS AGE
web1 0/1 Init:0/1 0 1s
web1 0/1 Init:1/2 0 3s
web1 0/1 Init:Error 0 5s
web1 0/1 Init:Error 0 7s
容器探针
- 什么是容器探针(可选配置)
- 容器探针的检查方式共有4种,分别为:
- exec:在容器内执行指定命令进行检测
- httpGet:使用HTTP协议诊断服务状态
- tcpSocket:对指定的IP地址上的端口执行TCP检查
- gRPC:使用gRPC健康检查协议进行检测,多用于检测用户自己开发的程序或返回状态
- 每次探测都会获得以下三种结果之一:
- Success 成功,容器通过了诊断
- Failure 失败,容器未通过诊断
- Unknown 未知,诊断失败,不会采取任何行动
- 探测类型
- startupProbe(启动探测):探测目标应用是否已经启动正常
- livenessProbe(生命探测):探测容器是否能够正常运行
- readinessProbe(就绪探测):指示容器是否准备好为请求提供服务
- startupProbe启动探测类型
- startupProbe用于检测容器 启动过程中依赖的某个重要服务
- 探测失败:kubelet将杀死容器,依据重启策略执行
- 如果配置了启动探针,其他所有探针都会被禁用,直到此探针执行成功为止
- 如果启动探针执行成功,且主容器已经启动,启动探针不会重复执行
- 如果未定义启动探针,默认为Success状态
- 使用topSocket配置startupProbe检测:
- 在tcpSocket的检测中,如果端口的状态是Open打开,则诊断被认为是成功的(不需要返回任何数据)
[root@master ~] vim startupProbe.yml
---
kind: Pod
apiVersion: v1
metadata:
name: startupprobe
spec:
containers:
- name: startup
image: myos:httpd
startupProbe: #启动探针
tcpSocket: #使用tcp协议检测
host: 192.168.1.252 #跳板机IP地址
port: 80
[root@ecs-proxy ~] systemctl stop nginx #切换至跳板机关闭nginx
[root@master other] kubectl create -f startupProbe.yml
pod/startupprobe created
[root@master other] kubectl get pods -w
NAME READY STATUS RESTARTS AGE
startupprobe 0/1 Running 0 4s
startupprobe 0/1 Running 1 (1s ago) 31s
startupprobe 0/1 Running 2 (1s ago) 61s
[root@ecs-proxy ~] systemctl start nginx #切换至跳板机开启nginx
[root@master other] kubectl get pods -w #跳板机的80端口只要是被监听状态就容器就能起来,不让就是一直探测和尝试重启
NAME READY STATUS RESTARTS AGE
startupprobe 0/1 Running 0 4s
startupprobe 0/1 Running 1 (1s ago) 31s
startupprobe 0/1 Running 2 (1s ago) 61s
startupprobe 1/1 Running 3 (1s ago) 91s
- readinessProbe就绪探测型
- readinessProbe在Pod的生命周期中一直存在,用来探测容器是否准备好提供服务
- 配置了就绪探测探针,初始的值默认状态为Failure
- 探测失败:端点控制器将拒绝Pod所提供的服务(这里是等待,并不重启容器)
- 如果未定义就绪探针,默认为Success状态
- 使用exec配置readinessProbe检测:
- exec选项用来执行自定义命令的检测,通过返回的状态码判断是否成功,如果$?==0则诊断被认为是成功的,其他判断为失败
[root@master ~]# vim readinessprobe.yml
---
kind: Pod
apiVersion: v1
metadata:
name: readinessprobe
spec:
containers:
- name: startup
image: myos:httpd
readinessProbe:
periodSeconds: 10 #检测间隔时间
exec:
command: #执行命令进行探测
- sh
- -c
- |
read ver < /test.txt
if (( ${ver:-0} >= 3 ));then
tes=0
fi
exit ${tes:-1}
[root@master other] kubectl get pods -w
NAME READY STATUS RESTARTS AGE
readinessprobe 0/1 Running 0 15m
[root@master ~] kubectl exec -it readinessprobe -- bash #切换终端进入容器在/test.txt重定向数字3进去
[root@readinessprobe html] echo 3 > /test.txt
[root@master other] kubectl get pods -w #经过10秒后容器启动成功
NAME READY STATUS RESTARTS AGE
readinessprobe 0/1 Running 0 15m
readinessprobe 1/1 Running 0 15m
- livenessProbe生命探测类型
- livenessProbe用来判断某个核心资源是否可用
- livenessProbe在Pod的全部生命周期中运行,如果发现资源无法获取,kubelet将杀死容器,依据重启策略执行
- 如果没有设置restartPolicy默认使用镜像重建容器
- liveenssProbe检测失败重启容器的行为会重新激活startupProbe但不会重新执行InitContainer
- 如果未定义生命探针,默认为Success状态
- 使用httpGet配置livenessProbe检测
- 在httpGet的检测中,kubelet目标IP上指定的端口和路径执行HTTP GET请求。如果响应的状态码大于等于200且小于400,则诊断被认为是成功的
[root@master other] vim livenessProbe.yml
[root@master other] kubectl create -f livenessProbe.yml
pod/livenessprobe created
[root@master other] kubectl get pods -w
NAME READY STATUS RESTARTS AGE
livenessprobe 1/1 Running 0 44s
[root@master ~] kubectl exec -it livenessprobe -- rm -rf /var/www/html/info.php
[root@master other] kubectl get pods -w
NAME READY STATUS RESTARTS AGE
livenessprobe 1/1 Running 0 44s
livenessprobe 1/1 Running 1(1s ago) 89s
事件处理函数
- postStart和prestop
- postStart是一个生命周期钩子函数,它与InitContainer不同,postStart是在主容器创建之后被调用。这可以用于执行主容器的初始化工作,通常用于确保容器对外提供服务之前已经完全准备好
- prestop也是一个生命周期钩子函数,它在容器被停止之前被调用。这可以用于执行清理工作,通常用于确保资源被正确释放,避免数据丢失或损坏
- 定义postStart和preStop
[root@master other] vim postpre.yml
---
kind: Pod
apiVersion: v1
metadata:
name: postpre
spec:
containers:
- name: test
image: myos:httpd
lifecycle:
postStart:
exec:
command:
- sh
- -c
- |
echo "poststart" | tee -a /test.log
sleep 10
preStop:
exec:
command:
- sh
- -c
- |
echo "prestop" | tee -a /test.log
sleep 10
[root@master other] kubectl create -f postpre.yml
pod/postpre created
[root@master other] kubectl exec -it postpre -- tail -f /test.log
poststart
[root@master ~] kubectl delete pods --all #新开终端删除postper
pod "postpre" deleted
[root@master other] kubectl exec -it postpre -n work -- tail -f /test.log
poststart
prestop
Pod资源管理
Pod资源管理
资源管理概述
- 为啥要资源配额
- 当多个应用共享固定节点数目的集群时,人们担心某些应用
- 无法获得足够的资源,从而影响到其正常运行,我们需要设定一些规则,用来保证应用能获得其运行所需资源
- CPU资源类型
- CPU资源的约束和请求以毫核(m)为单位。在 k8s中1m是最小的调度单元,CPU的一个核心可以看作1000m
- 如果你有2颗CPU,且每CPU为4核心,那么你的CIPU资源总量就是8000m
lscpu
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 2 #2cpu
On-line CPU(s) list: 0,1
Thread(s) per core: 2 #每个核心2个线程数
Core(s) per socket: 1 #每个插槽1个核心
- 内存资源类型
- memory的约束和请求以字节为单位
- 你可以使用以下单位来表示内存:E、P、T、G、M、k
- 你也可以使用对应的2的幂数:Ei、Pi、Ti、Gi、Mi、K!
- 例如,以下表达式所代表的是相同的值:
1k = = 1000 = = 1ki
资源配额
[root@master other] vim requests.yml
---
kind: Pod
apiVersion: v1
metadata:
name: requests
spec:
containers:
- name: startup
image: myos:httpd
resources:
requests:
cpu: 1000m
memory: 1200Mi
[root@master other] kubectl create -f requests.yml
pod/resources created
[root@master other] kubectl describe pod requests
Name: requests
......
......
Requests:
cpu: 1 #1=1000m
memory: 1200Mi
资源限额
- 为什么要使用资源限额
- 限额策略是为了防止某些应用对节点资源过度使用,而配置的限制性策略,限额与配额相反,它不检查节点资源的剩余余情况,只限制应用对资源的最大使用量
- 资源限额使用 limits进行配置
- 资源限额需要与配额共同配置
- 配额不能大于限额
- 创建资源清单文件
[root@master other] vim limits.yml
---
kind: Pod
apiVersion: v1
metadata:
name: limits
spec:
containers:
- name: startup
image: myos:httpd
resources:
requests:
cpu: 1000m
memory: 1200Mi
[root@master other] kubectl create -f limits.yml
pod/resources created
[root@master other] kubectl describe pod limits
Name: limits
......
......
limits:
cpu: 1 #1=1000m
memory: 1200Mi
Requests:
cpu: 1 #1=1000m
memory: 1200Mi
# 资源清单文件没有设置资源配额,但是查看资源策略时却有,这表名限额和配额同时存在的,资源清单文件中不指定配额的话,默认与限额一致
[root@master other] kubectl cp ../memtest.py limits:/usr/bin
[root@master other] kubectl exec -it limits -- memtest.py 1099
use memory success
press any key to exit :
[root@master ~]# kubectl exec -it limits -- bash
[root@limits html]# cat /dev/zero > /dev/null
[root@master ~]# kubectl top pods #切换终端查看资源消耗
NAME CPU(cores) MEMORY(bytes)
limits 301m 1125Mi
- 节点压力驱逐
- kubelet监控集群节点的内存、磁盘空间和文件系统等资源,当这些资源中的其中一个或者多个出现消耗瓶颈的时候,kubelet会主动终止一个或多个Pod,回收资源以防止饥饿的过程
- 在节点压力驱逐过程期间,kubelet将所选Pod的状态设置为Failed并终止Pod的运行
- 一般来说,k8s在出发节点压力驱逐时会考虑QoS类别,进行如下处理
- Guaranteed(保障型):这类Pod有稳定(配限额相等)的资源限额/配额,通常情况下最不易被驱逐
- Burstable(爆发型):限额值大于配额值,它们在节点资源不足时可能会被驱逐
- BestEffort(尽量型):没有设置配限额的Pod,被认为是首选被驱逐的对象
全局资源管理
全局配额概述
- 全局资源配额
- 如果有大量的容器需要设置资源配额,为每个Pod设置资源配额策略不方便且不好管理。管理员可以以名称空间为单位(namespace),限制其资源的使用与创建。在该名称空间中创建的容器都会受到规则的限制。
- k8s支持的全局资源配额方式有:
- 对单个Pod内存、CPU进行配额:LimitRange
- 对资源总量进行配额:ResourceQuota
ResourceQuota
- 创建资源清单文件
[root@master other] vim reourcequota.yml
---
kind: ResourceQuota
apiVersion: v1
metadata:
name: quota1
namespace: test
spec:
hard:
pods: 5
scopes:
- NotBestEffort #NotBestEffort scope 适用于有明确资源设置的 Pods,包括Guaranteed和Burstable类型的 Pods。
---
kind: ResourceQuota
apiVersion: v1
metadata:
name: quota2
namespace: test
spec:
hard:
pods: 10
cpu: 2000m
memory: 6Gi
[root@master other] kubectl create ns test
[root@master other] kubectl create -f reourcequota.yml
[root@master other] kubectl describe ns test
Name: test
Labels: kubernetes.io/metadata.name=test
Annotations: <none>
Status: Active
Resource Quotas
Name: quota1
Scopes: NotBestEffort
* Matches all pods that have at least one resource requirement set. These pods have a burstable or guaranteed quality of service.
Resource Used Hard
-------- --- ---
pods 0 5
Name: quota2
Resource Used Hard
-------- --- ---
cpu 0 2
memory 0 6Gi
pods 0 10
No LimitRange resource.
- 验证配额策略
[root@master other] vim guaranteed.yml
---
kind: Pod
apiVersion: v1
metadata:
name: limits
namespace: test
spec:
containers:
- name: startup
image: myos:httpd
resources:
limits:
cpu: 300m
memory: 1200Mi
[root@master other] kubectl create -f guaranteed.yml
pod/limits created
[root@master other] kubectl describe ns test
Name: test
Labels: kubernetes.io/metadata.name=test
Annotations: <none>
Status: Active
Resource Quotas
Name: quota1
Scopes: NotBestEffort
* Matches all pods that have at least one resource requirement set. These pods have a burstable or guaranteed quality of service.
Resource Used Hard
-------- --- ---
pods 1 5
Name: quota2
Resource Used Hard
-------- --- ---
cpu 300m 2
memory 1200Mi 6Gi
pods 1 10
No LimitRange resource.
[root@master other] sed "s,name: limits,name: limits1," guaranteed.yml | kubectl create -f -
pod/limits1 created
[root@master other] sed "s,name: limits,name: limits2," guaranteed.yml | kubectl create -f -
pod/limits2 created
[root@master other] kubectl describe ns test
Name: test
Labels: kubernetes.io/metadata.name=test
Annotations: <none>
Status: Active
Resource Quotas
Name: quota1
Scopes: NotBestEffort
* Matches all pods that have at least one resource requirement set. These pods have a burstable or guaranteed quality of service.
Resource Used Hard
-------- --- ---
pods 3 5
Name: quota2
Resource Used Hard
-------- --- ---
cpu 900m 2
memory 3600Mi 6Gi
pods 3 10
No LimitRange resource.
[root@master other] sed "s,name: limits,name: limits3," guaranteed.yml | kubectl create -f -
pod/limits3 created
[root@master other] sed "s,name: limits,name: limits4," guaranteed.yml | kubectl create -f -
pod/limits4 created
[root@master other] kubectl describe ns test
Name: test
Labels: kubernetes.io/metadata.name=test
Annotations: <none>
Status: Active
Resource Quotas
Name: quota1
Scopes: NotBestEffort
* Matches all pods that have at least one resource requirement set. These pods have a burstable or guaranteed quality of service.
Resource Used Hard
-------- --- ---
pods 5 5
Name: quota2
Resource Used Hard
-------- --- ---
cpu 1500m 2
memory 6000Mi 6Gi
pods 5 10
No LimitRange resource.
[root@master other] sed "s,name: limits,name: limits5," guaranteed.yml | kubectl create -f -
Error from server (Forbidden): error when creating "STDIN": pods "limits5" is forbidden: exceeded quota: quota1, requested: pods=1, used: pods=5, limited: pods=5
标签:kubectl,生命周期,name,容器,master,Pod,root
From: https://blog.csdn.net/m0_44986752/article/details/143843549