1 命名空间(NameSpace)简介
在Kubernetes中,命名空间(NameSpace)是一种逻辑隔离机制,用于将集群资源划分为多个虚拟集群。
2 命名空间的使用
2.1 基本操作
查看当前系统上的命名空间
使用kubectl get namespace获取当前系统上的命名空间,其中default为缺省值,如果创建资源时不指定namespace,则默认会创建到这个命名空间。
下面kube-开头的几个命名空间为Kubernetes初始化时创建的,用于运行k8s系统。
[root@master 3-namespace]# kubectl get namespace
NAME STATUS AGE
default Active 75m
kube-node-lease Active 75m
kube-public Active 75m
kube-system Active 75m
# ns是namespace的缩写,k8s中对于常用的字段,都有一些缩写,如deployment缩写为deploy,serviceaccount缩写为sa,等等。
[root@master 3-namespace]# kubectl get ns
NAME STATUS AGE
default Active 75m
kube-node-lease Active 75m
kube-public Active 75m
kube-system Active 75m
创建名字为dev的命名空间
# 编辑配置文件
[root@master 3-namespace]# cat dev-namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: dev
labels:
name: dev
# 创建命名空间
[root@master 3-namespace]# kubectl apply -f dev-namespace.yaml
namespace/dev created
# 可以看到创建成功
[root@master 3-namespace]# kubectl get ns
NAME STATUS AGE
default Active 76m
dev Active 12s
kube-node-lease Active 76m
kube-public Active 76m
kube-system Active 76m
删除名字为dev的命名空间[root@master 3-namespace]# kubectl delete ns dev
namespace "dev" deleted
2.2 示例:在dev命名空间下创建pod
在上一章,我们使用yaml资源清单文件创建了一个pod,其中,metadata.namespace: default,表示在默认命名空间下创建资源。接下来,我们准备在namespace为dev的命名空间创建一个pod
(1)清理之前的资源[root@master 3-namespace]# kubectl get pod
No resources found in default namespace.
(2) 编辑配置文件
这个配置文件与前面nginx-pod.yaml不同的地方在于,nginx-pod.yaml的metadata.namespace为defalut,这里改为了dev
[root@master 3-namespace]# cat nginx-namespace-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
namespace: dev #注意这里由default修改为dev
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.27.3
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
(3) 创建pod
创建pod,报错,提示没有找到名称为dev的NameSpace。[root@master 3-namespace]# kubectl apply -f nginx-namespace-pod.yaml
Error from server (NotFound): error when creating "nginx-namespace-pod.yaml": namespaces "dev" not found
(4) 查看当前系统下的命名空间
发现并没有名字为dev的命名空间,因此pod创建失败
[root@master 3-namespace]# kubectl get ns
NAME STATUS AGE
default Active 10h
kube-node-lease Active 10h
kube-public Active 10h
kube-system Active 10h
(5) 编辑创建命名空间的yaml配置文件
为了使pod创建成功,我们创建一个名字为dev的namespace。下面是yaml配置文件。
[root@master 3-namespace]# cat dev-namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: dev
labels:
name: dev
(6) 创建dev命名空间
执行,提示namespace/dev创建成[root@master 3-namespace]# kubectl apply -f dev-namespace.yaml
namespace/dev created
(7) 查看命名空间
查看namespace,可以看到dev命名空间。
[root@master 3-namespace]# kubectl get ns
NAME STATUS AGE
default Active 10h
dev Active 4s
kube-node-lease Active 10h
kube-public Active 10h
kube-system Active 10h
(8)再次创建pod
再次创建pod,可以看到创建成功[root@master 3-namespace]# kubectl apply -f nginx-namespace-pod.yaml
pod/nginx-pod created
(9)查看pod
查看刚创建的pod,发现没有找到[root@master 3-namespace]# kubectl get pod
No resources found in default namespace.
这是因为如果不指定命名空间,查找资源时将默认限制范围在default命名空间,但我们创建的资源在dev命名空间,因此需要显示指定,使用-n namespace-name
,指定查找范围。[root@master 3-namespace]# kubectl get pod -n dev
NAME READY STATUS RESTARTS AGE
nginx-pod 1/1 Running 0 8s
2.3 示例:不同命名空间下创建名字相同的pod
如果一个pod已经被创建,再次执行相同命令,则pod不会被再次创建,这是因为,由于k8s检测到同一命名空间下已经存在该pod,且配置没有发生变化,就不会做任何操作。如果配置有更新,则原来的pod会被删除,继而使用新配置创建pod。总之,同一命名空间下无法创建多个相同名字的pod。[root@master 3-namespace]# kubectl apply -f nginx-namespace-pod.yaml
pod/nginx-pod unchanged
下面我们试一下在不同命名空间下是否可以创建相同名字的pod。
(1) 使用上一节创建pod的yaml文件
首先切换到之前的创建pod的目录,查看配置文件,可以看到pod的名称和3-namespace下nginx-namespace-pod.yaml配置文件中pod名称相同。
[root@master 3-namespace]cd ../2-pod
[root@master 2-pod]# cat nginx-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod # 可以看到pod名相同
namespace: default # 但不再同一个命名空间
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.27.3
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
(2) 创建pod资源
使用kubectl apply创建pod资源
[root@master 2-pod]# kubectl apply -f nginx-pod.yaml
pod/nginx-pod created
[root@master 2-pod]# kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx-pod 1/1 Running 0 2s
[root@master 3-pod]# kubectl get pod -n dev
NAME READY STATUS RESTARTS AGE
nginx-pod 1/1 Running 0 71s
可以看到由于命名空间不同,相同名称的pod资源可以创建成功。
3 命名空间使用场景
命名空间在多用户或多团队环境中非常有用,用于管理资源。以下是一些常见的使用场景:
3.1 多用户环境的资源隔离
在多用户环境中,命名空间可以用来隔离不同用户的工作负载,确保每个用户只能访问自己的资源。
如果有多个开发团队共享Kubernetes集群,则可以为每个团队创建一个命名空间,如team-a、team-b等。kubectl create namespace team-a
kubectl create namespace team-b
然后再为每个团队分配不同的资源配额(Resource Quotas)和角色(RBAC)。
3.2 多环境隔离
在开发、测试和生产环境中,可以使用命名空间来隔离不同环境的资源,确保它们互不干扰。
如,先创建三个命名空间dev/test/prod:kubectl create namespace dev
kubectl create namespace test
kubectl create namespace prod
后续就可以将开发环境的资源放在dev命名空间中,测试环境的资源放在test命名空间中,生产环境的资源放在prod命名空间中。
3.3 资源配额管理
命名空间可以用来管理资源配额(Resource Quotas),限制每个命名空间可以使用的资源量。
以下是通过创建ResourceQuota资源限制dev命名空间的资源占用示例。
apiVersion: v1
kind: ResourceQuota
metadata:
name: compute-resources
namespace: dev
spec:
hard:
limits.cpu: "1"
limits.memory: "1Gi"
requests.cpu: "0.5"
requests.memory: "512Mi"
通过这种方式,dev命名空间下的所有资源,都不会超过设置的资源配额。
3.4 基于角色的访问控制(RBAC)
命名空间可以与RBAC结合使用,为不同用户或团队分配不同的权限。
下面例子创建了两个RBAC资源,Role和RoleBinding。在Role中,指定命名空间为dev,指定角色名称为pod-reader,rules定义了一组规则,规定了pod-reader角色可以执行的操作。
在RoleBinding中,将用户dev-user绑定到pod-reader角色,使得dev-user在命名空间中具有访问pods资源的权限,这个权限就是Role资源中的那组规则。
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: dev
name: pod-reader
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods
namespace: dev
subjects:
- kind: User
name: dev-user
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
在这个例子中,dev-user被授予了在dev命名空间中读取Pod的权限。
3.5 多租户环境
在多租户环境中,命名空间可以用来隔离不同租户的资源,确保每个租户只能访问自己的资源。
如下命令可以快速创建tenant-a和tenant-b两个命名空间,分别给两个租户使用。kubectl create namespace tenant-a
kubectl create namespace tenant-b
然后就可以为每个租户分配不同的资源配额和角色。
3.6 项目隔离
在大型项目中,通常使用命名空间来隔离不同子项目的资源,确保它们互不干扰。
如下所示,创建前后端两个项目的命名空间:kubectl create namespace project-frontend
kubectl create namespace project-backend
前端项目的资源放在project-frontend命名空间中,后端项目的资源放在project-backend命名空间中,互不干扰。
但是,为了方便起见,我们后续创建的资源都不显式指定namespace,即所有资源都创建到default这个默认命名空间。