伴随着Kubernetes的迅猛发展,depolying、scaling和managing containeried applications等概念在开发、运维管理等相关工做人员间普遍流传。不管技术概念多么的新颖,一项工程技术在大规模应用实践生产环境前,首先须要考量安全问题。所以生产环境安所有署的相关问题也是kubernetes最重要的内容之一。Kubernetes对用户和应用请求认证和受权管理的底层逻辑也是相关工做人员最应该掌握的硬核知识。数据库
这一系列文档都是关于Kubernetes集群内部pods等资源对外部请求的认证与受权的管以及如何使用roles和role binding控制Kubernetes内部资源的访问权限。json
下面的示例都是运行在最新版的Kubernetes集群中,固然你也可使用运行在本地的Minikube做为实验环境bootstrap
Kubernetes一切资源(Nodes,Labels,Pods,Deployments,Services,Secrets,Configmaps,Ingress等)都是对象,Kubernetes经过API Service控制着这些资源的访问权限。经过使用暴露给外部用户REST API接口执行对Kubernetes资源的CRUD操做。api
API Server是Kubernetes内部的核心模块之一,扮演者集群网关的角色。Kubernetes内部模块(诸如:Kubelet, Scheduler, Controller) 都是经过API Service进行调度和调谐。分布式键值对数据库(etcd)也只能经过API Server访问。安全
Kubectl素有集群管理的瑞士军刀之称,它操做Kubernetes的全部请求最终都会发送到Api Server。其它相似的工具或者模块也是经过API Server操做Kubernetes的资源对象。bash
在Kubernetes对象被操做前,Kubernetes集群使用API Server验证请求的合法性。发送请求的客户端使用X.509认证对发出的请求进行加密,加密使用X.509认证的CA certificate和client certificate都是Kubectl从本地获取的。app
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: DATA+OMITTED
server: https://35.203.146.149:6443
name: kubernetes-the-hard-way
contexts:
- context:
cluster: kubernetes-the-hard-way
user: admin
name: kubernetes-the-hard-way
current-context: kubernetes-the-hard-way
kind: Config
preferences: {}
users:
- name: admin
user:
client-certificate: /Volumes/BOOTCAMP/dev/gcp/gcloud-k8s-config/script/admin.pem
client-key: /Volumes/BOOTCAMP/dev/gcp/gcloud-k8s-config/script/admin-key.pem
复制代码
ca.pem(介于安全考量,我并未配置在Kubectl Config中)本地认证中心须要一个CA证书。 显而易见,Kubectl正是经过上下文配置中的certificates和keys加密请求。运维
咱们可否经过curl命令向API Server发送请求吗?固然能够了!curl
除了须要相关的CA加密文件,咱们也要将token按照base64编码后嵌入到请求体的header中。分布式
kubectl config view -o jsonpath='{"Cluster name\tServer\n"}{range .clusters[*]}{.name}{"\t"}{.cluster.server}{"\n"}{end}'
复制代码
export CLUSTER_NAME="kubernetes-the-hard-way"
复制代码
APISERVER=$(kubectl config view -o jsonpath="{.clusters[?(@.name==\"$CLUSTER_NAME\")].cluster.server}")
复制代码
下面的命令将获取default service account中的token:
TOKEN=$(kubectl get secrets -o jsonpath="{.items[?(@.metadata.annotations['kubernetes\.io/service-account\.name']=='default')].data.token}"|base64 -D)
复制代码
如今咱们可使用curl命令请求api server:
curl -X GET \
--cacert /Volumes/BOOTCAMP/dev/gcp/gcloud-k8s-config/script/ca.pem \
--header "Authorization: Bearer $TOKEN" \
$APISERVER/version
复制代码
像上面所说的那样,全部的外部用户或者pods在操做Kubernetes内部对象前都须要对API Server进行认证。
当一个合法的请求到达API Server后,系统将会经过三层认证验证对请求的资源是否有操做权限。
在请求被TLS认证后,API Server将使用Kubernetes中已经开启的一个或多个认证模块对它进行相关的认证操做。相关的认证模块在集群建立时就已经指定,多个认证模块会被放在队列中,只有上一个认证模块成功认证后,才会被下一个模块进行认证。
Kubernetes中的认证模块主要有client certificates、password、plain tokens、bootstrap tookens和JWT tokens。Clinet certifiactes是集群中默认也是最多见的认证模块。关于认证模块的更多内容,你能够参照相关模块文档。
Kubernetes并未维护专门的用户表或者认证用户的画像,而是经过认证X.509认证文件或者传递给认证模块的token。理解这一点后就能够很容易明白Kubernetes经过将OpenID,Github甚至LDAP协议集成到Kubernetes认证体系的原理。
一旦API请求被认证后,下一步将会验证请求是否被受权操做Kubernetes内部资源,这一行为发生在请求验证流程中的第二步。
在受权验证时,Kubernetes将主要考查请求的用户名、请求的行为和请求将会影响的对象。用户名是从请求的header中提取的,请求行为是对应CRUD操做中的Http行为(GET,PUT,DELETE等),请求将会影响的对象是Kubernetes内部的Pods,Service等。
Kubernetes对资源对象的受权策略遵循由关到开的哲学,这就意味着若是想要访问资源必须配置相关的受权策略。
像认证同样,受权的行为也能够经过一个或多个受权模块配置权限,诸如ABAC,RBAC和Webhook中。在管理员建立集群时就已经将相应的受权模块集成到Kubernetes API Server中了。若是Kubernetes集群启用了多个受权模块,API Server会逐一使用受权模块对请求进行验证。只有全部的模块验证经过后,请求才能经过受权的验证,不然请求将会被拒绝(Http的status code是403)。关于受权模块的更多内容,你能够参照相关模块文档。
请求经过认证和受权后最后来到准入控制,像认证和受权同样,准入控制器也是插件式模块。
与认证和受权不一样的是准入控制可能会修改请求资源对象。除了读取资源对象,准入控制能够对建立、删除、更新和代理资源对象的请求发生了做用。例如准入控制拦截建立存储数据卷(PVC)请求,指定PVC资源的存储类型。还能够在建立Pod时强制从新拉取镜像。关于更多准入控制模块,参照Kubernetes文档。
在准入控制器处理的过程当中,请求一旦被任何一个控制器拒绝,请求马上就会被Kubernetes拒绝。只有请求顺利经过全部的准入控制器后,请求才具有操做相应资源对象的权限。
在下一篇文章中,我将会进一步讲解如何建立用户和认证用户,加油吧小伙伴!
文章翻译自A Primer on Kubernetes Access Control,行文时略有删减