赞
踩
展示如何将内存请求(request)和内存限制(limit)分配给一个容器。 我们保障容器拥有它请求数量的内存,但不允许使用超过限制数量的内存。
创建新的命名空间
kubectl create namespace mem-example
编辑yaml文件
#创建一个拥有一个容器的Pod apiVersion: v1 kind: Pod metadata: name: memory-demo namespace: mem-example spec: containers: - name: memory-demo-ctr image: polinux/stress #容器会请求100MiB的内存,并且内存会被限制在200MiB以内 resources: requests: memory: "100Mi" limits: memory: "200Mi" #容器启动时使用压力测试工具stress command: ["stress"] # "--vm","1" 产生一个子进程; --vm 2 产生两个进程 # "--vm-bytes","150M" 每个进程分配150M # "--vm-hang","1" 指每个消耗内存的进程在分配内存后转入睡眠1秒,然后释放内存一直重复执行这个过程 args: ["--vm","1","--vm-bytes","150M","--vm-hang","1"]
配置文件的 args 部分提供了容器启动时的参数。 “–vm-bytes”, “150M” 参数告知容器尝试分配 150 MiB 内存。
创建pod
kubectl apply -f memory-request-limit.yaml
查看Pod是否正常运行
kubectl get pod memory-demo -n mem-example
查看 Pod 相关的详细信息
kubectl get pod memory-demo -n mem-example -o yaml
输出结果显示:该 Pod 中容器的内存请求为 100 MiB,内存限制为 200 MiB。
运行 kubectl top 命令,获取该 Pod 的指标数据:
如果出现以下问题
W0323 15:03:25.034693 2441 top_pod.go:140] Using json format to get metrics. Next release will switch to protocol-buffers, switch early by passing --use-protocol-buffers flag
error: Metrics API not available
解决办法
下载部署文件
wget https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml -O metrics-server-components.yaml
修改镜像地址
sed -i 's/registry.k8s.io/metrics-server\/registry.cn-hangzhou.aliyuncs.com\/google_containers/g' metrics-server-components.yaml
如果更改不成功,可手动更改或者参照《史上最全操作教程——利用阿里云FREE镜像仓库构建国外DOCKER镜像》这篇文章
在metrics-server-components.yaml文件中添加这一行内容“- --kubelet-insecure-tls”这个配置,就不会去验证Kubelets提供的服务证书的CA。
部署metrics-server
kubectl apply -f metrics-server-components.yaml
查看该 Pod 的指标数据
kubectl top pod memory-demo --namespace=mem-example
输出结果显示:Pod 正在使用的内存大约为 150 MiB。 这大于 Pod 请求的 100 MiB,但在 Pod 限制的 200 MiB之内。
当节点拥有足够的可用内存时,容器可以使用其请求的内存。 但是,容器不允许使用超过其限制的内存。 如果容器分配的内存超过其限制,该容器会成为被终止的候选容器。 如果容器继续消耗超出其限制的内存,则终止容器。 如果终止的容器可以被重启,则 kubelet 会重新启动它,就像其他任何类型的运行时失败一样。
创建一个 Pod,尝试分配超出其限制的内存。 这是一个 Pod 的配置文件,其拥有一个容器,该容器的内存请求为 50 MiB,内存限制为 100 MiB
编写memory-request-limit2.yaml
apiVersion: v1 kind: Pod metadata: name: memory-demo-2 namespace: mem-example spec: containers: - name: memory-demo-2-ctr image: polinux/stress resources: #请求50MiB requests: memory: "50Mi" #限制为100MiB limits: memory: "100Mi" #分配250MiB内存 command: ["stress"] args: ["--vm", "1", "--vm-bytes", "250M", "--vm-hang", "1"]
创建超出限制的Pod并查看容器相关信息
#创建Pod
kubectl apply -f memory-request-limit2.yaml
#查看容器相关信息
kubectl get pod memory-demo-2 --namespace=mem-example
NAME READY STATUS RESTARTS AGE
memory-demo-2 0/1 OOMKilled 2 26s
此时,容器可能正在运行或被杀死。重复前面的命令,直到容器被杀掉
#查看更详细的状态信息
kubectl get pod memory-demo-2 --output=yaml --namespace=mem-example
输出结果显示:由于内存溢出(OOM),容器已被杀掉
容器可以被重启,所以 kubelet 会重启它。 多次运行下面的命令,可以看到容器在反复的被杀死和重启,输出结果显示:容器被杀掉、重启、再杀掉、再重启……
kubectl get pod memory-demo-2 --namespace=mem-example
NAME READY STATUS RESTARTS AGE
memory-demo-2 0/1 CrashLoopBackOff 6 6m19s
查看关于该 Pod 历史的详细信息
kubectl describe pod memory-demo-2 --namespace=mem-example
Normal Pulled 8m16s kubelet Successfully pulled image "polinux/stress" in 678.098976ms
Warning BackOff 3m58s (x25 over 8m58s) kubelet Back-off restarting failed container
内存请求和限制是与容器关联的,但将 Pod 视为具有内存请求和限制,也是很有用的。 Pod 的内存请求是 Pod 中所有容器的内存请求之和。 同理,Pod 的内存限制是 Pod 中所有容器的内存限制之和。
Pod 的调度基于请求。只有当节点拥有足够满足 Pod 内存请求的内存时,才会将 Pod 调度至节点上运行。
将创建一个 Pod,其内存请求超过了你集群中的任意一个节点所拥有的内存。 这是该 Pod 的配置文件,其拥有一个请求 1000 GiB 内存的容器,这应该超过了你集群中任何节点的容量。
编写memory-request-limit3.yaml
apiVersion: v1 kind: Pod metadata: name: memory-demo-3 namespace: mem-example spec: containers: - name: memory-demo-3-ctr image: polinux/stress resources: requests: memory: "1000Gi" limits: memory: "1000Gi" command: ["stress"] args: ["--vm", "1", "--vm-bytes", "150M", "--vm-hang", "1"]
创建Pod容器
kubectl apply -f memory-request-limit3.yaml
查看容器状态
kubectl get pod memory-demo-3 -n mem-example
输出结果显示:Pod 处于 PENDING 状态。 这意味着,该 Pod 没有被调度至任何节点上运行,并且它会无限期的保持该状态
kubectl get pod memory-demo-3 --namespace=mem-example
NAME READY STATUS RESTARTS AGE
memory-demo-3 0/1 Pending 0 25s
查看关于 Pod 的详细信息,包括事件
kubectl describe pod memory-demo-3 --namespace=mem-example
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedScheduling 3m47s default-scheduler 0/1 nodes are available: 1 Insufficient memory.
Warning FailedScheduling 3m46s default-scheduler 0/1 nodes are available: 1 Insufficient memory.
如果你没有为一个容器指定内存限制,则自动遵循以下情况之一:
容器可无限制地使用内存。容器可以使用其所在节点所有的可用内存, 进而可能导致该节点调用 OOM Killer。 此外,如果发生 OOM Kill,没有资源限制的容器将被杀掉的可行性更大。
运行的容器所在命名空间有默认的内存限制,那么该容器会被自动分配默认限制。 集群管理员可用使用 LimitRange 来指定默认的内存限制。
通过为集群中运行的容器配置内存请求和限制,你可以有效利用集群节点上可用的内存资源。 通过将 Pod 的内存请求保持在较低水平,你可以更好地安排 Pod 调度。 通过让内存限制大于内存请求,你可以完成两件事:
Pod 可以进行一些突发活动,从而更好的利用可用内存。
Pod 在突发活动期间,可使用的内存被限制为合理的数量。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。