K8s之RBAC模型

RBAC

RBAC模型(Role-Based Access Control:基于角色的访问控制),k8s集群中的身份有两种:用户(User)和服务账号(Service Account),其中service account是k8s为pod内部的进程访问apiserver创建的一种用户。我们可以通过sa中的token与apierver进行通信,也可以基于用户的kubeconfig与apierver进行通信。

img

用户user

对于User账户,主要分为系统管理员账户和普通账户,系统管理员账户为创造集群时自带,权限很高,普通账户也是由系统管理员账户创建并赋予期对应的访问操作权限。

创建用户

对于User账户,我们可以通过创建k8s集群时自带的证书对我们(admin)权限(几乎)手动管理master中的凭证文件,并且将每个凭证文件和一个字符串对应起来,只要用户请求中有信息(一般来自本地保存的.kube/config文件中)能够证明自己有任意一个凭证文件的授权,那么这个请求就被认为是一个合法用户发出的,同时,在证书中还可以加入用户所在的组(group)的信息,k8s可以据此认为user在一个组中或者后期通过rolebinding等赋予操作权限。

img
通过CSR创建为例,(参考官方文档https://kubernetes.io/zh-cn/docs/reference/access-authn-authz/certificate-signing-requests)

1.生成一个 2048 位的 morece.key 文件
openssl genrsa -out morece.key 2048
2.在 morece.key 文件的基础上,生成 morece.crt 文件(用参数 -days 设置证书有效期)
这里注意两个字段Common Name输入的是用户名。
Organization Name 是用户组,如果写system:masters则归属于系统组获取系统管理权限,这块可以写一个新的,后边我们通过role或clusterrole来限制账号的权限。
openssl req -new -key morece.key -out morece.csr

img

创建 CertificateSigningRequest
  cat <<EOF | kubectl apply -f -
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
  name: morece
spec:
  request: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0KTUlJQ2p6Q0NBWGNDQVFBd1NqRUxNQWtHQTFVRUJoTUNRMDR4RlRBVEJnTlZCQWNNREVSbFptRjFiSFFnUTJsMAplVEVUTUJFR0ExVUVDZ3dLYTNWaVpYSnVaWFJsY3pFUE1BMEdBMVVFQXd3R2JXOXlaV05sTUlJQklqQU5CZ2txCmhraUc5dzBCQVFFRkFBT0NBUThBT==..
  signerName: kubernetes.io/kube-apiserver-client
  expirationSeconds: 86400  # one day
  usages:
  - client auth
EOF
  • usage 字段必须是 ‘client auth

  • expirationSeconds 可以设置为更长(例如 864000 是十天)或者更短(例如 3600 是一个小时)

  • request 字段是 CSR 文件内容的 base64 编码值。 要得到该值,可以执行命令

    cat morece.csr | base64 | tr -d "\n"
    

    批准证书kubectl certificate approve morece

取得证书

从 CSR 取得证书:

kubectl get csr/morece -o yaml

证书的内容使用 base64 编码,存放在字段 status.certificate

从 CertificateSigningRequest 导出颁发的证书。

kubectl get csr morece -o jsonpath='{.status.certificate}'| base64 -d > morece.crt
添加到 kubeconfig

最后一步是将这个用户添加到 kubeconfig 文件。

首先,你需要添加新的凭据:

kubectl config set-credentials morece --client-key=morece.key --client-certificate=morece.crt --embed-certs=true

然后,你需要添加上下文:

kubectl config set-context morece --cluster=kubernetes --user=morece

img

这里也推荐个工具看用户,切换context很方便https://github.com/sunny0826/kubecm.git

img
来测试一下,把上下文切换为 morece

kubectl config use-context morece

img

这里可以看到报错了,错误原因是more测用户并没有权限去访问default空间下的pod,这时候就要引入RBAC来分配权限了

RBAC来分配权限

RBAC API 声明了四种 Kubernetes 对象:RoleClusterRoleRoleBindingClusterRoleBinding

创建角色Role和ClusterRole

Role 总是用来在某个名字空间内设置访问权限; 在你创建 Role 时,你必须指定该 Role 所属的名字空间。

与之相对,ClusterRole 则是一个集群作用域的资源

接下来创建个读取default pod的权限(注意要切换为管理员context再进行资源创建)

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: morecepod-reader
rules:
- apiGroups: [""] # "" 标明 core API 组
  resources: ["pods"]
  verbs: ["get", "watch", "list"]//允许的操作行为
//get和list区别在于如果是get可以查看详情kubectl describe这在secret时获取详情中的token很好用,list只能获取列表不能查看详情
RoleBindingClusterRoleBinding

简单来说RoleBindingClusterRoleBinding就是将Role和ClusterRole规则作用效果绑定到用户或serveraccount,使其拥有与Role和ClusterRole一样的权限。

一个 RoleBinding 可以引用同一的名字空间中的任何 Role。 或者,一个 RoleBinding 可以引用某 ClusterRole 并将该 ClusterRole 绑定到 RoleBinding 所在的名字空间。 如果你希望将某 ClusterRole 绑定到集群中所有名字空间,你要使用 ClusterRoleBinding。

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

然后再把上下文切换为 morece看下default空间下pod可以了:

img

权限划分

Role和ClusterRole的权限控制主要通过rules下字段
apiGroups:设定资源组"" 标明 core API 组,“" 标明所有组
resource内容为常见资源类(crontabs、jobs、pods、pods/log、configmaps、deployments等)
同时也支持nonResourceURLs通过api url加载
nonResourceURLs: [“/healthz”, "/healthz/
”] # nonResourceURL 中的 ‘*’ 是一个全局通配符

verbs主要控制对资源的行为[“get”, “list”, “watch”, “create”, “update”, “patch”, “delete”]

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: morecepod-reader
rules:
- apiGroups: [""] # "" 标明 core API 组
  resources: ["pods"]
  verbs: ["get", "watch", "list"]//允许的操作行为
//get和list区别在于如果是get可以查看详情kubectl describe这在secret时获取详情中的token很好用,list只能获取列表不能查看详情
手动创建证书方法

利用手动创建证书创建用户,前面生成密钥部分都相同,但是签名通过利用集群中CA自带的CA证书进行签名即可。详细在http://blog.itpub.net/69955379/viewspace-2778141

创建用户server account

服务账号对象主体更多为pod,比如当有pod需要运行时,必须以一个service account的身份去运行他。一个pod不需要区分是那个用户的,只需要对service account权限进行控制即可。

我们在创建 Pod 时,如果没有指定服务账号,Pod 会被指定给命名空间中的 default 服务账号。

角色role和roleBinding

下面我们在namespace为ceshi下创建一个service account,接着在pod中使用这个账户

kubectl create serviceaccount morece -n ceshi //创建sa
挂载sa起pod
apiVersion: v1
kind: Pod
metadata:
  name: morecewithsa
  namespace: ceshi
spec:
  serviceAccount: morece
  containers:
    - name: morece
      image: nginx
      imagePullPolicy: IfNotPresent 
将kubectl cp进去测试用
kubectl cp /usr/bin/kubectl ceshi/morecewithsa:/
find / -name "*token"找一下pod里挂载的token,也可以直接用kubectl
kubectl get pod

img

可以看到我们光是创建一个service account,在pod内是没什么权限的,现在创建个role,通过rolebinding绑定在我们的sa上

 cat <<EOF | kubectl apply -f -
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: ceshi
  name: morecepod-create
rules:
- apiGroups: ["*"]
  # 在 HTTP 层面,用来访问 Secret 资源的名称为 "secrets"
  resources: ["secrets","pods","nodes","services"]
  verbs: ["get", "watch", "list","create"]
EOF
cat <<EOF | kubectl apply -f -
apiVersion: rbac.authorization.k8s.io/v1
# 此角色绑定允许 service account 读取 "ceshi" 名字空间中的 Pod
# 你需要在该命名空间中有一个名为 “morecepod-create” 的 Role
kind: RoleBinding
metadata:
  name: morececreate-pods
  namespace: ceshi
subjects:
# 你可以指定不止一个“subject(主体)”
- kind: ServiceAccount
  name: morece # "morece" 是区分大小写的
roleRef:
  # "roleRef" 指定与某 Role 或 ClusterRole 的绑定关系
  kind: Role        # 此字段必须是 Role 或 ClusterRole
  name: morecepod-create  # 此字段必须与你要绑定的 Role 或 ClusterRole 的名称匹配
  apiGroup: rbac.authorization.k8s.io
EOF

在里边试试创建个pod,可以了

cat <<EOF | ./kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: createinmorecewithsa
  namespace: ceshi
spec:
  containers:
    - name: createinmorecewithsacon
      image: nginx
      imagePullPolicy: IfNotPresent  
EOF

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zmpCoF6c-1678978192710)(https://prefect12.oss-cn-beijing.aliyuncs.com/8.png?Expires=1676567430&OSSAccessKeyId=TMP.3Kk4pSrSmBFm96NfgY6GZKm1qhse1DffMaig8NhGPYR9RcQ4j74QAFhCvmGWDyXkr2E7wtHv71FS2rrVZhzZTQXAJUXuCo&Signature=iOG9FI4viDa8002eio23AIw0dw0%3D)]

我们再试试在别的命名空间创建pod,失败了。于是现在创建个clusterrole,通过clusterrolebinding绑定在我们的sa上

img

  cat <<EOF | kubectl apply -f -
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  # "namespace" 被忽略,因为 ClusterRoles 不受名字空间限制
  name: pod-create
rules:
- apiGroups: ["*"]
  # 在 HTTP 层面,用来访问 Secret 资源的名称为 "secrets"
  resources: ["secrets","pods","nodes","services"]
  verbs: ["get", "watch", "list","create"]
EOF
  cat <<EOF | kubectl apply -f -
apiVersion: rbac.authorization.k8s.io/v1
# 此集群角色绑定允许 “manager” 组中的任何人访问任何名字空间中的 Secret 资源
kind: ClusterRoleBinding
metadata:
  name: create-pod-glob
subjects:
- kind: ServiceAccount
  namespace: ceshi
  name: morece      # 'name' 是区分大小写的
roleRef:
  kind: ClusterRole
  name: pod-create
  apiGroup: rbac.authorization.k8s.io
EOF
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值