乐趣区

关于云计算:Kubernetes官方java客户端之五proto基本操作

欢送拜访我的 GitHub

https://github.com/zq2599/blog_demos

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

概览

  1. 本文是《Kubernetes 官网 java 客户端》系列的第五篇,以下提到的 <font color=”blue”>java 客户端 </font> 都是指 <font color=”red”>client-jar.jar</font>;
  2. 通过后面四篇文章的筹备和尝试,咱们对 java 客户端有了初步理解,也胜利运行了 hello world,接下来要做的是持续深刻学习和实际,把握这门利器;

两个次要脉络

  • java 客户端的基本功能并不简单,就是以何种伎俩发动对 K8S 资源的增删改查申请,把握以下两个主脉络即可:
  1. <font color=”blue”>proto 主线 </font>:用 K8S 官网的 protobuf 定义将各种资源生成 java 类,用大量 API 解决这些对象 (特点,API 极少,每个 API 都通用,解决所有类型的资源对象);
  2. <font color=”blue”>openapi 主线 </font>:应用 openapi 工具,将所有资源都主动生成增删改查的 API(特点:API 极多,每个资源都有本身的 API);

明天的文章咱们来学习和理解 <font color=”red”>proto 主线 </font>;

proto 主线的外围类 ProtoClient

  1. 后面曾提到 proto 主线的特点是 API 极少,咱们来看看这些大量的 API 的源头:<font color=”blue”>ProtoClient 类 </font>

  1. 如上图所示,ProtoClient 提供了增删改查接口,咱们能够用这些接口实现对 K8S 资源的操作;
  2. 有了接口,接下来要搞清楚参数怎么筹备,先看 create 办法的源码,看它须要什么样的参数:

  1. 如上图所示,create 办法的第一个参数就是 <font color=”blue”>K8S 资源类 </font>,该类的个性是在泛型中束缚的,必须实现 <font color=”blue”>com.google.protobuf.Message</font> 的子接口;
  2. 这些入参 Message 的子类从哪里来呢?例如咱们要创立一个 NameSpace 的时候,是本人写一个 Message 子类?还是说哪里有现成的?接下来要做的就是搞清楚 K8S 资源类来自哪里?毕竟所有 K8S 资源的操作都要用上这些 java 类;
  3. 一起去 <font color=”blue”>java 客户端 </font> 的源码寻找线索,这是父子构造的 maven 工程,在名为 <font color=”blue”>client-java-proto</font> 的子工程中,它的 README 文件给出了线索,地址是:https://github.com/kubernetes…,如下图:

  1. 上图红框中的操作向咱们揭示了整个过程:先去下载另一个 github 仓库,而后此仓库里有脚本 generate.sh,该脚本依据 protobuf 配置生成 java 类,这些 java 文件被搁置在 <font color=”blue”>java/proto/src/main/java</font> 目录下;
  2. 本文是学习 K8S 官网 java 客户端的文章,无关 K8S 的 protobuf 详情不在这里开展,只给出一段要害脚本供您参考,这是依据 proto 主动生成代码时执行的脚本,用于下载 protobuf 文件,地址:https://github.com/kubernetes…,如下图:

  1. 上图红框中的地址是:https://raw.githubusercontent…,内容如下,java 客户端中的 java 代码就是依据这些内容生成的:

  1. 联合后面的剖析,再回到 java 客户端源码的子工程 <font color=”blue”>client-java-proto</font>,能够找到 generate.sh 脚本生成的 V1.java,这个 java 文件外面有 V1 版本的所有 protobuf 对象,如下图:

  1. 上图红框中 <font color=”blue”>Namespace</font> 类是 GeneratedMessageV3 的子类,来看下 GeneratedMessageV3 的继承关系,如下图,该类实现了 Message 接口,满足 ProtoClient.create 办法对入参的泛型束缚:

小结

  1. ProtoClient 类提供的操作 K8S 资源的增删改查办法;
  2. java 客户端的 client-java-proto 子工程内,有通过 K8S 官网 protobuf 生成的对象类,这些类就是 ProtoClient 的增删查用到的参数;
  3. 增删改查办法有了,波及的对象也有了,接下来能够实战了;

实战前的筹备

当初还不能马上写代码,还差最初一个筹备步骤:<font color=”red”> 确认 API 参数 </font>;

  • 假如实战的内容是查问 kube-system 这个 namespace 上面的所有 pod 列表,那么 API 相干信息在哪获取:
  1. 关上 API 在线文档,我这里 K8S 版本是 1.15,地址是:https://v1-15.docs.kubernetes…
  2. 如下图,红框 1 是 pod 列表的接口文档,红框 2 显示了该 URL,有了这个 URL 咱们能够编码了:

  1. 在今后的操作中,所有资源都能够依据该文档找到对应的 API 信息,辅助咱们编码;
  2. 终于,能够开始实战了;

源码下载

  1. 如果您不想编码,能够在 GitHub 下载所有源码,地址和链接信息如下表所示 (https://github.com/zq2599/blo…:
名称 链接 备注
我的项目主页 https://github.com/zq2599/blo… 该我的项目在 GitHub 上的主页
git 仓库地址 (https) https://github.com/zq2599/blo… 该我的项目源码的仓库地址,https 协定
git 仓库地址 (ssh) git@github.com:zq2599/blog_demos.git 该我的项目源码的仓库地址,ssh 协定
  1. 这个 git 我的项目中有多个文件夹,本章的利用在 <font color=”blue”>kubernetesclient</font> 文件夹下,如下图红框所示:

开始编码

  1. 关上《Kubernetes 官网 java 客户端之一:筹备》中创立的 kubernetesclient 工程,在外面新建子工程 <font color=”blue”>protobufclient</font>,其 pom.xml 内容如下,要留神的是 spring-boot-starter-json 曾经被排除,因而序列化工具会变为 Gson(本来默认是 jackson):
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <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>protobufclient</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>protobufclient</name>
    <description>Demo project for protobuf client</description>
    <packaging>jar</packaging>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-json</artifactId>
                </exclusion>
            </exclusions>
        </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>
            </plugin>
        </plugins>
    </build>

</project>
  1. 新增 <font color=”blue”>ProtobufApplication.java</font>,这是新工程的疏导类,也有通过 ProtoClient 查问 pod 列表的代码:
package com.bolingcavalry.protobufclient;

import com.google.gson.GsonBuilder;
import io.kubernetes.client.ProtoClient;
import io.kubernetes.client.ProtoClient.ObjectOrStatus;
import io.kubernetes.client.openapi.ApiClient;
import io.kubernetes.client.proto.Meta;
import io.kubernetes.client.proto.V1.Namespace;
import io.kubernetes.client.proto.V1.PodList;
import io.kubernetes.client.util.ClientBuilder;
import io.kubernetes.client.util.KubeConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.io.FileReader;

@SpringBootApplication
@RestController
@Slf4j
public class ProtobufApplication {public static void main(String[] args) {SpringApplication.run(ProtobufApplication.class, args);
    }

    /**
     * 依据配置文件创立 ProtoClient 实例
     * @return
     * @throws Exception
     */
    private ProtoClient buildProtoClient() throws Exception {
        // 寄存 K8S 的 config 文件的全门路
        String kubeConfigPath = "/Users/zhaoqin/temp/202007/05/config";
        // 以 config 作为入参创立的 client 对象,能够拜访到 K8S 的 API Server
        ApiClient client = ClientBuilder
                .kubeconfig(KubeConfig.loadKubeConfig(new FileReader(kubeConfigPath)))
                .build();

        // 创立操作类
        return new ProtoClient(client);
    }

    @RequestMapping(value = "/createnamespace/{namespace}", method = RequestMethod.GET)
    public ObjectOrStatus<Namespace> createnamespace(@PathVariable("namespace") String namespace) throws Exception {
        // 创立 namespace 资源对象
        Namespace namespaceObj =
                Namespace.newBuilder().setMetadata(Meta.ObjectMeta.newBuilder().setName(namespace).build()).build();

        // 通过 ProtoClient 的 create 接口在 K8S 创立 namespace
        ObjectOrStatus<Namespace> ns = buildProtoClient().create(namespaceObj, "/api/v1/namespaces", "v1", "Namespace");

        // 应用 Gson 将汇合对象序列化成 JSON,在日志中打印进去
        log.info("ns info \n{}", new GsonBuilder().setPrettyPrinting().create().toJson(ns));

        return ns;
    }

    @RequestMapping(value = "/pods/{namespace}", method = RequestMethod.GET)
    public ObjectOrStatus<PodList> pods(@PathVariable("namespace") String namespace) throws Exception {
        // 通过 ProtoClient 的 list 接口获取指定 namespace 下的 pod 列表
        ObjectOrStatus<PodList> pods = buildProtoClient().list(PodList.newBuilder(), "/api/v1/namespaces/" + namespace + "/pods");

        // 应用 Gson 将汇合对象序列化成 JSON,在日志中打印进去
        log.info("pod info \n{}", new GsonBuilder().setPrettyPrinting().create().toJson(pods));

        return pods;
    }
}
  1. 上述代码展现了 ProtoClient 的 API 的用法,一个是获取 pod 列表,一个是创立 namespace;

验证

  1. 确保 K8S 环境的 config 文件在本地能够拜访 (代码中 kubeConfigPath 变量的值);
  2. 运行 ProtobufApplication;
  3. 先尝试获取 <font color=”blue”>kube-system</font> 这个 namespace 下的所有 pod 列表,在浏览器拜访:http://localhost:8080/pods/kube-system,响应如下图,红框中的 items_数组就是所有 pod 信息:

  1. 上图中的 <font color=”blue”>items_</font> 数组,开展一个却 name 字段是 byte 数组,没方法看出实在内容:

  1. 借助 IDEA 的断点性能,能够看清上述 <font color=”blue”>name_</font> 字段的内容,如下图:

  1. 再来试试创立 namespace 的性能,浏览器执行:http://localhost:8080/createnamespace/aaabbbccc,就会创立名为 <font color=”blue”>aaabbbccc</font> 的 namespace,并将 <font color=”blue”>ProtoClient.create</font> 的返回信息展示到浏览器上:

  1. SSH 登录上 K8S 服务器,查看 namespace,如下图红框,能够见到新增的 namespace:

  1. 验证实现,基于 ProtoClient 的 API 和 K8S 官网的在线 API 文档,咱们能够轻松操作 K8S 环境;

ProtoClient 的短板

  1. ProtoClient 的短板其实在后面曾经提到了,如下图红框 4 所示,在线 API 文档中提到查问 pod 列表的时候能够输出一些参数(例如过滤条件),然而 ProtoClient 提供的 API 咱们也看过了,并不反对输出查问参数:

  1. 来看下 ProtoClient 申请 K8S Api service 的外围代码,如下图红框所示,<font color=”red”> 申请参数字段曾经写死 </font>,所以里面调用 ProtoClient 的 API 时基本没方法把参数传进来:

  1. 咱们能够参考上述代码本人写一段,把红框地位改为 API 文档中指定的参数,然而,这样仿佛稍微麻烦,还有更好的方法吗?
  • 当然有,敬请期待下一篇,一起学习和实战 openapi 主线;

你不孤独,欣宸原创一路相伴

  1. Java 系列
  2. Spring 系列
  3. Docker 系列
  4. kubernetes 系列
  5. 数据库 + 中间件系列
  6. DevOps 系列

欢送关注公众号:程序员欣宸

微信搜寻「程序员欣宸」,我是欣宸,期待与您一起畅游 Java 世界 …
https://github.com/zq2599/blog_demos

退出移动版