一、前言
API Server作为K8S集群的网关,是访问和管理K8S集群资源对象的唯一入口,其集群内各种组件的资源访问都需要经过网关才能进行正常访问和管理。每一次的访问请求都需要进行合法性的检验,其中包括身份验证(Authenticating)、操作权限验证(Authorization))以及操作规范验证(Admission Control))等,需要通过一系列验证通过之后才能访问或者存储数据到etcd当中。如下图:
二、用户认证
如上图所示,首先访问kubernetes API的主体大致分为两类:一类是 User Account,以用户的身份访问API,另一类是 Service Account,主要是kubernetes中的服务程序访问APi接口,比如创建calico网络插件、coredns等时会先创建对应的Service Account。Kubernetes API 为了保证传输层安全端口运行在6443上,同时使用证书认证,在构建kubernetes集群时,会将认证信息写入到$HOME/.kube/config中。
Authentication认证,在TLS第一次建立时,就会开始完成认证操作步骤。身份认证的模块包括客户端证书、密码、Token令牌、JWT Tokens、Bootstrap Tokens等,如果请求认证不能通过,kubernetes会返回HTTP 401状态码。虽然kubernetes使用username作为认证主体,但是不会写入存储中。
Service account与User account不同之处
1、User account是为人设计的,而Service account是为了方便Pod里面的进程调用Kubernetes API或其他外部服务而设计的
2、User account是跨namespace的,而service account则是仅局限它所在的namespace
3、每个namespace都会自动创建一个default service account
当创建pod的时候,如果没有指定一个service account,系统会自动在与该pod相同的namespace下为其指派一个default service account。而pod和apiserver之间进行通信的账号,称为serviceAccountName。如下图所示:
从下图可以看到每个Pod是否定义都会存在一个存储卷,这个存储卷名称为为default-token-xxx,pod和apiserver的认证信息通过secret进行定义,由于认证信息属于敏感信息,所以需要保存在secret资源当中,并以存储卷的方式挂载到Pod当中。从而让Pod内运行的应用通过对应的secret中的信息来连接apiserver,并完成认证。
三、鉴权
用户通过认证后,需要进行一些后续的授权操作,才能对K8S集群内的资源进行管理,kubernetes1.6版本之后开始有RBAC(基于角色的访问控制机制)授权检查机制。Kubernetes的授权是基于插件形成的,其常用的授权插件有以下几种:
1、Node(节点认证)
2、ABAC(基于属性的访问控制)
3、RBAC(基于角色的访问控制)
4、Webhook(基于http回调机制的访问控制)
ABAC(Attribute Based Access Control)本来是不错的概念,但是在Kubernetes中的实现比较难于管理和理解,而且需要对Master所在节点的SSH和文件系统权限,而且要使得对授权的变更成功生效,还需要重新启动API Server。
而 RBAC的授权策略可以利用kubectl或者Kubernetes API 直接进行配置。RBAC可以授权给用户,让用户有权进行授权管理,这样就可以无需接触节点,直接进行授权管理。RBAC在Kubernetes中被映射为API资源和操作。
因为Kubernetes社区的投入和偏好,相对于ABAC而言,RBAC是更好的选择。
3.1、RBAC模式概述
RBAC的全称是Role Base Access Control,是基于角色的访问控制,它是一种灵活的访问控制机制,可以将用户作为角色,通过角色绑定完成资源的权限分配。由于kubernetes API本身不需要有任何改动,所以在权限控制和重新定义时无需重启API server端。
RBAC使用rbac.authorization.k8s.io这个API Group,通过这个API Group可以允许用户动态配置策略,在kubernetes 1.8之后RBAC模式的API版为rbac.authorization.k8s.io/v1
在apiserver启动时可以通过–authorization-mode=RBAC启用RBAC模式,如下图所示:
3.2、API资源对象
RBAC API声明了四种Kubernetes对象:Role、ClusterRole、RoleBinding、ClusterRoleBinding,4种对象类型均可以通过kubectl与API操作。
1、Role:普通角色
2、ClusterRole:集群角色
3、RoleBinding:普通角色绑定
4、ClusterRoleBinding:集群角色绑定
可以将不同的动作(create、get、update)创建成Role角色。比如创建一个pod,将其设置成create pod的角色名,然后进行RoleBinding 绑定。绑定给后端的user用户、Group组、ServiceAccount(SA),如下图所示:
3.3、Verbs动作
verbs:对资源对象的操作方法列表
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
注释如下:
1、get查看:读取Pod 动作/资源
2、list 列出:读取Pod 动作/资源
3、watch:读取Pod 动作/资源
4、create 创建:写入Pod 动作/资源
5、update 更新:写入Pod 动作/资源
6、delete 删除:写入Pod 动作/资源
7、patch:写入Pod 动作/资源
3.4、Role
在RBAC API中, Role表示一组规则权限,权限只会增加(累加权限),不存在一个资源一开始就有很多权限。可以通过RBAC对其进行权限减少的操作。
Role可以定义在一个namespace名称空间下,如果要跨namespace则需要创建ClusterRole实现。
下面是一个位于default名字空间的Role的示例,可用来授予对pods的读访问权限,如下所示:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pod-reader #Role角色名称
namespace: default #Role角色名称空间
rules: # 权限规则
- apiGroups: [""] # 为空"" 默认API核心组
resources: ["pods"] # 对象为Pod容器
verbs: ["get","watch","list"] #动作:获取信息、监听、列出
3.5、ClusterRole
clusterRole具有与Role相同的权限角色控制能力,不同的是ClusterRole是集群级别的, ClusterRole常用于:
1、集群范围资源,比如节点(Node)
2、非资源端点,比如/healthz
3、所有命名空间资源控制,如Pods,比如你可以使用 ClusterRole来允许某特定用户执行kubectl get pods --all-namespaces
下面是一个ClusterRole的示例,可用来为任一特定名字空间中的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"]
3.6、Role-RoleBinding
下面的例子中的RoleBinding将pod-reader这个Role授予在 default名称空间中的用户jane。 这样用户jane就具有了读取default名称空间中pods的权限。如下所示:
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods
namespace: default
subjects: #你可以指定不止一个subject(主体)
- kind: User
name: jane #name字段的value值是区分大小写的
apiGroup: rbac.authorization.k8s.io
roleRef: #roleRef指定与某Role或ClusterRole的绑定关系
kind: Role # 此字段必须是Role或ClusterRole
name: pod-reader #此字段必须与你要绑定的Role或ClusterRole的名称匹配
apiGroup: rbac.authorization.k8s.io
3.7、ClusterRole-RoleBinding
RoleBinding引用了一个ClusterRole ,这个ClusterRole具有整个集群内对secrets的访问权限;但是其授权用户dave只能访问development空间中的secrets,因为RoleBinding定义在development命名空间。如下所示:
apiVersion: rbac.authorization.k8s.io/v1
# 此角色绑定使得用户 "dave" 能够读取 "development" 名字空间中的 Secrets
# 你需要一个名为 "secret-reader" 的 ClusterRole
kind: RoleBinding
metadata:
name: read-secrets
# RoleBinding 的名字空间决定了访问权限的授予范围。
# 这里隐含授权仅在 "development" 名字空间内的访问权限。
namespace: development
subjects:
- kind: User
name: dave # 'name' 是区分大小写的
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole #集群角色
name: secret-reader #集群角色名称
apiGroup: rbac.authorization.k8s.io #集群角色的API接口
3.8、ClusterRole-ClusterRoleBinding
使用ClusterRoleBinding可以对整个集群中的所有命名空间资源权限进行授权。下面的ClusterRoleBinding允许manager组内的所有用户访问任何名字空间中的Secrets。如下所示:
apiVersion: rbac.authorization.k8s.io/v1
# 此集群角色绑定允许 “manager” 组中的任何人访问任何名字空间中的 secrets
kind: ClusterRoleBinding
metadata:
name: read-secrets-global
subjects:
- kind: Group
name: manager # 'name' 是区分大小写的
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: secret-reader
apiGroup: rbac.authorization.k8s.io
四、准入控制
4.1、什么是准入控制?
Kubernetes准入控制器是控制和强制使用集群的一种插件。我们可以把它看作是拦截(已认证)API请求的拦截器,它可以更改请求对象,甚至完全拒绝请求。
Kubernetes准入控制器的“准入控制链”分为两阶段: 变更(Mutating)准入控制,修改请求的对象;验证(Validating)准入控制,验证请求的对象。因此准入控制器即可以被用作变更和验证,也可以两者结合起来使用。
4.2、常见的准入控制器
4.3、启用或关闭控制器
1、只启用NamespaceLifecycle和LimitRanger准入控制插件
--enable-admission-plugins=NamespaceLifecycle,LimitRanger
说明:–enable-admission-plugins 标志是用( 顺序不重要 )来启用默认设置以外的其他准入控制器,并非只启用列表中的准入控制器。
2、关闭PodNodeSelector和AlwaysDeny准入控制插件
--disable-admission-plugins=PodNodeSelector,AlwaysDeny
3、查看哪些插件是默认启用的
默认开启:NamespaceLifecycle、LimitRanger、ServiceAccount、TaintNodesByCondition、PodSecurity、Priority、DefaultTolerationSeconds、DefaultStorageClass、StorageObjectInUseProtection、PersistentVolumeClaimResize、RuntimeClass、CertificateApproval、CertificateSigning、CertificateSubjectRestriction、DefaultIngressClass、MutatingAdmissionWebhook、ValidatingAdmissionWebhook、ResourceQuota
手动开启:AlwaysAdmit、AlwaysDeny、AlwaysPullImages、CertificateApproval、CertificateSigning、CertificateSubjectRestriction、DefaultIngressClass、DefaultStorageClass、DefaultTolerationSeconds、DenyServiceExternalIPs、EventRateLimit、ExtendedResourceToleration、ImagePolicyWebhook、LimitPodHardAntiAffinityTopology、LimitRanger、MutatingAdmissionWebhook、NamespaceAutoProvision、NamespaceExists、NamespaceLifecycle、NodeRestriction、OwnerReferencesPermissionEnforcement、PersistentVolumeClaimResize、PersistentVolumeLabel、PodNodeSelector、PodSecurity、PodSecurityPolicy、PodTolerationRestriction、Priority、ResourceQuota、RuntimeClass、SecurityContextDeny、ServiceAccount、StorageObjectInUseProtection、TaintNodesByCondition、ValidatingAdmissionWebhook
总结:整理不易,如果对你有帮助,可否点赞关注一下?
更多详细内容请参考:企业级K8s集群运维实战