网站首页 > java教程 正文
最近项目需要开发一个功能,需要监控 k3s 集群上每个应用的状态。因为 k3s 和 k8s 核心功能是一样的,我们可以通过 k8s 的 API 得到这些信息,而且官方也提供了 io.kubernetes 的 client-java ,所以使用这个 SDK 包就能通过 java 代码的方式获取到数据。
那么事不宜迟,马上动手开发吧!
首先,当然是在 pom.xml 引入 io.kubernetes 的 client-java。
<dependency>
<groupId>io.kubernetes</groupId>
<artifactId>client-java</artifactId>
<version>10.0.0</version>
</dependency>
然后是初始化API的客户端,有三种方式。
第一种最简单的方式:使用 ClientBuilder.cluster().build() 直接进行初始化
@Slf4j
@Component
public classK3sClient{
/**
* 初始化API客户端
*/
@PostConstruct
privatevoidsetDefaultApiClient()throws IOException {
// 自动获取配置初始化
ApiClient apiClient = ClientBuilder.cluster().build();
// 创建操作类
Configuration.setDefaultApiClient(apiClient);
}
/**
* 获取所有的Pod
*
* @return podList
*/
public V1PodList getAllPodList(){
CoreV1Api api = new CoreV1Api();
try {
V1PodList list = api.listPodForAllNamespaces(null, null, null, null, null, null, null, null, null, null);
return list;
} catch (ApiException e) {
log.error("获取podlist异常:" + e.getResponseBody(), e);
}
return null;
}
}
第二种方式:读取 k3s 的配置文件进行初始化 ApiClient
@Slf4j
@Component
public classK3sClient{
//pod内部指定存放k3s配置文件的路径
@Value("${k3sConf.path}")
private String k3sConfigPath;
/**
* 初始化API客户端
*/
@PostConstruct
privatevoidsetDefaultApiClient()throws IOException {
KubeConfig conf = KubeConfig.loadKubeConfig(new FileReader(k3sConfigPath));
ApiClient apiClient = ClientBuilder.kubeconfig(conf).build();
// 创建操作类
Configuration.setDefaultApiClient(apiClient);
}
/**
* 获取所有的Pod
*
* @return podList
*/
public V1PodList getAllPodList(){
CoreV1Api api = new CoreV1Api();
try {
V1PodList list = api.listPodForAllNamespaces(null, null, null, null, null, null, null, null, null, null);
return list;
} catch (ApiException e) {
log.error("获取podlist异常:" + e.getResponseBody(), e);
}
return null;
}
}
k3s 集群的配置文件可以从宿主机挂到Pod内部的指定路径,最好挂的时候设置为只读权限,以免因为代码的问题误修改了配置文件导致k3s出问题。
接下来测试一下,看看能否成功初始化。
从结果可以看出初始化失败,从报错信息中可以看出连接 k3s 集群的IP是127.0.0.1,显然是不对的。因为初始化配置读的是配置文件,肯定是配置文件的问题。
那么从pod内部访问k3s集群的IP该怎么获取呢?我们可以进入pod内部查看环境变量可以发现。
那么只要对 KubeConfig 的 server 配置修改成 pod 内部能访问的 k3s 集群的 IP 和端口即可。可惜 KubeConfig 并不提供修改 server 的方法,那么我们可以参考源码的方式进行初始化。
@Slf4j
@Component
public classK3sClient{
//pod内部指定存放k3s配置文件的路径
@Value("${k3sConf.path}")
private String k3sConfigPath;
/**
* 初始化API客户端
*/
@PostConstruct
private void setDefaultApiClient() throws IOException {
Yaml yaml = new Yaml(new SafeConstructor());
Object config = yaml.load(new FileReader(k3sConfigPath));
Map<String, Object> configMap = (Map)config;
String currentContext = (String)configMap.get("current-context");
ArrayList<Object> contexts = (ArrayList)configMap.get("contexts");
ArrayList<Object> clusters = (ArrayList)configMap.get("clusters");
// 替换server地址
Map<String, Object> map = findObject(clusters, "default");
if (map != null) {
Map<String, Object> cluster = (Map)map.get("cluster");
cluster.put("server", String.format("https://%s:%s", System.getenv("KUBERNETES_SERVICE_HOST"),
System.getenv("KUBERNETES_SERVICE_PORT")));
}
ArrayList<Object> users = (ArrayList)configMap.get("users");
Object preferences = configMap.get("preferences");
// 以config作为入参创建的client对象,可以访问到K8S的API Server
KubeConfig kubeConfig = new KubeConfig(contexts, clusters, users);
kubeConfig.setContext(currentContext);
kubeConfig.setPreferences(preferences);
ApiClient client = ClientBuilder.kubeconfig(kubeConfig).build();
// 创建操作类
Configuration.setDefaultApiClient(client);
}
private Map<String, Object> findObject(ArrayList<Object> list, String name) {
if (list == null) {
return null;
} else {
Iterator var2 = list.iterator();
Map map;
do {
if (!var2.hasNext()) {
return null;
}
Object obj = var2.next();
map = (Map)obj;
} while(!name.equals(map.get("name")));
return map;
}
}
/**
* 获取所有的Pod
*
* @return podList
*/
public V1PodList getAllPodList() {
CoreV1Api api = new CoreV1Api();
try {
V1PodList list = api.listPodForAllNamespaces(null, null, null, null, null, null, null, null, null, null);
return list;
} catch (ApiException e) {
log.error("获取podlist异常:" + e.getResponseBody(), e);
}
return null;
}
}
第三种方式:Token 认证的方式初始化 ApiClient
k3s 集群的地址同样可以通过环境变量中获取,而 token 是存放在 Pod 内的 /var/run/secrets/kubernetes.io/serviceaccount/token 文件。此方式要确认已经为Pod 创建好 serviceAccount。
@Slf4j
@Component
public classK3sClient{
//ApiServer地址
@Value("${k3s.apiServer}")
private String k3sApiServer;
//请求Token
@Value("${k3s.token}")
private String k3sToken;
//是否本机k3s集群
@Value("${k3s.local}")
private Boolean isK3sLocal;
/**
* 初始化API客户端
*/
@PostConstruct
privatevoidsetDefaultApiClient()throws IOException {
if (isK3sLocal) {
// 本机k3s集群地址
k3sApiServer = String.format("https://%s:%s", System.getenv("KUBERNETES_SERVICE_HOST"),
System.getenv("KUBERNETES_SERVICE_PORT"));
// 获取Token
FileReader fr = new FileReader("/var/run/secrets/kubernetes.io/serviceaccount/token");
BufferedReader br = new BufferedReader(fr);
k3sToken = br.readLine();
br.close();
}
ApiClient client = new ClientBuilder().setBasePath(k3sApiServer).setVerifyingSsl(false)
.setAuthentication(new AccessTokenAuthentication(k3sToken)).build();
// 创建操作类
Configuration.setDefaultApiClient(apiClient);
}
/**
* 获取所有的Pod
*
* @return podList
*/
public V1PodList getAllPodList(){
CoreV1Api api = new CoreV1Api();
try {
V1PodList list = api.listPodForAllNamespaces(null, null, null, null, null, null, null, null, null, null);
return list;
} catch (ApiException e) {
log.error("获取podlist异常:" + e.getResponseBody(), e);
}
return null;
}
}
通过这几种方式,我们就可以从 pod 内部访问 k3s 集群 API 了。其实客户端初始化使用 ClientBuilder.cluster().build() 是最简单的,刚开始时我为了读配置文件还绕了个大弯,很多东西官方其实早就为用户考虑到了,所以使用之前要多看看官方文档。
下期给大家分享如何简单使用pysyncobj,敬请期待~
欢迎各位关注、留言,大家的支持就是我的动力!
猜你喜欢
- 2025-08-05 java-socket长连接demo体验
- 2025-08-05 Redis教程——数据类型(基数统计、地理空间、位域)
- 2025-08-05 django python数据中心、客户、机柜、设备资源管理平台源码分享
- 2025-08-05 XXL-TOOL v1.4.0 发布 | Java工具类库
- 2025-08-05 java redis 客户端生产环境基本操作
- 2025-08-05 服务压测发现怪异现象,一顿排查,揪出“TIME_WAIT”这个内鬼
- 2025-08-05 稳定代理IP深入解析:辨别、获取与利用全攻略
你 发表评论:
欢迎- 08-05深入理解 Spring 设计模式:从实现原理到思想精髓
- 08-05工作中最常用的 8 种设计模式
- 08-05一文读懂设计模式,看这篇就够了
- 08-05java设计模式之责任链模式
- 08-05从复杂到优雅:用建造者和责任链重塑代码架构
- 08-05带你读Effective系列:创建对象-Builder构建器
- 08-05面试官:JDK中都用了哪些设计模式?
- 08-05工厂、建造者、装饰器、适配器:解密JDK设计模式的实战妙用
- 最近发表
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)