k8s-身份认证与权限

k8s-身份认证与权限

K8s中的用户

k8s中的有两类型的用户:被k8s集群管理的服务账号 ( Service Account Pod 对象)和常规用户 (User Account 现实中的“人”)。

**User Account(用户账号):**一般是指由独立于Kubernetes之外的其他服务管理的用户账号,例如由管理员分发的密钥、Keystone一类的用户存储(账号库)、甚至是包含有用户名和密码列表的文件等。Kubernetes中不存在表示此类用户账号的对象, 因此不能被直接添加进 Kubernetes 系统中 。普通用户若要安全访问集群API Server,往往需要证书、Token或者用户名+密码。

**Service Account(服务账号):**是指由Kubernetes API 管理的账号,用于为Pod 之中的服务进程在访问Kubernetes API时提供身份标识( identity ) 。Service Account通常要绑定于特定的命名空间,它们由 API Server 创建,或者通过 API 调用手动创建 ,附带着一组存储为Secret的用于访问API Server的凭据。

K8s API的访问控制

用户访问API服务的途径通常有三种:kubectl、客户端库或者直接使用 REST接口。 用户和 K8s 服务账户访问K8S集群的资源需要过三关:认证、鉴权、准入控制,如下图所示:

img

Step1 认证 Authentication

认证模块负责鉴定⽤户⾝份。

一旦建立了安全传输层协议(TLS),请求会进入认证步骤。API server 会执行配置的一个或多个认证模块 。认证模块一般通过检查请求头或者客户端证书来进行认证。认证模块支持客户端证书、用户名+密码、令牌、bootstrap tokens和 JSON Web 令牌(JWT,用于服务账户)。可以指定多个认证模块,认证时会遍历认证模块直到有一个模块认证通过。如果认证未认证通过,会拒绝请求,返回401状态码。认证通过后会指定相应的username,用于后续步骤。

Step2 鉴权 Authorization

授权模块⽤于操作权限许可鉴别。

当请求被认证模块认证通过,认证为一个特定的用户后,请求会继续进行鉴权检查。可以配置多个鉴权模块进行鉴权检查。Kubernetes 支持多种鉴权模式,例如 ABAC 模式、RBAC 模式和 Webhook 模式等。 管理员创建集群时,会在 API Server中配置使用的鉴权模块。 如果配置了多个鉴权模块,则 Kubernetes 会检查每个模块,任意一个模块授权请求,请求即可继续; 如果所有模块拒绝了该请求,请求将会被拒绝(HTTP 状态码 403)。

Step3 准入控制 Admission control

准⼊控制⽤于在资源对象的创建、删除、更新或连接(proxy)操作时实现更精细的许可检查。

准入控制模块是可以修改或拒绝请求的软件模块。 除鉴权模块可用的属性外,准入控制模块还可以访问正在创建或修改的对象的内容。准入控制器对创建、修改、删除或(通过代理)连接对象的请求进行操作。

准入控制器不会对仅读取对象的请求起作用。

有多个准入控制器被配置时,服务器将依次调用它们。

与身份认证和鉴权模块不同,如果任何准入控制器模块拒绝某请求,则该请求将立即被拒绝。

请求通过所有准入控制器后,将使用检验程序检查对应的 API 对象,然后将其写入对象存储(如步骤 4 所示)。

API Server 服务端口

API Server使用HTTP协议在两个端口上提供服务,localhost端口和Secure端口:

  1. localhost端口:用于测试和引导,以及主控节点上的其他组件(调度器,控制器管理器)与 API 通信

    1. 没使用安全传输层协议(TLS)
    2. 默认为端口 8080,使用 --insecure-port 进行更改
    1. 默认 IP 为 localhost,使用 --insecure-bind-address 进行更改
    2. 请求 绕过 身份认证和鉴权模块
    1. 由准入控制模块处理的请求
    2. 受需要访问主机的保护
  2. Secure端口

    1. 使用 TLS。 用 --tls-cert-file 设置证书,用 --tls-private-key-file 设置密钥
    2. 默认端口 6443,使用 --secure-port 更改
    1. 默认 IP 是第一个非本地网络接口,使用 --bind-address 更改
    2. 请求须经身份认证模块、鉴权模块处理
    1. 请求须经准入控制模块处理

