前言
最近主要在获取到的k8s中的相关service和pod的信息的变化,将原来全量获取数据的方式改进为增量的方式,此篇主要记录使用过程中遇到的坑和相信的解决方式
KubernetesClient的包的依赖的引用
使用的是fabric8的kubernetes-client,添加如下依赖即可
<!--在pom.xml文件-->
<dependency>
<groupId>io.fabric8</groupId>
<artifactId>kubernetes-client</artifactId>
<version>4.0.5</version>
</dependency>
配置文件配置相关的属性
application.yml文件
添加k8s集群的主机url,token
api:
server:
k8s:
key: "kubernetes.auth.token"
token: "***********************************"
url: "https://10.0.0.0:6443"
这里就有一个坑,就是这个token,由于kubernetes的安全机制,原来获取到的token都只有一天的时效,第二天都需要重新更新一个新的token
这样是肯定不行的,解决的方式有大概下面几种:
- 使用证书的方式,需要三个文件,CaCertFile,ClientCertFile,ClientKeyFile
- 获取一种长效的永久的token,这个需要的权限比较高,需要找到kubernetes的负责人,拥有的权限比较高的人
(查看本地的token,cd ~/.kube,然后cat config,就能看到自己本地的token) - 使用账号密码进行登录
configuration的实现
在configuration文件夹下面新建一个class,取名为KubernetesConfig
主要文件内容如下
@Setter
@Configuration
@ConfigurationProperties(prefix = "api.server")
public class KubernetesConfig {
private K8s k8s;
private static final int REQUEST_TIMEOUT = 3 * 1000;
private static final int CONNECTION_TIMEOUT = 3 * 1000;
@Bean("kubernetesClient")
public KubernetesClient kubernetesClient() {
Config config = new ConfigBuilder()
.withMasterUrl(k8s.getUrl())
.withOauthToken(k8s.getToken())
.withTrustCerts(true)
.removeFromTlsVersions(TlsVersion.TLS_1_0)
.removeFromTlsVersions(TlsVersion.TLS_1_1)
.removeFromTlsVersions(TlsVersion.TLS_1_2)
.withRequestTimeout(REQUEST_TIMEOUT)
.withConnectionTimeout(CONNECTION_TIMEOUT)
.build();
KubernetesClient client = new DefaultKubernetesClient(config);
return client;
}
@Bean("k8s")
public K8s getK8s() {
return k8s;
}
@Setter
@Getter
public static class K8s {
private String token;
private String key;
private String url;
}
}
以上是使用的是token的方式,进行的登录
还可以使用证书的方式:
-
将需要的三个证书文件放到项目当中,右键copy path,然后删除src前面的路径
-
将上面代码中的.withOauthToken(k8s.getToken())替换为
.withCaCertFile(“src/main/resources/CaCert.crt”)
.withClientCertFile(“src/main/resources/ClientCert.crt”)
.withClientKeyFile(“src/main/resources/ClientKey.key”)
还可以使用账号密码的方式进行登录:
-
将上面代码中的.withOauthToken(k8s.getToken())替换为
.withUsername(“username”)
.withPassword(“password”)
使用KubernetesClient实现watch的功能
kubernetesClient.services().inAnyNamespace().watch(new Watcher<Service>() {
@Override
public void eventReceived(Action action, Service service) {
log.debug("service watch action:{}",action);
log.debug("service watch service:{}",service.toString());
log.debug(" ");
}
@Override
public void onClose(KubernetesClientException e) {
}
});
主要的功能实现都在这个event类中实现了,如果想watch pod的话,只需要将services()换成pods()即可
主要的坑是在何处实现?
原本的kubernetes中相关的信息收集,是在定时任务中实现的
但是kubernetes的watch就已经相当于是一个线程了,如果做到让这个功能随着服务的启动而直接就启动了呢?
我的处理方式,依然是使用的定时任务,不过是将定时任务的时间,设置了一个特别长的间隔,这样就算是只启动了一次了
代码如下:
@Scheduled(fixedDelay = 999999999)
public void collectPod() {
kubernetesService.watchPods();
}