简介

api server 是集群访问控制的统一入口

k8s认证过程: 认证 -> 授权 - > 准入控制 (adminationcontroller

1 认证()是对客户端的认证,简单说就是账户密码

2 授权()是资源的授权,容器、网络存储资源的权限

3 准入机制

准入控制器位于api server ,在对象被持久化之前,准入控制器拦截对api server 的请求,一般用来做认证和授权。其中包括连个控制器:

MutatingAdmissionWebhook 和 ValidatingAdmissionWebhook。分别作为配置的变异和验
证准入控制 webhook。
变更(Mutating)准入控制:修改请求的对象
验证(Validating)准入控制:验证请求的对象

准入控制是api server 启动时参数配置。一个准入控制器可以属于以上两者中的一种,也可能两者都属于。当请求到达 API Server 的时候首先执行变更准入控制,然后再执行验证准入控 制。

我们在部署 Kubernetes 集群的时候都会默认开启一系列准入控制器,如果没有设置这些准入控制
器的话可以说你的 Kubernetes 集群就是在裸奔,应该只有集群管理员可以修改集群的准入控制
器。
例如我会默认开启如下的准入控制器。
--admission-
control=ServiceAccount,NamespaceLifecycle,NamespaceExists,LimitRanger,ResourceQ
uota,MutatingAdmissionWebhook,ValidatingAdmissionWebhook
k8s 的整体架构也是一个微服务的架构,所有的请求都是通过一个 GateWay,也就是 kube-apiserver 这个组件(对外提供 REST 服务),k8s 中客户端有两类,一种是普通用户,一种是集群 内的 Pod,这两种客户端的认证机制略有不同,但无论是哪一种,都需要依次经过认证,授权,准 入这三个机制。

1 认证

认证支持多种插件

1 令牌认证

客户端和服务端使用共享秘钥,认证信息经由http协议认证头部进行传递。

2 ssl 认证

通过ca签发的证书,完成客户端与服务端的认证

kubernetes 上的账号
ServiceAccount(服务账号)为pod调用api server 准备的账号
User account(用户账号)为用户调用api server 准备的
ServiceAccount
Service account 是为了方便 Pod 里面的进程调用 Kubernetes API 或其他外部服务而设计的。它 与 User account 不同,User account 是为人设计的,而 service account 则是为 Pod 中的进程 调用 Kubernetes API 而设计;User account 是跨 namespace 的,而 service account 则是仅 局限它所在的 namespace;每个 namespace 都会自动创建一个 default service account;
开启 ServiceAccount Admission Controller 后
1)每个 Pod 在创建后都会自动设置 spec.serviceAccount 为 default(除非指定了其他
ServiceAccout)
2)验证 Pod 引用的 service account 已经存在,否则拒绝创建;
当创建 pod 的时候,如果没有指定一个 serviceaccount,系统会自动在与该 pod 相同的
namespace 下为其指派一个 default service account。这是 pod 和 apiserver 之间进行通信的
账号,
查看默认空间下的pod
默认会挂载一个secret
挂载的这个secret ,是命名空间中默认存在的,通过这个secret可以和api server 连接认证,获取本命名空间中pod 等状态信息

 进入pod可以查看pod中的secret

 创建一个serviceaccount:

# 通过命令可以直接创建:
kubectl create serviceaccount 服务账户名称

通过查看sa详情,可以发现它属于default命名空间, 自动生成一个token

 

这个 token 就是 sa 连接 apiserver 的认证信息,这个 token 也是登陆 k8s dashboard 的 token,这些是一个认证信息,能够登陆 k8s,能认证到 k8s,但是不能做别的事情,不代表权限,想要做其他事情,需要授权.

kubeconfig 文件

用户对资源访问需要通过apiserver进行通讯认证才能进行访问,此机制可以通过token,也可以通过配置文件

# 查看config文件
kubectl config view
# 展示信息
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: DATA+OMITTED
    # apiserver 的地址
    server: https://192.168.241.191:6443
  # 集群的名字
  name: kubernetes
contexts:
- context:
    cluster: kubernetes
    namespace: default
    user: kubernetes-admin
  # 上下文的名字
  name: kubernetes-admin@kubernetes
# 当前上下文的名字
current-context: kubernetes-admin@kubernetes
kind: Config
preferences: {}
users:
- name: kubernetes-admin
  user:
    client-certificate-data: REDACTED
    client-key-data: REDACTED

2 授权

如果用户通过认证,什么权限都没有,需要一些后续的授权操作,如对资源的增删该查等,
kubernetes1.6 之后开始有 RBAC(基于角色的访问控制机制)授权检查机制。
Kubernetes 的授权是基于插件形成的,其常用的授权插件有以下几种:
1)Node(节点认证)
2)ABAC(基于属性的访问控制)
3)RBAC(基于角色的访问控制)
4)Webhook(基于 http 回调机制的访问控制)
什么是 RBAC(基于角色的访问控制)?
让一个用户(Users)扮演一个角色(Role),角色拥有权限,从而让用户拥有这样的权限,随后在 授权机制当中,只需要将权限授予某个角色,此时用户将获取对应角色的权限,从而实现角色的访问 控制
在 k8s 的授权机制当中,采用 RBAC 的方式进行授权,其工作逻辑是,把对对象的操作权限定义到 一个角色当中,再将用户绑定到该角色,从而使用户得到对应角色的权限。如果通过 rolebinding 绑定 role,只能对 rolebingding 所在的名称空间的资源有权限。另外,k8s 为此还有一种集群级别的授权机制,就是定义一个集群角色(ClusterRole),对集群内 的所有资源都有可操作的权限,从而将 User2 通过 ClusterRoleBinding 到 ClusterRole,从而使 User2 拥有集群的操作权限。
上面我们说了两个角色绑定:
(1)用户通过 rolebinding 绑定 role
(2)用户通过 clusterrolebinding 绑定 clusterrole
还有一种:rolebinding 绑定 clusterrole
rolebinding 绑定 clusterrole 的好处:
假如有 n 个名称空间,每个名称空间的用户都需要对自己的名称空间有管理员权限,那么需要定义 n 个 role 和 rolebinding,然后依次绑定,如果名称空间更多,我们需要定义更多的 role,这个是很 麻烦的,所以我们引入 clusterrole,定义一个 clusterrole,对 clusterrole 授予所有权限,然后用 户通过 rolebinding 绑定到 clusterrole,就会拥有自己名称空间的管理员权限了
注:RoleBinding 仅仅对当前名称空间有对应的权限。

