目录

访问控制基本流程

认证

授权

准入控制

RBAC

ServiceAccount

认证


访问控制基本流程

主要分为三个部分,认证、授权和准入控制。

认证


k8s将所有客户端发起的请求的请求主体分为两类:用户账户(User Account)和服务账户(Service Account)

用户账户:其使用主体一般是真正的用户,比如集群管理员用户。这类账户一般由外部的用户管理系统存储和管理,k8s本身并不维护这一类任何用户账户的信息,仅仅用于检验用户是否有权限执行其请求的操作
服务账户:其使用主体是应用程序,专用于为Pod中的进程提供访问API Server的身份标识;Service Account属于名称空间级别,有API Server或者管理员手动创建,通常会绑定一个保存着访问API Sever认账凭据的Secret,可用同一名称空间下的Pod方式API Server时使用

k8s支持的认证方式有如下几种

静态令牌文件
X509客户端证书验证
引导令牌(Bootstarp Token)
Service Account令牌认证
Webhook令牌认证
OpenID Connect令牌认证

授权


为了校验用户的操作许可,成功通过身份验证后的请求还要交给授权插件进行权限检查,以确保其拥有执行相应操作的许可。API Server主要支持以下4类内置的授权插件来检查用户的操作权限:

Node:基于Pod资源的调度目标节点来实现对kubelet的访问控制
ABAC:基于属性的访问控制
RBAC:基于角色的访问控制
Webhook:基于HTTP的回调机制实现外部服务REST检查,确认用户授权的访问控制
目前默认启用Node和RBAC两个插件,可以通过kube-apiserver的–authorization-mode选项指定要启用的插件,多个值以逗号分割。

准入控制


准入控制器(admission controller)用于客户端请求在通过身份验证和权限检查之后,将对象数据保存到etcd数据库之前拦截请求,从而实现在资源的创建、修改和删除操作期间强制执行对象的语义验证等功能,读取资源信息的请求不会经过准入控制器检查。API Server内置了许多准入控制器,常用的包括以下几种:

AlwaysPullImage:总是下载镜像,每次创建Pod都要下载镜像
NamespaceLifecycle:拒绝在不存在的名称空间创建资源,而删除名称空间会删除名称空间下的所有资源
LimitRanger:用于确保资源请求不会超出LimitRange的限制范围
ServiceAccount:用于实现服务账户管控机制的自动化,实现创建Pod对象时自动为其附加相关的Service Account对象
ResourceQuota:用于为名称空间设置资源配额,确保在名称空间中创建了任何资源对象时不会超出配额
DefaultStorageClass:监控所有创建PVC对象的请求,保证那些没有附加任何专用StorageClass的请求会被设置一个默认值。如果没有设置默认StorageClass则此准入控制器不执行任何操作
可以通过kube-apiserver的–enable-admission-plugins指定要启用的准入控制插件,通过–disable-admission-plugins指定要禁用的准入控制插件
 

RBAC

RBAC就是一种访问控制模型,它以角色为中心界定了“谁”(subject)能够对哪个或哪类“对象”(object)执行哪些“操作”(verb)。动作的发出这是“主体”,在k8s上,可以是普通账户也可以是服务账户。“动作”用于表明要执行的具体操作,包括增删改查等,对API Server来说就是POST、GET、PUT、DELETE等请求方法。而“对象”则指管理操作能够施加的目标主体,对k8s来说主要是各类资源对象以及非资源型URL。

RBAC的三个基本概念:
Subject: 被作用者,它表示k8s中的三类主体, user, group, serviceAccountRole:角色,它其实是一组规则,定义了一组对 Kubernetes API对象的操作权限RoleBinding:定义了“被作用者”和“角色”的绑定关系。
Role 和 ClusterRole
Role是一系列的权限的集合,Role只能授予单个namespace 中资源的访问权限ClusterRole 跟 Role 类似,但是可以在集群中全局使用。

ServiceAccount

之前说到,如果镜像放在一个私有仓库中,拉取镜像是会失败的。产生一个secret,名字叫myregistrykey,其中指定了仓库名字,给定了仓库的用户名和密码。

pod绑定sa,创建ServiceAccount,为用户自动生成认证信息,但没有授权

[root@k8s2 ~]# kubectl create sa admin

[root@k8s2 ~]# kubectl get secrets myregistrykey

NAME TYPE DATA AGE

myregistrykey kubernetes.io/dockerconfigjson 1 16d

添加secrets到serviceaccount中

[root@k8s2 secret]# kubectl patch serviceaccount admin -p '{"imagePullSecrets": [{"name": "myregistrykey"}]}'

现在如果有pod使用admin这个serviceaccount就可以调用myregistrykey,但无法破解具体密码

可以看到myregistrykey和admin绑定成功

[root@k8s2 secret]# kubectl describe sa admin

Name: admin

Namespace: default

Labels: <none>

Annotations: <none>

Image pull secrets: myregistrykey

Mountable secrets: <none>

Tokens: <none>

Events: <none>

编辑pod,使用sa,所需要的权限则通过sa即可

[root@k8s2 secret]# vim pod3.yaml

apiVersion: v1

kind: Pod

metadata:

name: mypod

spec:

serviceAccountName: admin  #使用admin这个sa

containers:

- name: game2048

image: reg.westos.org/westos/game2048 #拉取私有仓库的镜像

查看,拉取私有仓库成功 

认证

UserAccount

进入k8s证书默认生成位置

[root@k8s2 secret]# cd /etc/kubernetes/pki/

生成自签名,2048位,可以用4096

[root@k8s2 pki]# openssl genrsa -out test.key 2048

提交证书申请请求

[root@k8s2 pki]# openssl req -new -key test.key -out test.csr -subj "/CN=test"

产生x509证书,有效期365天

