缘由

之前学习kubernetes api的时候,对权限的获取直接进行了一个照猫画虎的导入kubeconfig,所以调度程序一直获取的是admin的权限,这是显然是不安全的做法,当然在实验室重建集群时候,原来的配置文件已经不生效了,决定趁次机会进行一个权限的改进

RBAC

在此之前,我们需要了解RBAC鉴权,它一共涉及四种kubernetes 对象:

Role, ClusterRole,RoleBingding,ClusterRoleBinding

Role 和 ClusterRole

简单来说,Role建立于namespace,而ClusterRole建立于集群,也就是说,Role只能设定本namespace的权限,ClusterRole可以设置其他namespace的权限

示例(官方文档):对于secret授予读的访问权限:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  # "namespace" 被忽略,因为 ClusterRoles 不受名字空间限制
  name: secret-reader
rules:
- apiGroups: [""]
  # 在 HTTP 层面,用来访问 Secret 资源的名称为 "secrets"
  resources: ["secrets"]
  verbs: ["get", "watch", "list"]

RoleBinding 和 ClusterRoleBinding

简单来说,RoleBinding 在指定的名字空间中执行授权,而 ClusterRoleBinding 在集群范围执行授权。

官方示例:

将Role名称为”pod-reader”的Role 授予在’default’namespace中的用户’jane’

apiVersion: rbac.authorization.k8s.io/v1
# 此角色绑定允许 "jane" 读取 "default" 名字空间中的 Pod
# 你需要在该命名空间中有一个名为 “pod-reader” 的 Role
kind: RoleBinding
metadata:
  name: read-pods
  namespace: default
subjects:
# 你可以指定不止一个“subject(主体)”
- kind: User
  name: jane # "name" 是区分大小写的
  apiGroup: rbac.authorization.k8s.io
roleRef:
  # "roleRef" 指定与某 Role 或 ClusterRole 的绑定关系
  kind: Role        # 此字段必须是 Role 或 ClusterRole
  name: pod-reader  # 此字段必须与你要绑定的 Role 或 ClusterRole 的名称匹配
  apiGroup: rbac.authorization.k8s.io

创建用户并设置权限

ServiceAccount

这是K8S给pod直接分配的角色,可以通过指定对应的serviceaccount来指定具体的角色。

首先我们创建一个serviceaccount

kubectl create sa xxxx-sa -n xxxx-ns

这之后,我们赋予这个sa对应的权限

创建Role并为sa设置权限

我们先创建一个权限Role

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: yyyy-ns
  name: xxxx-control
rules:
- apiGroups: ["*"]
  resources: ["pods","services","ingresses","configmaps"]
  verbs: ["*"]

这之后,与service accout进行绑定

kubectl create rolebinding my-sa-view \
  --role=xxxx-control \
  --serviceaccount=xxxx-ns:xxxx-sa \
  --namespace=yyyy-ns

在绑定完之后,我们就设置好了具有对应权限的sa

现在,只需要将这个sa绑定到对应的应用中即可

配置imagepullsecret

此时的sa是没有拉取镜像的权限的,我们需要给当前账户添加sa

kubectl patch serviceaccount default -p '{"imagePullSecrets": [{"name": ""}]}'

为应用配置sa

挂载当前

在spec.template.spec 添加:

serviceAccountName: ctf-ctpod

此时token和证书(以及namespace信息)将会挂载在/var/run/secrets/kubernetes.io/serviceaccount目录下

调用,python 例:

configuration = client.Configuration()
configuration.host = "https://x.x.x.x:443"
configuration.verify_ssl = True/False
configuration.api_key = {"authorization": 'Bearer ' + token}
client.Configuration.set_default(configuration)

关于跨namespace赋予的权限

其实主要和rolebinding有关,rolebinding和role处于相同位置,账户sa处于另外的名称空间,即将当前名称空间的权限赋予给sa