3 准入控制

准入控制只是用来定义我们授权检查完成之后的后续的其他安全检查操作的,进一步补充
了授权机制,由多个插件组合实行,一般而言在创建,删除,修改或者做代理时做补充;
Kubernetes 的 Admission Control 实际上是一个准入控制器(Admission Controller)插件列
表,发送到 APIServer 的请求都需要经过这个列表中的每个准入控制器插件的检查,如果某一个控 制器插件准入失败,就准入失败。
准入插件在api server 启动时进行配置。可以参考官网查看都有哪些准入插件。

RBAC 认证授权策略

RBAC 有四个资源对象,分别是 Role、ClusterRole、RoleBinding、ClusterRoleBinding
Role:角色
一组权限的集合,在一个命名空间中,可以用其来定义一个角色,只能对命名空间内的资源进行
授权。如果是集群级别的资源,则需要使用 ClusterRole。
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: role1
  # 指定所属名称空间
  namespace: dev
rules:
# 支持的 API 组列表,例如:"apiVersion: batch/v1"等
- apiGroups: [""]
#  资源类型
  resources: ["pods"]
# 具体资源名,空代表所有
  resourceNames: []
# 操作权限
  verbs: ["get","list","watch"]
ClusterRole:集群角色
具有和角色一致的命名空间资源的管理能力,还可用于以下特殊元素的授权
1、集群范围的资源,例如 Node
2、非资源型的路径,例如:/healthz
3、包含全部命名空间的资源,例如 Pods
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: clusterrole1
rules:
- apiGroups: [""]
  resources: ["secrets"]
  resourceNames: []
  verbs: ["get","list","watch"]
RoleBinding:角色绑定、ClusterRolebinding:集群角 色绑定
角色绑定和集群角色绑定用于把一个角色绑定在一个目标上,可以是 User,Group,Service
Account,使用 RoleBinding 为某个命名空间授权,使用 ClusterRoleBinding 为集群范围内授
权。
# 将在dev 命名空间中把 role1 角色授予用户 test
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: role-binding
  namespace: dev
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: role1
subjects:
- kind: User
  name: test
  apiGroup: rbac.authorization.k8s.io

绑定集群角色

# 通过绑定集群角色cluster-admin,对dev空间有完全权限
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: clusterrole-binding
  namespace: dev
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: User
  name: all-test
  apiGroup: rbac.authorization.k8s.io

使用 RBAC 鉴权 | Kubernetes

限制不同的用户操作 k8s 集群

# ssl 认证 生成一个证书 
# (1)生成一个私钥
cd /etc/kubernetes/pki/
umask 077; openssl genrsa -out lucky.key 2048
# (2)生成一个证书请求 
openssl req -new -key lucky.key -out lucky.csr -subj "/CN=lucky"
# (3)生成一个证书
openssl x509 -req -in lucky.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out lucky.crt -days 3650
# 在 kubeconfig 下新增加一个 lucky 这个用户
# (1)把 lucky 这个用户添加到 kubernetes 集群中,可以用来认证 apiserver 的连接
kubectl config set-credentials lucky --client-certificate=./lucky.crt --client-key=./lucky.key --embed-certs=true
# (2)在 kubeconfig 下新增加一个 lucky 这个账号
kubectl config set-context lucky@kubernetes --cluster=kubernetes --user=lucky
# (3)切换账号到 lucky,默认没有任何权限
kubectl config use-context lucky@kubernetes
# 通过这个命令切换回集群用户
kubectl config use-context kubernetes-admin@kubernetes
# 把 user 这个用户通过 rolebinding 绑定到 clusterrole 上,授予权限,权限只是在 lucky 这个名称空间有效
# (1)把 lucky 这个用户通过 rolebinding 绑定到 clusterrole 上
kubectl create ns lucky
kubectl create rolebinding lucky -n lucky --clusterrole=cluster-admin --user=lucky
# (2)切换到 lucky 这个用户
kubectl config use-context lucky@kubernetes
# (3)测试是否有权限 
kubectl get pods -n lucky 
# 有权限操作这个lucky名称空间 没有权限操作其他名称空间
kubectl get pods 
# 添加一个 lucky 的普通用户
useradd lucky 
# 要删除config文件中kubernetes-admin@kubernetes的信息,不然还可以通过切换用户使用admin用户
cp -ar /root/.kube/ /home/lucky/ 
chown -R lucky.lucky /home/lucky/ 
su - lucky 
kubectl get pods -n lucky

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