Kubernetes 如何限制特定 namespace 的权限

扫码或搜索: 进击的Coder

发送

即可 立即永久 解锁本站全部文章

最近遇到一个问题,那就是需要给别人共享一下 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 的限制,大功告成。

我来评几句
登录后评论

已发表评论数()

相关站点

+订阅
热门文章