上一篇【第10篇】Label和Selector——K8s的“贴标签“艺术下一篇【第12篇】Annotation——K8s的便利贴文化摘要前几篇文章咱们一直在default这个Namespace里折腾你可能都没注意到它的存在——因为K8s悄悄帮你把它填上了。Namespace这东西说白了就是K8s里的文件夹——把一个物理集群切分成多个逻辑区域每个区域里可以有同名的Pod、Service、ConfigMap互不影响。张三在他那Namepace里建了个nginx李四也可以在自己Namepace里建个nginx完全不冲突。但Namespace有个大坑——它只做逻辑隔离不是真正的安全边界。很多新手把Namespace当防火墙用结果发现A团队还是能访问B团队的Pod。本文从Namespace的本质讲起覆盖四个初始Namespace的来龙去脉、多团队共享集群的规划策略、跨Namespace通信的实际操作以及ResourceQuota怎么做真正的资源限制。一、Namespace是个什么东西——“文件夹还是防火墙”先给Namespace下个定义**Namespace是K8s里的一种逻辑分组机制把集群里的资源划分到不同的命名空间里。**同一Namespace内的资源名必须唯一不同Namespace的资源可以重名。【Namespace 文件夹】 集群根目录: / ├── default/ ← K8s 预置你的默认活动空间 │ ├── Pod: nginx │ ├── Pod: redis │ └── Service: nginx-svc ├── kube-system/ ← K8s 自己住的地方别乱动 │ ├── Pod: coredns-xxx │ ├── Pod: etcd-minikube │ └── Pod: kube-apiserver-minikube ├── kube-public/ ← 公共信息所有用户都能读 ├── kube-node-lease/ ← 节点心跳信息 ├── team-frontend/ ← 你的前端团队 │ ├── Pod: nginx ← 可以重名 │ └── Pod: vue-app └── team-backend/ ← 你的后端团队 ├── Pod: nginx ← 跟上面的 nginx 不冲突 └── Pod: go-service要点Namespace是逻辑隔离不是物理隔离。同一个集群里不同Namespace的Pod默认是可以通过IP互相访问的网络是通的。如果你想要真正的隔离——不让A团队访问B团队的Pod——得靠NetworkPolicy来做网络层面的控制。【Namespace提供的隔离 vs 没有提供的隔离】 ✅ Namespace 提供的 ❌ Namespace 不提供的 ┌─────────────────────────┐ ┌─────────────────────────┐ │ • 资源名称隔离 │ │ • 网络隔离 │ │ • 基于RBAC的访问控制 │ │ (Pod之间默认可以互通) │ │ • ResourceQuota 资源限制 │ │ • 物理节点隔离 │ │ • 独立的作用域 │ │ (不同NS的Pod可以在同一 │ │ (kubectl get pods 只 │ │ 台Node上) │ │ 看当前空间) │ │ • 真正的安全边界 │ └─────────────────────────┘ │ (不是多租户安全方案) │ └─────────────────────────┘二、四个初始Namespace——K8s自带的地盘一个新集群创建后你会看到四个自带的Namespace# 查看所有Namespacekubectl get namespaces# NAME STATUS AGE# default Active 7d# kube-system Active 7d# kube-public Active 7d# kube-node-lease Active 7d# 或用缩写kubectl get ns2.1 default——“新手的舒适区”这是你如果不指定Namespace时K8s默认使用的命名空间。你之前建的nginx Pod如果没有加-n参数全都落在了这里。要点我强烈建议你别在default里跑生产服务。default就像Windows桌面上那个新建文件夹——一开始觉得方便等东西多了就是灾难。生产环境建议创建专门的Namespacedefault只放测试和临时东西。2.2 kube-system——“K8s的心脏地带”这是K8s自己组件住的地方——API Server的Pod、etcd的Pod、CoreDNS、kube-proxy全在这。你从kubectl get pods -n kube-system里看到的那些Pod基本都在这儿。# 看看K8s自己的内脏kubectl get pods-nkube-system# NAME READY STATUS RESTARTS AGE# coredns-5dd5756b68-nk7zt 1/1 Running 0 7d# etcd-minikube 1/1 Running 0 7d# kube-apiserver-minikube 1/1 Running 0 7d# kube-controller-manager-minikube 1/1 Running 0 7d# kube-proxy-xyz123 1/1 Running 0 7d# kube-scheduler-minikube 1/1 Running 0 7d# storage-provisioner 1/1 Running 0 7d要点kube-system里的东西千万别乱删它是K8s的内脏器官——你不小心删了个CoreDNS Pod虽然Deployment会重建或者更糟——删了整个Namespace那就准备重装集群吧。我自己作死干过一次教训深刻。2.3 kube-public——“公告栏”这个Namespace里的资源对**所有用户包括未认证用户**都是可读的。通常用来放集群级别的公共信息比如cluster-infoConfigMap。kubectl get cm-nkube-public# NAME DATA AGE# cluster-info 1 7d# 这个ConfigMap里的内容对所有用户可见kubectl get cm cluster-info-nkube-public-oyaml2.4 kube-node-lease——“心跳档案室”K8s 1.14后引入的新Namespace用来存每个Node的Lease对象心跳信号。以前Node心跳是kubelet定期更新Node对象的一个字段效率不高现在改成每个Node一个Lease对象高频更新不影响Node对象的整体状态。Namespace用途可以动吗default默认命名空间不指定-n时的落点可以但不建议放生产服务kube-systemK8s系统组件别碰kube-public公共可读信息可以读一般不动kube-node-leaseNode心跳Lease对象别碰三、Namespace的日常操作——增删改查# 创建Namespacekubectl create namespace team-frontend kubectl create ns team-backend# ns 是 namespace 的缩写# 也可以用YAML创建推荐版本可控# namespace-team-frontend.yamlapiVersion:v1kind:Namespacemetadata:name:team-frontendlabels:team:frontendenvironment:productionkubectl apply-fnamespace-team-frontend.yaml# 查看所有Namespacekubectl get namespaces --show-labels# 切换当前上下文到指定Namespace省去每次敲 -nkubectl config set-context--current--namespaceteam-frontend# 查看当前所在的Namespacekubectl config view--minify|grepnamespace# 在指定Namespace里操作kubectl get pods-nteam-backend kubectl describe pod nginx-nteam-frontend kubectl logs deploy/nginx-nteam-frontend# 在所有Namespace里查找kubectl get pods-A# -A 等于 --all-namespaceskubectl get pods --all-namespaces-lappnginx# 删除Namespace会删除其中的所有资源kubectl delete namespace team-frontend# ⚠️ 上述命令会删除 team-frontend 里的所有 Pod/Service/...# 不可逆操作三思而后行要点删除Namespace是K8s里最危险的命令之一——Namespace一删里面所有的Pod、Service、ConfigMap、Secret、PVC……全部灰飞烟灭。执行前请再三确认kubectl get all -n target-ns看一眼里面到底有什么。四、多团队共享集群——Namespace规划实战假设你有个K8s集群要给三个团队用前端、后端、数据分析。怎么设计Namespace结构4.1 按团队划分最常见【按团队划Namespace】 集群 ├── team-frontend/ ← 前端团队的地盘 │ ├── Pod: vue-app │ ├── Pod: nginx │ └── Service: frontend-svc ├── team-backend/ ← 后端团队的地盘 │ ├── Pod: api-server │ ├── Pod: user-service │ └── Service: backend-svc └── team-data/ ← 数据团队的地盘 ├── Pod: spark-worker ├── Pod: flink-job └── Service:>4.2 按环境划分【按环境划Namespace】 集群 ├── dev/ ← 开发环境 ├── staging/ ← 预发布环境 └── prod/ ← 生产环境4.3 混合划分推荐【推荐团队×环境的混合划分】 集群 ├── frontend-dev/ ├── frontend-staging/ ├── frontend-prod/ ├── backend-dev/ ├── backend-staging/ ├── backend-prod/ ├──>五、ResourceQuota——给Namespace戴上紧箍咒Namespace只管名字隔离不管资源限制——后面这个任务由ResourceQuota出场。没有ResourceQuota某个团队可能一个Namespace就吃光了整个集群的资源。# 给 team-frontend 设置资源配额apiVersion:v1kind:ResourceQuotametadata:name:team-frontend-quotanamespace:team-frontendspec:hard:# 计算资源限制requests.cpu:10# 所有Pod的CPU requests总和 ≤ 10核requests.memory:20Gi# 所有Pod的内存requests总和 ≤ 20GiBlimits.cpu:20# 所有Pod的CPU limits总和 ≤ 20核limits.memory:40Gi# 所有Pod的内存limits总和 ≤ 40GiB# 对象数量限制pods:50# 最多50个Podservices:10# 最多10个Serviceconfigmaps:20# 最多20个ConfigMapsecrets:30# 最多30个Secretpersistentvolumeclaims:5# 最多5个PVC# 存储限制requests.storage:100Gi# 所有PVC请求总存储 ≤ 100GiB# 查看ResourceQuotakubectl describe resourcequota-nteam-frontend# 查看当前使用情况kubectl get resourcequota-nteam-frontend# NAME AGE REQUEST LIMIT# team-frontend-quota 1d requests.cpu: 8/10 limits.cpu: 15/20# requests.memory: 15Gi/20Gi limits.memory: 30Gi/40Gi限制类型说明典型值requests.cpuCPU请求总量上限10-100核requests.memory内存请求总量上限20-200GiBlimits.cpuCPU限制总量上限20-200核limits.memory内存限制总量上限40-400GiBpodsPod总数上限50-500servicesService总数上限10-100configmapsConfigMap总数上限20-200secretsSecret总数上限30-300要点ResourceQuota要配合每个Pod的resources.requests使用。如果Pod没有声明requestsResourceQuota就会拒绝创建它。这也是逼着你养成设置资源requests的好习惯。六、跨Namespace通信——“隔壁老王怎么找你”不同Namespace的Pod默认是可以互通的网络上没墙但Service的DNS域名是带Namespace的。K8s内部的DNS格式【K8s DNS 解析规则】 service-name.namespace.svc.cluster-domain 完整FQDN nginx-service.team-backend.svc.cluster.local 同Namespace 直接写 nginx-service 就行 跨Namespace 得写全nginx-service.team-backend 跨Namespace简写nginx-service.team-backend.svc cluster-domain 通常是 cluster.local安装时配置的# 在 team-frontend 空间的 Pod 里访问 team-backend 空间的 Service# 方法1完整FQDNcurlhttp://api-service.team-backend.svc.cluster.local:8080# 方法2DNS简写推荐curlhttp://api-service.team-backend.svc:8080# 方法3用环境变量注入不推荐太局限# K8s会给每个Pod注入同Namespace的Service环境变量# 但跨Namespace的Service不会注入【跨Namespace通信示意图】 Namespace: team-frontend Namespace: team-backend ┌────────────────────────┐ ┌────────────────────────┐ │ │ │ │ │ Pod: vue-app │ │ Service: api-service │ │ │ │ ClusterIP: 10.96.2.5 │ │ 需要访问后端API │ │ │ │ │ │ │ │ ┌─────┴─────┐ │ │ │ curl │ │ ▼ ▼ │ │ │ api-service. │ │ Pod:api-1 Pod:api-2 │ │ │ team-backend │ │ 10.244.2.3 10.244.3.7│ │ │ .svc:8080 │ │ │ │ ▼ │ │ │ │ ┌─────────────────┐ │ └────────────────────────┘ │ │ DNS: CoreDNS │ │ │ │ 解析出10.96.2.5 │ │ │ └────────┬────────┘ │ │ │ │ │ ▼ │ │ 请求发往 10.96.2.5:8080│ ──── kube-proxy 转发 ────► 10.244.2.3:8080 │ │ └────────────────────────┘要点如果你不想让A Namespace的Pod能访问B Namespace的Service得配NetworkPolicy——这才是真正的网络隔离。Namespace自身不挡流量别把它当防火墙用。本篇小结Namespace看着简单但用好了是利器用错了是坑逻辑隔离不是安全隔离——Namespace就像文件夹不同文件夹里的文件可以同名但文件夹本身不防删除和访问四个初始Namespacedefault你的大本营但别放生产、kube-system系统内脏别乱动、kube-public公告栏、kube-node-lease节点心跳档案规划的三种方式按团队、按环境、团队×环境混合——推荐第三种命名规范用team-environmentResourceQuota做真正的资源限制——配额要配合Pod的resources字段才有意义跨Namespace通信DNS用service.namespace.svc要网络隔离用NetworkPolicy下一篇咱们聊Annotation——如果说Label是分类标签Annotation就是便利贴专放那些不适合用来过滤和选择的元数据。上一篇【第10篇】Label和Selector——K8s的“贴标签“艺术下一篇【第12篇】Annotation——K8s的便利贴文化