写在前面
考虑这样的场景,现在有一个k8s集群,不同的技术部门都在使用,如java组,web组,c++组等,这些不同的技术部门之间是彼此独立的,那么在使用的过程是不是会出现包括但不限于如下的问题呢:
1:java组创建了一个名称叫做web的POD,web组也想创建名字是web的POD,但名字已经被占了,就不得不再想一个其它名字,如果是没有发现java组已经创建的POD,自己的POD就会将java组的POD覆盖,那么java部门就懵逼了,好好地程序不能用了(因为变成web组的POD了,能用才怪)。 2:c++组部署的某个POD并没有配置资源限制,而程序出现了一个严重bug,导致CPU被打满,所有其它组的工作都会受到影响针对以上的问题,k8s给出的解决方案是namespace,在这里的场景中就可以通过不同的namespace来隔离不同的技术部门的API对象,这样就可以避免以上的问题1,并给各自的namespace设置资源限额,这样就可以避免以上的问题2。下面我们就一起来看下吧。
1:使用namespace
想要使用namespace,首先需要定义namespace,如下:
kubectl create ns test-ns接着可以获取创建的namespace:
dongyunqi@mongodaddy:~/k8s$ kubectl get ns | egrep 'NAME|test-ns' NAME STATUS AGE test-ns Active 52m想要使用namespace的话只需要在yaml文件头的metadata中设置namespace就可以了,如下:
apiVersion: v1 kind: Pod metadata: name: ngx namespace: test-ns spec: containers: - image: nginx:alpine name: ngxapply后获取pod:
dongyunqi@mongodaddy:~/k8s$ kubectl get pod | egrep 'NAME|ngx' NAME READY STATUS RESTARTS AGE因为不指定-n的话默认是在default命名空间中查找,自然是找不到的,我们来设置-n,如下:
dongyunqi@mongodaddy:~/k8s$ kubectl get pod -n test-ns | egrep 'NAME|ngx' NAME READY STATUS RESTARTS AGE ngx 1/1 Running 0 3m8s可以看到就查找到了。但是在删除命名空间的时候一定要小心,因为同时会将内部的所有对象删除,如下:
dongyunqi@mongodaddy:~/k8s$ kubectl delete namespace test-ns namespace "test-ns" deleted dongyunqi@mongodaddy:~/k8s$ kubectl get pod -n test-ns | egrep 'NAME|ngx' No resources found in test-ns namespace.可以看到,pod确实也被删除了,个人认为这种方式不是很好,最好是如果namespace下还有对象的话应该提示不可删除才好。
2:资源配额
在[k8s之POD资源限制和健康监测]一文中我们分析了如何给POD设置资源限制,其实namespace也是可以的设置的,只不过其维度更大,是在一组对象之上。当然,首先我们还是先来定义一个namespace:
dongyunqi@mongodaddy:~/k8s$ kubectl create namespace resource-limit namespace/resource-limit created这样我们就创建了namespaceresource-limit,给该命名空间添加资源限制也比较简单,只需要创建另外一个API对象ResourceQuota就行了,主要配置项如下:
CPU 和内存配额,使用 request.*、limits.*,这是和容器资源限制是一样的。 存储容量配额,使 requests.storage 限制的是 PVC 的存储总量,也可以用 persistentvolumeclaims 限制 PVC 的个数。 核心对象配额,使用对象的名字(英语复数形式),比如 pods、configmaps、secrets、services。 其他 API 对象配额,使用 count/name.group 的形式,比如 count/jobs.batch、count/deployments.apps。如下yaml:
apiVersion: v1 kind: ResourceQuota metadata: name: dev-qt namespace: dresource-limit spec: hard: requests.cpu: 0.5 requests.memory: 2Gi limits.cpu: 1 limits.memory: 3Gi requests.storage: 15Gi persistentvolumeclaims: 100 pods: 100 configmaps: 100 secrets: 100 services: 10 count/jobs.batch: 1 count/cronjobs.batch: 1 count/deployments.apps: 1配置在namespace dresource-limit的限额如下:
所有 Pod 的需求总量最多是0.5个 CPU 和 2GB 的内存,上限总量是 1 个 CPU 和 3GB 的内存。 只能创建 100 个 PVC 对象,使用 15GB 的持久化存储空间。 只能创建 100 个 Pod,100 个 ConfigMap,100 个 Secret,10 个 Service。 只能创建 1 个 Job,1 个 CronJob,1 个 Deployment。apply后查看如下:
dongyunqi@mongodaddy:~/k8s$ kubectl get quota -n resource-limit NAME AGE REQUEST LIMIT dev-qt 30s configmaps: 1/100, count/cronjobs.batch: 0/1, count/deployments.apps: 0/1, count/jobs.batch: 0/1, persistentvolumeclaims: 0/100, pods: 0/100, requests.cpu: 0/500m, requests.memory: 0/2Gi, requests.storage: 0/15Gi, secrets: 1/100, services: 0/10 limits.cpu: 0/1, limits.memory: 0/3Gi信息不方便查看,可以使用describe,如下:
dongyunqi@mongodaddy:~/k8s$ kubectl describe quota -n resource-limit Name: dev-qt Namespace: resource-limit Resource Used Hard -------- ---- ---- configmaps 1 100 count/cronjobs.batch 0 1 count/deployments.apps 0 1 count/jobs.batch 0 1 limits.cpu 0 1 limits.memory 0 3Gi persistentvolumeclaims 0 100 pods 0 100 requests.cpu 0 500m requests.memory 0 2Gi requests.storage 0 15Gi secrets 1 100 services 0 10其中清晰的展示了使用量和允许的最大的量,下面我们来定义一个job,再来查看,如下:
dongyunqi@mongodaddy:~/k8s$ kubectl create job echo1 -n resource-limit --image=busybox -- echo hello job.batch/echo1 created dongyunqi@mongodaddy:~/k8s$ kubectl describe quota -n resource-limit Name: dev-qt Namespace: resource-limit Resource Used Hard -------- ---- ---- configmaps 1 100 count/cronjobs.batch 0 1 count/deployments.apps 0 1 count/jobs.batch 1 1 limits.cpu 0 1 limits.memory 0 3Gi persistentvolumeclaims 0 100 pods 0 100 requests.cpu 0 500m requests.memory 0 2Gi requests.storage 0 15Gi secrets 1 100 services 0 10从count/jobs.batch 1 1,可以看到Used已经变成1了,此时如果我们再创建job的话就会提示超出个数限制错误,如下:
dongyunqi@mongodaddy:~/k8s$ kubectl create job echo2 -n resource-limit --image=busybox -- echo hello error: failed to create job: jobs.batch "echo2" is forbidden: exceeded quota: dev-qt, requested: count/jobs.batch=1, used: count/jobs.batch=1, limited: count/jobs.batch=1 dongyunqi@mongodaddy:~/k8s$接下来我们再来定义一个POD看看,yaml如下:
dongyunqi@mongodaddy:~/k8s$ cat probe-podv2.yml apiVersion: v1 kind: Pod metadata: name: ngx namespace: resource-limit spec: containers: - image: nginx:alpine name: ngxapply:
dongyunqi@mongodaddy:~/k8s$ kubectl apply -f probe-podv2.yml Error from server (Forbidden): error when creating "probe-podv2.yml": pods "ngx" is forbidden: failed quota: dev-qt: must specify limits.cpu,limits.memory,requests.cpu,requests.memory竟然提示错误,不让我们创建,从错误提示中我们也可以看出是没有给POD设置资源限制导致的,其实这也很好理解,因为默认POD是没有资源限制的,所以不让创建也很合理,那么我们只要配置上资源限制就行了呗,但是如果是POD很多,都要配置,岂不是很麻烦,k8s当然也考虑到这一点了,因此其定义了API对象LimitRange来为各种对象设置默认的资源限制,其主要配置如下:
spec.limits 是它的核心属性,描述了默认的资源限制。 type 是要限制的对象类型,可以是 Container、Pod、PersistentVolumeClaim。d efault 是默认的资源上限,对应容器里的 resources.limits,只适用于 Container。 defaultRequest 默认申请的资源,对应容器里的 resources.requests,同样也只适用于 Container。 max、min 是对象能使用的资源的最大最小值。如下LimitRange yaml:
apiVersion: v1 kind: LimitRange metadata: name: dev-limits namespace: resource-limit spec: limits: - type: Container defaultRequest: cpu: 200m memory: 50Mi default: cpu: 500m memory: 100Mi - type: Pod max: cpu: 800m memory: 200Mi它设置了每个容器默认申请 0.2 的 CPU 和 50MB 内存,容器的资源上限是 0.5 的 CPU 和 100MB 内存,每个 Pod 的最大使用量是 0.8 的 CPU 和 200MB 内存。apply后再来创建POD就可以了,如下:
dongyunqi@mongodaddy:~/k8s$ kubectl apply -f probe-LimitRange.yml limitrange/dev-limits created dongyunqi@mongodaddy:~/k8s$ kubectl apply -f probe-podv2.yml pod/ngx created如下可以分别查看LimitRange和POD的资源配置:
dongyunqi@mongodaddy:~/k8s$ kubectl describe LimitRange dev-limits -n resource-limit Name: dev-limits Namespace: resource-limit Type Resource Min Max Default Request Default Limit Max Limit/Request Ratio ---- -------- --- --- --------------- ------------- ----------------------- Container cpu - - 200m 500m - Container memory - - 50Mi 100Mi - Pod cpu - 800m - - - Pod memory - 200Mi - - -dongyunqi@mongodaddy:~/k8s$ kubectl describe pod ngx -n resource-limit Name: ngx ... Containers: ngx: ... Limits: cpu: 500m memory: 100Mi Requests: cpu: 200m memory: 50Mi ...写在后面
小结
本文一起看了如何通过namespace来隔离对象,以及给namespace设置资源配额,并引入了用来设置namespace资源配额的ResourceQuota对象,以及给各种API对象设置默认资源限额的LimitRange对象。希望本文能够帮助到你。
参考文章列表
k8s之POD资源限制和健康监测 。