Kubernetes-认证

https://kubernetes.io/docs/admin/authentication/

Kubernetes中的用户


所有Kubernetes集群有两类用户:由Kubernetes管理的服务帐户和正常用户。

正常用户是假定被外部或独立服务管理的。管理员分配私钥,用户像Keystone或google账号一样,被存储在包含用户名和密码列表的文件里。在这点上,Kubernetes没有代表正常用户帐户的对象。不能通过API调用将普通用户添加到集群中。

相比之下,服务帐户是由Kubernetes API管理的用户。它们绑定到特定的命名空间,并由API服务器自动创建或通过API调用手动创建。服务帐户与存储为Secrets的一组证书相关联,这些凭据被挂载到pod中,以便集群进程与Kubernetes API通信。

API请求与普通用户或服务帐户相关联,或被视为匿名请求。这就意味着每个内部的进程或者集群外部的用户在工作站上使用kubectl在节点上操作,以及用户使用控制面板,只要请求API,都需要认证,或者被认为是匿名用户。

验证策略


Kubernetes用户可以使用客户端证书,承载令牌,身份验证代理或HTTP基本认证来通过身份验证插件验证API请求。比如HTTP请求到达API server,插件尝试将以下属性与请求关联:

  • Username:一个标识了最终用户的字符串。通常值可能像“kube-admin”或者“jane@example.com”。
  • UID:一个标识了最终用户的字符串,并尝试比用户名更一致和唯一。
  • Groups:用户组组名。
  • Extra fields:将一些有用的字符串信息映射成的列表。

所有值对于认证系统都是不透明的,只有在被授权者解释时才有意义。
你可以同时启用上面的多个认证方法。通常至少使用至少两种:

  • 为服务账号使用服务账号tokens。
  • 至少为用户认证使用另外一种方法。

当多个启用时,第一个认证模块成功地认证了请求,API server不能保证接下来的认证通过。

system:authenticated组被包括在所有已认证用户的组列表中。

X509 客户证书

通过将–client-ca-file = SOMEFILE选项传递给API服务器来启用客户端证书身份验证。引用的文件必须包含用以验证提交给API服务器的客户端证书的一个或多个证书颁发机构。如果客户端提交的证书通过,主体的通用名称(common name)将被用作请求的用户名。从Kubernetes 1.4起,客户端证书也可以通过证书的组织(organization)区域指定用户的组成员资格。

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

openssl req -new -key jbeda.pem -out jbeda-csr.pem -subj”/CN=jbeda/O=app1/O=app2”

这将会创建一个用户名为“jbeda”,所属组为”app1”和“app2”的签名请求。
有关如何生成客户端证书,请参见附录

Static Token File

当在命令行指定- -token-auth-file=SOMEFILE选项时,API服务器从文件中读取 bearer tokens。目前,tokens持续无限期,如果不重启 API server,token列表无法重启。

令牌文件是一个至少包含3列的csv文件: token, user name, user uid,后跟可选的组名。注意,如果您有多个组,则列必须是双引号,例如。

token,user,uid,"group1,group2,group3"
Putting a Bearer Token in a Request

当通过http客户端使用 bearer token 认证时,API服务器需要一个值为Bearer THETOKEN的授权头。bearer token必须是,可以放在HTTP请求头中且值不需要转码和引用的一个字符串。例如:如果bearer token是31ada4fd-adec-460c-809a-9e56ceb75269,它将会在HTTP头中按下面的方式呈现:

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


Bootstrap Tokens

Static Password File


Service Account Tokens

服务帐户是一个自动启用的使用签名的承载令牌来验证请求的认证器。该插件接受两个可选参数:

  • - -service-account-key-file 一个包含用户签名 bearer tokens的秘钥文件。如果不指定,将使用API​​服务器的TLS私钥。
  • - -service-account-lookup 如果指定,从API中删除的tokens将会撤销。

服务账号通常由API服务器自动创建,并通过ServiceAccount Admission Controller与集群中的pods关联。 Bearer tokens被挂载到pod中众所周知的位置,使集群中的进程可以与API服务器通信。账号可以在PodSpec的serviceAccountName字段中被明确。
注意:通常省略serviceAccountName,因为这是自动完成的。

apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: nginx-deployment
  namespace: default
spec:
  replicas: 3
  template:
    metadata:
    # ...
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        serviceAccountName: bob-the-bot

