Java简单操作k8s,创建Deployment、Service、访问Nginx实践

 更新时间:2026年04月16日 10:44:26   作者:0302huang  
文章介绍了使用Maven依赖并初始化KubernetesClient客户端,通过配置kubeconfig文件连接Kubernetes集群,编写配置类将KubernetesClient初始化为Bean,并测试连接,最后,提供了一个访问部署在Kubernetes中的Nginx服务的示例,以及后续扩展思路

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

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Java ServletContext对象原理及功能解析

    Java ServletContext对象原理及功能解析

    这篇文章主要介绍了Java ServletContext对象原理及功能解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-06-06
  • 引入SpringCloud-gateway报错的解决方案

    引入SpringCloud-gateway报错的解决方案

    这篇文章主要介绍了引入SpringCloud-gateway报错的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-07-07
  • Java实现大文件的切割与合并操作示例

    Java实现大文件的切割与合并操作示例

    这篇文章主要介绍了Java实现大文件的切割与合并操作,结合实例形式分析了java基于io及util操作大文件按指定个数分割与合并相关操作技巧,需要的朋友可以参考下
    2018-07-07
  • SpringMVC post请求的处理

    SpringMVC post请求的处理

    今天小编就为大家分享一篇解决SpringMVC接收不到ajaxPOST参数的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-07-07
  • springboot项目使用nohup将日志指定输出文件过大问题及解决办法

    springboot项目使用nohup将日志指定输出文件过大问题及解决办法

    在Spring Boot项目中,使用nohup命令重定向日志输出到文件可能会使日志文件过大,文章介绍了两种解决方法:一是创建脚本直接清除日志文件,二是创建脚本保留部分日志内容,并将这些脚本加入定时任务中,这可以有效控制日志文件的大小,避免占用过多磁盘空间
    2024-10-10
  • Java后台与微信小程序的数据交互实现

    Java后台与微信小程序的数据交互实现

    这篇文章主要介绍了Java后台与微信小程序的数据交互实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-12-12
  • Java获取classpath根路径的三种方法

    Java获取classpath根路径的三种方法

    本文介绍了在Java中获取classpath根路径的三种方法:ClassLoader.getResource、Class.getResource和System.getProperty,每种方法都有其适用场景,开发者可以根据具体需求选择合适的方法,需要的朋友可以参考下
    2026-01-01
  • SpringBoot项目中@RestControllerAdvice全局异常失效问题的解决

    SpringBoot项目中@RestControllerAdvice全局异常失效问题的解决

    @RestController注解是一个用于定义RESTful Web服务的控制器的特殊注解,它是@Controller和@ResponseBody注解的结合体,意味着你不需要在每个处理请求的方法上都添加@ResponseBody,本文给大家介绍了解决SpringBoot项目中@RestControllerAdvice全局异常失效问题
    2024-11-11
  • 深入剖析Java之String字符串

    深入剖析Java之String字符串

    这篇文章主要为大家详细介绍了Java之String字符串,重新带大家认识String字符串,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-07-07
  • MyBatis主键自增的两种实现方法

    MyBatis主键自增的两种实现方法

    本文主要介绍了MyBatis主键自增的两种实现方法,主要包括注解方式或配置文件方式来实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-01-01

最新评论