认证

Authentication

认证阶段的工作是识别用户身份,支持的认证方式有很多,比如:HTTP Base,HTTP token,TLS,Service Account,OpenID Connect 等,API Server 启动时可以同时指定多种认证方式,会逐个使用这些方法对客户请求认证,只要通过任意一种认证方式,API Server 就会认为 Authentication 成功。

kubernetes中的用户有两种:

  • service-account

  • 普通用户

要特别说的是普通用户在k8s中没有具体的api管理用户都是通过外部方式进行管理

认证方式:

  • X509 Client Certs: 客户端证书模式需要在 kubectl 命令中加入 --client-ca-file= 参数,指明证书所在位置。这是k8s默认的方式

  • bearer tokens: 在 HTTP 请求头中加入 Authorization: Bearer 。 主要适用JWT的认证方式

  • Bootstrap Tokens: 与 bearer tokens 一致,但 TOKEN 格式为 [a-z0-9]{6}.[a-z0-9]{16}。该方式称为 dynamically-managed Bearer token,以 secret 的方式保存在 kube-system namespace 中,可以被动态的创建和管理。同时,启用这种方式还需要在 APIServer 中打开 --enable-bootstrap-token-auth。

  • Basic Token认证方式, 通过--token-auth-file= 参数指明 bearer tokens 所在位置。

  • Service Account Tokens: 该方式通常被 pod 所使用,在 PodSpec 中指明 ServiceAccount 来访问 ApiServer。

  • OpenID Connect Tokens

  • Webhook Token Authentication

  • Basic auth: 以参数 --basic-auth-file= 指明 basic auth file 的位置。这个 basic auth file 以 csv 文件的形式存在,里面至少包含三个信息:password、username、user id,同时该模式在使用时需要在请求头中加入 Authorization: Basic BASE64ENCODED(USER:PASSWORD) 。

01.X509证书认证

建立完整TLS加密通信,需要有一个CA认证机构,会向客户端下发根证书、服务端证书以及签名私钥给客户端。ca.pem & ca-key.pem & ca.csr组成了一个自签名的CA机构。

我们把这种方式也称之为双向认证, 在所有的认证中也是最严格的认证。 需要kube-apiserver启动时指定:

  • client-ca-file: 指定CA根证书文件为/etc/kubernetes/pki/ca.pem,内置CA公钥用于验证某证书是否是CA签发的证书

  • tls-private-key-file: 指定ApiServer私钥文件为/etc/kubernetes/pki/apiserver-key.pem

  • tls-cert-file:指定ApiServer证书文件为/etc/kubernetes/pki/apiserver.pem

0101.kubeconfig文件详解

其中client-ca-file中指定的CA根证书会在类似kube-controller-manager的组件通信时验证证书是否为该CA根证书签发, 目前组件访问kube-apiserver主要是通过kubeconfig的方式, kubeconfig的文件中包含根CA、根CA签发的证书的公钥和私钥, 我们以kube-scheduler的kubeconfig为例进行说明, 下面为kube-scheduler.kubeconfig

可以看出文件分为三大部分:clusters、contexts、users

  • clusters 部分 定义集群信息,包括 api-server 地址certificate-authority-data, 其中certificate-authority-data用于服务端证书认证的自签名 CA 根证书

  • contexts 部分 集群信息和用户的绑定,kubectl 通过上下文提供的信息连接集群。

  • users 部分 多种用户类型,默认是客户端证书(x.509 标准的证书)和证书私钥,也可以是 ServiceAccount Token。这里重点说下前者:

    • client-certificate-data: base64 加密后的客户端证书;

    • client-key-data: base64 加密后的证书私钥;

一个请求在通过 api-server 的认证后,api-server 会从收到客户端证书中取用户信息,然后用于后面的授权,这里所说的用户并不是服务账号,而是客户端证书里面的 Subject 信息:O 代表用户组,CN 代表用户名。

每个组件对应的CN和O

组件

Common Name

Organization

Kube-apiserver

kubernetes

kube-scheduler

System:kube-scheduler

Kube-controller-manager

system:kube-controller-manager

Kubelet

System:node:${node_name}

system:nodes

Kube-proxy

system:kube-proxy

kubectl

admin

0102.双向认证的流程

