Kubernetes 如何只授予某一 Namespace 的访问权限
最近遇到一个问题,那就是需要给别人共享一下 Kubernetes 的某个资源的使用和访问权限,这个仅仅存在于某个 namespace 下,但是我又不能把管理员权限全都给它,我想只给他授予这一个 Namespace 下的权限,那应该怎么办呢?
比如我这边是需要只想授予 postgresql 这个 Namespace 的权限,这里我就需要利用到 Kubernetes 里面的 RBAC 机制来实现了,下面记录了我的操作流程。
创建 Namespace
kubectl create namespace postgresql
首先没有 Namespace 的话需要创建一个 Namespace,这里我创建的是 postgresql,大家可以自行修改。
创建 ServiceAccount
接下来需要创建一个 ServiceAccount,yaml 如下:
apiVersion: v1
kind: ServiceAccount
metadata:
name: postgresql
namespace: postgresql
创建 Role
然后还要创建一个 Role,来控制相应的权限,yaml 如下:
kind: Role
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: postgresql
namespace: postgresql
rules:
- apiGroups: ["", "extensions", "apps"]
resources: ["*"]
verbs: ["*"]
- apiGroups: ["batch"]
resources:
- jobs
- cronjobs
verbs: ["*"]
这里由于 Role 是 Namespace 级别的,所以只能在特定 Namespace 下生效,这里我要让授予本 Namespace 下的所有权限,这里 rules 就添加了所有的 API类型、资源类型和操作类型。
创建 RoleBinding
最后需要将 Role 和 ServiceAccount 绑定起来,yaml 如下:
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: postgresql
namespace: postgresql
subjects:
- kind: ServiceAccount
name: postgresql
namespace: postgresql
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: postgresql
创建 kubeconfig 文件
现在我们执行上述 yaml 文件之后,ServiceAccount 其实就已经创建好了,它会对应一个 secret,我们来看下详情,执行:
kubectl get serviceaccount postgresql -n postgresql -o yaml
好,运行结果类似如下:
apiVersion: v1
kind: ServiceAccount
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"v1","kind":"ServiceAccount","metadata":{"annotations":{},"name":"postgresql","namespace":"postgresql"}}
creationTimestamp: "2020-07-30T16:10:38Z"
name: postgresql
namespace: postgresql
resourceVersion: "17800240"
selfLink: /api/v1/namespaces/postgresql/serviceaccounts/postgresql
uid: 6327db1f-6a93-4f1e-b988-31842989bbbc
secrets:
- name: postgresql-token-v26k7
这里它实际关联了一个 secret,叫做 postgresql-token-v26k7,这里面就隐藏了 ServiceAccount 的 token 和证书。
好,那么我们就可以利用这个 secret 来制作 kubeconfig 文件了,命令如下:
server=https://your-server:443
name=postgresql-token-v26k7
namespace=postgresql
ca=$(kubectl get secret/$name -n $namespace -o jsonpath='{.data.ca\.crt}')
token=$(kubectl get secret/$name -n $namespace -o jsonpath='{.data.token}' | base64 --decode)
echo "apiVersion: v1
kind: Config
clusters:
- name: test
cluster:
certificate-authority-data: ${ca}
server: ${server}
contexts:
- name: test
context:
cluster: test
user: postgresql
current-context: test
users:
- name: postgresql
user:
token: ${token}
" > postgresql.kubeconfig
这里我们需要指定三个变量:
•server:就是 Kubernetes Server API 的地址•name:就是 ServiceAccount 对应的 secret•namespace:就是当前操作的 Namespace
运行之后就会生成一个 portgresql.kubeconfig 文件。
使用
那么怎么使用呢?很简单,设置下环境变量切换下就好了。
export KUBECONFIG=postgresql.kubeconfig
这里我们就将 KUBECONFIG 设置了下,这样再执行 kubectl 就会读取到当前的 kubeconfig 文件,就会生效了。
这时候我们来测试下:
kubectl get nodes
运行结果如下:
Error from server (Forbidden): nodes is forbidden: User "system:serviceaccount:postgresql:postgresql" cannot list resource "nodes" in API group "" at the cluster scope
可以看到这里就提示没有列出节点的权限了。
然后我们操作下 postgresql 下的权限试试:
kubectl get svc -n postgresql
运行结果如下:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
postgresql ClusterIP 10.0.193.137 <none> 5432/TCP 9d
postgresql-headless ClusterIP None <none> 5432/TCP 9d
postgresql-metrics ClusterIP 10.0.60.88 <none> 9187/TCP 9d
postgresql-read ClusterIP 10.0.236.184 <none> 5432/TCP 9d
这里就可以看到对 postgresql 这个命名空间的操作就成功了。
到此为止我们就成功实现了特定 Namespace 的限制,大功告成。
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 全网最简单!3分钟用满血DeepSeek R1开发一款AI智能客服,零代码轻松接入微信、公众号、小程
· .NET 10 首个预览版发布,跨平台开发与性能全面提升
· 《HelloGitHub》第 107 期
· 全程使用 AI 从 0 到 1 写了个小工具
· 从文本到图像:SSE 如何助力 AI 内容实时呈现?(Typescript篇)
2018-08-03 申请Let's Encrypt永久免费SSL证书
2018-08-03 轻量级git服务器