zl程序教程

您现在的位置是:首页 >  后端

当前栏目

Kubernetes_认证授权_UserAccount_用户账号各种认证方式

Kubernetes认证 方式 用户 各种 授权 账号
2023-09-14 09:15:24 时间

系列文章目录


前言

用户账号一条线就是从集群外访问进来的,服务账号一条线就是集群内之间访问,相同点都是都通过apiserver,都需要认证、授权、准入控制。

Pod只有一种方式连接K8S集群,那就是sa账号,可以是默认新建的,也可以是手动新建的。用户就有多种方式访问API服务,通常有三种:kubectl、客户端库(如fabric8)或者直接使用 REST接口进行请求。无论哪种方式,归根结底都是从集群外访问进入k8s集群。从集群外访问k8s集群,走的就是UserAccount认证体系,底层都是 user/userGroup 绑定某个具体的 role,一共有四种认证方式:X509客户端证书,静态token文件,静态账号密码文件,请求头中添加bearer。

无论哪种方式,对于所有通过身份认证的用户,system:authenticated 组都会被添加到其组列表中。

在这里插入图片描述

你可以同时启用多种身份认证方法,并且你通常会至少使用两种方法:

(1) 针对服务账号ServiceAccount使用服务账号令牌
(2) 至少另外一种方法对用户的身份进行认证

kubectl api-resources --verbs=list --namespaced -o name

解释

-o 表示输出 -o name 表示仅仅输出名称 (类似mysql语句中select的功能)

在这里插入图片描述

一、六种认证方式

Kubernetes 有以下六种鉴权方法:

(1) X509客户端证书
(2) 不记名令牌Token:Static Token File(静态令牌)、Service Account Tokens(服务账号令牌)、OpenID Connect Tokens(OIDC 令牌)
(3) 启动引导令牌
(4) Webhook Token Authentication
(5) Authenticating Proxy 第三方授权协议
(6) 匿名请求(不需要身份认证,直接给 system:anonymous 未授权用户组绑定上 cluster-admin 这个最高权限的cluster-role)

当 HTTP 请求发送到 API Server 时,Kubernetes 会从 Request 中关联以下信息:

Username:用户名,用来辨识最终用户的字符串,比如 kube-admin
UID:用户 ID,代表用户的唯一 ID
Groups:用户组,代表逻辑相关的一组用户,
Extra Fields,扩展字段,鉴权可能需要的其他信息

需要注意的是,当多种鉴权方法同时启用时,第一个鉴权方法鉴权成功即通过验证,其它方法不再鉴权,同时 api-server 也不保证鉴权方法的顺序。所有鉴权成功的用户都会加到 group “system:authenticated”中。

二、X509 客户证书(最重要的用户账号凭证文件,默认方式)

通过给 API 服务器传递 --client-ca-file=SOMEFILE 选项,就可以启动客户端证书身份认证。 所引用的文件必须包含一个或者多个证书机构,用来验证向 API 服务器提供的客户端证书。 如果提供了客户端证书并且证书被验证通过,则 subject 中的公共名称(Common Name)就被 作为请求的用户名。 自 Kubernetes 1.4 开始,客户端证书还可以通过证书的 organization 字段标明用户的组成员信息。 要包含用户的多个组成员信息,可以在证书种包含多个 organization 字段。

开发中最常用的,无论是 /etc/kubernetes/pki/ca.crt 文件认证,还是 /root/.kube/config 文件(从 /etc/kubernetes/admin.conf 文件复制过来) ,本质都是x509 ca客户端证书认证,两种文件原理是一样的。

所以说,x509 ca客户端证书认证是最重要的认证方式。

在这里插入图片描述

小结:ca.crt 底层还是 用户/组织 ,这个用户一定绑定了 role,才有权限通过 apiserver 的授权认证,操作 k8s 集群。

三、在HTTP请求中放入持有者令牌/不记名令牌(bearer)

持有者令牌/不记名令牌,英文是 bearer ,就是持有者的意思,如下:
在这里插入图片描述

