Kubernetes认证和授权

kubernetes ginotang 2922℃ 0评论

简介

Kubernetes以REST API的形式向外提供接口来管理集群。这就引发了安全问题:假如别人知道你的API地址,那么你的服务器就很容易遭到恶意破坏。当然Kubernetes开发团队不会不了解这些问题,因此,它提供了多种安全手段来保障服务器的安全。

API SERVER

所有的安全问题都是针对API SERVER而言的,因为它提供了管理集群的唯一接口。API SERVER使用https协议工作,使数据传输更加安全,传输内容不容器被窃听

Kubernetes安全的三个层次

kubernetes在三个层次上保证了集群的安全,其中之一是上面说的https协议(即TLS加密)。假如我们的集群是通过kubeadm命令建立的,那么TLS证书也由kubeadm负责创建,它们保存在/etc/kubernetes/pki目录下

除了TLS加密之外,另外两个是:

  • 认证(Authentication)
  • 授权(Authorization)

认证是为了识别访问者是谁,是否是一个合法的用户,而授权则决定用户可以干什么,拥有什么权限。

认证

认证过程中涉及的相关概念:

  • ServiceAccount
  • JWT
  • 用户

ServiceAccount中主要保存的信息就是一个令牌(token),令牌格式就是JWT(json web token)。JWT本身并不是Kubernetes中的概念,详细请参考JWT

用户、组和JWT之间的关系并不完全独立,JWT保存着用户和组的名称,下面是从Kubernetes默认ServiceAccount中解码的PAYLOAD部分JWT内容

可以看到,ServiceAccount所属的namespace是default,ServiceAccount名称也是default。

最后的sub由三个部分组成:

  • system:serviceaccount (用户所属的组)
  • default (namespace名称)
  • default (用户名称)

Kubernetes内置了几个特别的组:

  • system:unauthenticated 包括未认证的用户
  • system:authenticated 包括已经认证的用户
  • system:serviceaccounts 系统范围 serviceaccount中的所有用户
  • system:serviceaccounts:<namespace> 特定名称空间范围内serviceaccount中的所有用户

ServiceAccount

当kubernetes集群搭建好后,系统中就存在多个ServiceAccount,它们隶属于不同的名称空间,不同名称空间之间的ServiceAccount名称可以相同。通过下面的命令查看当前系统的ServiceAccount

如果不添加其他参数,默认只返回default名称空间中的ServiceAccount。

查看所有名称空间的account,下面的输出省略部分内容

创建自己的ServiceAccount

可以创建自己的ServiceAccount,创建方法很简单

如果没有指定名称空间,默认在default中创建。ServiceAccount创建的同时会自动创建secrets,名称以account的名称为前缀

ServiceAccount中的token

前面我们说过,ServiceAccount中主要用于保存JWT的token(不同ServiceAccount token不一样),那么怎样查看呢?很简单

输出的内容告诉我们,default ServiceAccount对应的token名称是default-token-7j4cw,拿到token的名称,就可以查看这个token,token属于Kubernetes中的secrets资源

最后一行就是具体token的内容,可以复制这个token到JWT官方解码,地址是JWT Debugger

Pod和ServiceAccount

每一个Pod创建的时候,都会被分配到指定的ServiceAccount下面,通常是default,也可以在编写Pod的manifest文件的时候指定。

例如

其中就可以看到它的ServiceAccount确实是default。

另外,在Pod创建的时候,相关的认证文件会被以volume的形式挂载进Pod,目的是方便在Pod里访问API SERVER(例如kubernetes的dashboard),下面的内容来自已经部署的Pod。

测试ServiceAccount中的token

token用于验证用户的合法性,现在我们使用default ServiceAccount的token进行测试。前面已经介绍了如何取得token,这里不再说明。

首先第一次向API SERVER发送请求,这次请求没有递交token

服务器响应的是匿名用户禁止访问

接下来进行第二次请求,这次请求包括token

注意curl中使用的请求头:"Authorization: Bearer $TOKEN",这是JWT认证的固定格式。

服务器响应的信息虽然还是是403,但是已经正确识别出了用户信息system:serviceaccount:default:default,证明认证已经通过。至于为什么是403,原因就是接下来要说的授权。

授权

当认证通过,下一步要做的就是授权,授权决定一个用户可以干什么。Kubernetes可以配置多种授权方式,其中目前使用的是RBAC(Role Based Access Control)。RBAC涉及几个重要概念,它们是:

  • Role
  • RoleBinding
  • ClusterRole
  • ClusterRoleBinding

首先必须清楚一点:授权离不开认证,授权是基于ServiceAccount的。Role可以理解为权限(例如get,list,update,delete,add),它决定了ServiceAccount可以干什么,RoleBinding用于把Role绑定到指定的ServiceAccount。

ClusterRole和ClusterRoleBinding的作用一样,不同的是,它们的作用域是整个集群,而Role和RoleBinding的作用域是namespace。

下图是Role的绑定

kubernetes rbac

从上图可知,Role不仅可以和ServiceAccount绑定,还可以和用户、组绑定。

创建Role

通过kubectl create role来创建role,由于default ServiceAccount不允许执行任何操作

现在我们尝试开放它的权限,允许它访问Pod的列表。

创建RoleBinding

RoleBinding的创建和Role的创建差不多

测试效果

现在我们已经为默认的ServiceAccount添加了权限,现在它应该可以获取所在名称空间里的pod列表。

curl测试:

下面使用的token依然是默认的。

转载请注明:Pure nonsense » Kubernetes认证和授权

喜欢 (3)