K8s 多租户管理

一、K8s 多租户管理

多租户是指在同一集群中隔离多个用户或团队,以避免他们之间的资源冲突和误操作。在K8s中,多租户管理的核心目标是在保证安全性的同时,提高资源利用率和运营效率。

K8s中,该操作可以通过命名空间(Namespaces)+ RBAC角色权限控制实现资源的隔离。每个租户都可以拥有自己的命名空间,从而避免资源名称的冲突。此外,通过资源配额(Resource Quotas)和限制范围(Limit Ranges),进一步确保每个租户只能使用一定量的计算资源,如CPU、内存,以及API对象的数量等。通过RBAC,为每个租户或用户组分配不同的角色和权限,从而确保他们只能访问和操作他们有权管理的资源。

例如下图所示,这是一个简单的多租户案例,租户A仅能操控命名空间 ns1 中的资源,而租户B也只能操控命名空间 ns2 中的资源,对于对方的的资源均无法操作。并且每个租户的资源也不是无限使用的,通过资源配额为每个命名空间限制了使用额度,这样就不会因为某一个租户资源使用过大影响其他租户的应用。

下面开始实践下上图中的结构。

二、创建租户

1. 创建租户的命名空间

这里创建两个命名空间,下面分配给租户A和租户B使用:

shell 复制代码
kubectl create ns ns1
kubectl create ns ns2

2. 对两个命名空间进行资源配额

shell 复制代码
vi ns_rq.yml
yml 复制代码
apiVersion: v1
kind: ResourceQuota
metadata:
  name: ns1-rq
  namespace: ns1
spec:
  hard:
    requests.cpu: "2"
    requests.memory: 2Gi
    limits.cpu: "4"
    limits.memory: 4Gi
    pods: "200"
    services: "50"
    persistentvolumeclaims: "30"
    secrets: "100"
    configmaps: "100"
---
apiVersion: v1
kind: ResourceQuota
metadata:
  name: ns2-rq
  namespace: ns2
spec:
  hard:
    requests.cpu: "2"
    requests.memory: 2Gi
    limits.cpu: "4"
    limits.memory: 4Gi
    pods: "200"
    services: "50"
    persistentvolumeclaims: "30"
    secrets: "100"
    configmaps: "100"

上面控制了cpu和内存的请求总和大小,以及一些资源的数量。

注意:这里为了方便后续的测试 cpu 和 内存 都给的比较少,根据你实际的情况进行配置。

shell 复制代码
kubectl apply -f ns_rq.yml

3. 创建租户A和租户B,指定命名空间,并分配权限

shell 复制代码
vi user.yml
yml 复制代码
# 创建租户
apiVersion: v1
kind: ServiceAccount
metadata:
  name: user-a
  namespace: ns1
---
# 分配操作权限
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: user-a-role
  namespace: ns1
rules:
  - apiGroups:
      - apps
      - ''
    resources:
      - deployments
      - replicasets
      - statefulsets
      - daemonsets
      - services
      - pods
      - pods/log
      - pods/exec
      - namespaces
      - configmaps
      - secrets
      - endpoints
      - storageclasss
      - persistentvolumes
      - persistentvolumeclaims
      - jobs
      - daemonsets
      - cronjobs
    verbs:
      - list
      - get
      - watch
      - create
      - update
      - delete
      - patch
      - edit
      - view

---
# 绑定用户
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: user-a-role-bd
  namespace: ns1
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: user-a-role
subjects:
- kind: ServiceAccount
  name: user-a
  namespace: ns1

---
# 创建租户
apiVersion: v1
kind: ServiceAccount
metadata:
  name: user-b
  namespace: ns2
---
# 分配操作权限
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: user-b-role
  namespace: ns2
rules:
  - apiGroups:
      - apps
      - ''
    resources:
      - deployments
      - replicasets
      - statefulsets
      - daemonsets
      - services
      - pods
      - pods/log
      - pods/exec
      - namespaces
      - configmaps
      - secrets
      - endpoints
      - storageclasss
      - persistentvolumes
      - persistentvolumeclaims
      - jobs
      - daemonsets
      - cronjobs
    verbs:
      - list
      - get
      - watch
      - create
      - update
      - delete
      - patch
      - edit
      - view

---
# 绑定用户
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: user-b-role-bd
  namespace: ns2
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: user-b-role
subjects:
- kind: ServiceAccount
  name: user-b
  namespace: ns2
shell 复制代码
kubectl apply -f user.yml

3. 查看租户 A 和 租户B 的 Token

查看租户A:

shell 复制代码
echo $(kubectl -n ns1 get secret $(kubectl -n ns1 get secret | grep user-a | awk '{print $1}') -o go-template='{{.data.token}}' | base64 -d)

查看租户B:

shell 复制代码
echo $(kubectl -n ns2 get secret $(kubectl -n ns2 get secret | grep user-b | awk '{print $1}') -o go-template='{{.data.token}}' | base64 -d)

下面就可以将用户名、tokenmaster 的地址给到具体租户去使用了,例如:

租户:user-a