服务账号的bearer tokens在集群外部使用是完全有效的,可以用于创建希望与API通信的长期工作的身份。要手动创建服务帐户,只需使用kubectl创建 serviceaccount(NAME)即可。这将在当前命名空间中创建一个服务帐户,并创建一个关联的密钥。

$ kubectl create serviceaccount jenkins
serviceaccount "jenkins" created
$ kubectl get serviceaccounts jenkins -o yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  # ...
secrets:
- name: jenkins-token-1yvwg

创建的秘密保存了API服务器的公共CA和签名的JSON Web Token(JWT)。

$ kubectl get secret jenkins-token-1yvwg -o yaml
apiVersion: v1
data:
  ca.crt: (APISERVER'S CA BASE64 ENCODED)
  token: (BEARER TOKEN BASE64 ENCODED)
kind: Secret
metadata:
  # ...
type: kubernetes.io/service-account-token

注意:值是base64编码的,因为秘钥通常被base64编码。

签名的JWT可以作为bearer token来验证给定的service account。请看上边关于token如何包含在request中。通常,这些秘钥被挂载到pods中,用于集群中访问API服务器,但也可以从群集外部使用。

服务账号使用用户名进行验证 system:serviceaccount:(NAMESPACE):(SERVICEACCOUNT),并分配给组 system:serviceaccounts 和 system:serviceaccounts:(NAMESPACE)。

警告:由于service account tokens存储在秘钥中,任何具有对这些秘钥的读取访问权限的用户都可以作为服务帐户进行身份验证。在授予服务帐户权限并阅读秘密功能时,要小心谨慎。

OpenID Connect Tokens

OpenID Connect 是一些由OAuth2提供商支持的OAuth2,特别是Azure Active Directory,Salesforce和Google。OAuth2的协议的主要扩展是增加一个额外字段,返回了一个叫ID token的access token。这个token是被服务器签名的JSON Web Token (JWT) ,具有众所周知的字段,比如用户的email。
为了识别用户,验证使用来自OAuth2 token响应的id_token (而不是 access_token)作为bearer token。token如何包含在请求中请参阅上面

这里写图片描述

1.Login to your identity provider

2.Your identity provider will provide you with an access_token, id_token and a refresh_token

3.When using kubectl, use your id_token with the –token flag or add it directly to your kubeconfig

4.kubectl sends your id_token in a header called Authorization to the API server
4.kubectl 在头部通过Authorization字段将id_token发送到 API server

5.The API server will make sure the JWT signature is valid by checking against the certificate named in the configuration
5.API server将通过检查配置中命名的证书确定JWT签名是有效的

6.Check to make sure the id_token hasn’t expired

7.Make sure the user is authorized

8.Once authorized the API server returns a response to kubectl

9.kubectl provides feedback to the user
9.kubectl向用户提供反馈

由于所有验证您身份需要的数据在id_token中,所以Kubernetes不需要向身份提供者的“phone home”。 每个请求都是无状态的模型中,它为身份验证提供了非常可扩展的解决方案。 也带来了一些挑战:

1.Kubernetes没有“Web 接口”来触发身份验证过程。没有任何浏览器或接口来收集凭据,这就是为什么您需要首先向您的身份提供者进行身份验证。
2.id_token不能被撤销,它像一个证书,所以它应该是短暂的(只有几分钟),所以每隔几分钟就得到一个新的令牌可能非常烦人。
3.如果不使用kubectl -proxy命令或注入id_token的反向代理,没有简单的方法来向Kubernetes仪表板进行身份验证。

Configuring the API Server

启用插件,请在API server上配置下面的选项:

参数描述举例是否必须
- -oidc-issuer-urlURL的提供者允许APIserver发现公共签名的秘钥。只有使用http://格式的URL被接受。通常提供商的发现URL没有路径,比如“https://accounts.google.com” 或 “https://login.salesforce.com”。如果发现网址为https://accounts.google.com/.well-known/openid-configuration,则值应为https://accounts.google.com
- -oidc-client-id所有token必须分发的客户端id。kubernetes
- -oidc-username-claimJWT声明使用的用户名。默认为sub,预期是最终用户的唯一标识符。管理员可以根据其提供者选择其他声明,例如电子邮件或名称。然而使用电子邮件以外的声明将以发行者URL为前缀,以防止与其他插件进行命名冲突。以防止命名与其它插件冲突。sub
- -oidc-groups-claim指定JWT使用的用户组,如果指定,必须是一个字符串数组。groups
- -oidc-ca-fileCA签署身份提供商网络证书的证书的路径。默认为主机的根CA。/etc/kubernetes/ssl/kc-ca.pem

……

Webhook Token Authentication

Webhook认证通过一个钩子验证承载令牌(bearer tokens)。

  • - -authentication-token-webhook-config-file 一个描述了如何访问远程webhook服务的配置文件
  • - -authentication-token-webhook-cache-ttl 缓存认证多长时间。默认2分钟

配置文件使用 kubeconfig 文件格式。文件中API服务器的webhook,“cluster”是指远程服务。例子:

# clusters refers to the remote service.
clusters:
  - name: name-of-remote-authn-service
    cluster:
      certificate-authority: /path/to/ca.pem         # CA for verifying the remote service.
      server: https://authn.example.com/authenticate # URL of remote service to query. Must use 'https'.

# users refers to the API server's webhook configuration.
users:
  - name: name-of-api-server
    user:
      client-certificate: /path/to/cert.pem # cert for the webhook plugin to use
      client-key: /path/to/key.pem          # key matching the cert

# kubeconfig files require a context. Provide one for the API server.
current-context: webhook
contexts:
- context:
    cluster: name-of-remote-authn-service
    user: name-of-api-sever
  name: webhook

当客户端尝试使用如上所述的承载令牌与API服务器进行身份验证时,认证webhook通过一个包含token的查看对象来查询远程服务。Kubernetes不会对缺少这样的头的请求提出质疑。( Kubernetes will not challenge a request that lacks such a header.)??

请注意,webhook API对象受到与其他Kubernetes API对象相同的版本兼容性规则的约束。实施者应该注意对于beta对象应放宽兼容性,并检查请求的“apiVersion”字段,以确保正确的反序列化。此外,API服务器必须启用authentication.k8s.io/v1beta1 API扩展组(–runtime-config = authentication.k8s.io / v1beta1 = true)。
请求体采用以下格式:

{
  "apiVersion": "authentication.k8s.io/v1beta1",
  "kind": "TokenReview",
  "spec": {
    "token": "(BEARERTOKEN)"
  }
}

远程服务预计将填写请求的TokenAccessReviewStatus字段,以示登录成功。 响应体的“spec”字段被忽略,可以省略。 承载令牌的成功验证将返回:

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

如果不成功返回:

{
  "apiVersion": "authentication.k8s.io/v1beta1",
  "kind": "TokenReview",
  "status": {
    "authenticated": false
  }
}

HTTP状态码可用于提供其他错误上下文。

Authenticating Proxy

API服务器可以配置为根据请求头值来识别用户,如X-Remote-User。 它被设计为通过设置请求头值与认证代理组合使用。

  • –requestheader-username-headers 必需,不区分大小写。按顺序检查头名字用于识别用户身份。 第一个包含的值用作用户名。
  • –requestheader-group-headers1.6+以上。 可选,不区分大小写。 建议使用“X-Remote-Group”。按顺序检查头名字用于识别用户组。头部中所有指定的所有值均用作组名称。
  • –requestheader-extra-headers-prefix 1.6+以上。 可选,不区分大小写。 建议使用“X-Remote-Extra-”。标题前缀,用于查找关于用户的额外信息(通常由配置的授权插件使用)。以任何指定的前缀开始的任何头都会删除前缀。其余的头名称将成为额外的键,而值是额外的值。

例如,使用此配置:

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

请求:

GET / HTTP/1.1
X-Remote-User: fido
X-Remote-Group: dogs
X-Remote-Group: dachshunds
X-Remote-Extra-Scopes: openid
X-Remote-Extra-Scopes: profile

将会产生这样的用户信息:

name: fido
groups:
- dogs
- dachshunds
extra:
  scopes:
  - openid
  - profile

为了防止标头欺骗,认证代理需要在检查请求标头之前,向API服务器呈现有效的客户端证书以针对指定的CA进行验证。

  • –requestheader-client-ca-file 需要。 PEM编码的证书包。 在通过请求头检查用户名之前,必须根据指定文件中的证书颁发机构呈现和验证有效的客户端证书。
  • –requestheader-allowed-names 可选的。 通用名称列表(cn)。如果设置,则在检查请求头中的用户名之前,必须呈递具有列表中指定名字的客户端证书。

Keystone Password

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值