这次聊聊mesos+k8s的安全性,还有多租户。

Kubernetes

鉴权和授权

身份认证分为鉴权(authentication)和授权(authorization)。前者是看你能不能登录,后者是看你登录后有什么权限。Kubernetes的1.2版支持以下5种鉴权方式:

  • CA认证(Client certificate authentication):就是基于SSL证书的认证,基本概念可以参考证书的那些事儿
  • Token文件认证(Token File):用一个CSV文件指定用户名、用户id和组名,组名是为了给下面的授权使用的
  • OpenID认证(OpenID Connect ID Token):基于第三方的OpenID
  • 基本认证(Basic authentication):也是CSV文件,指定了用户名、密码和用户id
  • Keystone认证(Keystone authentication):基于openstack的身份认证服务Keystone

身份验证通过,接下来就是授权。Kubernetes的1.2版支持以下4种授权方式:

  • 总是拒绝(AlwaysDeny):这个一般用于测试
  • 总是允许(AlwaysAllow):只要能登录进来,就有所有权限
  • 用户配置(ABAC):基于用户授权配置,可以对资源(比如pod、service等)和命名空间设置用户/组的只读或可写权限,多租户管理的时候很有用
  • 钩子(Webhook):也能实现类似用户配置的粒度,只不过是基于一个远程的REST服务

账户

用户账户(User account)和服务账户(Service account)在kubernetes里是不同的两个东西。用户账户是给人使用的,不可重复,目前创建的时候需要重启API Server。而服务账户是给pod里的容器使用的,在不同的命名空间中可以重复,比较轻量级一点,可以动态创建。如果创建pod的时候指定了服务账户,那就没的说,直接用就好了;但要是没有指定,k8s会自动为pod指定一个指定命名空间的名为default的服务账户。它是在创建命名空间时自动生成的。

秘密

想象一个正常的开发场景,比如tomcat容器访问mysql,攻城狮们理所当然地把mysql的密码存放在tomcat容器里。Kubernetes提供了秘密(Secret)这个对象用来保存这样的敏感信息。需要用的时候像挂卷一样把秘密挂载到pod里就好了,密码就不需要直接写了。有了秘密,妈妈再也不用担心我的霸气侧漏了。实际上,上面提到的服务账户本质上就是秘密的集合。

多租户

Kubernetes本身支持用不同的命名空间来区分多租户,它们之间不会相互干扰。还有一个系统使用的命名空间叫做kube-system。但是系统的资源是恒定的,如果有个租户打算扶着墙进来,再扶着墙出去,是不是其他人都没得吃了?Kubernetes有一个资源限额(Resource Quota)的概念,可以用于命名空间上。目前可以限制的资源有CPU和内存。除了资源,在pod、rc、服务等的数量上也可以进行限制。这样就能很方便地像现在的CaaS那样卖实例吧。

Mesos

Mesos默认使用CRAM-MD5鉴权。最典型的用法是master启动的时候,指定一个文件,里面含有用户名(mesos里叫principal)和密码(mesos里叫secret)。只有通过鉴权的framework和slave才能注册进来。授权是通过ACLs(Access Control Lists)来实现的,目前可以支持以下十种行为的授权:

  • register_frameworks: 注册framework
  • run_tasks: 运行任务
  • teardown_frameworks: 解除framework
  • set_quotas: 设置配额
  • remove_quotas: 移除配额
  • reserve_resources: 保留资源
  • unreserve_resources: 解除保留资源
  • create_volumes: 创建持久化卷
  • destroy_volumes: 删除持久化卷
  • update_weights: 更新权重

Kubernetes的这些多租户的概念,mesos基本上也都有。就是在名称和具体功效上略有差别。比如,mesos的角色(role)就像是k8s的命名空间一样,指定role的framework只能使用特定role的mesos slave。在资源限额上,mesos支持配额权重(Weights)。配额管的是保留资源以供未来使用,权重管的是角色分配的资源比例。可惜的是对角色和权重的修改都必须重新启动mesos master,而配额可以通过http请求动态修改。