zoukankan      html  css  js  c++  java
  • SpringBoot 调用 K8s metrics-server

    起因

    官方 API io.kubernetes.client-java无法调用 metrics-server API

    解决

    ApiClient 内部会创建一个 OkHttpClient 用于发送 http 请求,该 clinet 包含授权参数等信息

    K8sConfig

    public class K8sConfig {
        public static ApiClient getApiClient() {
            ApiClient client = null;
            try {
                File file = new File("E:\k3s.yaml");
                client = ClientBuilder.kubeconfig(KubeConfig.loadKubeConfig(new FileReader(file))).build();
                client.setDebugging(true);
                Configuration.setDefaultApiClient(client);
            } catch (IOException e) {
                log.error("K8s ApiClient 初始化失败!");
            }
            return client;
        }
    }
    

    MetricsService

    @Service
    public class MetricsService {
    
        private ApiClient apiClient;
    
        private static final String BASE_URL="/apis/metrics.k8s.io/v1beta1";
    
        private static final String URL_NODES = "/nodes";
    
        private static final String URL_PODS = "/pods";
    
        private static final String URL_NAMESPACES = "/namespaces/";
    
        public MetricsService() {
            this.apiClient = K8sConfig.getApiClient();
        }
    
        /**
         * 获取集群节点的资源统计信息
         */
        public MetricsNodeList getNodeMetrics() throws IOException, ApiException {
            String path = BASE_URL + URL_NODES;
            Call call = buildCall(path, "GET");
            ApiResponse<MetricsNodeList> r = apiClient.execute(call, MetricsNodeList.class);
            return r.getData();
        }
    
        /**
         * 获取所有pods的资源统计信息
         */
        public MetricsPodList getPodMetrics() throws IOException, ApiException {
            String path = BASE_URL + URL_PODS;
            Call call = buildCall(path, "GET");
            ApiResponse<MetricsPodList> r = apiClient.execute(call, MetricsPodList.class);
            return r.getData();
        }
    
        /**
         * 获取namespace下pods的资源统计信息
         */
        public MetricsPodList getPodsMetrics(String namespace) throws IOException, ApiException {
            String path = BASE_URL + URL_NAMESPACES + namespace + URL_PODS;
            Call call = buildCall(path, "GET");
            ApiResponse<MetricsPodList> r = apiClient.execute(call, MetricsPodList.class);
            return r.getData();
        }
    
        /**
         * 构建Call
         */
        private Call buildCall(String path, String method) throws ApiException {
            List<Pair> localVarQueryParams = new ArrayList<>();
            List<Pair> localVarCollectionQueryParams = new ArrayList<>();
            Map<String, String> localVarHeaderParams = new HashMap<>();
            localVarHeaderParams.put("Accept", apiClient.selectHeaderAccept(new String[]{"*/*"}));
            localVarHeaderParams.put("Content-Type", apiClient.selectHeaderContentType(new String[]{}));
            Map<String, String> localVarCookieParams = new HashMap<>();
            Map<String, Object> localVarFormParams = new HashMap<>();
            String[] localVarAuthNames = new String[]{"BearerToken"};
            return apiClient.buildCall(path, method, localVarQueryParams, localVarCollectionQueryParams, null, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, null);
        }
    }
    

    Models

    @Data
    public class MetricsNodeList {
        private String kind;
        private String apiVersion;
        private V1ListMeta metadata;
        private List<MetricsNode> items;
    
        @Data
        public static class MetricsNode{
            private V1ObjectMeta metadata;
            private DateTime timestamp;
            private String window;
            private MetricsUsage usage;
        }
    }
    
    @Data
    public class MetricsPodList {
        private String kind;
        private String apiVersion;
        private V1ListMeta metadata;
        private List<MetricsPod> items;
    
        @Data
        public static class MetricsPod{
            private V1ObjectMeta metadata;
            private DateTime timestamp;
            private String window;
            private List<MetricsPodContainer> containers;
        }
    
        @Data
        public static class MetricsPodContainer{
            private String name;
            private MetricsUsage usage;
        }
    }
    
    public class MetricsUsage {
    
        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 commomUnifiedUnit(cpu,1,UNIT_CPU) + "m";
        }
    
        public void setCpu(String cpu) {
            this.cpu = cpu;
        }
    
        public String getMemory() {
            return commomUnifiedUnit(memory, 2, UNIT_MEMORY) + "Mi";
        }
    
        public void setMemory(String memory) {
            this.memory = memory;
        }
    
        /**
         * 获取的cpu和memory是带单位的字符串,加入转换逻辑,cpu统一单位为m,memory统一单位为Mi,如果不需要转换单位可以去掉相关逻辑
         */
        private static String commomUnifiedUnit(String unitValStr, int unitLength, Map<String, Double> unitMap) {
            Long r = 0L;
            if(unitValStr == null) {
                return "0";
            }
            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 + "";
        }
    }
    

    参考:https://blog.csdn.net/suo082407128/article/details/106804811

  • 相关阅读:
    django 基础1
    django 权限管理
    django 统计表
    关于RF中类似于异常(TRY语句)情况的处理
    关于提BUG的一点思考以及工作中总结的规范
    关于爬虫的学习
    关于RF中元素定位问题
    RobotFrameWork(五)控制流之if语句——Run Keyword If
    最完整的自动化测试流程
    关于python语言学习心得
  • 原文地址:https://www.cnblogs.com/lb477/p/14927885.html
Copyright © 2011-2022 走看看