资源限制
资源限制
当创建一个 Pod 时,我们可以指定每个容器中可以消耗的 CPU 和内存(RAM)的数量。当任何容器包含资源限制设置时,调度器负责根据可用资源将该容器分配到最佳节点。我们可以配置两种类型的资源,CPU 是以核为单位指定的,内存是以字节为单位指定的。我们将用有限的资源创建我们的第一个 Deployment,为此我们将上传一个 nginx 的镜像,并使用下面的命令复制 yaml deployment 镜像。
$ kubectl create deployment nginx --image=nginx
deployment.apps/nginx created
# Scaling the deployment to 3 replicates
$ kubectl scale deployment nginx --replicas=3
deployment.apps/nginx scaled
# Getting the list of deployments
$ kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
nginx 3/3 3 3 24s
然后我们修改 yaml 配置文件来限制资源:
apiVersion : apps/v1
kind : Deployment
metadata :
labels :
app : nginx
name : nginx
namespace : default
spec :
progressDeadlineSeconds : 600
replicas : 3
revisionHistoryLimit : 10
selector :
matchLabels :
app : nginx
strategy :
rollingUpdate :
maxSurge : 25%
maxUnavailable: 25%
type : RollingUpdate
template :
metadata :
creationTimestamp : null
labels :
app : nginx
spec :
containers :
- image : nginx
imagePullPolicy : Always
name : nginx
# Add the following lines
resources :
limits :
memory : " 256Mi "
cpu : "200m "
requests :
memory : " 128Mi "
cpu : " 50m "
terminationMessagePath : / dev / termination-log
terminationMessagePolicy : File
dnsPolicy : ClusterFirst
restartPolicy : Always
schedulerName : default-scheduler
securityContext : {}
terminationGracePeriodSeconds : 30
1 个 CPU 核对应 1000m(1000 毫核)。当指定 200m 时,我们希望保留 1 个 CPU 核的 20%。如果告知,数值 0.2 也会有同样的效果,即保留 1 个 CPU 核的 20%。
$ kubectl delete deployments.apps nginx
$ kubectl create -f deployment-limitado.yaml
deployment.apps/nginx created
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 12m
nginx-f89759699-77v8b 1/1 Running 0 117s
nginx-f89759699-ffbgh 1/1 Running 0 117s
nginx-f89759699-vzvlt 1/1 Running 0 2m2s
然后我们可以在 Pod 中测试是否限制了资源:
$ kubectl exec -ti nginx-f89759699-77v8b -- /bin/bash
现在在容器中,安装并运行 stress 模拟我们资源的负载,在 CPU 和内存的情况下。
$ apt-get update && apt-get install -y stress
$ stress --vm 1 --vm-bytes 128M --cpu 1
stress: info: [221] dispatching hogs: 1 cpu, 0 io, 1 vm, 0 hdd
这里我们强调的是容器,使用 128M 的内存和一个 CPU 核心。按照你设置的限制进行游戏。当你超过配置的限制时,在执行下面的命令时,你会收到如图所示的错误,因为它将无法分配内存资源。
stress --vm 1 --vm-bytes 512M --cpu 1
stress: info: [230] dispatching hogs: 1 cpu, 0 io, 1 vm, 0 hdd
stress: FAIL: [230] (415) <-- worker 232 got signal 9
stress: WARN: [230] (417) now reaping child worker processes
stress: FAIL: [230] (451) failed run completed in 0s
要跟踪 pod 使用的资源量,我们可以使用 kubectl top。记住,要在节点上而不是容器上运行这个命令
$ kubectl top pod --namespace=default nginx-f89759699-77v8b
NAME CPU(cores) MEMORY(bytes)
nginx-85f7fb6b45-b6dsk 201m 226Mi
限制命名空间的资源
在 kubernetes 中,我们有一个叫 Namespaces 的家伙,我们之前也看到过。但什么是 Namespace 呢?它不过是 Kubernetes 物理集群本身内部的一个虚拟集群。命名空间是将集群的资源划分给多个环境、团队或项目的一种方式。
让我们创建我们的第一个命名空间:
$ kubectl create namespace primeiro-namespace
namespace/primeiro-namespace created
$ kubectl get namespaces
NAME STATUS AGE
default Active 55m
kube-node-lease Active 56m
kube-public Active 56m
kube-system Active 56m
primeiro-namespace Active 5s
$ kubectl describe namespace primeiro-namespace
Name: primeiro-namespace
Labels: <none>
Annotations: <none>
Status: Active
No resource quota.
No LimitRange resource.
我们可以看到,我们的命名空间仍然没有设置,所以我们将使用 LimitRang 来添加资源限制。让我们创建 LimitRange 的 manifest。
vim limitando-recursos.yaml
apiVersion : v1
kind : LimitRange
metadata :
name : limiting-resources
spec :
limits :
- default :
cpu : 1
memory : 100Mi
defaultRequest :
cpu : 0.5
memory : 80Mi
type : Container
现在让我们把这个 LimitRang 添加到 Namespace 中。
$ kubectl create -f limitando-recursos.yaml -n primeiro-namespace
limitrange/limitando-recursos created
$ kubectl get limitrange -n primeiro-namespace
NAME CREATED AT
limitando-recursos 2020-05-10T18:02:51Z
$ kubectl get limitrange --all-namespaces
NAMESPACE NAME CREATED AT
primeiro-namespace limitando-recursos 2020-05-10T18:02:51Z
$ kubectl describe limitrange -n primeiro-namespace
Name: limitando-recursos
Namespace: primeiro-namespace
Type Resource Min Max Default Request Default Limit Max Limit/Request Ratio
---- -------- --- --- --------------- ------------- -----------------------
Container cpu - - 500m 1 -
Container memory - - 80Mi 100Mi -
正如我们所看到的,我们为 Namespace 上去的每个容器添加了内存和 cpu 限制,如果在 Namespace 内部创建了任何容器,而没有 Limitrange 的设置,容器将继承 Namespace 的资源限制设置。我们来创建一个 pod,看看是否会适用限制。
vim pod-limitrange.yaml
apiVersion : v1
kind : Pod
metadata :
name : limit-pod
spec :
containers :
- name : my-container
image : nginx
现在让我们在默认命名空间之外创建一个 pod,在有限命名空间(第一个命名空间)内创建另一个 pod,让我们看看每个容器的资源限制以及它们是如何应用的。
$ kubectl create -f pod-limitrange.yaml
pod/limit-pod created
$ kubectl create -f pod-limitrange.yaml -n primeiro-namespace
pod/limit-pod created
$ kubectl get pods --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE
default limit-pod 1/1 Running 0 10s
primeiro-namespace limit-pod 1/1 Running 0 5s
$ kubectl describe pod limit-pod
Name: limit-pod
Namespace: default
Priority: 0
Node: elliot-02/172.31.19.123
Start Time: Sun, 10 May 2020 18:03:52 +0000
Labels: <none>
Annotations: <none>
Status: Running
IP: 10.32.0.4
IPs:
IP: 10.32.0.4
Containers:
meu-container:
Container ID: docker://19850dc935ffa41b1754cb58ab60ec5bb3616bbbe6a958abe1b2575bd26ee73d
Image: nginx
...
$ kubectl describe pod limit-pod -n primeiro-namespace
Name: limit-pod
Namespace: primeiro-namespace
Priority: 0
Node: elliot-03/172.31.24.60
Start Time: Sun, 10 May 2020 18:03:57 +0000
Labels: <none>
Annotations: kubernetes.io/limit-ranger:
LimitRanger plugin set: cpu, memory request for container meu-container; cpu, memory limit for container meu-container
Status: Running
IP: 10.46.0.3
IPs:
IP: 10.46.0.3
Containers:
meu-container:
Container ID: docker://ad3760837d71955df47263a2031d4238da2e94002ce4a0631475d301faf1ddef
Image: nginx
...
Limits:
cpu: 1
memory: 100Mi
Requests:
cpu: 500m
memory: 80Mi
我们可以看到,命名空间 primeiro-namespace 中的 Pod 配置的资源有限。