Kubernetes 中的用户与身份认证授权
PART
K8s中的用户
K8s集群中包含两类用户:一类是由 K8s管理的 Service Account,另一类是普通用户。
假设一个独立于集群的服务由以下方式管理普通用户:
- 由管理员分发私钥
- 用户存储(如 Keystone 或 Google 帐户)
- 带有用户名和密码列表的文件
K8s没有代表普通用户帐户的对象,无法通过 API 调用的方式向集群中添加普通用户。而Service Account 是由 K8s API 管理的帐户,它们都绑定到了特定的 namespace,并由 API server 自动创建,或者通过 API 调用手动创建。Service Account 关联了一套凭证,存储在 Secret中,这些凭证同时被挂载到 pod 中,从而允许 pod 与 K8s API 之间的调用。
API 请求被绑定到普通用户或Service Account上,或者作为匿名请求对待。这意味着集群内部或外部的每个进程,无论从在服务器上输入 kubectl 的用户、节点上的 kubelet或web控制面板的成员,都必须在向 API Server 发出请求时进行身份验证,或者被视为匿名用户。
PART
认证策略
K8s 使用客户端证书、bearer token、或认证代理等通过认证插件对 API 请求进行身份验证。当向API Server发送HTTP请求时,认证插件将以下属性与请求相关联:
- 用户名:标识最终用户的字符串。常用值可能是 kube-admin 或 jane@example.com。
- UID:标识最终用户的字符串,比用户名更加一致且唯一。
- 组:一组将用户和常规用户组相关联的字符串。
- 额外字段:包含其他有用认证信息的字符串列表的映射。
所有的值对身份认证系统都是不透明的,并只有在由[authorizer](https://kubernetes.io/docs/reference/access-authn-authz/authorization/)授权者解释时才具有重要意义。
您可以一次性启用多种身份验证方式。通常使用至少以下两种认证方式:
- 服务帐户的 Service Account Token
- 至少一种其他的用户认证的方式
当启用了多个认证模块时,第一个认证模块成功认证后将短路请求,不会进行第二个模块的认证。API server 不会保证认证的顺序。
system:authenticated 组包含在所有已验证用户的组列表中。
与其他身份验证协议(LDAP、SAML、Kerberos、x509 方案等)的集成可以使用身份验证代理或身份验证 webhook来实现。
PART
Service Account Token
Service Account 是一个自动启用的验证器,它使用签名的 bearer token 来验证请求。该插件包括两个可选的标志:
- --service-account-key-file:一个包含签名 bearer token 的 PEM 编码文件。如果未指定,将使用 API Server 的 TLS 私钥。
- --service-account-lookup:如果启用,从 API 中删除掉的 token 将被撤销。
Service Account 通常通过API server 自动创建,并通过 Service Account[注入控制器](https://kubernetes.io/docs/admin/admission-controllers/)关联到集群中运行的 Pod 上。Bearer token 挂载到 pod 中众所周知的位置,并允许集群进程与 API server 通信。 帐户可以使用 PodSpec 的 ServiceAccountName 字段显式地与Pod关联。
注意: ServiceAccountName 通常被省略,因为这会自动生成。
01
apiVersion: apps/v1 # this apiVersion is relevant as of Kubernetes 1.9
kind: Deployment
metadata:
name: nginx-deployment
namespace: default
spec:
replicas: 3
template:
metadata:
# ...
spec:
serviceAccountName: bob-the-bot
containers:
- name: nginx
image: nginx:1.14.2
Service Account bearer token 在集群外使用也是完全有效的,并且可以用于为希望与 K8s 长期通信的运行作业创建身份。要手动创建 Service Account,只需要使用 kubectl create serviceaccount (NAME) 命令。这将在当前的 namespace 和相关连的 secret 中创建一个 Service Account。
02
kubectl create serviceaccount jenkins
kubectl get serviceaccounts jenkins -o yaml
kubectl get secret jenkins-token-tg8cd -o yaml
所创建的Token是一个已签名的JSON Web令牌(JWT)。已签名的JWT可以用作承载令牌,以验证为给定的服务帐户。有关如何在请求中包含令牌,请参见上面的内容。通常,这些令牌被装入到pod中,以便在集群内对API Server进行访问,但也可以从集群外部使用。Service Account 验证时用户名
system:serviceaccount:(NAMESPACE):(SERVICEACCOUNT),被指定到组
system:serviceaccounts 和
system:serviceaccounts:(NAMESPACE)。
注意:由于 Service Account 的 token 存储在 secret 中,所以具有对这些 secret 的读取权限的任何用户都可以作为 Service Account 进行身份验证。授予 Service Account 权限和读取 secret 功能时要谨慎。
用户、组、Service Account 和匿名
PART
User
外部用户是 K8s 中非常常见的一种访问者身份,通常用于从 K8s 之外来访问集群中的资源。因为这种资源的定位就是外部用户,所以 K8s 是不会存储 User 信息的,我们可以通过 Keystone 或者 Google Accounts 这种外部应用来管理。
PART
Group
同外部用户,Group 也是一种外部的概念,在X509客户端证书认证的方式中,Group 名字就是证书的组织名(Orgnization)。
PART
Service Account
相对于外部用户 User 而言,Service Account 则是集群内部的用户,我们可以使用 K8s api 来查看和管理这种用户。
PART
Anonymous
当一个请求没有携带任何的认证信息时,它会自动获得用户名:system:anonymous和用户组
system:unauthenticated,我们可以配置分配特定的权限给这种匿名用户,适用于想要公开一些不敏感的资源等场景。kubelet 10250 未授权访问、kube-apiserver 8080端口未授权访问, 皆属于此种情况。
参考:
https://kubernetes.io/docs/reference/access-authn-authz/authentication/
https://www.kancloud.cn/chriswenwu/g_k8s/1006520
https://www.kancloud.cn/chriswenwu/g_k8s/1006519
https://blog.csdn.net/zhou920786312/article/details/126242601