跳转至

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 通信

  • 命名空间彼此之间是互不通信的。但它们并不是绝对的相互隔绝。一个 namespaceservice 可以和另一个 namespace 中的 service 通信。这在项目共享中非常有用,比如你项目的一个 service 要和另外一个项目的 service 通信,而你们的 service 都在各自的 namespace 中。

  • 当你的节点要访问 Kubernetesservice ,你可以使用内置的 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 
创建名为 ctx-dev 上下文,指定其命名空间为 development
kubectl config set-context ctx-dev --namespace=development --cluster=kubernetes-cluster --user=dev
创建名为 ctx-pro 上下文,指定其命名空间为 production
kubectl config set-context ctx-pro --namespace=production --cluster=kubernetes-cluster --user=prod

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