在 Kubernetes 中,主要有以下几种使用不记名令牌(Bearer token)的方法:

Static Token File(静态令牌)
Service Account Tokens(服务账号令牌)
OpenID Connect Tokens(OIDC 令牌)

Static Token File(静态令牌)

当 API 服务器的命令行设置了 --token-auth-file=SOMEFILE 选项时,就是 /etc/kubernetes/manifests/kube-apiserver.yaml 文件中设置了 --token-auth-file=SOMEFILE 选项时,会从文件中 读取持有者令牌。目前,令牌会长期有效,并且在不重启 API 服务器的情况下 无法更改令牌列表。

令牌文件是一个 CSV 文件,包含至少 3 个列:令牌、用户名和用户的 UID。 其余列被视为可选的组名。

如果要设置的组名不止一个,则对应的列必须用双引号括起来,例如

token,user,uid,"group1,group2,group3"

Service Account Tokens(服务账号令牌)

1.创建一个k8s-admin.yaml

apiVersion: v1
kind: ServiceAccount
metadata:
  name: dashboard-admin
  namespace: kube-system
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: dashboard-admin
subjects:
  - kind: ServiceAccount
    name: dashboard-admin
    namespace: kube-system
roleRef:
  kind: ClusterRole
  name: cluster-admin
  apiGroup: rbac.authorization.k8s.io

在RBAC权限中,能够与 role/clusterrole 绑定的只有三种资源,分别是:kind: User、kind: Group、kind: ServiceAccount ,所以,这里ServiceAccount绑定ClusterRole,很正常
注意:从来没有一种 kind: UserAcccount 的资源

2.应用k8s-admin.yaml配置

kubectl apply -f k8s-admin.yaml

3.获取admin-token名字

kubectl get secret -n kube-system|grep admin

4.Describe查询token内容

kubectl describe secret dashboard-admin-token-slc8x -n kube-system

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
请求头上增加 bearer 具体token

在这里插入图片描述

小结:底层原理还是 serviceAccount 绑定 role/clusterRole 的 rbac 授权认证,这里就是 serviceAccount: dashboard-admin
绑定 clusterRole: cluster-admin。

OpenID Connect Tokens(OIDC 令牌)

OpenID Connect 是一种 OAuth2 认证方式,Kubernetes 可以利用 OAuth2 Token Response 中的 ID Token 作为 Bearer Token 进行认证访问。

其流程如下:

在这里插入图片描述

(1) 登录到你的身份服务(Identity Provider)
(2) 你的身份服务将为你提供 access_token、id_token 和 refresh_token
(3) 在使用 kubectl 时,将 id_token 设置为 --token 标志值,或者将其直接添加到 kubeconfig 中
(4) kubectl 将你的 id_token 放到一个称作 Authorization 的头部,发送给 API 服务器
(5) API 服务器将负责通过检查配置中引用的证书来确认 JWT 的签名是合法的
(6) 检查确认 id_token 尚未过期
(7) 确认用户有权限执行操作
(8) 鉴权成功之后,API 服务器向 kubectl 返回响应
(9) kubectl 向用户提供反馈信息

四、启动引导令牌

为了支持方便地启动引导新的集群,Kubernetes 包含了一种动态管理的bearer token类型,称作启动引导令牌(Bootstrap Token)。 这些令牌以 Secret 的形式保存在 kube-system namespace中,可以被动态管理和创建。 控制器管理(Controller Manager)器包含的 TokenCleaner 控制器能够在启动引导令牌过期时将其删除。

Bootstrap Token令牌的格式为 [a-z0-9]{6}.[a-z0-9]{16}。第一个部分是令牌的 ID;第二个部分是令牌的 Secret。可以用如下所示的方式在 HTTP 头部设置令牌:

#781292就是用户ID
Authorization: Bearer 781292.db7bc3a58fc5f07e

在 API Server上设置 –enable-bootstrap-token-auth 标志来启用基于启动引导令牌的身份认证组件。