apiserver 对外不暴露8080端口,只能内部访问,对外使用6443端口

身份认证策略

Kubernetes 使用身份认证插件利用客户端证书、持有者令牌(Bearer Token)、身份认证代理(Proxy) 或者 HTTP 基本认证机制(通过用户名密码的方式认证)来认证 API 请求的身份。HTTP 请求发给 API Server时, 插件会将以下属性关联到请求:

  • 用户名:用来辩识最终用户的字符串。常见的值可以是 kube-admin 或 jane@example.com。

  • 用户ID:用来辩识最终用户的字符串,旨在比用户名有更好的一致性和唯一性。

  • 用户组:取值为一组字符串,其中各个字符串用来标明用户是某个命名的用户逻辑集合的成员。 常见的值可能是 system:masters 或者 devops-team 等。

  • 附加字段:一组额外的键-值映射,键是字符串,值是一组字符串;用来保存一些鉴权组件可能觉得有用的额外信息。

当集群中启用了多个身份认证模块时,第一个成功地对请求完成身份认证的模块会直接做出评估决定。API Server并不保证身份认证模块的运行顺序。所有通过验证的用户都会被添加进system:authenticated组。

https证书认证,基于X509 CA证书

基于CA根证书签名的双向数字证书认证方式。X509证书详解参考

要启用 X509证书认证,需要在apiserver的启动参数中添加***–client-ca-file=SOMEFILE***, API Server X509 认证的完整启动参数如下

kube-apiserver
  --advertise-address=192.168.10.50
  --allow-privileged=true
  --authorization-mode=Node,RBAC
  --client-ca-file=/etc/kubernetes/pki/ca.crt
  --enable-admission-plugins=NodeRestriction
  --enable-bootstrap-token-auth=true
  --etcd-cafile=/etc/kubernetes/pki/etcd/ca.crt
  --etcd-certfile=/etc/kubernetes/pki/apiserver-etcd-client.crt
  --etcd-keyfile=/etc/kubernetes/pki/apiserver-etcd-client.key
  --etcd-servers=https://127.0.0.1:2379
  --insecure-port=0
  --kubelet-client-certificate=/etc/kubernetes/pki/apiserver-kubelet-client.crt
  --kubelet-client-key=/etc/kubernetes/pki/apiserver-kubelet-client.key
  --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname
  --proxy-client-cert-file=/etc/kubernetes/pki/front-proxy-client.crt
  --proxy-client-key-file=/etc/kubernetes/pki/front-proxy-client.key
  --requestheader-allowed-names=front-proxy-client
  --requestheader-client-ca-file=/etc/kubernetes/pki/front-proxy-ca.crt
  --requestheader-extra-headers-prefix=X-Remote-Extra-
  --requestheader-group-headers=X-Remote-Group
  --requestheader-username-headers=X-Remote-User
  --secure-port=6443
  --service-account-key-file=/etc/kubernetes/pki/sa.pub
  --service-cluster-ip-range=10.96.0.0/12
  --tls-cert-file=/etc/kubernetes/pki/apiserver.crt
  --tls-private-key-file=/etc/kubernetes/pki/apiserver.key

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

例如,使用 openssl 命令行工具生成一个证书签名请求:

# 此命令将使用用户名 jbeda 生成一个证书签名请求(CSR),且该用户属于 "app" 和 "app2" 两个用户组。
openssl req -new -key jbeda.pem -out jbeda-csr.pem -subj "/CN=jbeda/O=app1/O=app2"

静态令牌文件

当 API Server的命令行设置了 –token-auth-file=SOMEFILE 选项时,会从文件中读取持有者令牌(bearer token)。令牌会长期有效,如果修改token file的内容,必须重启api server才能生效。

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

#令牌,用户名,uid,组名(多个用双引号括起来)
token,user,uid,"group1,group2,group3"

Bearer Token

使用http协议,添加**Authorization请求头。**格式为:Bearer THETOKEN。

API Server会根据请求头token内容进行身份认证。

