java连接kubernete

最近需要做一个项目,将k8s上的日志经过java工程输出到前端,大概想了下思路,首先要java连接kubernete监控到job的日志,然后通过websocket将日志持续输出到前端,因为这些从来没有写过,所以只能一点一点积累知识,一点一点攻破,目前是java连接kubernete成功了,并取到了日志,暂时记录一下

1、java连接kubernete方法:配置文件方式,这个文件需要配置到你的工程里面,怎么获取到配置文件?问你们单位的运维,告诉他在机器上帮你取这个文件~/.kube/config 运维说这个是开发环境的超级证书,这个证书只能运维取,因为估计普通测试员没有权限,运维有管理员权限的账号才能取下来

创建k8sclient文件

package com.example.demo.config;

/**
 * @Author: lxx
 * @Date: 2022/8/4 下午5:43
 */

import io.kubernetes.client.custom.IntOrString;
import io.kubernetes.client.openapi.ApiClient;
import io.kubernetes.client.openapi.ApiException;
import io.kubernetes.client.openapi.apis.CoreV1Api;
import io.kubernetes.client.openapi.apis.ExtensionsV1beta1Api;
import io.kubernetes.client.openapi.apis.NetworkingV1Api;
import io.kubernetes.client.openapi.models.*;
import io.kubernetes.client.util.ClientBuilder;
import io.kubernetes.client.util.KubeConfig;
import lombok.extern.slf4j.Slf4j;
import okhttp3.Call;
import org.slf4j.Logger;

import java.io.FileReader;
import java.io.IOException;
import java.util.Map;

/**
 * k8s客户端
 *
 * @author wanghuidong
 * @date 2021/6/18 14:14
 */
@Slf4j
public class K8sClient {

    /**
     * k8s-api客户端
     */
    private ApiClient apiClient;

    /**
     * 构建集群POD内通过SA访问的客户端
     * loading the in-cluster config, including:
     * 1. service-account CA
     * 2. service-account bearer-token
     * 3. service-account namespace
     * 4. master endpoints(ip, port) from pre-set environment variables
     */
    public K8sClient() {
        try {
            this.apiClient = ClientBuilder.cluster().build();
        } catch (IOException e) {
            log.error("构建K8s-Client异常", e);
            throw new RuntimeException("构建K8s-Client异常");
        }
    }

    /**
     * 构建集群外通过UA访问的客户端
     * loading the out-of-cluster config, a kubeconfig from file-system
     *
     * @param kubeConfigPath kube连接配置文件
     */
    public K8sClient(String kubeConfigPath) {
        try {
            this.apiClient = ClientBuilder.kubeconfig(KubeConfig.loadKubeConfig(new FileReader(kubeConfigPath))).build();
        } catch (IOException e) {
            log.error("读取kubeConfigPath异常", e);
            throw new RuntimeException("读取kubeConfigPath异常");
        } catch (Exception e) {
            log.error("构建K8s-Client异常", e);
            throw new RuntimeException("构建K8s-Client异常");
        }
    }

    /**
     * 获取所有的Pod
     *
     * @return podList
     */
    public V1PodList getAllPodList() throws Exception {
        // new a CoreV1Api
        CoreV1Api api = new CoreV1Api(apiClient);

        // invokes the CoreV1Api client
//        V1Pod pod = api.readNamespacedPod("reconcile-l75kp","dev5",null,null,null);
        try {
            //V1PodList list = api.listPodForAllNamespaces(null, null, null, null, null, null, null, null, null, null);
            V1PodList list = api.listNamespacedPod("dev5",null,null,null,null,null,null,null,null,null,null);
            return list;
        } catch (ApiException e) {
            log.error("获取podlist异常:" + e.getResponseBody(), e);
        }
        return null;
    }

    /**
     * 创建k8s service
     *
     * @param namespace   命名空间
     * @param serviceName 服务名称
     * @param port        服务端口号(和目标pod的端口号一致)
     * @param selector    pod标签选择器
     * @return 创建成功的service对象
     */
    public V1Service createService(String namespace, String serviceName, Integer port, Map<String, String> selector) {
        //构建service的yaml对象
        V1Service svc = new V1ServiceBuilder()
                .withNewMetadata()
                .withName(serviceName)
                .endMetadata()
                .withNewSpec()
                .addNewPort()
                .withProtocol("TCP")
                .withPort(port)
                .withTargetPort(new IntOrString(port))
                .endPort()
                .withSelector(selector)
                .endSpec()
                .build();

        // Deployment and StatefulSet is defined in apps/v1, so you should use AppsV1Api instead of CoreV1API
        CoreV1Api api = new CoreV1Api(apiClient);
        V1Service v1Service = null;
        try {
            v1Service = api.createNamespacedService(namespace, svc, null, null, null);
        } catch (ApiException e) {
            log.error("创建service异常:" + e.getResponseBody(), e);
        } catch (Exception e) {
            log.error("创建service系统异常:", e);
        }
        return v1Service;
    }

