1.Maven依赖

<!-- k8s client -->
<dependency>
    <groupId>io.fabric8</groupId>
    <artifactId>kubernetes-client</artifactId>
    <version>4.10.2</version>
</dependency>

2.初始化 k8s 客户端

初始化KubernetesClient客户端

首先需要找到 /etc/kubernetes/admin.conf文件

在这里插入图片描述

这是连接k8s的配置文件,通过这个文件,就可以在Java程序中连接上k8s,初始化KubernetesClient客户端

将该文件的内容复制进kubeconfig,预先存好kubeconfig的文件位置:C:\Users\26411\Desktop\AI平台\kubeconfig

application.yml

k8s:
  kubeconfig: C:\Users\26411\Desktop\AI平台\kubeconfig

编写配置类,初始化KubernetesClient为Bean

@Configuration
public class K8sConfig {
    
    @Value("${k8s.kubeconfig}")
    private String kubeconfigPath;
    
    @Bean
    public KubernetesClient getClient() throws IOException {
        File configFile = new File(kubeconfigPath);
        final String configYaml = String.join("\n", Files.readAllLines(configFile.toPath()));
        Config config = Config.fromKubeconfig(configYaml);
        config.setTrustCerts(true);
        return new DefaultKubernetesClient(config);
    }
}

3.测试类测试简单功能

测试后,在 Xshell 中使用 kubectl 命令查看正常,测试成功。

@SpringBootTest
public class K8sTest {
    String namespace = "default";
    @Autowired
    private KubernetesClient kubernetesClient;

    /**
     * 获取Pod
     */
    @Test
    void testGetPod(){
        Pod pod = kubernetesClient.pods().inNamespace("kube-system").withName("kube-apiserver-master").get();
        System.out.println(pod);
    }

    /**
     * 创建deployment
     */
    @Test
    void testCreateDeployment(){
        Deployment deployment = getDeployment();
        Deployment de = kubernetesClient.apps().deployments().inNamespace(namespace).create(deployment);
    }
    
    private Deployment getDeployment() {
        Map<String, String> labels = new HashMap<>();
        labels.put("run","nginx");
        LabelSelector labelSelector = new LabelSelector();
        labelSelector.setMatchLabels(labels);
        return new DeploymentBuilder()
                .withNewMetadata()
                    .withName("nginx")
                    .withNamespace(namespace)
                    .addToLabels(labels)
                .endMetadata()
                .withNewSpec()
                    .withSelector(labelSelector)
                    .withNewTemplate()
                        .withNewMetadata()
                            .withName("nginx")
                            .addToLabels(labels)
                            .withNamespace(namespace)
                        .endMetadata()
                        .withNewSpec()
                           .addToContainers(buildContainer())
                        .endSpec()
                    .endTemplate()
                .endSpec()
                .build();
    }

    private Container buildContainer() {
        ContainerPort containerPort = new ContainerPort();
        containerPort.setProtocol("TCP");
        containerPort.setContainerPort(80);

        return new ContainerBuilder()
                .withNewName("nginx")
                .withNewImage("nginx:latest")
                .withPorts(containerPort)
                .build();
    }

    /**
     * 创建Service
     */
    @Test
    void testCreateService(){
        Service service = kubernetesClient.services().inNamespace(namespace).create(getService());
        System.out.println(service);
    }

    private Service getService() {
        HashMap<String, String> selector = new HashMap<>();
        selector.put("run","nginx");
        ServicePort port = new ServicePort();
        port.setProtocol("TCP");
        port.setPort(80);
        port.setTargetPort(new IntOrString(80));
        return new ServiceBuilder()
                .withNewMetadata()
                    .withName("svc-nginx")
                    .withNamespace(namespace)
                .endMetadata()
                .withNewSpec()
                    .withClusterIP("10.109.179.231")
                    .withPorts(port)
                    .withSelector(selector)
                    .withType("NodePort")
                .endSpec().build();
    }

}

4.编写工具类封装简单功能

@Component
public class K8sUtil {
    
    @Autowired
    private KubernetesClient kubernetesClient;

    /**
     * 获取一个 Pod
     *
     * @param namespace 名称空间
     * @param podName   Pod名字
     * @return {@link Pod}
     */
    public Pod getOnePod(String namespace, String podName){
        return kubernetesClient.pods().inNamespace(namespace).withName(podName).get();
    }

