K8s集群:命名空间(Namespace) ¶
一、k8s - namespace 介绍 ¶
命名空间
namespace
用于资源隔离,不同环境下的资源可以放置到同一个集群下不同的 namespace
下,如 dev、rc、demo
环境分别使用不同的 namespace
。也可用不同的 namespace
区分客户。
命名空间用途
-
名字空间适用于存在很多跨多个团队或项目的用户的场景。对于只有几到几十个用户的集群,根本不需要创建或考虑名字空间。当需要名称空间提供的功能时,请开始使用它们。
-
名字空间为名称提供了一个范围。资源的名称需要在名字空间内是唯一的,但不能跨名字空间。 名字空间不能相互嵌套,每个
Kubernetes
资源只能在一个名字空间中。 -
名字空间是在多个用户之间划分集群资源的一种方法。
-
namespace
还可以对namespace
下的所有pod
进行资源限制,如最多允许使用cpu
、内存
、创建多少个pod
等。 -
不必使用多个名字空间来分隔仅仅轻微不同的资源,例如同一软件的不同版本: 应该使用
标签
来区分同一名字空间中的不同资源。
二、 namespace 管理 ¶
系统默认 namespace
大多数的 K8s 集群中,默认会有几个 默认的 namespace。
root@jenkins:~# kubectl get ns
NAME STATUS AGE
default Active 7d22h
kube-node-lease Active 7d22h
kube-public Active 7d22h
kube-system Active 7d22h
-
default:你的service和app默认被创建于此。
-
kube-system:kubernetes系统组件使用。
-
kube-public:公共资源使用。但实际上现在并不常用。
-
kube-node-lease:此命名空间用于与各个节点相关的租期(Lease)对象;此对象的设计使得集群规模很大时节点心跳检测性能得到提升。
创建 namespace ¶
注意
创建命名空间时,应避免使用 kube-作为前缀。因为它是为 Kubernetes 系统名字空间保留的。
命名规范
- 不能带小数点 .
- 不能带下划线 _
- 使用数字、小写字母和减号 - 组成的字符串
约束
- 在同一个命名空间中,资源名称须保持唯一。但在不同命名空间中,可以存在相同名称的资源。
- 每一个资源只能隶属于一个命名空间。
- 但命名空间本身不能属于另一个命名空间。
kubectl create namespace datarc
# cat my-datarc.yaml
apiVersion: v1
kind: Namespace
metadata:
name: datarc
labels:
name: dev
kubectl apply -f my-datarc.yaml
查看 namespace ¶
kubectl get ns
kubectl describe ns datarc # 查看详细信息
kubectl get pods -n datarc # 查看某个 namespace 下的资源
输出 namespace 为 json yaml 文件
kubectl get ns datarc -o <格式参数>
删除 namespace ¶
删除namespace,其下的所有资源将全部被删除
kubectl delete namespaces datarc
三、在 namespace 创建资源 ¶
# cat pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: mypod
labels:
name: mypod
spec:
containers:
- name: mypod
image: nginx
kubectl apply -f pod.yaml --namespace=datarc
创建 yaml 文件 指定资源的 namespace
创建文件 pod-datarc.yaml ,内容如下:
apiVersion: v1
kind: Pod
metadata:
name: mypod
namespace: datarc
labels:
name: mypod
spec:
containers:
- name: mypod
image: nginx
kubectl apply -f pod-datarc.yaml
提示
目前 使用命令 kubectl get pods
查看您的 pod
,您会得到:资源未找到的错误。
这是因为命令是在当前(default)
命名空间中,如果要查看其他 namespace
资源,你需要指定 namespace
,如下所示:
kubectl get pods --namespace=datarc
四、 管理当前已经创建的 namespace ¶
快捷使用 namespace
默认创建的命名空间是 default
。因此,当您在其他 namespace
创建了资源,那么每次使用 kubectl
命令都要带上 namespace
将会很麻烦。正好 kubens
工具可以解决这个麻烦。
安装 kubens
curl -L https://github.com/ahmetb/kubectx/releases/download/v0.9.4/kubens -o /bin/kubens && chmod +x /bin/kubens
使用 kubens
- 当您运行
kubens
命令时,会自动高亮当前的namespace
: - 如果要切换
datarc
空间时,运行
kubens datarc
- 这时后续执行的所有命令都会在
datarc
这个namespace
下执行。
五、跨 namespace 通信 ¶
namespace 通信
-
命名空间彼此之间是互不通信的。但它们并不是绝对的相互隔绝。一个
namespace
中service
可以和另一个namespace
中的service
通信。这在项目共享中非常有用,比如你项目的一个service
要和另外一个项目的service
通信,而你们的service
都在各自的namespace
中。 -
当你的节点要访问
Kubernetes
的service
,你可以使用内置的DNS
服务发现并把你的节点
指到Service
的名称。你可以在多个namespace
中创建同名的service
。解决这个问题,就用到DNS
地址的扩展形式。 在Kubernetes
中,Service
通过一个DNS
模式来暴露endpoint
。这个模式类似:
<Service Name>.<Namespace Name>.svc.cluster.local
一般情况下,你只需要service的名称,DNS会自动解析到它的全地址。然而,如果你要访问其他namespace中的service,那么你就需要同时使用service名称和namespace名称。例如,你想访问test中的“database”服务,你可以使用下面的地址:
database.test
六、namespace 资源限制 ¶
Resource
即资源配额,限定单个namespace中可使用集群资源的总量,包括两个维度
- 限定某个对象类型(如Pod)可创建对象的总数;
- 限定某个对象类型可消耗的计算资源(CPU、内存)与存储资源(存储卷声明)总数
举个栗子
-
如果在 namespace 中为计算资源 CPU 和内存设定了 ResourceQuota,用户在创建对象(Pod、Service等)时,必须指定 requests 和 limits;
-
如果在创建或更新对象时申请的资源与 namespace 的 ResourceQuota 冲突,则 apiserver 会返回 HTTP 状态码 403,以及对应的错误提示信息。
-
当集群中总的容量小于各个 namespace 资源配额的总和时,可能会发生资源争夺,此时 Kubernetes 将按照先到先得的方式分配资源。
通过创建 YAML
的描述文件,k8s
根据这个 YAML
来限制该配置文件中编辑最大最小内存和cpu限制以及默认运行参数限制。
创建文件 limitrange.yaml ,内容如下: ¶
# 创建 测试环境 namespace
apiVersion: v1
kind: Namespace
metadata:
name: datarc-dev
labels:
name: datarc-dev
---
# 定义 ResourceQuota
apiVersion: v1
kind: ResourceQuota
metadata:
name: quota-dev
namespace: datarc-dev
spec:
hard:
requests.cpu: "2" # 限制 CPU 资源为 2 核心
requests.memory: 2Gi # 限制内存资源为 2 GiB
limits.cpu: "4" # 限制 CPU 资源最大为 4 核心
limits.memory: 4Gi # 限制内存资源最大为 4 GiB
requests.nvidia.com/gpu: 4 # 限制 NVIDIA GPU 资源为 4 个
pods: "6" # 限制 POD 6 个
services: "6" # 限制 Service 数量为 6 个
kubectl apply -f limitrange.yaml
查看详细信息 ¶
kubectl describe quota quota-dev -n datarc-dev
Limitrange
- 用于强制执行某些 Pod 或 Container 的最小或最大资源请求和限制。
- 可以使用 LimitRange 限制容器请求的最小和最大 CPU、内存和存储。
- LimitRange 可以在一个命名空间中为多个 Pod 和容器设置限制,并且它可以确保所有 Pod 和容器都满足一组最小要求。
- 跨多个命名空间共享该资源配置也是可能的。
- 与 ResourceQuota 相比,LimitRange 更加针对 Pod 和容器级别的资源管理,而 ResourceQuota 更加针对整个命名空间的资源管理。
Namespace:集群环境共享与隔离 ¶
为什么需要集群环境共享与隔离
- k8s通过 namespace 和 Context 的设置来对不同的工作组进行分区,使可以共享同一个k8s集群服务,也互不干扰。
- 假设在我们的组织中有两个工作组:开发组和生产运维组。
- 开发组在k8s集群中需要不断创建、修改、删除各Pod、RC、Service等资源对象,以便实现敏捷开发的过程。
- 生产运维组则需要使用严格的权限设置来确保生产系统中的Pod、RC、Service处于正常运行状态。
namespace 与 context
Namespace 和 Context 是两个不同的概念。
-
Namespace 是 Kubernetes 中用于隔离资源的一种机制,它可以将一个物理集群划分为多个虚拟集群。通过在不同的 Namespace 中创建相同名称的资源对象(如 Pod、Service 等),可以避免名称冲突和资源之间的干扰。例如,开发人员可以将测试和生产环境分别创建在不同的 Namespace 中,从而实现资源的隔离。
-
Context 是管理 kubectl 命令的配置文件,它定义了访问 Kubernetes 集群所需的信息(如 API Server 的 URL、用户名、密码等)。通常情况下,Context 包含三个属性:集群、用户和命名空间。当您使用 kubectl 命令时,会自动加载当前上下文所需的配置文件来访问 Kubernetes 集群。
总结: Namespace 关注资源隔离和管理。Context 关注如何连接到 Kubernetes 集群并使用 kubectl 命令进行管理。
1. 创建 测试环境 namespace ¶
分别创建开发组与生产运维组的命名空间
# cat namespace-development.yaml
apiVersion: v1
kind: Namespace
metadata:
name: development
labels:
name: datarc-development
kubectl apply -f namespace-development.yaml
# cat namespace-production.yaml
apiVersion: v1
kind: Namespace
metadata:
name: production
labels:
name: datarc-production
kubectl apply -f namespace-production.yaml
2. 定义 Context (运行环境) ¶
为两个工作组分别定义一个Context,这个运行环境将属于某个特定的命名空间
# 创建或修改名为 kubernetes-cluster 的 Kubernetes 集群(Cluster)配置。
kubectl config set-cluster kubernetes-cluster --server=http://192.168.1.99:8080
Context 相关参数
Namespace (命名空间):development
Cluster (集群):kubernetes-cluster
User (用户):dev
查看已定义的 Context ¶
kubectl config view
kubectl config命令在$HOME/.kube目录生成了一个名为config的文件,文件内容就是kubectl config view命令查看到的内容
3. 设定工作组在自己的 Context 环境中工作 ¶
kubectl config use-context 命令来设置当前的运行环境 ¶
kubectl config use-context ctx-dev
kubectl config view
kubectl config use-context ctx-pro
kubectl config view