您的位置 首页 java

K8S官方java客户端之四:内部应用

欢迎访问我的GitHub

内容:所有原创文章分类汇总及配套源码,涉及 Java docker 、Kubernetes、DevOPS等;

概览

  • 本文是《K8S官方java客户端》系列的第四篇,以下提到的 java客户端 都是指 client-jar.jar
  • 前文《 》中,咱们开发了一个名为 OutsideclusterApplication 的SpringBoot应用,该应用并未部署在K8S环境,而是远程访问K8S环境内部的API Server,整体结构如下:

K8S官方java客户端之四:内部应用

  • 除了前文中部署在外部的方式,还有一种常见场景:使用 java客户端 的应用自身也部署在K8S环境中,如下图所示,名为 DemoApplication 的SpringBoot应用部署在K8S环境内,调用 java客户端 库的API对K8S进行各种操作,整体结构如下:
  • K8S官方java客户端之四:内部应用

  • 本文的内容就是开发上图中名为 DemoApplication 的应用,并且部署在K8S环境中进行验证;
  • 额外准备

  • 前文《 》的实战是一次常规的SpringBoot应用开发,本文的实战和前文略有不同,您需要对以下知识点有所了解:
    1. SpringBoot制作成docker镜像,首选官方推荐的方式,参考《 》、《 》
    2. SpringBoot应用在K8S环境下的探针技术,参考《 》、《 》、《 》

    源码下载

  • 如果您不想编码,可以在GitHub下载所有源码,地址和链接信息如下表所示(
    • 这个git项目中有多个文件夹,《K8S官方java客户端》系列的源码在 kubernetes client 文件夹下,如下图红框所示:

    开发K8S环境内的应用:DemoApplication

    • 打开《K8S官方java客户端:准备》中创建的的 kubernetesclient 工程,在里面创建子工程,名为 helloworld ,这是个SpringBoot工程, pom .xml内容如下:
     <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="#34; xmlns:xsi="#34;
             xsi:schemaLocation=" #34;>
        <modelVersion>4.0.0</modelVersion>
    
        <parent>
            <groupId>com.bolingcavalry</groupId>
            <artifactId>kubernetesclient</artifactId>
            <version>1.0-SNAPSHOT</version>
            <relativePath>../pom.xml</relativePath>
        </parent>
    
        <groupId>com.bolingcavalry</groupId>
        <artifactId>helloworld</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>helloworld</name>
        <description>Demo project for Spring Boot</description>
        < packaging >jar</packaging>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-actuator</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <optional>true</optional>
            </dependency>
            
            <dependency>
                <groupId>io.kubernetes</groupId>
                <artifactId>client-java</artifactId>
            </dependency>
    
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                    <version>2.3.0.RELEASE</version>
                    <!--该配置会在jar中增加layer描述文件,以及提取layer的工具-->
                    <configuration>
                        <layers>
                            <enabled>true</enabled>
                        </layers>
                    </configuration>
                </plugin>
            </plugins>
        </build>
    
    </project>  
    • 编写java代码,创建DemoApplication.java,这里为了简单起见,将引导类和web controller的代码都写在DemoApplication类中:
     package com.bolingcavalry.demo;
    
    import com.google.gson.Gson;
    import io.kubernetes.client. openapi .ApiClient;
    import io.kubernetes.client.openapi.Configuration;
    import io.kubernetes.client.openapi.apis.CoreV1Api;
    import io.kubernetes.client.openapi.models.V1PodList;
    import io.kubernetes.client.util.Config;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.web.bind. annotation .RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import java.util.List;
    import java.util.stream.Collectors;
    
    @SpringBootApplication
    @RestController
    @Slf4j
    public class DemoApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(DemoApplication.class, args);
        }
    
        @RequestMapping(value = "/hello")
        public List<String> hello() throws Exception {
            ApiClient client = Config.defaultClient();
            Configuration.setDefaultApiClient(client);
    
            CoreV1Api api = new CoreV1Api();
    
            // 调用客户端API取得所有pod信息
            V1PodList v1PodList = api.listPodForAllNamespaces(null, null, null, null, null, null, null, null, null);
    
            // 使用Gson将集合对象 序列化 成JSON,在日志中打印出来
            log.info("pod info n{}", new Gson().toJson(v1PodList));
    
            return v1PodList
                    .getItems()
                    .stream()
                    .map(value ->
                            value.getMetadata().getNamespace()
                            + ":"
                            + value.getMetadata().getName())
                    .collect(Collectors.toList());
        }
    
    }
      
    • 还记得《 》提到的序列化问题吗?上述代码中,log.info那段代码里对V1PodList执行序列化的是Gson,并且hello方法返回的也不是V1PodList实例,而是新做的一个List实例,这样做是因为jackson对V1PodList做序列化会导致异常,这里要避免jackson参与序列化操作;
    • 应用的代码已经写完,接下来是镜像制作用到的Dockerfile文件,该文件和刚才创建的pom.xml文件在同一个目录下(即子工程 helloworld 的文件夹下),Dockerfile文件内容如下:
     # 指定基础镜像,这是分阶段构建的前期阶段
    FROM openjdk:8u212-jdk-stretch as builder
    # 执行工作目录
    WORKDIR application
    # 配置参数
    ARG JAR_FILE=target/*.jar
    # 将编译构建得到的jar文件复制到镜像空间中
    COPY ${JAR_FILE} application.jar
    # 通过工具spring-boot-jarmode-layertools从application.jar中提取拆分后的构建结果
    RUN java -Djarmode=layertools -jar application.jar extract
    
    # 正式构建镜像
    FROM openjdk:8u212-jdk-stretch
    WORKDIR application
    # 前一阶段从jar中提取除了多个文件,这里分别执行COPY命令复制到镜像空间中,每次COPY都是一个layer
    COPY --from=builder application/dependencies/ ./
    COPY --from=builder application/spring-boot-loader/ ./
    COPY --from=builder application/snapshot-dependencies/ ./
    COPY --from=builder application/application/ ./
    ENTRYPOINT ["java", "org.springframework.boot.loader.JarLauncher"]  
    • 在子工程pom.xml文件所在目录执行以下命令完成编译构建:
     mvn clean package -U -DskipTests  
    • 接下来要制作镜像文件了,请确保当前电脑已经安装并运行了docker,另外构建docker镜像的操作我仅在macOS和Linux操作系统下执行成功,在Windows环境能否成功请自行尝试;
    • 在Dockerfile所在目录执行以下命令即可创建docker镜像文件:
     docker build -t 192.168.50.43:5888/common/helloworld:1.0-SNAPSHOT .  
    • 上述命令执行成功后,镜像文件还只是在本机的docker仓库中,请放置到K8S环境可以访问的地方,我这里是在内网部署了镜像仓库Harbor,执行以下命令即可从本地仓库推送到Harbor(可能需要先登录,与Harbor的设置有关):

    • 镜像准备完成,接下来就是在K8S环境部署了,在K8S环境创建名为helloworld.yaml的文件,内容如下,可见deployment和service都配置好了,另外请注意serviceAccountName属性的值为kubernates-client-service-account,此serviceAccountName是在《 》一文中创建好的RBAC资源,令咱们开发的 helloworld 应用有权限请求API Server:
     apiVersion: v1
    kind: Service
    metadata:
      name: helloworld
      namespace : kubernetesclient
    spec:
      type: NodePort
      ports:
        - port: 8080
          nodePort: 30100
      selector:
        name: helloworld
    ---
    apiVersion: extensions/v1beta1
    kind: Deployment
    metadata:
      namespace : kubernetesclient
      name: helloworld
    spec:
      replicas: 1
      template:
        metadata:
          labels:
            name: helloworld
        spec:
          serviceAccountName: kubernates-client-service-account
          containers:
            - name: helloworld
              image: 192.168.50.43:5888/common/helloworld:1.0-SNAPSHOT
              tty: true
              livenessProbe:
                httpGet:
                  path: /actuator/health/liveness
                  port: 8080
                initialDelaySeconds: 5
                failureThreshold: 10
                timeoutSeconds: 10
                periodSeconds: 5
              readinessProbe:
                httpGet:
                  path: /actuator/health/readiness
                  port: 8080
                initialDelaySeconds: 5
                timeoutSeconds: 10
                periodSeconds: 5
              ports:
                - containerPort: 8080
              resources:
                requests:
                  memory: "512Mi"
                  cpu: "100m"
                limits:
                  memory: "1Gi"
                  cpu: "1000m"  
    • helloworld.yaml所在目录执行命令: kubectl apply -f helloworld.yaml

    • 我这边,上图中的Pod所在宿主机IP地址是 192.168.50.135 ,因此用浏览器访问 ,如下图,可见当前K8S环境下所有Pod名称都返回了:

    至此,SpringBoot应用通过K8S官方java客户端,成功获取了自身所在K8S环境的信息,通过前文和本章,咱们对K8S官方java客户端已经有了基本的认识,接下来的实战会开启这个客户端更丰富的能力;

    欢迎关注我的公众号:程序员欣宸

    文章来源:智云一二三科技

    文章标题:K8S官方java客户端之四:内部应用

    文章地址:https://www.zhihuclub.com/183759.shtml

    关于作者: 智云科技

    热门文章

    网站地图