必须通过控制器管理器的 –controllers 标志来启用 TokenCleaner 控制器: --controllers=*,tokencleaner

如果使用 kubeadm 来启动引导新的集群时自动完成这些设置。

身份认证组件的认证结果为 system:bootstrap:<令牌 ID>,该用户属于 system:bootstrappers 用户组。

这里的用户名和组设置都是有意设计成这样,其目的是阻止用户在启动引导集群之后继续使用这些令牌。 这里的用户名和组名可以用来在启动引导新的的集群时构造合适的鉴权策略(kubadm中使用)。

五、Webhook Token Authentication

Webhook 身份认证是一种用来验证bearer token的回调机制。

–authentication-token-webhook-config-file: 指向一个配置文件,其中描述如何访问远程的Webhook服务。

–authentication-token-webhook-cache-ttl: 用来设定身份认证的缓存时间。 默认时长为 2 分钟。

–authentication-token-webhook-version:指定TokenReview对象的使用版本,authentication.k8s.io/v1beta1 或者 authentication.k8s.io/v1,默认为v1beta1。TokenReview对象用于从webhook中发送或接收信息。

配置文件使用 kubeconfig 文件的格式。文件中,clusters 指代远程服务,users 指代远程 API 服务 Webhook。

# Kubernetes API 版本
apiVersion: v1
# API 对象类别
kind: Config
# clusters 指代远程服务
clusters:  
 - name: name-of-remote-authn-service    
   cluster:      
     certificate-authority: /path/to/ca.pem         # 用来验证远程服务的 CA      
     server: https://authn.example.com/authenticate # 要查询的远程服务 URL。必须使用 'https'。
# users 指代 API Server的 Webhook 配置
users:  
- name: name-of-api-server    
  user:      
    client-certificate: /path/to/cert.pem # Webhook 插件要使用的证书      
    client-key: /path/to/key.pem          # 与证书匹配的密钥
# kubeconfig 文件需要一个上下文(Context),此上下文用于本 API Servercurrent-context: webhook
contexts:
- context:    
    cluster: name-of-remote-authn-service    
    user: name-of-api-sever  
  name: webhook

当客户端尝试在 API Server上使用bearer token完成身份认证时, 身份认证 Webhook 会用 POST 请求发送一个 JSON 序列化的对象到远程服务。 该对象是 authentication.k8s.io/v1beta1 组的 TokenReview 对象, 其中包含bearer token。

POST请求Body:

{  "apiVersion": "authentication.k8s.io/v1beta1",  "kind": "TokenReview",  "spec": {    "token": "<持有者令牌>"  }}

远程服务会填充请求的 status 字段,以标明登录操作是否成功,并还返回用户信息。

{
  "apiVersion": "authentication.k8s.io/v1beta1",
  "kind": "TokenReview",
  "status": {
    "authenticated": true, // 认证失败返回false
    "user": {
      "username": "janedoe@example.com",
      "uid": "42",
      "groups": [
        "developers",
        "qa"
      ],
      "extra": {
        "extrafield1": [
          "extravalue1",
          "extravalue2"
        ]
      }
    }
  }
}

六、Authenticating Proxy 第三方授权协议

API Server可以配置成从请求头的字段值(如 X-Remote-User)中识别用户。 主要是用来与身份认证代理一起使用,代理负责设置请求头的字段值。配置参数:

  1. –requestheader-username-headers: 必需字段,大小写不敏感。用来设置要获取用户身份的请求头字段名,可以指定多个,在请求中第一个有数值的字段会被用来提取用户名。

  2. –requestheader-group-headers: 可选字段,在 Kubernetes 1.6 版本以后支持,大小写不敏感。 建议设置为 “X-Remote-Group”。用来根据配置的请求头名称获取用户所属的组名。所找到的全部头部字段的取值都会被用作用户组名。

  3. –requestheader-extra-headers-prefix 可选字段,在 Kubernetes 1.6 版本以后支持,大小写不敏感。 建议设置为 “X-Remote-Extra-”。用来设置一个头部字段的前缀字符串,API Server会基于所给前缀来查找与用户有关的一些额外信息。这些额外信息通常用于所配置的鉴权插件。 API Server会将与所给前缀匹配的头部字段过滤出来,去掉其前缀部分,将剩余部分转换为小写字符串并在必要时执行 percent-decoded 解码后,作为新的附加信息字段扩展键名。header的值作为扩展键的值。

