上篇介绍了如何安装metrics-server,本篇主要介绍如何使用java程序远程调用metrics-server的api
kubernetes-client为kubernetes官方维护的访问集群的api,各种语言基本都有,kubernetes-client/java为java版的api,用法示例
import io.kubernetes.client.openapi.ApiClient;
import io.kubernetes.client.openapi.ApiException;
import io.kubernetes.client.openapi.Configuration;
import io.kubernetes.client.openapi.apis.CoreV1Api;
import io.kubernetes.client.openapi.models.V1Pod;
import io.kubernetes.client.openapi.models.V1PodList;
import io.kubernetes.client.util.Config;
import java.io.IOException;
public class Example {
public static void main(String[] args) throws IOException, ApiException{
ApiClient client = Config.fromConfig("G:/config");
Configuration.setDefaultApiClient(client);
CoreV1Api api = new CoreV1Api();
V1PodList list = api.listPodForAllNamespaces(null, null, null, null, null, null, null, null, null);
for (V1Pod item : list.getItems()) {
System.out.println(item.getMetadata().getName());
}
}
}
该API的核心类就是ApiClinet,使用Config类中各种重载的fromConfig方法来得到ApiClient
kubernetes API的授权方式有三种:
示例中使用的是第一种方式,G:/config为k8s集群master节点.kube下的config文件,即证书
maven依赖
<dependency>
<groupId>io.kubernetesgroupId>
<artifactId>client-javaartifactId>
<version>8.0.2version>
dependency>
遗憾的是官方标准API中没有metrics-server的,那我们如何调用呢?网上有人使用kubernetes-client/gen生成包含metrics-server API的jar,具体可参考这里, kubernetes-client本身就是使用kubernetes-client/gen生成的,但该方案问题较多
有没有别的方案呢?
我通过查看源码,发现kubernetes-client/java是对okhttp3的封装,k8s集群对外提供http接口,kubernetes-client/java使用okhttp3访问
ApiClient在创建时,内部会构建一个OkHttpClient用于发送http请求,该clinet会包含授权参数
因此,只要使用ApiClient即可,示例
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.lenovo.brain.controlagent.metrics.dto.MetricsNodeList;
import com.lenovo.brain.controlagent.metrics.dto.MetricsPodList;
import io.kubernetes.client.openapi.ApiClient;
import io.kubernetes.client.openapi.ApiException;
import io.kubernetes.client.openapi.ApiResponse;
import io.kubernetes.client.openapi.Configuration;
import io.kubernetes.client.openapi.Pair;
import okhttp3.Call;
/**
*
* @author suozq
*
*/
public class MetricsServerApi {
private ApiClient localVarApiClient;
public final static String BASE_URL="/apis/metrics.k8s.io/v1beta1";
private String url_get_nodes="/nodes";
private String url_get_namespace_pods = "/namespaces/{namespace}/pods";
public MetricsServerApi() {
this(Configuration.getDefaultApiClient());
}
public MetricsServerApi(ApiClient apiClient) {
this.localVarApiClient = apiClient;
}
public ApiClient getApiClient() {
return localVarApiClient;
}
public void setApiClient(ApiClient apiClient) {
this.localVarApiClient = apiClient;
}
/**
* 获取集群各个node节点的cpu和内存用量
*/
public MetricsNodeList getNodesAndUsage() throws IOException, ApiException {
String path = BASE_URL+url_get_nodes;
Call call = buildGetSimpleCall(path, "GET");
ApiResponse<MetricsNodeList> r = localVarApiClient.execute(call,MetricsNodeList.class);
return r.getData();
}
/**
* 获取namespace下pods的cpu和内存用量
* @param namespace
* @return
* @throws IOException
* @throws ApiException
*/
public MetricsPodList getPodsAndUsage(String namespace) throws IOException, ApiException {
String path = new String(url_get_namespace_pods);
path=path.replaceAll("\\{namespace\\}", namespace);
path = BASE_URL+path;
Call call = buildGetSimpleCall(path, "GET");
ApiResponse<MetricsPodList> r = localVarApiClient.execute(call,MetricsPodList.class);
return r.getData();
}
/**
* 构建简单的Call
*/
private Call buildGetSimpleCall(String path, String method) throws ApiException {
String[] localVarAuthNames = new String[] { "BearerToken" };
List<Pair> localVarQueryParams = new ArrayList<Pair>();
List<Pair> localVarCollectionQueryParams = new ArrayList<Pair>();
Map<String, String> localVarHeaderParams = new HashMap<String, String>();
Map<String, String> localVarCookieParams = new HashMap<String, String>();
Map<String, Object> localVarFormParams = new HashMap<String, Object>();
final String[] localVarAccepts = {
"*/*"
};
final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts);
if (localVarAccept != null) {
localVarHeaderParams.put("Accept", localVarAccept);
}
final String[] localVarContentTypes = {
};
final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes);
localVarHeaderParams.put("Content-Type", localVarContentType);
return localVarApiClient.buildCall(path, method, localVarQueryParams, localVarCollectionQueryParams, null, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, null);
}
}
import java.util.List;
import org.joda.time.DateTime;
import io.kubernetes.client.openapi.models.V1ListMeta;
import io.kubernetes.client.openapi.models.V1ObjectMeta;
/**
*
* @author suozq
*
*/
public class MetricsNodeList {
private String kind;
private String apiVersion;
private V1ListMeta metadata;
private List<MetricsNode> items;
public static class MetricsNode{
private V1ObjectMeta metadata;
private DateTime timestamp;
private String window;
private MetricsUsage usage;
public DateTime getTimestamp() {
return timestamp;
}
public void setTimestamp(DateTime timestamp) {
this.timestamp = timestamp;
}
public String getWindow() {
return window;
}
public void setWindow(String window) {
this.window = window;
}
public MetricsUsage getUsage() {
return usage;
}
public void setUsage(MetricsUsage usage) {
this.usage = usage;
}
public V1ObjectMeta getMetadata() {
return metadata;
}
public void setMetadata(V1ObjectMeta metadata) {
this.metadata = metadata;
}
}
public String getKind() {
return kind;
}
public void setKind(String kind) {
this.kind = kind;
}
public String getApiVersion() {
return apiVersion;
}
public void setApiVersion(String apiVersion) {
this.apiVersion = apiVersion;
}
public List<MetricsNode> getItems() {
return items;
}
public void setItems(List<MetricsNode> items) {
this.items = items;
}
public V1ListMeta getMetadata() {
return metadata;
}
public void setMetadata(V1ListMeta metadata) {
this.metadata = metadata;
}
}
/**
*
* @author suozq
*
*/
import java.util.List;
import org.joda.time.DateTime;
import io.kubernetes.client.openapi.models.V1ListMeta;
import io.kubernetes.client.openapi.models.V1ObjectMeta;
public class MetricsPodList {
private String kind;
private String apiVersion;
private V1ListMeta metadata;
private List<MetricsPod> items;
public static class MetricsPod{
private V1ObjectMeta metadata;
private DateTime timestamp;
private String window;
private List<MetricsPodContainer> containers;
public DateTime getTimestamp() {
return timestamp;
}
public void setTimestamp(DateTime timestamp) {
this.timestamp = timestamp;
}
public String getWindow() {
return window;
}
public void setWindow(String window) {
this.window = window;
}
public List<MetricsPodContainer> getContainers() {
return containers;
}
public void setContainers(List<MetricsPodContainer> containers) {
this.containers = containers;
}
public V1ObjectMeta getMetadata() {
return metadata;
}
public void setMetadata(V1ObjectMeta metadata) {
this.metadata = metadata;
}
}
public static class MetricsPodContainer{
private String name;
private MetricsUsage usage;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public MetricsUsage getUsage() {
return usage;
}
public void setUsage(MetricsUsage usage) {
this.usage = usage;
}
}
public String getKind() {
return kind;
}
public void setKind(String kind) {
this.kind = kind;
}
public String getApiVersion() {
return apiVersion;
}
public void setApiVersion(String apiVersion) {
this.apiVersion = apiVersion;
}
public List<MetricsPod> getItems() {
return items;
}
public void setItems(List<MetricsPod> items) {
this.items = items;
}
public V1ListMeta getMetadata() {
return metadata;
}
public void setMetadata(V1ListMeta metadata) {
this.metadata = metadata;
}
}
import java.util.HashMap;
import java.util.Map;
/**
*
* @author suozq
*
*/
public class MetricsUsage {
//获取的cpu和memory是带单位的字符串,加入转换逻辑,cpu统一单位为m,memory统一单位为Mi,如果不需要转换单位可以去掉相关逻辑
private static Map<String,Double> UNIT_CPU = new HashMap<>();
private static Map<String,Double> UNIT_MEMORY = new HashMap<>();
static {
UNIT_CPU.put("n",Math.pow(10, -6));
UNIT_CPU.put("u",Math.pow(10, -3));
UNIT_CPU.put("m",Math.pow(10, 0));
UNIT_CPU.put("",Math.pow(10, 3));
UNIT_CPU.put("k",Math.pow(10, 6));
UNIT_CPU.put("M",Math.pow(10, 9));
UNIT_CPU.put("G",Math.pow(10, 3*4));
UNIT_CPU.put("T",Math.pow(10, 3*5));
UNIT_CPU.put("P",Math.pow(10, 3*6));
UNIT_CPU.put("E",Math.pow(10, 3*7));
UNIT_MEMORY.put("Ki",Math.pow(1024, -1));
UNIT_MEMORY.put("Mi",Math.pow(1024, 0));
UNIT_MEMORY.put("Gi",Math.pow(1024, 1));
UNIT_MEMORY.put("Ti",Math.pow(1024, 2));
UNIT_MEMORY.put("Pi",Math.pow(1024, 3));
UNIT_MEMORY.put("Ei",Math.pow(1024, 4));
}
private String cpu;
private String memory;
public String getCpu() {
return cpu;
}
public void setCpu(String cpu) {
this.cpu = cpu;
}
public String getMemory() {
return memory;
}
public void setMemory(String memory) {
this.memory = memory;
}
public static Long commomUnifiedUnit(String unitValStr,int unitLength,Map<String,Double> unitMap) {
Long r = 0l;
if(unitValStr == null) {
return r;
}
String unit = unitValStr.substring(unitValStr.length()-unitLength, unitValStr.length());
String val = unitValStr.substring(0,unitValStr.length()-unitLength);
if(unit.matches("\\d")) {
unit="";
val=unitValStr;
}
Double factor = unitMap.get(unit);
if(factor==null) {
throw new IllegalArgumentException("无法解析单位:"+unitValStr);
}
r = Math.round(Integer.parseInt(val)*factor);
return r;
}
public Long getCpuInM() {
return commomUnifiedUnit(cpu,1,UNIT_CPU);
}
public Long getMemoryInMi() {
return commomUnifiedUnit(memory, 2, UNIT_MEMORY);
}
}
import io.kubernetes.client.openapi.ApiClient;
import io.kubernetes.client.openapi.ApiException;
import io.kubernetes.client.openapi.Configuration;
import io.kubernetes.client.openapi.apis.CoreV1Api;
import io.kubernetes.client.openapi.models.V1Pod;
import io.kubernetes.client.openapi.models.V1PodList;
import io.kubernetes.client.util.Config;
import java.io.IOException;
/**
*
* @author suozq
*
*/
public class Example {
public static void main(String[] args) throws IOException, ApiException{
ApiClient client = Config.fromConfig("G:/config");
metricsServerApi = new MetricsServerApi(clinet);
MetricsNodeList metricsNodeList = metricsServerApi.getNodesAndUsage();
}
}