这是本系列的最后一篇文章,前面我们了解了访问控制中的基本概念以及身份认证和授权的具体操作,本文我们将进一步了解访问控制中的 service account。
Kubernetes 中有用户和 service account 的概念,可用于访问资源。用户与密钥和证书相关联用于验证 API 请求,使用其中一个配置方案对在集群外部发起的任何请求进行身份验证。最常见的方案是通过 X.509 证书进行身份认证请求。有关创建证书和将证书与用户关联的信息,请参阅Kubernetes身份验证教程。
请记住,Kubernetes 不维护数据库或用户和密码的配置文件。相反,它希望在集群之外进行管理。通过身份验证模块的概念,Kubernetes 可以将身份验证委派给第三方,如 OpenID 或 Active Directory。
尽管 X.509 证书可用于身份验证的外部请求,但 service account 可以用于验证集群中运行的进程。此外,service account 与进行 API server 内部调用的 pod 相关联。
每个 Kubernetes 安装都有一个默认的 service account,它与每个正在运行的 pod 相关联。类似地,为了使 pod 能够调用内部 API Server 端点,有一个名为 Kubernetes 的 ClusterIP 服务,它与默认的 service account 一起使内部进程可以调用 API 端点。
kubectl get serviceAccounts
复制代码
NAME SECRETS AGE
default 1 122m
复制代码
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 443/TCP 123m
复制代码
请注意,这个 service account 指向嵌在每个 pod 内部的 secret。这一 secret 包含 API Server 所需的令牌。
NAME TYPE DATA AGE
default-token-4rpmv kubernetes.io/service-account-token 3 123m
复制代码
当我们开始调度 pod 并且访问它时,一切都变得明朗起来。我们将使用 curl 命令启动一个基于 BusyBox 的 pod。
kubectl run -i --tty --rm curl-tns --image=radial/busyboxplus:curl
复制代码
kubectl run --generator=deployment/apps.v1 is DEPRECATED and will be removed in a future version. Use kubectl run --generator=run-pod/v1 or kubectl create instead.
If you don't see a command prompt, try pressing enter.
[ root@curl-tns-56c6d54585-6v2xp:/ ]$
复制代码
当我们在 BusyBox shell 中时,让我们尝试访问 API Server 端点。
[ root@curl-tns-56c6d54585-6v2xp:/ ]$ curl https://kubernetes:8443/api
复制代码
由于请求缺少身份验证令牌,因此不会产生任何结果。让我们看看如何检索可以嵌入 HTTP 头部的令牌。
如之前所讨论的,令牌作为一个 secret 安装在 pod 里。查看/var/run/secrets/kubernetes.io/serviceaccount 来查找令牌。
[ root@curl-tns-56c6d54585-6v2xp:/ ]$ cd /var/run/secrets/kubernetes.io/serviceaccount
复制代码
[ root@curl-tns-56c6d54585-6v2xp:/tmp/secrets/kubernetes.io/serviceaccount ]$ ls
ca.crt namespace token
复制代码
让我们来设置一些环境变量以简化 curl 命令。
CA_CERT=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
NAMESPACE=$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace)
复制代码
以下 curl 命令请求在默认命名空间中的服务。让我们看看我们能否从 API Server 中获得回应。
[ root@curl-tns-56c6d54585-6v2xp:~ ]$ curl --cacert $CA_CERT -H "Authorization: Bearer $TOKEN" "https://kubernetes/api/v1/namespaces/$NAMESPACE/services/"
复制代码
{
"kind": "Status",
"apiVersion": "v1",
"metadata": {
},
"status": "Failure",
"message": "services is forbidden: User \"system:serviceaccount:default:default\" cannot list resource \"services\" in API group \"\" in the namespace \"default\"",
"reason": "Forbidden",
"details": {
"kind": "services"
},
"code": 403
}
复制代码
然而,默认的 service account 并没有足够的权限来检索在同一命名空间内的服务。
请记住,Kubernetes 遵循封闭开放的惯例,这意味着在默认情况下用户和 service account 没有任何权限。
为了满足这一请求,我们需要创建一个角色绑定,将默认 service account 和适当的角色相关联。这一步与我们将角色绑定到 Bob 的方式类似,后者授予他列出 pod 的权限。
退出 pod 并且运行以下命令,为默认 service account 创建一个角色绑定。
kubectl create rolebinding default-view \
--clusterrole=view \
--serviceaccount=default:default \
--namespace=default
复制代码
rolebinding.rbac.authorization.k8s.io/default-view created
复制代码
以上命令将默认 service account 与集群角色视图相关联,该角色视图使 pod 能够列出资源。
如果你十分好奇,想看所有可用的集群角色,运行命令:kubectl get clusterroles。
让我们再次启动 BusyBox pod 并且访问 API Server。
kubectl run -i --tty --rm curl-tns --image=radial/busyboxplus:curl
复制代码
kubectl run --generator=deployment/apps.v1 is DEPRECATED and will be removed in a future version. Use kubectl run --generator=run-pod/v1 or kubectl create instead.
If you don't see a command prompt, try pressing enter.
[ root@curl-tns-56c6d54585-2cx44:/ ]$
复制代码
CA_CERT=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
NAMESPACE=$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace)
复制代码
curl --cacert $CA_CERT -H "Authorization: Bearer $TOKEN" "https://kubernetes/api/v1/namespaces/$NAMESPACE/services/"
复制代码
{
"kind": "ServiceList",
"apiVersion": "v1",
"metadata": {
"selfLink": "/api/v1/namespaces/default/services/",
"resourceVersion": "11076"
},
"items": [
{
"metadata": {
"name": "kubernetes",
"namespace": "default",
"selfLink": "/api/v1/namespaces/default/services/kubernetes",
"uid": "b715a117-6be1-4de0-8830-45bddcda701c",
"resourceVersion": "151",
"creationTimestamp": "2019-08-13T09:45:27Z",
"labels": {
"component": "apiserver",
"provider": "kubernetes"
}
},
"spec": {
"ports": [
{
"name": "https",
"protocol": "TCP",
"port": 443,
"targetPort": 8443
}
],
"clusterIP": "10.96.0.1",
"type": "ClusterIP",
"sessionAffinity": "None"
},
"status": {
"loadBalancer": {
}
}
}
]
}
复制代码
您可以随意为默认 service account 创建其他绑定,以检查 RBAC 如何扩展到 pod。
关于 Kubernetes 身份认证与授权系列文章到此结束,我们讨论了身份验证,授权和 Service account 的基本概念,希望能对你有所帮助。
评论