k8s 认证

Authentication modules include client certificates, password, and plain tokens, bootstrap tokens, and JSON Web Tokens (used for service accounts).

整体过程简述:请求发起方进行 K8s API 请求,经过 Authentication(认证)、Authorization(鉴权)、AdmissionControl(准入控制)三个阶段的校验,最后把请求转化为对 K8s 对象的变更操作持久化至 etcd 中。 认证阶段。当请求发起方建立与 API Server 的安全连接后,进入请求的认证阶段(图中步骤
1)。认证的方式主要有:客户端证书、密码、普通 token、bootstrap token 和 JWT 认证 (主要用于 Service Account)。认证模块会检查请求头或者客户端证书的内容,我们可以同时配置一种或几种方式对请求进行认证。多种认证方式会被依次执行,只要一种方式通过,请求便得到合法认证。当所有方式都未通过时,会返回 401 状态码并中断请求。认证解决的问题是校验访问方是否合法并识别其身份。 鉴权阶段。K8s API 访问请求必须包括请求者的用户名、请求的操作以及操作对象,该阶段就是对用户的操作合法性进行校验。如果现有策略声明用户具有完成请求操作的权限,则对请求进行授权。K8s 支持 ABAC 模式、RBAC 模式、Webhook 模式等多种授权模块。同样的,当多个授权模块被配置时,请求只要满足其中任意一种授权规则便会被放行,反之,API Server 会返回 403 状态码并终止该请求。鉴权是为了判别用户的操作权限范围。 准入控制阶段。准入控制是请求操作被持久化到 etcd 之前的 “拦截器”。准入控制模块由多个 “准入控制器” 构成,“准入控制器” 就是一段自定义代码,它们能够在请求对 K8s 创建、修改、删除或者连接一个 K8s 对象时生效。官方自带了 30 多个准入控制器可供使用,同时支持用户扩展。准入控制器的作用往往是检查请求的规范性或者赋予一些默认信息。例如,我们在创建一个 pod 时,准入控制器会检查提交的信息是否符合 pod 资源的规范,并对请求中没有明确规定的字段,设置对应的默认值填充到请求中。与前两个阶段不同的是,只要有一个 “准入校验” 逻辑未通过,那么请求就会被拒绝。若请求仅仅是读取一个对象,“准入控制器” 将不会生效。准入控制作用于 K8s 中的对象,通过校验规范和默认值的设置,能够保证系统的安全可靠。 持久化阶段。当我们的请求通过了前面三个阶段的校验,它会被转换为一个 K8s 对象相应的变更请求,最终持久化到 etcd 中。 需要注意的是,认证授权过程只存在 HTTPS 形式的 API 中。即是说,客户端使用 HTTP 连接到 API Server,是不会进行认证授权的。但 API Server 的非安全认证端口 8080 已经在 v1.12 中废弃了,全面使用了 HTTPS。接下来让我们来详细了解下 K8s 的认证。 K8s 的用户模型 从图 1 中我们可以看出,K8s 的用户主要分为两类:通过客户端进行连接的人类操作者和 K8s 内诸如进程、控制器等非人类操作的客户端。我们称前者为 Normal Users(常规用户),后者为 Service Account(服务账户)。因为 K8s 内没有为 Normal Users 定义存储对象,我们无法像操作 pod 一样在 K8s 内部管理这类用户,它们通常是由外部服务进行管理,借由证书凭证或者静态配置文件进行认证。而 Service Account 可由 K8s API 直接进行管理。 下表给出了其主要区别: 类目 Normal Users Service Account 针对对象 人类用户 进程 范围 全 cluster 唯一 namespace 设计目的 与企业数据库同步,在用户级别进行操作权限的控制 更轻量化,在任务进程级别进行管控 主要认证方法 Basic 认证、X509 证书认证 Service Account token 认证 例子 我们使用 kubectl 操作客户端,K8s 是把我们映射成 kubectl 所使用客户端证书中 CN 字段所对应的信息,而不是真正你身份证上的信息 Pod 等通过 API Server 从 etcd 中检索和更新自身状态时,API Server 对其进行身份认证,只有通过校验的 pod 才能获取信息 我们可以一次性启用多种认证方式,但通常应该至少包含以下两方面: 1. 针对于 Service Account 的 token 方式; 2. 至少一种用于 Normal Users 身份验证的其他方式。通过认证的用户会被包含在名为 system:authenticated 的 group 中。 Basic 认证 认证方法是管理员将 password、user、uid、group 信息加入到 csv 格式的静态文件中,并在 API Server 启动时使用参数–Basic-authfile={文件路径},指定使用的凭证文件。之后,认证凭证就将一直有效,只有在重启 API Server 时才能修改密码。凭证文件中的数据示例如下: password,user,uid,"group1,group2,group3" 其中,当一个 user 对应多个组,多个 group 之间需要用逗号分隔并且使用双引号。 客户端请求时,需要在头部加入 Basic BASE64ENCODED (USER:PASSWORD),服务端会校验用户名和密码。该方式使用简单,但是因为用户名和密码使用明文,用户名和密码修改必须重启服务,十分不灵活,一般只用于测试场景。 X509 证书认证 本文我们假设读者已经了解数字证书和 CA 的基本原理,若不了解可以先阅读下这篇文章《数字证书原理》[1]。 K8s 中组件之间通信,证书的验证是在协议层通过 TLS 完成的,TLS 验证分为 2 种: • 服务器单向认证:服务器端持有证书证明自己身份,用于服务端不关心客户端身份而客户端需要确认服务器身份的场景。例如火车票购票网站,我们必须保证其是官方而非恶意服务器,但网站允许任何客户端进行连接访问; • 双向 TLS 认证:双方都要持有证书,并验证对方证书确认身份。一般用于服务端持有信息比较敏感,只有特定客户端才能访问的场景。例如:K8s 内组件提供的接口往往包含集群内部信息,若被非法访问会影响整体安全,所以 K8s 内部组件之间都是双向 TLS 认证。 双向认证的简化过程如下图 2 所示 图 2 双向 TLS 过程 当两个组件进行双向 TLS 认证时,会涉及到下表中的相关文件: 名称 作用 例子 服务端证书 包含服务端公钥和服务端身份信息 通过根证书手动或者 kubeadm 自动生成的 API Server 服务端证书文件 apiserver.crt 服务器私钥 主要用于 TLS 认证时进行数字签名,证明自己是服务端证书的拥有者 通过根证书手动或者 kubeadm 生成的 API Server 服务端私钥文件 apiserver.key 客户端证书 包含客户端公钥和客户端身份信息 由同一个 CA 根证书签发的.crt 文件 客户端私钥 主要用于 TLS 认证时进行数字签名,证明自己是客户端证书的拥有者 由同一个 CA 根证书签发的.key 文件 服务端 CA 根证书 签发服务端证书的 CA 根证书 通过 openssl 等工具生成的 ca.crt 文件,并在服务端启动时进行指定 客户端 CA 根证书 签发客户端证书的 CA 根证书 通过 openssl 等工具生成的 ca.crt 文件,并在客户端启动时进行指定 (一般与服务端使用一个)

 