当组件kube-scheduler访问kube-apiserver时是双向认证, 流程如下

  1. kube-scheduler发送请求到kube-apiserver

  2. kube-apiserver将tls-cert-file配置的公钥发送给kube-scheduler

  3. kube-scheduler使用kubeconfig中的certificate-authority-data验证证书是否合法

  4. 如果证书合法kube-scheduler发送kubeconfig中的client-certificate-data给kube-apiserver

  5. kube-apiserver使用client-ca-file验证证书是否合法

  6. 如果证书全部合法可以进行通信

02.Static Token File

kube-apiserver启动时需要使用--token-auth-file=bootstrap-token.csv

客户端请求的时候需要在http header中加入:”Authorization: Bearer THETOKEN”,如下实例:

或者使用kubectl:

03.Bootstrap Tokens认证

Bootstrap Token 和 Static Token的区别是Bootstrap Token在 k8s 中动态的管理一种type为bootstrap token的token,这些token作为secret放在kube-system namespace中。controller-manager中的tokencleaner controller会在bootstrap token 过期时进行删除。

生成Bootstrap Token:

这个 f455f5.db29ddb7b7d01ab9 就是生成的 Bootstrap Token,保存好 token,因为后续要用;关于这个 token 解释如下:

Token 必须满足 [a-z0-9]{6}.[a-z0-9]{16} 格式;以 . 分割,前面的部分被称作 Token ID,Token ID 并不是 “机密信息”,它可以暴露出去;相对的后面的部分称为 Token Secret,它应该是保密的

创建 Bootstrap Token Secret:

对于 Kubernetes 来说 Bootstrap Token Secret 也仅仅是一个特殊的 Secret 而已;对于这个特殊的 Secret 样例 yaml 配置如下:

需要注意几点:

作为 Bootstrap Token Secret 的 type 必须为 bootstrap.kubernetes.io/token,name 必须为 bootstrap-token- (Token ID 就是上一步创建的 Token 前一部分) usage-bootstrap-authentication、usage-bootstrap-signing 必须存才且设置为 true expiration 字段是可选的,如果设置则 Secret 到期后将由 Controller Manager 中的 tokencleaner 自动清理 auth-extra-groups 也是可选的,令牌的扩展认证组,组必须以 system:bootstrappers: 开头 最后使用kubectl create -f bootstrap.secret.yaml创建即可

04.Service Account Tokens

Service Account Token 是一种比较特殊的认证机制,适用于上文中提到的pod内部服务需要访问apiserver的认证情况,默认enabled。

apiserver 的启动配置参数有--service-account-key-file=/srv/kubernetes/pki/service-account.pem,用于检验 ServiceAccount 的 token, 如果没有指明文件,默认使用–tls-private-key-file的值,即API Server的私钥。

controller-manager的启动配置参数--service-account-private-key-file=/srv/kubernetes/pki/service-account-key.pem该文件是PEM 编码的 X509 RSA,用于签署 Service Account Token。

特别说明:

apiserver 和 controller-manager中指定的key可以是同一个文件, 可以直接使用如下命令生成

0401.资源说明

service accout本身是作为一种资源在k8s集群中,我们可以通过命令行获取

默认的情况下k8s会在集群中的所有namespace创建一个default的serviceaccount,并且这个serviceaccount关联一个default-token-xxxx这样的token

查看serviceaccout和token的对应关系:

查看default-token的具体内容:

可以看到default-token-xl2hw资源包含的数据有三部分:

  • ca.crt,这是API Server的CA公钥证书,用于Pod中的Process对API Server的服务端数字证书进行校验时使用的;

  • namespace,这是Secret所在namespace的值的base64编码:# echo -n “kube-system”|base64 => “a3ViZS1zeXN0ZW0=”

  • token:该token就是由service-account-key-file的值签署(sign)生成。

这种认证方式主要由k8s集群自己管理,用户用到的情况比较少。我们创建一个pod时,默认就会将该namespace对应的默认service account token mount到Pod中,所以无需我们操作便可以直接与apiserver通信

05.OpenID Connect Tokens

如果集群需要根据用所属的部门或者职能进行权限划分最好使用OpenID的方式进行访问授权。

06.参考

官方文档Authenticating

Kubernetes-- 漫谈kubernetes 中的认证 & 授权 & 准入机制

Kubernetes 的证书认证

Kubernetes TLS bootstrapping 那点事

使用 Bootstrap Token 完成 TLS Bootstrapping

最后更新于

这有帮助吗?