通过MetricsAPI监控pod资源使用情况(k8s资源监控,java)
metrics-server是Kubernetes的一个集群范围内的聚合器,用于收集所有节点和Pods的资源使用信息,如CPU和内存。这样简单读取pod资源的任务就完成了,主要工程就是 metrics server服务器的部署,然后使用restful api读取信息。但是k8s提供了一套k8s的对接标准,只要适配这套标准,就可以通过kubelet采集资源数据,并且通过k8s api服务器输出。我想
1. 目的:简单监控pod
我想使用java监控k8s pod的资源的简单使用情况,但是k8s内部并没有采集资源的实现。
但是k8s提供了一套k8s的对接标准,只要适配这套标准,就可以通过kubelet采集资源数据,并且通过k8s api服务器输出。这些对于故障排查以及自动伸缩至关重要。
2. 部署指南
metrics-server是Kubernetes的一个集群范围内的聚合器,用于收集所有节点和Pods的资源使用信息,如CPU和内存。metrics指标统计器(github)
- 如果证书没问题,部署最新的metrics-server
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/download/v0.4.1/components.yaml
- 如果你的集群使用自签名的证书,你可能需要添加参数来忽略 TLS 验证错误
把commponents.yaml wget下来后, 在 components.yaml 文件中,找到 metrics-server 的 Deployment 部分,并添加以下参数到 args:
- --kubelet-insecure-tls
- 查看是否部署成功
kubectl get deployment metrics-server -n kube-system
# 查看所有命名空间的pod资源
kubectl top pods -A
top 命令就可以使用了。
3. java Api调用
在官方提供的客户端 java库里是没有直接调用metrics的方法的。我们只能使用restful api进行访问,
- 添加maven依赖(获取tls上下文,如果只是过去资源可以不添加)
<dependency>
<groupId>io.kubernetes</groupId>
<artifactId>client-java</artifactId>
<version>18.0.0</version>
</dependency>
- 测试restful api(测试,可不做)
我这里是手动把证书导入到了postman(k8s的权限认证非常关键,没有权限是无法访问api的)
- java访问 restapi
我这里吧k8s 客户端和 rest http前后文都注入spring了,这样调用起来比较方便
注入k8s客户端
在这里插入代码片@Configuration
public class KubernetesClientConfig {
@Bean
public AppsV1Api appsV1Api(ApiClient apiClient) {
return new AppsV1Api(apiClient);
}
}
注入8sRestTemplate
@Configuration
public class RestTemplateConfig {
private final ApiClient apiClient;
public RestTemplateConfig(ApiClient apiClient) {
this.apiClient = apiClient;
}
@Bean
public RestTemplate extendK8sRestTemplate() {
return new RestTemplate(new OkHttp3ClientHttpRequestFactory(apiClient.getHttpClient()));
}
}
4. 定时任务读取该数据,存储到redis,保留60分钟,可以根据自动目的设置。
里面代码看起来比较杂乱,整体思路是使用上面注入的extendK8sRestTemplate访问api,然后存入redis,只保留30分钟
@Service
public class LogResourceTaskService implements TaskService {
@Resource
private final RedisService redisService;
@Resource
private final RestTemplate extendK8sRestTemplate;
@Resource
private final KubernetesServiceImpl kubernetesServiceImpl;
@Resource
private final ApiClient apiClient;
public LogResourceTaskService(RedisService redisService,RestTemplate extendK8sRestTemplate, KubernetesServiceImpl kubernetesServiceImpl,ApiClient apiClient) {
this.redisService = redisService;
this.extendK8sRestTemplate = extendK8sRestTemplate;
this.apiClient = apiClient;
this.kubernetesServiceImpl = kubernetesServiceImpl;
}
@Override
public void work(String guid) {
String mapKey0 = "metrics_cpu:"+PodDataSynConfig.CURRENT_POD;
String mapKey1 = "metrics_memory:"+PodDataSynConfig.CURRENT_POD;
String url = String.format("%s/apis/metrics.k8s.io/v1beta1/namespaces/%s/pods/%s", apiClient.getBasePath(),kubernetesServiceImpl.getNamespace(), PodDataSynConfig.CURRENT_POD);
ResponseEntity<PodMetrics> response = extendK8sRestTemplate.getForEntity(url, PodMetrics.class);
if (response.getBody() != null && response.hasBody()){
if(response.getBody().getContainers() != null && response.getBody().getContainers().get(0) != null){
String cpu = response.getBody().getContainers().get(0).getUsage().getCpu();
String memory = response.getBody().getContainers().get(0).getUsage().getMemory();
long timestamp = Instant.now().getEpochSecond();
redisService.getRedisTemplate().opsForZSet().add(mapKey0, timestamp+":"+cpu,timestamp);
redisService.getRedisTemplate().opsForZSet().add(mapKey1, timestamp+":"+memory,timestamp);
}
}
removeOldData(mapKey0,mapKey1);
}
public void removeOldData(String key0, String key1) {
long cutoffTimestamp = Instant.now().getEpochSecond() - 3600; // 60分钟前
redisService.getRedisTemplate().opsForZSet().removeRangeByScore(key0, -Double.MAX_VALUE, cutoffTimestamp);
redisService.getRedisTemplate().opsForZSet().removeRangeByScore(key1, -Double.MAX_VALUE, cutoffTimestamp);
}
}
4. 完工:
这样简单读取pod资源的任务就完成了,主要步骤就是 metrics server服务器的部署,然后使用restful api读取信息。
更多推荐
所有评论(0)