Java程序调kubernetes(k8s1.30.7)core API简朴示例,并解决403权限验证问题 ...

打印 上一主题 下一主题

主题 826|帖子 826|积分 2480

简朴记录问题
一、问题描述

希望通过Java程序利用Kubernetes提供的工具包实现对Kubernetes集群core API的调用,但是在高版本上遇见权限验证问题4xx。
  1.         <dependency>
  2.             <groupId>io.kubernetes</groupId>
  3.             <artifactId>client-java</artifactId>
  4.             <version>20.0.0</version> <!-- 请根据需要选择合适的版本 -->
  5.         </dependency>
复制代码
权限验证的问题:
  1. {
  2.   "kind": "Status",
  3.   "apiVersion": "v1",
  4.   "metadata": {},
  5.   "status": "Failure",
  6.   "message": "pods is forbidden: User "system:anonymous" cannot list resource "pods" in API group "" at the cluster scope",
  7.   "reason": "Forbidden",
  8.   "details": {
  9.     "kind": "pods"
  10.   },
  11.   "code": 403
  12. }
复制代码
大意是system:anonymous匿名用户被禁止去访问相应集群的pods资源信息。
Kubernetes支持许多不同的身份验证方案,这些方案险些总是在集群外部实现,包罗X.509证书,根本身份验证,bearer令牌,用于通过可信身份提供商进行身份验证的OpenID Connect(OIDC)等。利用API服务器上的相关配置选项可以启用多种方案,因此请务必为筹划利用的身份验证方案提供这些选项。比方,X.509客户端证书身份验证须要包罗一个或多个CA证书( -client-ca-file)文件路径。须要记住的一点是,默认情况下,任何未通过其中一种身份验证方案验证的API请求都会被视为匿名请求。匿名用户(system:anonymous)默认被拒绝访问任何 API。即使是根本的 API(如列出 Pods),也须要显式分配权限,现阶段,所有 API 调用都须要颠末明确的认证和授权
查看一下集群的默认验证模式设置:
  1. grep -C3 'authorization-mode' /etc/kubernetes/manifests/kube-apiserver.yaml
复制代码

默认开启的是RBAC(基于角色的访问控制)。
各类模式以及下方各类k8s资源的先容可参见:
Kubernetes K8S之鉴权RBAC详解 - 踏歌行666 - 博客园
二、解决方案

我须要针对集群中相关资源(pods lists)通过Java client进行增删改查操纵,那么最直接快速的方式就是创建一个具有集群超等用户权限的用户,并将其对应的Key用于Java client,进行API的访问操纵。
Prepare:查看clusterrole

clusterrole是集群范围的角色,用于管理整个集群中的资源。
通过指令
  1. kubectl get clusterroles
复制代码
查看到集群下有众多的clusterrole

其中有cluster-admin角色,我们可以通过如下指令查看其权限:
  1. kubectl get clusterrole cluster-admin -o yaml
复制代码

我们能看出它是 Kubernetes 内置的超等权限角色,其中rules部门均为通配符,表明该角色对所有 API 组的所有资源具有所有操纵权限,即为管理员提供对集群所有资源的完全控制。
具体操纵

1.将用户与cluster-admin角色相绑定

  1. kubectl create clusterrolebinding admin-access --clusterrole=cluster-admin --user=apiinvoker
复制代码

2.创建serviceaccount

  1. #serviceaccount 后接名称  
  2. kubectl create serviceaccount apiinvoker -n kube-system
复制代码

2.将serviceaccount绑定到cluster-admin

  1. kubectl create clusterrolebinding admin-sa-binding --clusterrole=cluster-admin --serviceaccount=kube-system:apiinvoker
复制代码

3.创建Token

分为临时的(选择一)以及永世的(选择二)两种方式。
选择一

 下述代码能直接天生并显示token,但是该方式的token是存在有效期的。
  1. # 需要设置有效期 添加参数--duration 其他参数使用指令kubectl -n kube-system create token --help查看
  2. kubectl -n kube-system create token apiinvoker
