Namespace
Kubernetes 的名字空间并不是一个实体对象,只是一个逻辑上的概念。它可以把集群切分成一个个彼此独立的区域,然后我们把对象放到这些区域里,就实现了类似容器技术里 namespace 的隔离效果,应用只能在自己的名字空间里分配资源和运行,不会干扰到其他名字空间里的应用。
避免资源配额冲突、命名冲突、访问控制问题的出现,就需要把集群给适当地“局部化”,为每一类用户创建出只属于它自己的“工作空间”
Kubernetes使用名称空间
名字空间也是一种 API 对象,使用命令 kubectl api-resources 可以看到它的简称是“ns”,命令 kubectl create 不需要额外的参数
kubectl create ns test-ns
kubectl get ns
把一个对象放入特定的名字空间,需要在它的 metadata 里添加一个 namespace 字段,比如我们要在“test-ns”里创建一个简单的 Nginx Pod
apiVersion: v1
kind: Pod
metadata:
name: ngx
namespace: test-ns
spec:
containers:
- image: nginx:alpine
name: ngx
kubectl apply 创建这个对象之后,直接用 kubectl get 是看不到它的,因为默认查看的是“default”名字空间,想要操作其他名字空间的对象必须要用 -n 参数明确指定:
kubectl get pod -n test-ns
因为名字空间里的对象都从属于名字空间,所以在删除名字空间的时候一定要小心,一旦名字空间被删除,它里面的所有对象也都会消失。
kubectl delete ns test-ns
资源配额
有了名称空间,就可以像管理容器一样,给名字空间设定配额,把整个集群的计算资源分割成不同的大小,按需分配使用。
不过集群和单机不一样,除了限制最基本的 CPU 和内存,还必须限制各种对象的数量,否则对象之间也会互相挤占资源。
名字空间的资源配额需要使用一个专门的 API 对象,叫做 ResourceQuota,简称是 quota
export out="--dry-run=client -o yaml"
kubectl create quota dev-qt $out
资源配额对象必须依附在某个名字空间上,所以在它的 metadata 字段里必须明确写出 namespace(否则就会应用到 default 名字空间)
创建一个名字空间“dev-ns”
ns-dev.yml
apiVersion: v1
kind: Namespace
metadata:
name: dev-ns
再创建一个资源配额对象“dev-qt”:
ns-quota.yml
apiVersion: v1
kind: ResourceQuota
metadata:
name: dev-qt
namespace: dev-ns
spec:
hard:
requests.cpu: 10
requests.memory: 10Gi
limits.cpu: 10
limits.memory: 20Gi
requests.storage: 100Gi
persistentvolumeclaims: 100
pods: 100
configmaps: 100
secrets: 100
services: 10
count/jobs.batch: 1
count/cronjobs.batch: 1
count/deployments.apps: 1
ResourceQuota 对象的使用方式比较灵活,既可以限制整个名字空间的配额,也可以只限制某些类型的对象(使用 scopeSelector)。
第一种,它需要在 spec 里使用 hard 字段,意思就是“硬性全局限制”。
ResourceQuota 里可以设置各类资源配额
- CPU 和内存配额,使用 request.、limits.,这是和容器资源限制是一样的。
- 存储容量配额,使 requests.storage 限制的是 PVC 的存储总量,也可以用 persistentvolumeclaims 限制 PVC 的个数。
- 核心对象配额,使用对象的名字(英语复数形式),比如 pods、configmaps、secrets、services。
- 其他 API 对象配额,使用 count/name.group 的形式,比如 count/jobs.batch、count/deployments.apps。
ns-quota.yml内容解析
- 所有 Pod 的需求总量最多是 10 个 CPU 和 10GB 的内存,上限总量是 10 个 CPU 和 20GB 的内存。
- 只能创建 100 个 PVC 对象,使用 100GB 的持久化存储空间。
- 只能创建 100 个 Pod,100 个 ConfigMap,100 个 Secret,10 个 Service。
- 只能创建 1 个 Job,1 个 CronJob,1 个 Deployment。
使用资源配额
kubectl apply -f ns-dev.yml
kubectl apply -f ns-quota.yml
kubectl get quota -n dev-ns
输出了 ResourceQuota 的全部信息,但都挤在了一起,看起来很困难,这时可以再用命令 kubectl describe 来查看对象,它会给出一个清晰的表格:
kubectl describe quota -n dev-ns
尝试在这个名字空间里运行两个 busybox Job,同样要加上 -n 参数:
kubectl create job echo1 -n dev-ns --image=busybox -- echo hello
kubectl create job echo2 -n dev-ns --image=busybox -- echo hello
ResourceQuota 限制了名字空间里最多只能有一个 Job,所以创建第二个 Job 对象时会失败,提示超出了资源配额。
再用命令 kubectl describe 来查看,也会发现 Job 资源已经到达了上限:
kubectl describe quota -n dev-ns
删除运行的 Job,就又可以运行一个新的离线业务了
kubectl get job -n dev-ns
kubectl delete job -n dev-ns echo1
kubectl create job echo2 -n dev-ns --image=busy-box -- echo hello
kubectl get job -n dev-ns
默认资源配额
在名称空间加上了资源配额限制之后,它会有一个合理但比较“烦人”的约束:要求所有在里面运行的 Pod 都必须用字段 resources 声明资源需求,否则就无法创建。
比如说,现在想用命令 kubectl run 创建一个 Pod:
kubectl run ngx --image=nginx:alpine -n dev-ns
如果 Pod 里没有 resources 字段,就可以无限制地使用 CPU 和内存,这显然与名字空间的资源配额相冲突。为了保证名字空间的资源总量可管可控,Kubernetes 就只能拒绝创建这样的 Pod 了。
让 Kubernetes 自动为 Pod 加上资源限制 – LimitRange,简称是 limits,它能为 API 对象添加默认的资源配额限制。
- spec.limits 是它的核心属性,描述了默认的资源限制。
- type 是要限制的对象类型,可以是 Container、Pod、PersistentVolumeClaim。
- default 是默认的资源上限,对应容器里的 resources.limits,只适用于 Container。
- defaultRequest 默认申请的资源,对应容器里的 resources.requests,同样也只适用于 Container。
- max、min 是对象能使用的资源的最大最小值。
dev-ns-limit-range.yml
apiVersion: v1
kind: LimitRange
metadata:
name: dev-limits
namespace: dev-ns
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 内存。
vim dev-ns-limit-range.yml
kubectl apply -f dev-ns-limit-range.yml
kubectl describe limitranges -n dev-ns
不用编写 resources 字段直接创建 Pod :
kubectl run ngx --image=nginx:alpine -n dev-ns
kubectl get pod -n dev-ns
用 kubectl describe 查看 Pod 的状态,也可以看到 LimitRange 为它自动加上的资源配额:
kubectl describe pod -n dev-ns ngx