例如:如果持有者令牌为 31ada4fd-adec-460c-809a-9e56ceb75269,则请求头Authorization如下所示:

Authorization: Bearer 31ada4fd-adec-460c-809a-9e56ceb75269

Bootstrap Tokens

为了支持方便地启动引导新的集群,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中使用)。

Service Account Tokens

服务账号(Service Account)是一种自动被启用的用户认证机制,使用经过签名的bearer token来验证请求。该插件可接受两个可选参数:

  • –service-account-key-file:包含PEM编码密钥的文件,用于对token进行签名。如果未指定,将使用API服务器的TLS私钥。
  • –service-account-lookup 如果启用,通过API 删除的令牌会被回收。

服务账号通常由 API Server自动创建,并通过ServiceAccount Controller Manager与集群中运行的pod相关联。token被挂载到已知位置的pods中,并允许集群内进程与API Server通信。帐户可以使用PodSpec的serviceAccountName字段显式地与pod关联。

# 创建serviceaccount: jenkins
kubectl create serviceaccount jenkins
serviceaccount "jenkins" created

# 获取serviceaccount: jenkins
kubectl get serviceaccounts jenkins -o yaml

apiVersion: v1
kind: ServiceAccount
metadata:
  # ...
secrets:
- name: jenkins-token-1yvwg



# 创建的secret包含API Server的公共CA和一个签名的JSON Web令牌(JWT)。
kubectl get secret jenkins-token-1yvwg -o yaml

apiVersion: v1
data:
  ca.crt: (APISERVER'S CA BASE64 ENCODED)
  namespace: ZGVmYXVsdA==
  token: (BEARER TOKEN BASE64 ENCODED)
kind: Secret
metadata:
  # ...
type: kubernetes.io/service-account-token

OpenID Connect Tokens

OpenID Connect 是一种 OAuth2 认证方式, 被某些 OAuth2 IDP身份提供者支持,例如Windows Azure Active Directory、Salesforce 和 Google。 协议对 OAuth2 的主要扩展体现在有一个附加字段会和访问令牌一起返回, 这一字段称作 ID Token(ID 令牌)。 这种令牌是一种由服务器签名的 JSON Web 令牌(JWT),其中包含一些可预知的字段, 例如用户的邮箱地址,要识别用户,身份认证组件使用 OAuth2 令牌响应 中的 id_token(而非 access_token)作为bearer token。认证中心把用户信息放在json里,用私钥加密,k8s拿到token后用公钥解密,只要解密成功token就是合法的而且能拿到用户信息,不需要再像认证中心请求。

OAuth2认证时序图:

img

  1. 用户登录IDP(身份认证提供器)

  2. 认证用户,返回acces

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
org.apache.hadoop.ipc.client是一个用于与Hadoop集群中的远程服务器进行通信的客户端库。在这个特定的错误信息中,它显示了客户端正在尝试连接到服务器“k8s-master/192.168”。 这个错误可能有几个可能的原因: 1. 连接问题:客户端无法与服务器建立连接。可能的原因是服务器故障、网络问题或客户端配置错误。首先,我们应该检查服务器是否可用,并确保网络连接正常。然后,我们可以检查客户端的配置文件,确保服务器地址和端口号正确配置。 2. 服务器问题:服务器可能无法响应客户端的请求。这可能是由于服务器过载、资源不足或程序错误引起的。我们可以检查服务器的日志文件,以了解是否有任何错误或异常。 3. 安全问题:如果服务器设置了安全配置,客户端可能无法通过身份验证,导致连接失败。这是一个常见的问题,在这种情况下,我们需要确保客户端具有正确的凭据和权限来连接服务器。 为了解决这个问题,我们可以采取以下步骤: 1. 检查服务器的可用性和网络连接。确保服务器正常运行,并且可以通过网络连接到它。 2. 检查客户端的配置文件,确保服务器地址和端口号正确配置。 3. 检查服务器的日志文件,寻找任何异常或错误信息。 4. 如果服务器配置了安全性,确保客户端具有正确的凭据和权限来连接服务器。 如果以上步骤仍然无法解决问题,可能需要进一步调试和排除故障,包括与系统管理员或开发人员进行联系以获取更多支持。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值