zoukankan      html  css  js  c++  java
  • java使用io.kubernetes.client-java调用k8s api创建pod/service/ingress示例

    1.maven配置

    <!-- k8s client -->
    <dependency>
        <groupId>io.kubernetes</groupId>
        <artifactId>client-java</artifactId>
        <version>12.0.1</version>
    </dependency>                

    2.工具类

    /**
     * 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() {
            // new a CoreV1Api
            CoreV1Api api = new CoreV1Api(apiClient);
    
            // invokes the CoreV1Api client
            try {
                V1PodList list = api.listPodForAllNamespaces(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;
        }
    }

    3.测试类

    /**
     * @author wanghuidong
     * @date 2021/6/18 14:33
     */
    public class K8sClientTest {
    
    
    //    @Test
        public void getAllPodListTest() {
            String kubeConfigPath = "C:\Users\admin\.kube\config";
            if (!new File(kubeConfigPath).exists()) {
                System.out.println("kubeConfig不存在,跳过");
                return;
            }
            K8sClient k8sClient = new K8sClient(kubeConfigPath);
            V1PodList podList = k8sClient.getAllPodList();
            for (V1Pod item : podList.getItems()) {
                System.out.println(item.getMetadata().getNamespace() + ":" + item.getMetadata().getName());
            }
        }
    
    
    //    @Test
        public void createServiceTest() {
            String kubeConfigPath = "C:\Users\admin\.kube\config";
            if (!new File(kubeConfigPath).exists()) {
                System.out.println("kubeConfig不存在,跳过");
                return;
            }
            K8sClient k8sClient = new K8sClient(kubeConfigPath);
            String namespace = "default";
            String serviceName = "my-nginx-service";
            Integer port = 80;
            Map<String, String> selector = new HashMap<>();
            selector.put("run", "my-nginx");
            V1Service v1Service = k8sClient.createService(namespace, serviceName, port, selector);
            System.out.println(v1Service != null ? v1Service.getMetadata() : null);
        }
    
    //    @Test
        public void createV1IngressTest() {
            String kubeConfigPath = "C:\Users\admin\.kube\config";
            if (!new File(kubeConfigPath).exists()) {
                System.out.println("kubeConfig不存在,跳过");
                return;
            }
            K8sClient k8sClient = new K8sClient(kubeConfigPath);
            String namespace = "default";
            String ingressName = "my-nginx-ingress";
            Map<String, String> annotations = new HashMap<>();
            annotations.put("nginx.ingress.kubernetes.io/rewrite-target", "/");
            String path = "/my-nginx";
            String serviceName = "my-nginx-service";
            Integer servicePort = 80;
            V1Ingress v1Ingress = k8sClient.createV1Ingress(namespace, ingressName, annotations, path, serviceName, servicePort);
            System.out.println(v1Ingress != null ? v1Ingress.getMetadata() : null);
        }
    
    //    @Test
        public void createExtensionIngressTest() {
            String kubeConfigPath = "C:\Users\admin\.kube\config";
            if (!new File(kubeConfigPath).exists()) {
                System.out.println("kubeConfig不存在,跳过");
                return;
            }
            K8sClient k8sClient = new K8sClient(kubeConfigPath);
            String namespace = "default";
            String ingressName = "my-nginx-ingress";
            Map<String, String> annotations = new HashMap<>();
            annotations.put("nginx.ingress.kubernetes.io/rewrite-target", "/");
            String path = "/my-nginx";
            String serviceName = "my-nginx-service";
            Integer servicePort = 80;
            ExtensionsV1beta1Ingress extensionsV1beta1Ingress = k8sClient.createExtensionIngress(namespace, ingressName, annotations, path, serviceName, servicePort);
            System.out.println(extensionsV1beta1Ingress != null ? extensionsV1beta1Ingress.getMetadata() : null);
        }
    }

    4.附录

    4.1 创建pod应用

    my-nginx.yaml

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: my-nginx
    spec:
      selector:
        matchLabels:
          run: my-nginx
      replicas: 2
      template:
        metadata:
          labels:
            run: my-nginx
        spec:
          containers:
          - name: my-nginx
            image: nginx
            ports:
            - containerPort: 80

    应用部署单,生成pod

    kubectl apply -f ./my-nginx.yaml

    查看相关pod信息
    kubectl get pods -l run=my-nginx -o wide

    4.2 创建service

    my-nginx-service.yaml

    apiVersion: v1
    kind: Service
    metadata:
      name: my-nginx-service
      labels:
        run: my-nginx-service
    spec:
      ports:
      - port: 80
        targetPort: 80
        protocol: TCP
      selector:
        run: my-nginx     

    应用service单,创建service

    kubectl apply -f ./my-nginx-service.yaml

    查看相关服务
    kubectl get svc my-nginx-service

    查询服务详情
    kubectl describe svc my-nginx-service

    查看service后端结点
    kubectl get ep my-nginx-service

    4.3 创建ingress(ExtensionV1beta1)

    my-nginx-ingress.yaml

    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      name: my-nginx-ingress
      annotations:
        nginx.ingress.kubernetes.io/rewrite-target: /
    spec:
      rules:
      - http:
          paths:
          - path: /my-nginx
            backend:
              serviceName: my-nginx-service
              servicePort: 80

    应用ingress单,创建ingress

    kubectl apply -f ./my-nginx-ingress.yaml

    查看ingress

    kubectl get ingress

    4.4 创建Ingress(V1)

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: my-nginx-ingress
      annotations:
        nginx.ingress.kubernetes.io/rewrite-target: /
    spec:
      rules:
      - http:
          paths:
          - path: /my-nginx
            pathType: Prefix
            backend:
              service:
                name: my-nginx-service
                port:
                  number: 80

    4.5 相关概念总结

    k8s中配置客户端访问pod中应用的流程如下:

    client->ingress->service->pod->container

    INGRESS

    Ingress 是对集群中服务的外部访问进行管理的 API 对象,典型的访问方式是 HTTP。

    Ingress 可以提供负载均衡、SSL 终结和基于名称的虚拟托管。

    SERVICE

    将运行在一组 Pods 上的应用程序公开为网络服务的抽象方法。Kubernetes Service 定义了这样一种抽象:逻辑上的一组 Pod,一种可以访问它们的策略 —— 通常称为微服务。 Service 所针对的 Pods 集合通常是通过选择算符来确定的。

    POD

    Pod 是可以在 Kubernetes 中创建和管理的、最小的可部署的计算单元。

    Pod (就像在鲸鱼荚或者豌豆荚中)是一组(一个或多个) 容器; 这些容器共享存储、网络、以及怎样运行这些容器的声明。 Pod 中的内容总是并置(colocated)的并且一同调度,在共享的上下文中运行。 Pod 所建模的是特定于应用的“逻辑主机”,其中包含一个或多个应用容器, 这些容器是相对紧密的耦合在一起的。 在非云环境中,在相同的物理机或虚拟机上运行的应用类似于 在同一逻辑主机上运行的云应用。

    节点(Node)

    Kubernetes 集群中其中一台工作机器,是集群的一部分。

    集群(Cluster)

    一组运行由 Kubernetes 管理的容器化应用程序的节点。 在此示例和在大多数常见的 Kubernetes 部署环境中,集群中的节点都不在公共网络中。

  • 相关阅读:
    Java输入输出流详解2
    Java输入输出流详解(转)
    java泛型
    E-R图学习笔记
    MongoDB工具
    MongoDB安装
    mongodb-参考其他
    mongodb学习笔记
    WebService学习笔记
    nutch笔记
  • 原文地址:https://www.cnblogs.com/hdwang/p/14902828.html
Copyright © 2011-2022 走看看