[root@k8s2 pki]# openssl x509 -req -in test.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out test.crt -days 365

查看证书

​​​​​​openssl x509 -in test.crt -text -noout 

设定test用户使用认证

[root@k8s2 pki]# kubectl config set-credentials test --client-certificate=/etc/kubernetes/pki/test.crt --client-key=/etc/kubernetes/pki/test.key --embed-certs=true

创建上下文切换

[root@k8s2 pki]# kubectl config set-context test@kubernetes --cluster=kubernetes --user=test

查看配置

[root@k8s2 pki]# kubectl config view

apiVersion: v1

clusters:

- cluster:

certificate-authority-data: DATA+OMITTED

server: https://192.168.56.172:6443

name: kubernetes

contexts:

- context:

cluster: kubernetes

user: kubernetes-admin

name: kubernetes-admin@kubernetes

- context:

cluster: kubernetes

user: test

name: test@kubernetes

current-context: kubernetes-admin@kubernetes

kind: Config

preferences: {}

users:

- name: kubernetes-admin

user:

client-certificate-data: REDACTED

client-key-data: REDACTED

- name: test

user:

client-certificate-data: REDACTED

client-key-data: REDACTED

切换用户

[root@k8s2 pki]# kubectl config use-context test@kubernetes

默认用户没有任何权限,需要授权

切回admin

[root@k8s2 pki]# kubectl config use-context kubernetes-admin@kubernetes

进行授权工作,对pod资源进行授权,仅在default的ns

[root@k8s2 rbac]# vim roles.yaml

kind: Role

apiVersion: rbac.authorization.k8s.io/v1

metadata:

namespace: default

name: myrole

rules:

- apiGroups: [""]

resources: ["pods"] #对pod可以操作,其他不行

verbs: ["get", "watch", "list", "create", "update", "patch", "delete"]

---

kind: RoleBinding #通过RB赋予给作用对象

apiVersion: rbac.authorization.k8s.io/v1

metadata:

name: test-read-pods

namespace: default #只针对default的ns,其他不行

subjects:

- kind: User

name: test

apiGroup: rbac.authorization.k8s.io

roleRef:

kind: Role

name: myrole

apiGroup: rbac.authorization.k8s.io

运行,对test角色权限设定成功

[root@k8s2 rbac]# kubectl apply -f roles.yaml

role.rbac.authorization.k8s.io/myrole created

rolebinding.rbac.authorization.k8s.io/test-read-pods created

切换到test

[root@k8s2 rbac]# kubectl config use-context test@kubernetes

Switched to context "test@kubernetes".

测试,创建和查询pod都可以

[root@k8s2 rbac]# kubectl run demo --image nginx

pod/demo created

[root@k8s2 rbac]# kubectl get pod

NAME READY STATUS RESTARTS AGE

demo 1/1 Running 0 2s

但现在只能操作pod资源,其它不行

切回admin

[root@k8s2 rbac]# kubectl config use-context kubernetes-admin@kubernetes

添加权限,使用全局clusterrole,增加pod和deployments

[root@k8s2 rbac]# vim roles.yaml

kind: Role

apiVersion: rbac.authorization.k8s.io/v1

metadata:

namespace: default

name: myrole

rules:

- apiGroups: [""]

resources: ["pods"]

verbs: ["get", "watch", "list", "create", "update", "patch", "delete"]

---

kind: RoleBinding

apiVersion: rbac.authorization.k8s.io/v1

metadata:

name: test-read-pods

namespace: default

subjects:

- kind: User

name: test

apiGroup: rbac.authorization.k8s.io

roleRef:

kind: Role

name: myrole

apiGroup: rbac.authorization.k8s.io

---

kind: ClusterRole #全局资源,不需要指定ns

apiVersion: rbac.authorization.k8s.io/v1

metadata:

name: myclusterrole

rules:

- apiGroups: [""]

resources: ["pods"]

verbs: ["get", "watch", "list", "delete", "create", "update"]

- apiGroups: ["extensions", "apps"]

resources: ["deployments"]

verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]

---

apiVersion: rbac.authorization.k8s.io/v1

kind: RoleBinding #RoleBinding必须指定namespace

metadata:

name: rolebind-myclusterrole

namespace: default

roleRef:

apiGroup: rbac.authorization.k8s.io

kind: ClusterRole

name: myclusterrole

subjects:

- apiGroup: rbac.authorization.k8s.io

kind: User

name: test

---

apiVersion: rbac.authorization.k8s.io/v1

kind: ClusterRoleBinding #ClusterRoleBinding全局授权

metadata:

name: clusterrolebinding-myclusterrole

roleRef:

apiGroup: rbac.authorization.k8s.io

kind: ClusterRole

name: myclusterrole

subjects:

- apiGroup: rbac.authorization.k8s.io

kind: User

name: test

运行

[root@k8s2 rbac]# kubectl apply -f roles.yaml

role.rbac.authorization.k8s.io/myrole unchanged

rolebinding.rbac.authorization.k8s.io/test-read-pods unchanged

clusterrole.rbac.authorization.k8s.io/myclusterrole unchanged

rolebinding.rbac.authorization.k8s.io/rolebind-myclusterrole unchanged

clusterrolebinding.rbac.authorization.k8s.io/clusterrolebinding-myclusterrole created

切回test

[root@k8s2 rbac]# kubectl config use-context test@kubernetes

deployments创建没问题了,但是也仅限于pod和这个,其他的svc没有

切回admin

[root@k8s2 rbac]# kubectl config use-context kubernetes-admin@kubernetes

回收

[root@k8s2 rbac]# kubectl delete -f roles.yaml

[root@k8s2 rbac]# kubectl config delete-user test

[root@k8s2 rbac]# kubectl config delete-context test@kubernetes

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