    /**
     * 创建一个 Pod
     *
     * @param namespace 名称空间
     * @param podBody   Pod内容
     * @return {@link Pod}
     */
    public Pod createOnePod(String namespace, Pod podBody){
        return kubernetesClient.pods().inNamespace(namespace).create(podBody);
    }

    /**
     * 创建Deployment
     *
     * @param deploymentDto 部署dto
     * @return {@link Deployment}
     */
    public Deployment createDeployment(DeploymentDto deploymentDto){
        Deployment deployment = getDeployment(deploymentDto);
        return  kubernetesClient.apps().deployments()
                .inNamespace(deploymentDto.getNamespace())
                .create(deployment);
    }
    
    private Deployment getDeployment(DeploymentDto deploymentDto) {
        return new DeploymentBuilder()
                .withNewMetadata()
                    .withName(deploymentDto.getDeploymentName())
                    .withNamespace(deploymentDto.getNamespace())
                    .addToLabels(deploymentDto.getLabels())
                .endMetadata()
                .withNewSpec()
                    .withReplicas(deploymentDto.getReplicas())
                    .withSelector(deploymentDto.getLabelSelector())
                    // Template() Pod模板
                    .withNewTemplate()
                        .withNewMetadata()
                            .addToLabels(deploymentDto.getLabels())
                        .endMetadata()
                        .withNewSpec()
                            .addToContainers(buildContainer(deploymentDto))
                        .endSpec()
                    .endTemplate()
                .endSpec()
                .build();
    }

    private Container buildContainer(DeploymentDto deploymentDto) {
        ContainerPort containerPort = new ContainerPort();
        containerPort.setProtocol(deploymentDto.getProtocol());
        containerPort.setContainerPort(deploymentDto.getContainerPort());

        return new ContainerBuilder()
                .withNewName(deploymentDto.getContainerName())
                .withNewImage(deploymentDto.getImage())
                .withPorts(containerPort)
                .build();
    }

    /**
     * 创建Service
     *
     * @param serviceDto 服务dto
     * @return {@link Service}
     */
    public Service createService(ServiceDto serviceDto) {
        Service service = getService(serviceDto);
        return kubernetesClient.services().inNamespace(serviceDto.getNamespace()).create(service);
    }

    private Service getService(ServiceDto serviceDto) {
        ServicePort port = new ServicePort();
        port.setProtocol(serviceDto.getProtocol());
        port.setPort(serviceDto.getPort());
        port.setTargetPort(new IntOrString(serviceDto.getTargetPort()));
        
        return new ServiceBuilder()
                .withNewMetadata()
                    .withName(serviceDto.getServiceName())
                    .withNamespace(serviceDto.getNamespace())
                .endMetadata()
                .withNewSpec()
                    //.withClusterIP()
                    .withPorts(port)
                    .withSelector(serviceDto.getSelector())
                    .withType(serviceDto.getType())
                .endSpec()
                .build();
    }
    
}

附上两个封装信息的实体类

@Data
public class DeploymentDto {
    /**
     * 名称空间
     */
    private String namespace;
    /**
     * deployment名字
     */
    private String deploymentName;
    /**
     * 副本个数
     */
    private Integer replicas;
    /**
     * Pod模板的标签、Deployment标签选择器 会匹配到的标签
     */
    private Map<String,String> labels;
    /**
     * Deployment标签选择器
     */
    private LabelSelector labelSelector;

    // spec下的 containers
    /**
     * 容器要拉取运行的镜像
     */
    private String image;
    /**
     * 容器名称
     */
    private String containerName;
    /**
     * 容器端口
     */
    private Integer containerPort;
    /**
     * 协议
     */
    private String protocol;
}

@Data
public class ServiceDto {
    /**
     * 名称空间
     */
    private String namespace;
    /**
     * Service名称
     */
    private String serviceName;
    /**
     * 端口
     */
    private Integer port;
    /**
     * 协议
     */
    private String protocol;
    /**
     * 目标端口
     */
    private Integer targetPort;
    /**
     * Service的标签选择器    选择有对应标签的Pod (但是其实通过Deployment操控)
     */
    private Map<String,String> selector;
    /**
     * 类型   :NodePort、ClusterIP等等
     */
    private String type;
}

5.访问部署的Nginx

在这里插入图片描述

访问 http://192.168.242.100:30439/

在这里插入图片描述

6.后续扩展

封装操作更多的功能,操作更多资源,例如 ingress

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