Pod资源管理进阶-Pod对象的生命周期
目录
8、设置Pod对象的安全上下文securityContext
1、存活性探测行为属性 (Liveness probe)
使用kubectl describe命令查看配置了存活性探测的Pod对象的详细信息时,其相关容器中会输出类似如下一行的内容:
Liveness: exec [test -e /tmp/healthy] delay=0s timeout=1s period=10s
#success=1 #failure=3
它给出了探测方式及其额外的配置属性delay、timeout、period、success和failure及其各自的相关属性值。用户没有明确定义这些属性字段时,它们会使用各自的默认值,例如上面显示出的设定。这些属性信息可通过“spec.containers.livenessProbe”的如下属性字段来给出。
- initialDelaySeconds<integer>
存活性探测延迟时长,即容器启动多久之后再开始第一次探测操作,显示为delay属性;默认为0秒,即容器启动后立刻便开始进行探测。
- timeoutSeconds<integer>
存活性探测的超时时长,显示为timeout属性,默认为1s,最小值也为1s
- periodSeconds<integer>
存活性探测的频度,显示为period属性,默认为10s,最小值为1s;过高的频率会对Pod对象带来较大的额外开销,而过低的频率又会使得对错误的反应不及时。
- successThreshold<integer>
处于失败状态时,探测操作至少连续多少次的成功才被认为是通过检测,显示为#success属性,默认值为1,最小值也为1。
- failureThreshold
处于成功状态时,探测操作至少连续多少次的失败才被视为是检测不通过,显示为#failure属性,默认值为3,最小值为1。
现在我们查看一个liveness-exec.yaml实例:
[[email protected] ~]# git clone https://github.com/iKubernetes/Kubernetes_Advanced_Practical
Cloning into 'Kubernetes_Advanced_Practical'...
remote: Enumerating objects: 489, done.
remote: Total 489 (delta 0), reused 0 (delta 0), pack-reused 489
Receiving objects: 100% (489/489), 148.75 KiB | 13.00 KiB/s, done.
Resolving deltas: 100% (122/122), done.[[email protected] ~]# cd Kubernetes_Advanced_Practical/
[[email protected] Kubernetes_Advanced_Practical]# ls
chapter10 chapter11 chapter12 chapter13 chapter14 chapter15 chapter2 chapter3 chapter4 chapter5 chapter6 chapter7 chapter8 chapter9 conf_files README.md
[[email protected] Kubernetes_Advanced_Practical]# cd chapter4[[email protected] chapter4]# vim liveness-exec.yaml
apiVersion: v1
kind: Pod
metadata:
labels:
test: liveness-exec
name: liveness-exec
spec:
containers:
- name: liveness-demo
image: busybox
args:
- /bin/sh
- -c
- touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600 #创建/tmp/healthy;睡眠30s以后,在删除 /tmp/healthy这个文件,在睡眠600s
livenessProbe:
exec:
command:
- test
- -e
- /tmp/healthy #这个文件只要是存在得我就认为是健康得 注意这里我们只指定了exec没指定其他的 其它得都会使用默认值[[email protected] chapter4]# kubectl apply -f liveness-exec.yaml
pod/liveness-exec created[[email protected] chapter4]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
liveness-exec 1/1 Running 0 37s 10.244.2.5 node2 <none> <none>
mypod 1/1 Running 0 41h 10.244.2.4 node2 <none> <none>
ng-dep-5fb7d74687-vfssn 1/1 Running 0 5d16h 10.244.2.3 node2 <none> <none>间隔30s以后查看容器得详细信息
[[email protected] chapter4]# kubectl describe pods liveness-exec
Name: liveness-exec
Namespace: default
Priority: 0
Node: node2/172.21.16.33
Start Time: Wed, 11 Nov 2020 10:57:17 +0800
Labels: test=liveness-exec
Annotations: <none>
Status: Running
IP: 10.244.2.5
IPs:
IP: 10.244.2.5
Containers:
liveness-demo:
Container ID: docker://bf8f3d77ecadf8f86c50dccc87d1d27e8e215af160cc58dfde631eee088d31e0
Image: busybox
Image ID: docker-pullable://[email protected]:a9286defaba7b3a519d585ba0e37d0b2cbee74ebfe590960b0b1d6a5e97d1e1d
Port: <none>
Host Port: <none>
Args:
/bin/sh
-c
touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600
State: Running
Started: Wed, 11 Nov 2020 10:59:14 +0800
Last State: Terminated
Reason: Error
Exit Code: 137
Started: Wed, 11 Nov 2020 10:57:39 +0800
Finished: Wed, 11 Nov 2020 10:59:02 +0800
Ready: True
Restart Count: 1 #这里可以查看到重启了1次
Liveness: exec [test -e /tmp/healthy] delay=0s timeout=1s period=10s #success=1 #failure=3
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-2jsh9 (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
default-token-2jsh9:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-2jsh9
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 2m38s default-scheduler Successfully assigned default/liveness-exec to node2
Normal Pulled 2m16s kubelet Successfully pulled image "busybox" in 21.497183923s
Normal Killing 83s kubelet Container liveness-demo failed liveness probe, will be restarted
Normal Pulling 53s (x2 over 2m37s) kubelet Pulling image "busybox"
Normal Pulled 42s kubelet Successfully pulled image "busybox" in 11.010754251s
Normal Created 41s (x2 over 2m16s) kubelet Created container liveness-demo
Normal Started 41s (x2 over 2m16s) kubelet Started container liveness-demo
Warning Unhealthy 3s (x4 over 103s) kubelet Liveness probe failed:[[email protected] chapter4]# kubectl get pods
NAME READY STATUS RESTARTS AGE
liveness-exec 1/1 Running 4 7m23s #这里我们可以看到liveness-exec这个pod被重启了4次
mypod 1/1 Running 0 41h
ng-dep-5fb7d74687-vfssn 1/1 Running 0 5d16h
查看 liveness-http.yaml实例
[[email protected] chapter4]# vim liveness-http.yamlapiVersion: v1
kind: Pod
metadata:
labels:
test: liveness
name: liveness-http
spec:
containers:
- name: liveness-demo
image: nginx:1.14-alpine
ports:
- name: http
containerPort: 80
lifecycle: # 2、上面是我们运行了一个Nginx镜像,我们又借助于lifecycle启动后事件专门创建了一个用于做健康状态检测的URL放在了ng的网页文件路径下
postStart:
exec:
command:
- /bin/sh
- -c
- 'echo Healty > /usr/share/nginx/html/healthz'
livenessProbe: # 3、随着我们健康状态检测 就是像 /usr/share/nginx/html/healthz这个网页发请求,如果能请求成功我们认为是健康得,如果失败我们则认为是不健康得
httpGet: # 1、我们使用 httpGet去向本机得/healthz的URL发送请求,这个文件来自于哪里是我们借助于 lifecycle创建的
path: /healthz
port: http #这里的http是调用上面的ports的name 这两个值必须保持一致
scheme: HTTP
periodSeconds: 2 #每两s中检测一次
failureThreshold: 2 #探测操作至少连续2次的失败才被视为是检测不通过
initialDelaySeconds: 3 #即容器启动3s之后再开始第一次探测操作[[email protected] chapter4]# kubectl apply -f liveness-http.yaml
pod/liveness-http created[[email protected] chapter4]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
liveness-exec 0/1 CrashLoopBackOff 9 26m 10.244.2.5 node2 <none> <none>
liveness-http 1/1 Running 0 58s 10.244.1.5 node1 <none> <none>
mypod 1/1 Running 0 42h 10.244.2.4 node2 <none> <none>
ng-dep-5fb7d74687-vfssn 1/1 Running 0 5d17h 10.244.2.3 node2 <none> <none>[[email protected] chapter4]# kubectl describe pods liveness-http #查看健康状态检测的详细信息
Name: liveness-http
Namespace: default
Priority: 0
Node: node1/172.21.96.13
Start Time: Wed, 11 Nov 2020 11:22:23 +0800
Labels: test=liveness
Annotations: <none>
Status: Running
IP: 10.244.1.5
IPs:
IP: 10.244.1.5
Containers:
liveness-demo:
Container ID: docker://e099143e80a5d9fbaf8fd01f85e07afdaef85d20c5a43e9cdf6fbc6d3934dae5
Image: nginx:1.14-alpine
Image ID: docker-pullable://[email protected]:485b610fefec7ff6c463ced9623314a04ed67e3945b9c08d7e53a47f6d108dc7
Port: 80/TCP
Host Port: 0/TCP
State: Running
Started: Wed, 11 Nov 2020 11:22:34 +0800
Ready: True
Restart Count: 0
Liveness: http-get http://:http/healthz delay=3s timeout=1s period=2s #success=1 #failure=2
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-2jsh9 (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
default-token-2jsh9:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-2jsh9
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 2m14s default-scheduler Successfully assigned default/liveness-http to node1
Normal Pulling 2m14s kubelet Pulling image "nginx:1.14-alpine"
Normal Pulled 2m3s kubelet Successfully pulled image "nginx:1.14-alpine" in 10.768366105s
Normal Created 2m3s kubelet Created container liveness-demo
Normal Started 2m3s kubelet Started container liveness-demo[[email protected] chapter4]# kubectl exec -it liveness-http -- /bin/sh #连接到容器里面模拟删除healthz的网页文件查看健康状态检测
/ # ls
bin dev etc home lib media mnt opt proc root run sbin srv sys tmp usr var
/ # cd /usr/share/nginx/html/
/usr/share/nginx/html # ls
50x.html healthz index.html
/usr/share/nginx/html # rm healthz[[email protected] chapter4]# kubectl get pods #可以查看liveness-http的Pod的重启了1次
NAME READY STATUS RESTARTS AGE
liveness-exec 1/1 Running 11 31m
liveness-http 1/1 Running 1 6m17s
mypod 1/1 Running 0 42h
ng-dep-5fb7d74687-vfssn 1/1 Running 0 5d17h
2、Pod就绪性探测
- Pod对象启动后,容器应用通常需要一段时间才能完成其初始化过程,例如加载配置或数据,甚至有些程序需要运行某类的预热过程,若在此阶段完成之前即接入客户端的请求,势必会因为等待太久而影响用户体验。因此,应该避免于Pod对象启动后立即让其处理客户端请求,而是等待容器初始化工作执行完成并转为“就绪”状态,尤其是存在其他提供相同服务的Pod对象的场景更是如此。
- 与存活性探测机制类似,就绪性探测是用来判断容器就绪与否的周期性(默认周期为10秒钟)操作,它用于探测容器是否已经初始化完成并可服务于客户端请求,探测操作返回“success”状态时,即为传递容器已经“就绪”的信号。
- 与存活性探测机制相同,就绪性探测也支持Exec、HTTP GET和TCP Socket三种探测方式,且各自的定义机制也都相同。但与存活性探测触发的操作不同的是,探测失败时,就绪性探测不会杀死或重启容器以保证其健康性,而是通知其尚未就绪,并触发依赖于其就绪状态的操作(例如,从Service对象中移除此Pod对象)以确保不会有客户端请求接入此Pod对象。不过,即便是在运行过程中,Pod就绪性探测依然有其价值所在,例如Pod A依赖到的PodB因网络故障等原因而不可用时,Pod A上的服务应该转为未就绪状态,以免无法向客户端提供完整的响应。
- 将容器定义中的livenessProbe字段名替换为readinessProbe即可定义出就绪性探测的配置,一个简单的示例如下面的配置清单(readiness-exec.yaml)所示,它会在Pod对象创建完成5秒钟后使用test-e/tmp/ready命令来探测容器的就绪性,命令执行成功即为就绪,探测周期为5秒钟:
[[email protected] chapter4]# vim readiness-exec.yaml
apiVersion: v1
kind: Pod
metadata:
labels:
test: readiness-exec
name: readiness-exec
spec:
containers:
- name: readiness-demo
image: busybox
args: ["/bin/sh", "-c", "while true; do rm -f /tmp/ready; sleep 30; touch /tmp/ready; sleep 300; done"] #模拟就绪检测不成功不成功 30s之后成功了
readinessProbe:
exec:
command: ["test", "-e", "/tmp/ready"] # readinessProbe检测就看这个文件存在与否
initialDelaySeconds: 5 #延迟5s中检测
periodSeconds: 5[[email protected] chapter4]# kubectl apply -f readiness-exec.yaml
pod/readiness-exec created
[[email protected] chapter4]# kubectl get pods -w #实时去检测容器的状态
NAME READY STATUS RESTARTS AGE
liveness-exec 1/1 Running 49 3h8m
liveness-http 1/1 Running 1 163m
mypod 1/1 Running 0 44h
ng-dep-5fb7d74687-vfssn 1/1 Running 0 5d19h
readiness-exec 0/1 Running 0 28s
readiness-exec 1/1 Running 0 39s #看这里
liveness-exec 0/1 CrashLoopBackOff 49 3h9m模拟把文件删除,查看是否还是就绪的状态
[[email protected] chapter4]# kubectl get pods -w
NAME READY STATUS RESTARTS AGE
liveness-exec 0/1 CrashLoopBackOff 49 3h12m
liveness-http 1/1 Running 1 167m
mypod 1/1 Running 0 44h
ng-dep-5fb7d74687-vfssn 1/1 Running 0 5d20h
readiness-exec 1/1 Running 0 4m9s
readiness-exec 0/1 Running 0 4m9s #可以看到左边的为1我们在人为的创建一个看下效果
^C[[email protected] chapter4]# kubectl exec readiness-exec -- touch /tmp/ready
[[email protected] chapter4]# kubectl get pods -w
NAME READY STATUS RESTARTS AGE
liveness-exec 0/1 CrashLoopBackOff 49 3h14m
liveness-http 1/1 Running 1 169m
mypod 1/1 Running 0 44h
ng-dep-5fb7d74687-vfssn 1/1 Running 0 5d20h
readiness-exec 0/1 Running 0 6m2s
readiness-exec 1/1 Running 0 6m4s
liveness-exec 1/1 Running 50 3h14m #可以看到左边的为1
3、Pod对象的相位
- Pending:API Server创建了Pod资源对象并已存入etcd中,但它尚未被调度完成,或者仍处于从仓库下载镜像的过程中。 (一般是资源无法满足调度的需求时会出现pending)
- Running:Pod已经被调度至某节点,并且所有容器都已经被kubelet创建完成。
- Succeeded:Pod中的所有容器都已经成功终止并且不会被重启。
- Failed:所有容器都已经终止,但至少有一个容器终止失败,即容器返回了非0值的退出状态或已经被系统终止。
- Unknown:API Server无法正常获取到Pod对象的状态信息,通常 是由于其无法与所在工作节点的kubelet通信所致。
4、Pod的创建过程
- 1)用户通过kubectl或其他API客户端提交Pod Spec给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尝试在当前节点上调用Docker启动容器,并将容器的结果状态回送至API Server。
- 9)API Server将Pod状态信息存入etcd系统中。
- 10)在etcd确认写入操作成功完成后,API Server将确认信息发送至相关的kubelet,事件将通过它被接受。
5、Pod生命周期中的重要阶段
- 1)初始化容器必须运行完成直至结束,若某初始化容器运行失 败,那么Kubernetes需要重启它直到成功完成。
- 2)每个初始化容器都必须按定义的顺序串行运行。
注意: 如果Pod的spec.restartPolicy字段值为“Never”,那么运行失败的初始化容器不会被重启。
- 1)用于运行特定的工具程序,出于安全等方面的原因,这些程序不适于包含在主容器镜像中。
- 2)提供主容器镜像中不具备的工具程序或自定义代码。
- 3)为容器镜像的构建和部署人员提供了分离、独立工作的途径,使得他们不必协同起来制作单个镜像文件。
- 4)初始化容器和主容器处于不同的文件系统视图中,因此可以分别安全地使用敏感数据,例如Secrets资源。
- 5)初始化容器要先于应用容器串行启动并运行完成,因此可用于延后应用容器的启动直至其依赖的条件得到满足。
[[email protected] ~]# vim initialized.yaml
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
spec:
containers:
- name: myapp-container
image: ikubernetes/myapp:v1
initContainers:
- name: init-something
image: busybox
command: ['sh', '-c', 'sleep 10'][[email protected] ~]# kubectl apply -f initialized.yaml
pod/myapp-pod created
[[email protected] ~]# kubectl get pods -w
NAME READY STATUS RESTARTS AGE
liveness-exec 0/1 CrashLoopBackOff 59 3h54m
liveness-http 1/1 Running 1 3h29m
myapp-pod 0/1 Init:0/1 0 9s
mypod 1/1 Running 0 45h
ng-dep-5fb7d74687-vfssn 1/1 Running 0 5d20h
readiness-exec 1/1 Running 0 46m
myapp-pod 0/1 Init:0/1 0 29s
myapp-pod 0/1 PodInitializing 0 39s
myapp-pod 1/1 Running
- postStart:于容器创建完成之后立即运行的钩子处理器(handler),不过Kubernetes无法确保它一定会于容器中的 ENTRYPOINT之前运行
- preStop:于容器终止操作之前立即运行的钩子处理器,它以同步的方式调用,因此在其完成之前会阻塞删除容器的操作的调用
钩子处理器的实现方式有“Exec”和“HTTP”两种,前一种在钩子事 件触发时直接在当前容器中运行由用户定义的命令,后一种则是在当前 容器中向某URL发起HTTP请求。
apiVersion: v1
kind: Pod
metadata:
name: lifecycle-demo
spec:
containers:
- name: lifecycle-demo-container
image: ikubernetes/myapp:v1
lifecycle:
postStart:
exec:
command: ["/bin/sh","-c","echo 'lifecycle hooks handler' > /usr/share/nginx/html/test.html"]
3.容器探测
- ·ExecAction:在容器中执行一个命令,并根据其返回的状态码进行诊断的操作称为Exec探测,状态码为0表示成功,否则即为不健康状 态。
- ·TCPSocketAction:通过与容器的某TCP端口尝试建立连接进行诊断,端口能够成功打开即为正常,否则为不健康状态。
- ·HTTPGetAction:通过向容器IP地址的某指定端口的指定path发起HTTP GET请求进行诊断,响应码为2xx或3xx时即为成功,否则为失败。
- ·kubelet可在活动容器上执行两种类型的检测:存活性检测(livenessProbe)和就绪性检测(readinessProbe)。·
- 存活性检测:用于判定容器是否处于“运行”(Running)状态;一 此类检测未通过,kubelet将杀死容器并根据其restartPolicy决定是否将 其重启;未定义存活性检测的容器的默认状为“Success”。
- 就绪性检测:用于判断容器是否准备就绪并可对外提供服务;未通过检测的容器 意味着其尚未准备就绪,端点控制器(如Service对象)会将其IP从所有 匹配到此Pod对象的Service对象的端点列表中移除;检测通过之后,会再次将其IP添加至端点列表中。
6、容器的重启策略
- 1)Always:但凡Pod对象终止就将其重启,此为默认设定。 Always时默认的
- 2)OnFailure:仅在Pod对象出现错误时方才将其重启。 正常终止就不重启
- 3)Never:从不重启。
7、Pod的终止过程
- 1)用户发送删除Pod对象的命令。
- 2)API服务器中的Pod对象会随着时间的推移而更新,在宽限期内(默认为30秒),Pod被视为“dead”。
- 3)将Pod标记为“Terminating”状态。
- 4)(与第3步同时运行)kubelet在监控到Pod对象转为“Terminating”状态的同时启动Pod关闭过程。
- 5)(与第3步同时运行)端点控制器监控到Pod对象的关闭行为时将其从所有匹配到此端点的Service资源的端点列表中移除。
- 6)如果当前Pod对象定义了preStop钩子处理器,则在其标记为“terminating”后即会以同步的方式启动执行;如若宽限期结束后, preStop仍未执行结束,则第2步会被重新执行并额外获取一个时长为2秒 的小宽限期。
- 7)Pod对象中的容器进程收到TERM信号。
- 8)宽限期结束后,若存在任何一个仍在运行的进程,那么Pod对象即会收到SIGKILL信号。
- 9)Kubelet请求API Server将此Pod资源的宽限期设置为0从而完成删除操作,它变得对用户不再可见。
8、设置Pod对象的安全上下文securityContext
- 基于用户ID(UID)和组ID(GID)控制访问对象(如文件)时的权限。
- 以特权或非特权的方式运行。
- 通过Linux Capabilities为其提供部分特权。
- 基于Seccomp过滤进程的系统调用。
- 基于SELinux的安全标签。
- 是否能够进行权限升级。
apiVersion: v1
kind: Pod
metadata:
name: pod-with-securitycontext
spec:
containers:
- name: busybox
image: busybox
command: ["/bin/sh","-c","sleep 86400"]
securityContext:
runAsNonRoot: true
runAsUser: 1000
allowPrivilegeEscalation: false
将上面的配置清单保存于配置文件(如pod-with- securitycontext.yaml文件)中,而后创建于集群中即可验证容器进程的
运行者身份:
[[email protected] ~]# kubectl apply -f pod-with-securitycontext.yaml[[email protected] ~]# kubectl exec pod-with-securitycontext -- ps auxPID USER TIME COMMAND1 1000 0:00 sleep 86
9、资源需求及资源限制
9.1资源需求
apiVersion: v1kind: Pod
metadata:
name: stress-pod
spec:
containers:
- name: stress
image: ikubernetes/ stress-ng
command: ["/usr/bin/stress-ng", "-m 1", "-c 1", "-metrics-brief"]
resources:
requests:
memory: "128Mi"
cpu: "200m"
[[email protected] ~]# kubectl apply -f pod-resources-test.yaml
[[email protected] ~]# kubectl exec stress-pod -- topMem: 2884676K used, 13531796K free, 27700K shrd, 2108K buff, 1701456K cachedCPU: 25% usr 0% sys 0% nic 74% idle 0% io 0% irq 0% sirqLoad average: 0.57 0.60 0.71 3/435 15PID PPID USER STAT VSZ %VSZ CPU %CPU COMMAND9 8 root R 262m 2% 6 13% {stress-ng-vm} /usr/bin/stress-ng7 1 root R 6888 0% 3 13% {stress-ng-cpu} /usr/bin/stress-ng1 0 root S 6244 0% 1 0% /usr/bin/stress-ng -c 1 -m 1 --met
top命令的输出结果显示,每个测试进程的CPU占用率为13%(实际为12.5%),{stress-ng-vm}的内存占用量为262m(VSZ),此两项资源 占用量都远超其请求的用量,原因是stress-ng会在可用的范围内尽量多 地占用相关的资源。两个测试线程分布于两个CPU核心以满载的方式运 行,系统共有8个核心,因此其使用率为25%(2/8)。另外,节点上的内存资源充裕,虽然容器的内存用量远超128M,但它依然可运行。一 旦资源紧张时,节点仅保证容器有五分之一个CPU核心可用,对于有着 8个核心的节点来说,它的占用率为2.5%,于是每个进程为1.25%,多占 用的资源会被压缩。内存为非可压缩型资源,
对于压缩型的资源CPU来说,未定义其请求用量以确保其最小的可用资源时,它可能会被其他的Pod资源压缩至极低的水平,甚至会达到 Pod不能够被调度运行的境地。而对于非压缩型资源来说,内存资源在 任何原因导致的紧缺情形下都有可能导致相关的进程被杀死。因此,在 Kubernetes系统上运行关键型业务相关的Pod时必须使用requests属性为 容器定义资源的确保可用量所以此Pod在内存资源紧 张时可能会因OOM被杀死(killed)。
集群中的每个节点都拥有定量的CPU和内存资源,调度Pod时,仅那些被请求资源的余量可容纳当前被调度的Pod的请求量的节点才可作 为目标节点。也就是说,Kubernetes的调度器会根据容器的requests属性 中定义的资源需求量来判定仅哪些节点可接收运行相关的Pod资源,而 对于一个节点的资源来说,每运行一个Pod对象,其requests中定义的请 求量都要被预留,直到被所有Pod对象瓜分完毕为止。
9.2资源限制
容器的资源需求仅能达到为其保证可用的最少资源量的目的,它并不会限制容器的可用资源上限,因此对因应用程序自身存在Bug等多种 原因而导致的系统资源被长时间占用的情况则无计可施,这就需要通过 limits属性为容器定义资源的最大可用量。资源分配时,可压缩型资源 CPU的控制阀可自由调节,容器进程无法获得超出其CPU配额的可用时 间。不过,如果进程申请分配超出其limits属性定义的硬限制的内存资 源时,它将被OOM killer杀死,不过,随后可能会被其控制进程所重 启,例如,容器进程的Pod对象会被杀死并重启(重启策略为Always或 OnFailure时),或者是容器进程的子进程被其父进程所重启。
piVersion: v1kind: Pod
metadata:
name: memleak-pod
labels:
app: memleak
spec:
containers:
- name: simmemleak
image: saadali/simmemleak
resources:
requests:
memory: "64Mi"
cpu: "1"
limits:
memory: "64Mi"
cpu: "1"
[[email protected] ~]# kubectl get pods -l app=memleakNAME READY STATUS RESTARTS AGEmemleak-pod 0/1 CrashLoopBackOff 1 24s
[[email protected] ~]#kubectl describe pods memleak-pod
Name: memleak-pod
……Last State: TerminatedReason: OOMKilledExit Code: 137Started: Wed, 02 May 2018 12:42:50 +0800Finished: Wed, 02 May 2018 12:42:50 +0800Ready: FalseRestart Count: 3……
10、Pod得服务质量类别
- ·Guaranteed:每个容器都为CPU资源设置了具有相同值的requests和limits属性,以及每个容器都为内存资源设置了具有相同值的requests和limits属性的Pod资源会自动归属于此类别,这类Pod资源具有最高优先级。
- ·Burstable:至少有一个容器设置了CPU或内存资源的requests属性,但不满足Guaranteed类别要求的Pod资源将自动归属于此类别,它们 具有中等优先级。
- ·BestEffort:未为任何一个容器设置requests或limits属性的Pod资源将自动归属于此类别,它们的优先级为最低级别。