IT 铁人赛 k8s 入门30天 -- day9 Organizing your components with K8s Namespaces

前言

今天将会介绍 k8s Namespace

针对 Namespace 的作用, 还有何时该使用 Namespace 跟用法做说明

什麽是 Namespace?

在 k8s 丛集可以允许一个实体丛集具有多个虚拟丛集

而这些虚拟丛集就是所谓的 Namespace

在 k8s 丛集使用 Namespace 来针对丛集资源做管理

基础的 k8s 丛集系统会有预设的以下4个 Namespace

kube-system

内部有一些 k8s 在使用系统程序

比如说 Kublet 还有 Control Plane 等等

kube-public

内部存放一些可以被公开存取的资源

比如说 ConfigMap

kube-node-lease

用来存放一些结点相关的物件

可以用来侦测结点状态, 让 kubelet 对结点送 heartbeats 检测

default

预设存放使用者建立的资源

使用要者要使用自定义的 Namespace

可以使用以下指令

kubectl create namespace $namespace_name

举例来说: 建立名称为 my-namespace 的 Namespace

kubectl create namespace my-namespace

或者使用设定档 my-namespace.yaml

apiVersion: v1
kind: Namespace
metadata:
  name: my-namespace

再使用下面指令建立:

kubectl create -f my-namespace

为何要使用 Namespace?

资源分类

想像假设把所有资源都直接放在 default namespace

当系统变复杂, 所有资源都会散布在一起, 不好分类检视

所以比较好的方式是把每个资源根据用途做分类

并且切割出分类项目的 Namespaces, 再依据不同分类放置对应的 Namespace

避免布署冲突: 多个团队使用同一个 k8s cluster

多个团队使用同一个 k8s cluster, 有可能在布署资源时遇到布署名称冲突的问题

举例来说: 恰巧两个 team 都发布一个叫作 logger-app 的 deployment

这时, 如果没有用 Namespace 切分就会遇到同名称的 deployment 相互干扰的问题

这时就可以用 Namespace 做资源隔离给每个 team 给不同 Namespace , 这样就不用担心会被其他 team 影响

资源分享: 在不同的环境透过 Namespace 共享相同 Service

如果根据布署环境切分成 staging 与 production 两个 Namespace

另外把 nginx, elastic 相关的分别放置在 Nginx-Ingress-Controller, Elastic-Stack 两个 Namespace

这时两个布署环境就可以透过 Namespace 共享这些 Service

资源分享案例: 蓝绿布署

蓝绿布署是指同一个应用或是服务根据设定同时布署两种版本来做测试

而再两种布署里, 底层用到的资源是相同的比如 Nginx-Ingress-Controller, Elastic-Stack

透过 Namespace 限制存取或是资源

假设有2个团队 team A, team B

可以利用 Namespace 限制

team A 只能在 Namespace team_A_space 发布服务, 建立资源

team B 只能再 Namespace team_B_space 发布服务, 建立资源

彼此不干预各自团队的开发布署

另外也可以限制每个 Namespace 最多拥有多少资源比如CPU, RAM 等等

如此可以避免某一个 team 过度占用共有资源

Namespace 的特性

大多数的资源无法跨 Namespace 来存取

举例来说:

假设有一个 Namespace Project_A 内部有一个 ConfigMap 设定关於存取 Namespace database 的 database_url

在另一个 Namespace Project_B 内部的服务就无法透过 Namespace Project_A 内部的 ConfigMap 来存取 Namespace database

必须要在 Namespace Project_B 内部建立一个 ConfigMap 设定关於存取 Namespace database 的 database_url

这样 Namespace Project_B 的服务才能透过内部的 ConfigMap 拿到存取 Namespace database 的 database_url 来存取 DB

所以每个 Namespace 必须有自己的 ConfigMap, Secrets

注意的是 Service 可以跨 Namespace 来存取

而体现在设定档就如下:

apiVersion: v1
kind: ConfigMap
metadata:
  name: mysql-configmap
data:
  db_url: mysql-service.database

注意的是 上面 ConfigMap 的 db_url 组成是以下模式组成

${service_name}.${namespace_name}

有些元件无法在 Namespace 建立

这些元件在 k8s 丛集里是全域的

无法用 Namespace 来隔离

比如: Volume, Node

可以透过以下指令列出无法使用 Namespace 隔离的所有元件

kubectl api-resources --namespaced=false

相对的, 也可以用以下指令列出所有可用 Namespace 隔离的元件

kubectl api-resources --namespaced=true

建立在 Namespace 的元件

首先建立一个设定档 mysql-configmap.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: mysql-configmap
data:
  db_url: mysql-service.database

假设直接操作以下指令

kubectl apply -f mysql-configmap.yaml

会发现因为没指定 Namespace 最後会直接放到 Default Namespace

而如果要把这个 ConfigMap 放到 my-namespace 下

有两个方式

1 kubectl 指令

kubectl apply -f mysql-configmap.yaml --namespace=my-namespace

2 设定档的方式
更新 mysql-configmap.yaml 如下

apiVersion: v1
kind: ConfigMap
metadata:
  name: mysql-configmap
  namespace: my-namespace
data:
  db_url: mysql-service.database

在 metadata的部份指定 namespace

查询已存在的 ConfigMap

更换使用中的 Namespace

假设今天在不同团队使用不同 Namespace 变成要一直指定 -n 在 kubectl 指令会很麻烦

所以比较好的方式是用一个 command 去修改目前操作的 Namespace

然而原生的 kubectl 没有这项功能

所以只能透过一个外挂工具 kubectx/kubens 来处理

安装 kubectx

ref: https://snoopy30485.github.io/2020/10/06/%E4%BD%BF%E7%94%A8kubectx-kubens%E5%BF%AB%E9%80%9F%E5%88%87%E6%8D%A2context%E5%92%8Cnamespace/

git clone https://github.com/ahmetb/kubectx

sudo cp kubectx/kube* /usr/local/bin/

当安装成功後

就可以执行以下指令列出所有的 namespace

上面显示黄色的就是预设的 namespace

然後透过以下指令切换 namespace

kubens $namespace_name

切换到 my-namespace 就是以下指令

切换之後结果

其他

删除 Namespace 指令

kubectl delete namespaces $namespace_name

要注意的是, 当删除 namespace, 代表 namespace 下的所有布署都会被删除

後记

使用 Namespace 能够有效地分类资源

虽然官方建议当丛集少於10人的时候就不需要使用 Namespace

可是透过 Namespace 将资源分类其实对於资源管理来说其实还是优於散布所有资源在 default Namespace


<<:  DAY8-EXCEL统计分析:认识趋势量数

>>:  [Day23]What's Cryptanalysis?

【Day 25】C String

接着我们要说说 C String!C string 是字元阵列,通常会使用 pointer 来做应用...

解决Windows总是把Typescript文件夹看成影音档

最近用Typescript开发专案,小弟用的是Windows10笔电 遇到一个小烦恼,那就是每次打开...

Day12-你好 安安 对不起我要去洗澡了 如何跟pod互动

前一章介绍如何建立,删除pod之後,就要来谈谈如何对pod本身进行互动了。 当我们建立完有应用程序的...

JavaScript入门 Day06_如何使用字串

在讲完魔法的那些东东後,那来讲讲字串的一些小小小的用法 如果今天施展了两个咒语,我们变出了两个字串,...

[Day18] 箭头函式

Arrow Function 这个从 ES6 开始新增的一种写法,叫做 Arrow Function...