k8s的认证分为: 

  • HTTP Token:Authorization: Bearer $TOKEN

  • HTTP Basic: Authorization: Basic $(base64encode USERNAME:PASSWORD),

  • HTTPS: 基于CA根证书签名的客户端身份认证方式(推荐)

client certificates, 
password,
and plain tokens,

1. 证书、 ssl证书
2. HTTP Basic
--basic-auth-file=
3. 普通令牌、   普通secret 例如单独创建的imagePullSecret  
4. 引导令牌和 bootstrap tokens  --token-auth-file
5. JSON Web 令牌(JWT,用于服务账户)  sa的secret 

6.  webhook Token认证:
集群中需要配置如下两个参数:
--authentication-token-webhook-config-file 用于配置remote service(负责认证)的文件
--authentication-token-webhook-cache-ttl 用于配置身份认证结果的缓存时间,默认2分钟
webhook采用kubeconfig文件格式进行配置,文件中clusters是指remote service,而users是指API服务器webhook,如下示例:

 



客户端证书、密码、普通 token、bootstrap token 和 JWT 认证 (主要用于 Service Account)。认证模块会检查请求头或者客户端证书的内容,我们可以同时配置一种或几种方式对请求进行认证。多种认证方式会被依次执行,只要一种方式通过,请求便得到合法认证。当所有方式都未通过时,会返回 401 状态码并中断请求。认证解决的问题是校验访问方是否合法并识别其身份。 鉴权阶段。K8s API 访问请求必须包括请求者的用户名、请求的操作以及操作对象,该阶段就是对用户的操作合法性进行校验。如果现有策略声明用户具有完成请求操作的权限,则对请求进行授