Api Server配置示例:

--requestheader-username-headers=X-Remote-User
--requestheader-group-headers=X-Remote-Group
--requestheader-extra-headers-prefix=X-Remote-Extra-

请求头:

GET / HTTP/1.1X-Remote-User: fidoX-Remote-Group: dogsX-Remote-Group: dachshundsX-Remote-Extra-Acme.com%2Fproject: some-projectX-Remote-Extra-Scopes: openidX-Remote-Extra-Scopes: profile

认证后的用户信息为:

name: fidogroups:- dogs- dachshundsextra:  acme.com/project:  - some-project  scopes:  - openid  - profile

X-Remote-Extra-Acme.com%2Fproject 去掉了*X-Remote-Extra-*前缀,Acme.com%2Fproject 经过percent-decoded解码后作为扩展字段的key,请求头的值作为该扩展字段键的值。

为了防止请求头欺骗,在检查请头之前,需要身份验证代理向API Server提供有效的客户端证书,以便针对指定的CA进行验证。相关配置:

–requestheader-client-ca-file:必需字段,PEM 编码的证书包。 在检查请求头中的用户名之前,必须提供有效的客户端证书并根据指定文件中的证书颁发机构进行验证。
–requestheader-allowed-names:可选字段,用来给出一组公共名称(CN)。 如果设置了,则必须在检查请求头的用户名之前提供具有指定列表中的CN的有效客户端证书。如果为空,则允许任何CN。

七、匿名请求

启用匿名请求支持之后,如果请求没有被已配置的其他身份认证策略拒绝,则被视作匿名请求(Anonymous Requests)。这类请求的用户名为:**system:anonymous,**对应的用户组为: system:unauthenticated。

在一个配置了令牌身份认证且启用了匿名访问的服务器上,如果请求提供了非法的bearer token,则会返回 401 Unauthorized 错误。 如果请求没有提供bearer toekn,则被视为匿名请求。

启用匿名请求语句:

kubectl create clusterrolebinding test:anonymous --clusterrole=cluster-admin --user=system:anonymous

底层原理:还是 user/userGroup 绑定 role/clusterRole,然后就可以有权限通过 apiserver 授权认证。这里就是将 system:anonymous 用户组中的用户,绑定到最高权限的 cluster-admin 上面去,这样匿名权限就可以直接操作 k8s 集群,如下:

在这里插入图片描述


总结

Human人使用的是User和UserGroup,使用的x509客户证书、静态token、账号密码

对于UserAccount所有的认证方式,都是要通过apiserver的,如果是 kubeadm init 安装的k8s集群,查看
如果有 --client-ca-file=SOMEFILE ,则启用 x509 ca客户端证书认证;
如果有 --token-auth-file=SOMEFILE,则启用 静态令牌证书认证;
如果有–enable-bootstrap-token-auth,则启用基于引导令牌的身份认证。

默认情况下,采用的是 x509 ca客户端证书认证,并且启用基于引导令牌的身份认证

在这里插入图片描述

Pod 使用的是 ServiceAccount,里面的 namespace+ca.crt+token 保留在 secrets 中.

三项资源 User、UserGroup和ServiceAccount,都是可以根据 RBAC 规则与 Role/ClusterRole 绑定的。

参考资料:https://blog.csdn.net/Mclaughling/article/details/121010794

参考资料:https://andyoung.blog.csdn.net/article/details/121809583
https://blog.csdn.net/cbmljs/article/details/102953428 【自定义x509客户端证书】
https://blog.csdn.net/weixin_39590635/article/details/112188662