token:eyJhbGciOiJSUzI1NiIsImtpZCI6IlA5SnRxTkVjcGV3bVdmeWV5SHo0VFBSaXdWVVYwWGMzNmYtY1NZMVRwYkUifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJuczEiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlY3JldC5uYW1lIjoidXNlci1hLXRva2VuLWx3Yjc4Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6InVzZXItYSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6IjRhZTUwZWI4LThhMTEtNDQ2Yy05NTEyLWE1MmI3NzMxNDNlMSIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpuczE6dXNlci1hIn0.LI72bJeJERegwnwkAp8AKlvplcJMrhhYvr6K70dtQ02MXepbhVtouB_1yUiZODQZvyaRgrbgFUhEzVFB6YunB7cm2WH2blOaj_3hvuLw9FZRQ7IWmeKV7a07aviUg58ZGlrdOzUXYKNBT-A3y1zb6XrHOXNSiOZjHwQob1ft1GOM04bu7GnO6docgDXjQ0h6knpiwNFUqG-I9tI9I52dUOsUbxnhyrCzxUIJsfa2eoHOP-mz3m8ud-WLFwaOmH0G49STZnmkWs2pJJqBqP0LRJ_fs2gmgS6kMITwxraR81kBXywmVi6szNReX74fHhNVyNa-kE0gZSG6S9C-uqEJUw

master-server:https://11.0.1.144:6443

三、租户使用测试

使用 kubectl 指向提供的集群,如果已经指定可不设置:

shell 复制代码
kubectl config set-cluster cluster --insecure-skip-tls-verify=true --server=https://11.0.1.144:6443

设置租户的 token

格式:kubectl config set-credentials {租户名} --token={token}

shell 复制代码
kubectl config set-credentials user-a --token=eyJhbGciOiJSUzI1NiIsImtpZCI6IlA5SnRxTkVjcGV3bVdmeWV5SHo0VFBSaXdWVVYwWGMzNmYtY1NZMVRwYkUifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJuczEiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlY3JldC5uYW1lIjoidXNlci1hLXRva2VuLWx3Yjc4Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6InVzZXItYSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6IjRhZTUwZWI4LThhMTEtNDQ2Yy05NTEyLWE1MmI3NzMxNDNlMSIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpuczE6dXNlci1hIn0.LI72bJeJERegwnwkAp8AKlvplcJMrhhYvr6K70dtQ02MXepbhVtouB_1yUiZODQZvyaRgrbgFUhEzVFB6YunB7cm2WH2blOaj_3hvuLw9FZRQ7IWmeKV7a07aviUg58ZGlrdOzUXYKNBT-A3y1zb6XrHOXNSiOZjHwQob1ft1GOM04bu7GnO6docgDXjQ0h6knpiwNFUqG-I9tI9I52dUOsUbxnhyrCzxUIJsfa2eoHOP-mz3m8ud-WLFwaOmH0G49STZnmkWs2pJJqBqP0LRJ_fs2gmgS6kMITwxraR81kBXywmVi6szNReX74fHhNVyNa-kE0gZSG6S9C-uqEJUw

设置 context ,指定默认的命名空间名称:

shell 复制代码
kubectl config set-context user-context --cluster=cluster --user user-a --namespace=ns1

切换到上面的 context 中:

shell 复制代码
kubectl config use-context user-context

测试访问其他命名空间的资源

查看 ns2 下有哪些 pod

shell 复制代码
kubectl get pods -n ns2

可以看出无法访问。

测试创建资源,申请配额大于限制时

shell 复制代码
vi test-nginx.yml
yml 复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  
spec:
  replicas: 3
  selector:
    matchLabels:
      run: nginx
  template:
    metadata:
      labels:
        run: nginx
    spec:
      containers:
      - image: nginx:1.20.1
        name: nginx
        ports:
        - containerPort: 80
          protocol: TCP
        resources: 
          limits:  
            cpu: "2" 
            memory: "2Gi" 
          requests: 
            cpu: "1"  
            memory: "1Gi"
shell 复制代码
kubectl apply -f test-nginx.yml

查看 pod

shell 复制代码
kubectl get pods

可以看到仅创建成功了两个 pod,因为资源已经使用完了。

可以通过管理员查看 ns 空间的配额情况:

shell 复制代码
kubectl get quota -n ns1

可以看到都已经使用满了。

如果此时管理员给 ns1 空间提高配额:

shell 复制代码
kubectl edit resourcequota ns1-rq -n ns1

更新服务:

shell 复制代码
kubectl apply -f test-nginx.yml

等待片刻后,使用租户A再次查看pod

pod 已经全部起来了

相关推荐
运维全栈笔记10 小时前
K8S部署Redis高可用全攻略:1主2从3哨兵架构实战
redis·docker·云原生·容器·架构·kubernetes·bootstrap
尘世壹俗人10 小时前
使用K8s部署模型
kubernetes
AI木马人12 小时前
9.人工智能实战:GPU 服务如何上 Kubernetes?从单机部署到 K8s + NVIDIA Device Plugin + HPA 的生产级改造
人工智能·容器·kubernetes
码点滴17 小时前
告别显存焦虑:PagedAttention 如何将大模型吞吐量提升 4 倍?
人工智能·架构·kubernetes·大模型·pagedattention
键盘鼓手苏苏18 小时前
Kubernetes 容器安全最佳实践
云原生·kubernetes·k8
键盘鼓手苏苏18 小时前
Kubernetes 安全最佳实践
云原生·kubernetes·k8
木雷坞2 天前
K8s GPU 推理服务 ImagePullBackOff 排查与预热
云原生·容器·kubernetes·gpu算力
吴爃2 天前
Spring Boot 项目在 K8S 中的打包、部署与运维发布实践
运维·spring boot·kubernetes
The Straggling Crow2 天前
Monitoring 2026-04-30
kubernetes
AOwhisky2 天前
Kubernetes调度与服务暴露:从“定时任务”到“服务发现”的完全指南
linux·运维·云原生·容器·kubernetes·服务发现