1.引入kubernetes java SDK maven依赖

        <!–k8sclient–>

        <dependency>

            <groupId>io.kubernetes</groupId>

            <artifactId>client-java</artifactId>

            <version>12.0.1</version>

        </dependency>

        <dependency>

            <groupId>org.projectlombok</groupId>

            <artifactId>lombok</artifactId>

            <optional>true</optional>

        </dependency>

2.增加工具类

package com.mfc.common;

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 java.io.FileReader;

import java.io.IOException;

import java.util.Map;

/**

 * @author cmf

 * @date 2022/12/21

 */

@Slf4j

public class K8sUtils {

    /**

     * 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 K8sUtils() {

        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 K8sUtils(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.测试类

package k8s;

import com.mfc.common.K8sUtils;

import io.kubernetes.client.openapi.models.*;

import java.io.File;

import java.util.HashMap;

import java.util.Map;

/**

 * @author cmf

 * @date 2022/12/21

 */

public class K8sClientTest {

    public void getAllPodListTest() {

        String kubeConfigPath = "C:\\Users\\mfc\\.kube\\config";

        if (!new File(kubeConfigPath).exists()) {

            System.out.println("kubeConfig不存在");

            return;

        }

        K8sUtils k8sClient = new K8sUtils(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;

        }

        K8sUtils k8sClient = new K8sUtils(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;

        }

        K8sUtils k8sClient = new K8sUtils(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;

        }

        K8sUtils k8sClient = new K8sUtils(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: nginx-deploy

spec:

 selector:                                    #定义标签选择器

  matchLabels:                                #定义匹配的标签,必须要设置

   app: nginx                                 #匹配的目标标签    

 replicas: 3                                  #开启Pod的数量

 template:                                    #定义模板,必须定义,模板是起到描述要创建的pod的作用

  metadata:                                   #定义模板元数据

    labels:                                   #定义模板label,Deployment.spec.template.metadata.labels  

     app : nginx                              #定义标签,必须等于 matchLabels 定义的标签

  spec:                                    

   containers:

   – image: msxt.harbor.com/k8s/nginx:1.18.0    #我的镜像是从本地的Harbor上拉取

     name: nginx                                 #镜像名称

     ports:

     – containerPort: 80                         #定义容器使用的端口

应用部署单,生成pod

 kubectl apply -f ./my-nginx.yam

查看相关pod信息

kubectl get pods -l run=nginx-deploy -o wide 

4.2 创建service

my-nginx-service.yaml

apiVersion: v1kind: Servicemetadata:  name: my-nginx-service  labels:    run: my-nginx-servicespec:  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/v1beta1kind: Ingressmetadata:  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/v1kind: Ingressmetadata:  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 部署环境中,集群中的节点都不在公共网络中。

转自:https://mp.weixin.qq.com/s?__biz=MzAxMjY5NDU2Ng==&mid=2651865371&idx=1&sn=91184d1214a31b84af993c3458a4eb47&chksm=80490452b73e8d4498135e04d9342a394414cd203e3e4f1c8892e7780c26fe4118578e148050&scene=27