Kubernetes使用三个步骤来强制执行安全性访问和权限-身份验证,授权和准入。 在本文中,我们将首先考虑身份验证。
身份验证中的第一件事是身份。
身分识别
Kubernetes假定“用户”在Kubernetes之外进行管理。在生产环境中,它可以是用于身份管理的LDAP(轻型目录访问协议),SSO(单点登录),Kerberos或SAML(安全断言标记语言)。
在开发或测试环境中,可以使用其他身份验证策略。
认证策略
Kubernetes使用身份验证代理,bearer tokens,客户端证书或HTTP基本授权来通过身份验证插件对API请求进行身份验证。在向API服务器发出HTTP请求时,插件会尝试将以下属性与请求相关联:
用户名:标识最终用户的字符串。
UID:一个字符串,用于标识最终用户,并尝试使其比用户名更加一致和唯一。
组:一组将用户与一组通常分组的用户相关联的字符串。
附加字段:包含附加信息的字符串映射,授权者可能会觉得有用。
所有这些值对于身份验证系统都是不透明的,并且仅在授权者解释时才有意义。 Kubernetes管理员通常启用多种身份验证方法。所需的两种最小方法是-服务帐户的服务帐户令牌和至少一种其他的用户身份验证方法。
X509客户证书
从Kubernetes 1.4开始,客户端证书还可以使用证书的组织字段指示用户的组成员身份。
要为用户包括多个组成员身份,请在证书中包括多个组织字段。
通过将–client-ca-file = <FILE>选项传递给API服务器来启用客户端证书认证。
引用的文件必须包含一个或多个证书颁发机构,用于验证提供给API服务器的客户端证书。
如果提供并验证了客户证书,则将主题的通用名称用作请求的用户名。
例如,使用openssl命令行工具生成证书签名请求:
1 |
openssl req -new -key <pem_file>.pem -out <out-csr-file>.pem -subj "/CN=admin/O=prod/O=dev/O=uat" |
这将为用户名admin创建一个CSR(证书签名请求),该用户名属于以下三个组:prod,dev和uat
静态令牌文件
在命令行上给–token-auth-file = <FILENAME>选项时,API服务器将从文件读取bearer tokens。 今天,令牌无限期地存在,并且令牌列表不能在不重新启动API服务器的情况下进行更改。 令牌文件是CSV文件,至少包含3列:令牌,用户名,用户uid,后跟可选的组名。
1 |
token, user, uid,"prod,dev,uat" |
注意:如果有多个组,则该列必须用双引号引起来。
将bearer tokens放入请求中
从HTTP客户端使用bearer tokens身份验证时,API服务器需要一个值为Bearer <令牌>的Authorization标头。 bearer tokens必须是一个字符序列,可以使用不超过HTTP的编码和引用功能的方式将其放入HTTP标头值中。 例如,如果bearer tokens是ad644f3f-bfch-295b-75bk-h9g8ngf36hb6,则它将出现在HTTP标头中,如下所示:
1 |
Authorization: Bearer ad644f3f-bfch-295b-75bk-h9g8ngf36hb6 |
静态密码文件
通过将–basic-auth-file = <FILENAME>选项传递给API服务器来启用基本身份验证。 现在,基本身份验证凭据将无限期地持续,并且不重新启动API服务器就无法更改密码。
基本认证文件是一个csv文件,至少包含3列:密码,用户名,用户ID。 在Kubernetes 1.6版和更高版本中,您可以指定一个可选的第4列,其中包含用逗号分隔的组名。 如果您有多个组,则必须将第4列的值括在双引号(“)中:
1 |
password,user,uid,"group1,group2,group3" |
使用来自HTTP客户端的基本身份验证时,API服务器期望的Authorizationheader值为:
1 |
Basic BASE64ENCODED(USER:PASSWORD) |
服务帐户令牌
服务帐户是自动启用的身份验证器,它使用签名的承载令牌来验证请求。 该插件带有2个可选标志:
1 |
--service-account-key-file |
包含用于对承载令牌签名的PEM编码密钥的文件。 如果未指定,将使用API服务器的TLS私钥
1 |
--service-account-lookip |
如果启用,将从API服务器删除的令牌将被吊销
服务帐户通常由API服务器自动创建,并通过ServiceAccount Admission Controller与群集中运行的Pod关联。
bearer tokens mounted到Pod中,并允许集群内进程与API服务器通信。 可以使用PodSpec的serviceAccountName字段将帐户与Pod明确关联。
注意,通常会省略serviceAccountName,因为这是自动完成的。
小实验:
使用ServiceAccount令牌
以下命令可用于创建ServiceAccount:
1 |
kubectl create serviceaccount testuser |
创建的secret 包含API服务器的公共CA和签名的JSON Web令牌(JWT)。 要显示揭示相关secret 的yaml:
1 |
kubectl get serviceaccount testuser -o yaml |
显示可用token和获取数据:
1 2 3 |
kubectl get secrets #获取数据 kubectl get secret testuser-token-mgtnp -o yaml |
可以获取编码的令牌数据,然后将其复制并粘贴到https://jwt.io/以查看有效负载。 要运行pod,请使用选择的编辑器输入以下yaml文件(test-pod.yaml)
1 2 3 4 5 6 7 8 9 10 11 12 |
apiVersion: v1 kind: pod metadata: name: test-pod spec: serviceAccountName: testuser container: - name: alpine:3.7 command: - "sh" - "-c" - "sleep 100" |
启动pod:
1 |
kubectl apply -f test-pod.yaml |
使用命令查看描述信息:
1 |
kubectl describe test-pod |
现在,我们有了一个名为test-pod的运行中的pod,让我们进入交互模式并运行一个shell:
1 |
kubectl exec -it test-pod -- sh |
如果要在Docker容器中运行Shell,则类似于docker命令。 到那时,我们将有一个提示,我们进入了Alpine Linux系统,该系统运行在pod内部的容器中。 为了打开复制到容器中的令牌,必须运行以下命令:
1 |
cat /var/run/sercrets/kubernetes.io/serviceaccount/token |
复制输出并将该令牌粘贴到https://jwt.io/的“编码”侧。 另一方面,将获得令牌的类型,名称空间,ServiceAccount名称,secret 名称等。
这以非常直观的方式向说明了Kubernetes如何在令牌中携带标识和身份验证有效负载。
原文:https://dzone.com/articles/kubernetes-authentication