认证
最后更新于
这有帮助吗?
最后更新于
这有帮助吗?
认证阶段的工作是识别用户身份,支持的认证方式有很多,比如: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) 。
建立完整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
其中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
当组件kube-scheduler
访问kube-apiserver时是双向认证, 流程如下
kube-scheduler发送请求到kube-apiserver
kube-apiserver将tls-cert-file配置的公钥发送给kube-scheduler
kube-scheduler使用kubeconfig中的certificate-authority-data验证证书是否合法
如果证书合法kube-scheduler发送kubeconfig中的client-certificate-data给kube-apiserver
kube-apiserver使用client-ca-file验证证书是否合法
如果证书全部合法可以进行通信
kube-apiserver启动时需要使用--token-auth-file=bootstrap-token.csv
客户端请求的时候需要在http header中加入:”Authorization: Bearer THETOKEN”,如下实例:
或者使用kubectl:
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
创建即可
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可以是同一个文件, 可以直接使用如下命令生成
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通信
如果集群需要根据用所属的部门或者职能进行权限划分最好使用OpenID的方式进行访问授权。
Kubernetes-- 漫谈kubernetes 中的认证 & 授权 & 准入机制