3

Kubernetes认证入门指南 - DockOne.io

 2 years ago
source link: http://dockone.io/article/2434338
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Kubernetes用来执行安全访问和权限的步骤有3个——认证(Authentication)、授权(Authorization)和准入(Admission)。在本文中,我们先开始了解认证(Authentication)。

在认证中第一个需要考虑的是身份认证(Identity)。

身份认证简介

Kubernetes假设“user”是在Kubernetes之外管理的。在生产环境中,可以采用LDAP(轻量级目录访问协议)、SSO(单点登录)、Kerberos或SAML(安全断言置标语言)进行身份认证管理。在开发或测试环境中,其他的认证策略也有可能会被使用到。

在Kubernetes中没有表达普通用户的对象,因此不能通过API将普通用户添加到集群中。

认证策略概览

Kubernetes通过认证插件使用认证代理、bearer token、客户端证书或HTTP基本授权来认证API请求。当向API server发出HTTP请求时,插件会尝试将以下属性与请求关联起来:
  • Username:识别最终用户的字符串
  • UID:识别最终用户的字符串,并试图比username格式更为一致,同时每个UID都是独特的。
  • Groups:一组字符串,将用户与一组常见的分组用户关联起来
  • Extra fields:字符串的映射,保存着授权者认为可能有用的额外信息。
所有这些值对认证系统来说都是不透明的,只有在authorizer对其进行解释时才有意义。Kubernetes管理员通常会启用多种认证方法。所需的两种最基本的方法是——服务账户的service account token再加上至少一种其他的用户认证方法。

X509客户端证书

  • 从Kubernetes 1.4开始,客户端证书可以使用证书组织字段来表明用户的组成员资格。
  • 要让一个用户拥有多个组成员资格,需要在证书中包含多个组织字段。
  • 通过向API server传递 --client-ca-file=<FILE>选项来启用客户端证书认证。
  • 引用的文件必须包含一个或多个证书颁发机构,用于验证提交给API server的客户证书。
  • 如果出示客户端证书并进行验证,则使用主体的通用名作为请求的用户名。
例如,使用openssl命令行工具来生成证书签名请求:
openssl req -new -key <pem_file>.pem -out <out-csr-file>.pem -subj "/CN=admin/O=prod/O=dev/O=uat"


这将为用户名admin创建一个CSR(证书签名请求),该用户名属于以下3个组:prod、dev和uat。

静态Token文件

当在命令行中给出--token-auth-file=<FILENAME>选项时,API Server会从文件中读取bearer token。如今,token无限期存在,如果不重启API Server,就无法更改token列表。Token文件是一个csv文件,至少有3列:token、用户名、user uid,后面可能还会有组名(这是可选的)。
token, user, uid,"prod,dev,uat"


请注意:如果你有超过1个组,该列必须使用双引号。

在请求中放入一个bearer token

当使用来自HTTP客户端的bearer token认证时,API server期望授权请求头的值为Bearer <Token>。bearer token必须是一个字符序列,可以只需使用HTTP的编码和引用功能就可以将其放在HTTP请求头的值中。例如,如果Bearer Token是ad644f3f-bfch-295b-75bk-h9g8ngf36hb6,那么它将出现在HTTP请求头中,如下所示:
Authorization: Bearer ad644f3f-bfch-295b-75bk-h9g8ngf36hb6

静态密码文件

通过向API server传递--basic-auth-file=<FILENAME>选项来启用基本认证。现在,基本的认证凭证将无限期地持续下去,而且如果不重新启动 API server,就无法更改密码。

基本的 auth 文件是一个 csv 文件,至少有 3 列:密码、用户名、用户 ID。在Kubernetes 1.6及以后的版本中,你可以指定一个可选的第4列,包含逗号分隔的组名。如果你有多个组,你必须用双引号(")括住第4列的值。
password,user,uid,"group1,group2,group3"


当使用来自HTTP客户端的基本认证时,API server期望Authorizationheader的值为:
Basic BASE64ENCODED(USER:PASSWORD)

服务账户Token

服务账户是一个自动启用的身份认证器,它使用签名的bearer token来验证请求。该插件需要2个可选的标志:
--service-account-key-file


一个包含PEM编码密钥的文件,用于签署bearer token。如果没有指定,将使用API server的TLS密钥。
--service-account-lookip


如果启用了,从API sever上删除的token将被撤销。

服务账户通常由API server自动创建,并通过ServiceAccount 准入控制器与集群中运行的Pod相关联。

Bearer Token会被挂载到众所周知的位置的Pod中,并允许集群内进程与API Server对话。账户可以使用PodSpec的serviceAccountName字段与Pod显式关联。

注意,serviceAccountName通常会被省略,因为这是自动完成的。

练习实践:使用ServiceAccount Token

使用以下命令可以创建ServiceAccount:
kubectl create serviceaccount testuser


创建的密钥包含API server的公共CA和签名的JSON web Token(JWT)。以下命令可以显示出揭示相关密钥的yaml:
kubectl get serviceaccount testuser -o yaml


以下命令可以显示可用Token:
kubectl get secrets


要获得编码的token数据,请输入:
kubectl get secret testuser-token-mgtnp -o yaml


你可以将编码后的token数据复制并粘贴到https://jwt.io/ 以查看有效载荷。使用你选择的编辑器输入以下yaml文件(test-pod.yaml),以运行一个pod:
apiVersion: v1 
kind: pod 
metadata:  
name: test-pod 
spec:  
serviceAccountName: testuser  
container:  
- name: alpine:3.7    
command:    
- "sh"    
- "-c"    
- "sleep 100"


然后使用以下命令启动pod:
kubectl apply -f test-pod.yaml


使用describe可以查看更详细的内容:
kubectl describe test-pod


现在,我们有一个正在运行的pod,名为test-pod,让我们进入交互模式并运行一个shell:
kubectl exec -it test-pod -- sh


如果你想在docker容器内运行shell,所使用的命令与docker命令类似。这时,我们将会收到一个提示,然后进入Alpine Linux系统,该系统是在pod中的一个容器内运行的。为了打开被复制到容器中的token,你需要运行以下命令:
cat /var/run/sercrets/kubernetes.io/serviceaccount/token


复制输出并将该token粘贴在https://jwt.io/上Encoded部分。在另一边你会得到token的类型、命名空间、ServiceAccount名称、密钥名称等。

这几乎以一种十分直观的方式向你说明了Kubernetes如何在token中进行身份验证有效载荷。

作者:
Sudip Sengupta
链接:
https://dzone.com/articles/kub ... ation


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK