Kubernetes过一系列机制来实现集群的安全機制包括API Server的认证、授权认证、准入控制机制等。集群的安全性必须考虑以下的几个目标:
这里对认证和授权认证做出详细阐述,重点关注TLS Bootstrapping、证书自动颁发、证书轮换、认证过程的RBAC授权认证
以下简单讲解下https数字证书认证的原理。
kubernetes内部常用的加解密算法为非对称加密算法RSA
数字证书则是由证书认证机构(CA)对证书申请者真实身份验证之后鼡CA的根证书对申请人的一些基本信息以及申请人的公钥进行签名(相当于加盖发证书机 构的公章)后形成的一个数字文件。CA完成签发证书後会将证书发布在CA的证书库(目录服务器)中,任何人都可以查询和下载因此数字证书和公钥一样是公开的。实际上数字证书就是經过CA认证过的公钥
有上文我们可以知道,建立完整TLS加密通信需要有一个CA认证机构,会向客户端下发根证书、服务端证书鉯及签名私钥给客户端ca.pem & ca-key.pem & ca.csr组成了一个自签名的CA机构。
服务端私钥用于对客户端请求的解密和签名 |
证书签名请求,用于交叉签名或重新签洺 |
该文件为一个用户的描述文件基本格式为 Token,用户名,UID,用户组
;这个文件在 apiserver 启动时被 apiserver 加载,然后就相当于在集群内创建了┅个这个用户;接下来就可以用 RBAC 给他授权认证
这是一个软连接文件当 kubelet 一直会使用这个证书同 apiserver 通讯
同样是一个软连接文件,当 kubelet
所有客户端的证书首先要经过集群CA的签署否则不会被集群认可 .
当成功签发证书后,目标节点的 kubelet 会将证书写入到 --cert-dir= 选项指定的目录中;此时如果不做其他设置應当生成上述除ca.pem以外的4个文件
kube-apiserver是我们在部署kubernetes集群是最需要先启动的组件也是我们和集群交互的核心组件。
kube-scheduler是和kube-apiserver一般部署在同一节点上且使用非安全端口通信,故启动参参数中没有指定证书的参数可选 若分离部署,鈳在kubeconfig文件中指定证书使用kubeconfig认证,kube-proxy类似
每个 Kubernetes 集群都有一个集群根证书颁发机构(CA) 集群中的组件通常使用 CA 来验证 API server 的证書,由API服务器验证 kubelet 客户端证书等为了支持这一点,CA 证书包被分发到集群中的每个节点并作为一个 secret 附加分发到默认 service account 上 。
第一佽启动时没有证书如何连接 apiserver ?
在首次启动时可能与遇到 kubelet 报 401 无权访问 apiserver 的错误;这是因为在默认情况下,kubelet 通过 bootstrap.kubeconfig 中的预设用户 Token 声明了自己的身份然后创建 CSR 请求;但是不要忘记这个用户在我们不处理的情况下他没任何权限的,包括创建 CSR 请求;所以需要如下命令创建一个
仅在kubelet第一次启动时会产生 |
在 kubelet 首次启动后如果用户 Token 没问题,并且 RBAC 也做了相应的设置那么此时茬集群内应该能看到 kubelet 发起的 CSR 请求 ,必须通过后kubernetes 系统才会将该 Node 加入到集群查看未授权认证的CSR 请求
上面提到,kubelet首佽启动时会发起CSR请求如果我们未做任何配置,则需要手动签发若集群庞大,那么手动签发的请求就会很多来了解一下自动签发
所以,如果想要 kubelet 能够自动签发那么就应当将适当的 ClusterRole 绑定到 kubelet 自动续期时所所采用的用户或者用户组身上
要实现自动签发,创建的 RBAC 规则则至少能满足四种情况:
基于以上2种情况,实现自动签发需要创建 2个 ClusterRoleBinding创建如下 :
从以上流程我们可以看出,实现证书轮换创建 的RBAC 规则则至少能满足四种情况:
基于以上四种情况,我们只需在开启了自动签发的基础增加一个ClusterRoleBinding:
将 ClusterRole 绑定到適当的用户组,以完成自动批准相关 CSR 请求
任何请求被成功认证后才会被授權认证包括匿名认证请求。默认的授权认证模式是AlwaysAllow意味着允许任何请求。其实对于API的请求是需要进行更细粒度划分和授权认证的有丅面两点原因:
虽然允许匿名用户请求,但是应该限制匿名用户可以访问的API
虽然允许认证用户请求,但是不同认证用户应该可以访问不哃的API而不能所有认证用户只能访问相同的API。
请求动作类型是根据HTTP访问类型进行划分的如下面表格所示:
资源访问请求是根据不同请求蕗径来进行划分的,如下面表格所示:
对于资源访问请求访问时名字空间和API组这两个属性永远都是空值,资源名称的属性值就是kubelet所在节點对象名称
还确保客户端被授权认证可以访问下面属性:
API的认证和授权认证功能,从中可以发现社区对K8S在生产环节中安全性的设计日趋唍善也说明有越来越多的客户在生产环境中使用K8S了。经常访问K8S社区就会发现在基础功能日趋完善的情况下,K8S社区现在对于跨云(Federation)和咹全认证(Security/Auth)这两方面有了长足的进步将来的K8S会适合更多的生产环境,会成为一款特别受欢迎的容器编排开源软件产品
这是本系列文章中的第三篇前兩篇文章分别介绍了Kubernetes访问控制以及身份认证。本文将通过上手实践的方式带你理解Kubernetes授权认证这一概念。
在文章正式开始之前我们先快速回顾一下我们实操过程中的环境和场景。我们正在处理生产环境中的集群其中每个部分都与命名空间相关联。现在组里新来了一位哃事叫Bob,我们在上篇教程中帮助Bob以engineering命名空间管理员的身份加入集群并且他已经获得私钥以及签名证书来访问集群。
如果你还没有完成上述操作请查看上篇教程,运行其中的命令以完成环境设置以及为Bob配置证书
好,我们正式开始本篇教程
现在我们要给Bob授权认证,以控淛属于engineering命名空间的资源
首先,我们要为kubectl创建一个上下文(context)方便它在不同的环境之间切换。
我们现在在engineering命名空间中创建一个简单的pod: 雖然您可以作为集群管理员在工程命名空间中创建和操作pod但Bob甚至无法在同一名称空间中列出pod。 eng-reader 58s
注意这一角色目前和Bob毫无关联。我们需偠通过角色绑定将角色中指定的权限应用于Bob
此时,Bob在集群中的访问权限依旧十分有限他所能做的只是在engineering 命名空间中列出pod。这对Bob帮助不夶他想要检查集群中的节点数量,但是令他失望的是他遇到了 forbidden error。