Pod 的 NameSpace


一、Pod 的 NameSpace

使用 kubectl 管理命名空间及其包含的资源相当简单。在这一节中,我们将演示一些最常见的命名空间操作,便于你开始有效地分割资源。

在我们进行创建命名空间之前,先说一下 Kubernetes 是如何自动设置它的,在默认情况下,新的集群上有四个命名空间:

要显示集群中可用的所有命名空间,使用 kubectl get namespaces 命令:

40.png

default: 向集群中添加对象而不提供命名空间,这样它会被放入默认的命名空间中。在创建替代的命名空间之前,该命名空间会充当用户新添加资源的主要目的地,无法删除。

kube-public: 此命名空间是自动创建的,并且所有用户(包括未经过身份验证的用户)都可以读取。此命名空间主要用于群集使用,以防某些资源在整个群集中可见且可公开读取。此命名空间的公共方面只是一个约定,而不是一个要求。

kube-system: kube-system 命名空间用于 Kubernetes 管理的 Kubernetes 组件,一般规则是,避免向该命名空间添加普通的工作负载。它一般由系统直接管理,因此具有相对宽松的策略。

kube-node-lease: 是 Kubernetes 集群中用于节点租约(Node Lease)的一个命名空间。Kubernetes 通过节点租约机制来优化节点的健康检查,从而提高整个集群的性能和可靠性。

使用 kubectl get namespaces kube-system 指定namespaces 查看:

41.png

使用 kubectl describe namespaces kube-system 指定namespaces查看详情:

42.png

namespaces status 有两个状态:

  • Active : 命名空间正在使用中
  • Terminating : 正在删除命名空间,不能用于新对象

使用 kubectl create namespace test 创建 namespaces :

43.png

正常使用 namespaces ,只需要在我们创建的资源清单内指定即可:

apiVersion: v1
kind: Pod
metadata:
  name: nginx
  namespace: test    # 指定namespace
  labels:
    app: web
spec:
  containers:
  - name: nginx
    image: docker.io/nginx
    ports:
    - containerPort: 80

45.png

可以看到,如果我们不指定查看具体是那个命名空间的 Pod ,那么会默认显示为 default 空间内的 Pod 信息。

使用 kubectl delete namespaces test 删除 namespaces :

44.png

Namespace

namespace命名空间,后面简称ns。在K8s上面,大部分资源都受ns的限制,来做资源的隔离,少部分如pv,clusterRole等不受ns控制,这个后面会讲到。 Kubernetes使用命名空间的概念帮助解决集群中在管理对象时的复杂性问题。命名空间允许将对象分组到一起,便于将它们作为一个单元进行筛选和控制。无论是应用自定义的访问控制策略,还是为了测试环境而分离所有组件,命名空间都是一个按照组来处理对象、强大且灵活的概念。

# 查看目前集群上有哪些ns
# kubectl get ns

image-20240429202445201

# 通过kubectl 接上 -n namespaceName 来查看对应ns上面的资源信息
# kubectl -n kube-system get pod

image-20240429202402985

# 我们通过不接-n 的情况下,都是在默认命令空间default下进行操作,在生产中,通过测试一些资源就在这里进行
# kubectl get pod
NAME                         READY   STATUS    RESTARTS   AGE
new-nginx-854cf59647-26bnh   2/2     Running   0          2s
new-nginx-854cf59647-98n9w   2/2     Running   0          2s

# kubectl -n default get pod
NAME                         READY   STATUS    RESTARTS   AGE
new-nginx-854cf59647-26bnh   2/2     Running   0          37s
new-nginx-854cf59647-98n9w   2/2     Running   0          37s


# 创建也很简单
[root@node-1 ~]# kubectl create ns test
namespace/test created
[root@node-1 ~]# kubectl get ns|grep test
test  

# 删除ns,注意删除很危险,慎用
# kubectl delete ns test 
namespace "test" deleted

排错技巧

# 生产中的小技巧:k8s删除namespaces状态一直为terminating问题处理
# kubectl get ns
NAME              STATUS        AGE
default           Active        5d4h
ingress-nginx     Active        30h
kube-node-lease   Active        5d4h
kube-public       Active        5d4h
kube-system       Active        5d4h
kubevirt          Terminating   2d2h   # <------ here

1、新开一个窗口运行命令  kubectl proxy
> 此命令启动了一个代理服务来接收来自你本机的HTTP连接并转发至API服务器,同时处理身份认证

2、新开一个终端窗口,将下面shell脚本整理到文本内`1.sh`并执行,$1参数即为删除不了的ns名称
#------------------------------------------------------------------------------------
#!/bin/bash

set -eo pipefail

die() { echo "$*" 1>&2 ; exit 1; }

need() {
        which "$1" &>/dev/null || die "Binary '$1' is missing but required"
}

# checking pre-reqs

need "jq"
need "curl"
need "kubectl"

PROJECT="$1"
shift

test -n "$PROJECT" || die "Missing arguments: kill-ns <namespace>"

kubectl proxy &>/dev/null &
PROXY_PID=$!
killproxy () {
        kill $PROXY_PID
}
trap killproxy EXIT

sleep 1 # give the proxy a second

kubectl get namespace "$PROJECT" -o json | jq 'del(.spec.finalizers[] | select("kubernetes"))' | curl -s -k -H "Content-Type: application/json" -X PUT -o /dev/null --data-binary @- http://localhost:8001/api/v1/namespaces/$PROJECT/finalize && echo "Killed namespace: $PROJECT"
#------------------------------------------------------------------------------------

3. 执行脚本删除
# bash 1.sh kubevirt
Killed namespace: kubevirt
1.sh: line 23: kill: (9098) - No such process

5、查看结果
# kubectl get ns    
NAME              STATUS   AGE
default           Active   5d4h
ingress-nginx     Active   30h
kube-node-lease   Active   5d4h
kube-public       Active   5d4h
kube-system       Active   5d4h