1. ssl证书x509 格式的证书认证。最多用的ssl证书认证。   

kube-proxy.kubeconfig 也是使用的证书认证。

2.  token认证。 

   sa本质上也是token,创建sa账户的时候生成挂载到pod里面,pod便具有了sa的访问认证。同时sa也是可以做权限绑定,所以使用sa相当于获取到了认证和授权两个维度的信息。

 例子: 所有sa  所有  都是使用的token认证 

Type: kubernetes.io/service-account-token

 

3.  HTTP Basic 认证是再api配置文件添加认证文件。直接写账号密码。

   在k8s的配置文件添加 --token-auth-file=/etc/kubernetes/token.csv  参数,bootstrap.kubeconfig 客户端访问集群。

 例子: bootstrap.kubeconfig

K8s支持X509 Client证书、token、basic auth认证等。

X509 Client证书:
      启动API Server时通过--client-ca-file=SOMEFILE选项提供给API Server。
静态token文件:
     1)启动API Server时通过--token-auth-file=SOMEFILE选项提供给API Server。
      token文件是csv文件,包含如下内容:
          token,user,uid,"group1,group2,group3"
     2)通过在http header中提供token信息以完成认证
        Authorization: Bearer 31ada4fd-adec-460c-809a-9e56ceb75269
            31ada4fd-adec-460c-809a-9e56ceb75269为具体的token值。
Bootstrap Token
    相比于静态token而言,此类token可动态管理。
basic auth:
     1)需要将包含password、username、uid、group等信息的csv文件通过--basic-auth-file=SOMEFILE选项提供给API Server,在API Server启动时加载。
     2) 需要在http的header中填写Authorization头,其中包含“USER:PASSWORD”的Base64编码后的字符串。
OpenID Connect Token:
    采用OAuth3令牌响应的id_token(而不是access_token)作为承载令牌。
    需要首先向身份提供商进行身份验证。然后采用身份提供商给你的id_token访问K8s。在Header中添加:Authorization: Bearer XXXXXXX
    要使用该认证方式,需要配置API Server:
          --oidc-issuer-url  身份提供商的URL,如:https://accounts.google.com,必选
          --oidc-client-id  客户端标识,如:kubernetes  ,必选
          其他可选参数参见:https://kubernetes.io/docs/reference/access-authn-authz/authentication/#openid-connect-tokens

    身份提供商需要支持OpenID Connect规范。
  webhook Token认证: 
      集群中需要配置如下两个参数:
      --authentication-token-webhook-config-file   用于配置remote service(负责认证)的文件
      --authentication-token-webhook-cache-ttl   用于配置身份认证结果的缓存时间,默认2分钟
      webhook采用kubeconfig文件格式进行配置,文件中clusters是指remote service,而users是指API服务器webhook,如下示例:

  

 

posted @ 2023-04-17 15:12  滴滴滴  阅读(143)  评论(0编辑  收藏  举报