    /**
     * 创建k8s V1Ingress
     *
     * @param namespace   命名空间
     * @param ingressName ingress名称
     * @param annotations ingress注解
     * @param path        匹配的路径
     * @param serviceName 路由到的服务名称
     * @param servicePort 路由到的服务端口
     * @return 创建成功的ingress对象
     */
    public V1Ingress createV1Ingress(String namespace, String ingressName, Map<String, String> annotations, String path,
                                     String serviceName, Integer servicePort) {
        //构建ingress的yaml对象
        V1Ingress ingress = new V1IngressBuilder()
                .withNewMetadata()
                .withName(ingressName)
                .withAnnotations(annotations)
                .endMetadata()
                .withNewSpec()
                .addNewRule()
                .withHttp(new V1HTTPIngressRuleValueBuilder().addToPaths(new V1HTTPIngressPathBuilder()
                        .withPath(path)
                        .withPathType("Prefix")
                        .withBackend(new V1IngressBackendBuilder()
                                .withService(new V1IngressServiceBackendBuilder()
                                        .withName(serviceName)
                                        .withPort(new V1ServiceBackendPortBuilder()
                                                .withNumber(servicePort).build()).build()).build()).build()).build())
                .endRule()
                .endSpec()
                .build();

        //调用对应的API执行创建ingress的操作
        NetworkingV1Api api = new NetworkingV1Api(apiClient);
        V1Ingress v1Ingress = null;
        try {
            v1Ingress = api.createNamespacedIngress(namespace, ingress, null, null, null);
        } catch (ApiException e) {
            log.error("创建ingress异常:" + e.getResponseBody(), e);
        } catch (Exception e) {
            log.error("创建ingress系统异常:", e);
        }
        return v1Ingress;
    }


    /**
     * 创建k8s ExtensionIngress
     *
     * @param namespace   命名空间
     * @param ingressName ingress名称
     * @param annotations ingress注解
     * @param path        匹配的路径
     * @param serviceName 路由到的服务名称
     * @param servicePort 路由到的服务端口
     * @return 创建成功的ingress对象
     */
    public ExtensionsV1beta1Ingress createExtensionIngress(String namespace, String ingressName, Map<String, String> annotations, String path,
                                                           String serviceName, Integer servicePort) {
        //构建ingress的yaml对象
        ExtensionsV1beta1Ingress ingress = new ExtensionsV1beta1IngressBuilder()
                .withNewMetadata()
                .withName(ingressName)
                .withAnnotations(annotations)
                .endMetadata()
                .withNewSpec()
                .addNewRule()
                .withHttp(new ExtensionsV1beta1HTTPIngressRuleValueBuilder().addToPaths(new ExtensionsV1beta1HTTPIngressPathBuilder()
                        .withPath(path)
                        .withBackend(new ExtensionsV1beta1IngressBackendBuilder()
                                .withServiceName(serviceName)
                                .withServicePort(new IntOrString(servicePort)).build()).build()).build())
                .endRule()
                .endSpec()
                .build();

        //调用对应的API执行创建ingress的操作
        ExtensionsV1beta1Api api = new ExtensionsV1beta1Api(apiClient);
        ExtensionsV1beta1Ingress extensionsV1beta1Ingress = null;
        try {
            extensionsV1beta1Ingress = api.createNamespacedIngress(namespace, ingress, null, null, null);
        } catch (ApiException e) {
            log.error("创建ingress异常:" + e.getResponseBody(), e);
        } catch (Exception e) {
            log.error("创建ingress系统异常:", e);
        }
        return extensionsV1beta1Ingress;
    }
public V1Pod readNamespacedPod(String podName,String spaceName)throws Exception{
    CoreV1Api api = new CoreV1Api(apiClient);
    V1Pod pod = api.readNamespacedPod(podName,spaceName,null,null,null);
    return pod;
}

    public Call readNamespacedPodLogCall (String podName, String spaceName, Integer tailLines)throws Exception{
        CoreV1Api api = new CoreV1Api(apiClient);
        Call log = api.readNamespacedPodLogCall(podName,spaceName,null,true,null,null,null,null,null,100,null,null);
        return log;
    }
    public String readNamespacedPodLog (String podName, String spaceName, Integer tailLines)throws Exception{
//        CoreV1Api api = new CoreV1Api(apiClient);
        CoreV1Api api = new CoreV1Api(apiClient);
        String log = api.readNamespacedPodLog(podName,spaceName,null,true,false,1024,"true",false,null,10,false);
        return log;
    }
}

写单元测试

package com.example.demo;

import com.example.demo.config.K8sClient;
import io.kubernetes.client.openapi.models.V1Pod;
import io.kubernetes.client.openapi.models.V1PodList;
import org.junit.Test;
import java.io.File;

/**
 * @Author: 
 * @Date: 2022/8/4 下午5:31
 */
public class KuberneteTest {

    @Test
public void testK8sLog()throws Exception{
        String kubeConfigPath = "/Users/xxx/k8s/config";
        if (!new File(kubeConfigPath).exists()) {
            System.out.println("kubeConfig不存在,跳过");
            return;
        }
        K8sClient k8sClient = new K8sClient(kubeConfigPath);
        String call=k8sClient.readNamespacedPodLog("test-l75kp","dev5",100);
        System.out.println(call);
    }
}

这样就可以连上kubernete啦,连接k8的用户名密码什么的都在/Users/xxx/k8s/config这个配置文件中,连上之后读取 space为dev5  job名为test-l75kp的日志

不要觉得代码多,亲自试一试吧!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值