为什么要有namespace?
1 是K8S的逻辑隔离机制,相当于在一个集群内部虚拟出来的集群或者说是资源分组。例如,开发环境的资源放在dev命名空间,production资源放到pro命名空间,为了让不同namespaces的资源(pod,deployment,services, configmaps等等)互不干扰。在同一个命名空间内,资源的名称比如nginx-pod必须是唯一的,但多个命名空间可以存在相同名称的资源。
2 Namespace 是 RBAC (基于角色的访问控制) 的关键边界。定义的role只允许用户在特定namespace里执行操作。
3 可以设置一个namesapce资源配额,从而保证一个集群种不同团队不会互相抢占资源。
默认情况下你会看到有以下命名空间:

| Namespace 名称 | 作用 |
|---|---|
default |
默认的命名空间,如果没有指定,资源通常会创建在这里。 |
kube-system |
供 Kubernetes 系统组件(如 kube-proxy, kube-dns/coredns)使用的命名空间。不要在此创建或修改您自己的应用资源。 |
kube-public |
供所有用户访问的命名空间,主要用于存放集群共用的配置数据。 |
kube-node-lease |
用于存储与节点心跳相关的 Lease 对象,属于系统内部机制。 |
namespace的创建、不同namespace之间的连通:
TypeScript
#查看namespace
kubectl get ns
#命令式创建namespace:
kubectl create namespace demo-ns
#声明式创建namespace:
#注意yaml文件中是Namespace而不是NameSpace:
apiVersion: v1
kind: Namespace
metadata:
name: demo2-ns
#---end
#下面尝试将不同namespace里的pod打开,尝试互相通信:
#创建nginx pod(default namespace也执行相同操作,只是没有'-n demo2-ns')
kubectl create deploy nginx-deploy -n demo2-ns
kubectl get deploy -n demo2-ns
kubectl get pods -n demo2-ns
#分别修改为3个replica
kubectl scale --replicas=3 deploy/nginx-deploy -n demo2-ns
#查看pod ip
kubectl get pods -n demo2-ns -o wide
10.244.3.2
10.244.2.3
#进入pod
kubectl exec -it nginx-deploy-6f47956ff4-zl8b4 -n demo2-ns -- sh
#curl
curl 10.244.3.2
curl 10.244.2.3
#都返回了<title>Welcome to nginx!</title>
#--最终结果--
#现在有两个namespace: default和demo2-ns,分别包含一个service: nginx-svc和nginx-svc2,每个service内部有3个一样的pod:ngnix-deploy
上文说明不同namespace的pod之间可以直接通过pod ip通信。但是pod ip每次重开会变化,因此尝试创建service,看不同service之间能不能连接:
TypeScript
kubectl delete svc nginx-svc -n demos-ns
#基于现有的deployment创建service
kubectl expose deploy nginx-deploy -n demo2-ns --name=nginx-svc2 --port=80
kubectl get svc -n demo2-ns
#进入pod
kubectl exec -it nginx-deploy-6f47956ff4-zl8b4 -n demo2-ns -- sh
#尝试curl <service name>看两个ns的service能否链接,-->会发现无法链接:
curl nginx-svc2
#curl <service name>.<namespace name>,-->能连接:
curl nginx-svc2.demo2-ns
# curl 完全限定域名FQDN,-->能连接:
curl nginx-svc.default.svc.cluster.local
#后缀.default.svc.cluster.local来自nginx容器的/etc/resolv.conf,是linux系统dns查询文件。下面解释它是什么、为什么能连通:
#/etc/resolv.conf内容:
nameserver 10.96.0.10 # 1. Kubernetes 集群 DNS 服务的 ClusterIP
search default.svc.cluster.local svc.cluster.local cluster.local
options ndots:5
/etc/resolv.conf配置项解释:
1. nameserver 10.96.0.10 (所在集群的DNS 服务器地址)
最重要的一行,指定了 Pod 应该向哪个 IP 地址发送 DNS 查询请求。
10.96.0.10 通常是 Kubernetes 集群中 CoreDNS (或 Kube-DNS)Service 的 ClusterIP。
这意味着 Pod 里的任何域名查询,都会被导向这个 ClusterIP,然后由 CoreDNS Service 来处理。
2. search default.svc.cluster.local ... (搜索域)
search 行定义了当进行一个非完全限定域名 (non-fully qualified domain name, FQDN) 的查询时,系统会自动在查询后面追加的后缀。
例如,如果 Pod 在 default 命名空间,尝试访问一个名为 my-service 的 Service:
Pod 首先会查询 my-service.default.svc.cluster.local。如果 CoreDNS 找到这个 Service,它就会返回 Service 的 ClusterIP。于是在 Pod 内部可以直接使用 Service 名称(例如 nginx-service)而不是完整的域名来访问其他服务。
3. options ndots:5 (点数阈值)
ndots 是一个优化设置,它定义了查询的域名中包含多少个点 (.) 时,才将其视为 完全限定域名 (FQDN) ,从而不 使用 search 列表中的后缀进行查询。
默认值通常是 5 或更高。由于 Service 的完整域名至少包含 4 个点(如 service.namespace.svc.cluster.local),设置较高的 ndots 保证了即使您只输入了 Service 的短名称(如 nginx-service),系统也会尝试用完整的搜索域后缀进行查询。
因此,curl nginx-svc.default.svc.cluster.local(完整的FQDN),是一个可直接将其解析为目标 Service 的 ClusterIP的域名。它精确地告诉 当前集群的CoreDNS:我要找 default 命名空间 里的 nginx-svc 服务。