复制代码
选择二

要创建永世有效的Token须要利用Secret方式
在创建serviceaccount之后为其手动创建Secret,并将其与serviceaccount绑定。
1. 创建apiinvoker-token.yaml
  1. apiVersion: v1
  2. kind: Secret
  3. metadata:
  4.   name: apiinvoker-token
  5.   namespace: kube-system
  6.   annotations:
  7.     kubernetes.io/service-account.name: "apiinvoker" # 绑定到服务账户 改成你自定义的serviceaccount
  8. type: kubernetes.io/service-account-token
复制代码
2. 运行yaml文件
  1. kubectl apply -f apiinvoker-token.yaml
复制代码
4.获取serviceaccount的Token

  1. kubectl -n kube-system describe secret apiinvoker-token
复制代码

 这样就能在Java client利用这个token进行API的调用了。
5.编写Java程序代码示例

在pom中添加依赖:
  1.         <dependency>
  2.             <groupId>io.kubernetes</groupId>
  3.             <artifactId>client-java</artifactId>
  4.             <version>20.0.0</version> <!-- 请根据需要选择合适的版本 -->
  5.         </dependency>
复制代码
运行如下示例代码:
  1. package com.yang.collector;
  2. import io.kubernetes.client.openapi.ApiClient;
  3. import io.kubernetes.client.openapi.Configuration;
  4. import io.kubernetes.client.openapi.apis.CoreV1Api;
  5. import io.kubernetes.client.openapi.models.V1NamespaceList;
  6. import io.kubernetes.client.openapi.models.V1PodList;
  7. import java.io.IOException;
  8. public class K8SAPITest {
  9.     public static void main(String[] args) {
  10.         try {
  11.             ApiClient client = new ApiClient();
  12.             client.setBasePath("https://k8s-master IP:6443"); // 集群的 API 地址
  13.             client.setApiKey("Bearer "+"生成的Token");
  14. //            client.setDebugging(true);
  15.             client.setVerifyingSsl(false);
  16.             Configuration.setDefaultApiClient(client);
  17.             // 将配置设置为默认的 API 客户端
  18.             io.kubernetes.client.openapi.Configuration.setDefaultApiClient(client);
  19.             // 创建 CoreV1Api 实例
  20.             CoreV1Api api = new CoreV1Api();
  21.             // 获取所有命名空间中的 Pod 列表
  22.             CoreV1Api.APIlistPodForAllNamespacesRequest list = api.listPodForAllNamespaces();
  23.             V1PodList execute = list.execute();
  24.             // 遍历并打印每个 Pod 的信息
  25.             execute.getItems().forEach(v1Pod -> {
  26.                 System.out.println(v1Pod.toJson());
  27.             });
  28.         } catch (Exception e) {
  29.             e.printStackTrace();
  30.         }
  31.     }
  32. }
复制代码
结果如下:

 说明调用成功,克服权限验证问题。
:固然在现实的生产情况中不建议直接将 超等权限(如 cluster-admin) 交给 Java 程序(或任何外部程序)。这样做存在高安全风险,大概导致集群被误操纵或恶意利用。
但是利用 服务账户(ServiceAccount) 的 Token的情势进行细粒度权限控制API的调用是保举的,本文直接赋值所有资源的所有操纵权限十分不可取,仅供学习参考。
保举方式:在生产情况中,所有权限分配都应该基于现实需求,授予 Java 程序仅须要的权限即可。创建自界说Role或ClusterRole,仅授予程序须要的权限,再通过Rolebinding或ClusterRoleBinding将权限绑定到服务账户,再将此token交给API调用程序。token的利用也不建议永世有效,通过利用kubectl create token动态天生短期 Token,供程序动态获取利用更为安全,避免了长期token的泄露风险。
参考文献

1.Kubernetes K8S之鉴权RBAC详解 - 踏歌行666 - 博客园
2.API 访问控制 | Kubernetes
3.Kubernetes集群组件的安全_手机搜狐网
 
 

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

南七星之家

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表