在 Pod 中,访问 Kubernetes API 接口,并控制访问权限
问题描述
在实际的应用场景中,我们的应用程序运行在集群中(以 Pod 的形式存在),并且该应用程序将在集群中进行创建资源、修改资源、删除资源等等操作。
在 Pod 中,访问 Kubernetes API 的方法有很多,而通过 Client Libraries(程序类库)是官方推荐的做法,也是我们接下来将要学习的方法。
该笔记将记录:在 Pod 中,通过 Client Libraries 访问 Kubernetes API(管理 Kubernetes 集群)的方法,以及相关问题的解决办法。
解决方案
接下来我们将介绍例如,如果创建 ServiceAccount 对应用程序进行访问控制,只允许其查看 Pod 资源(即查看 Pod 列表和详细信息)
第 1 步、创建 ServiceAccount 资源
而这其中最大的问题是,如何进行合理的授权,即对于既定的用户或应用程序,如何允许或拒绝特定的操作?—— 通过 ServiceAccount 实现。
# kubectl create serviceaccount myappsa
第 2 步、引用 ServiceAccount 资源
定义一个 Pod,使用为 myappsa 的 ServiceAccount 资源:
1 | kubectl apply -f - <<EOF |
ServiceAccount 是种身份,而在 Pod 中引用 ServiceAccount 则是将这种身份赋予 Pod 实例。而接下来的任务是给 ServiceAccount 这种身份赋予各种权限 —— 具体的做法便是将各种角色(Role)绑定(RoleBinding)到这个身份(ServiceAccount)上。
第 3 步、创建 Role 资源
定义名为 podreader 的 Role 资源,并定义其能够进行的访问操作:
1 | kubectl apply -f - <<EOF |
第 4 步、将 Role 与 ServiceAccount 绑定
1 | kubectl apply -f - <<EOF |
第 5 步、访问 Kubernetes API 测试
通过 Service Account 相关信息来访问资源:
1 | # 通过我们运行的 kubectl 容器访问 |
第 6 步、通过客户端类库访问集群
以 Java 客户端为例:
如果需要在集群内部访问集群:
1)按照如上示例,定义 ServiceAccount 资源,
2)并参照 InClusterClientExample.java 示例代码
如果需要在集群外部访问集群:
1)按照如上示例,在远端集群定义 ServiceAccount 资源,
2)并参照 java/KubeConfigFileClientExample.java 示例代码
补充说明
访问集群级别的资源
上面是命名空间内的访问控制设置,因为上述使用的是 Role 和 RoleBinding 资源,而对于集群范围的访问控制应该使用 ClusterRole 和ClusterRoleBinding 命令。
替换 kind 为 ClusterRole 及 ClusterRoleBinding 即可,其他部分与 Role、RoleBinding 类似,这里不再赘述。
通过 ServiceAccount 生成 Kubeconfig 的方法
如果需要使用 kubeconfig 文件,可通过 ServiceAccount 资源来创建,参考 How to create a kubectl config file for serviceaccount 讨论。
简而言之,kubeconfig 的 user 部分为 token,而非 client-certificate-data 与 client-key-data 参数。
参考文献
Accessing the Kubernetes API from a Pod | Kubernetes
dashboard - How to bind roles with service accounts - Kubernetes - Stack Overflow
A Quick Intro to the Kubernetes Java Client | Baeldung