欢送拜访我的GitHub
https://github.com/zq2599/blog_demos
内容:所有原创文章分类汇总及配套源码,波及Java、Docker、Kubernetes、DevOPS等;
概览
- 本文是《Kubernetes官网java客户端》系列的第五篇,以下提到的<font color="blue">java客户端</font>都是指<font color="red">client-jar.jar</font>;
- 通过后面四篇文章的筹备和尝试,咱们对java客户端有了初步理解,也胜利运行了hello world,接下来要做的是持续深刻学习和实际,把握这门利器;
两个次要脉络
- java客户端的基本功能并不简单,就是以何种伎俩发动对K8S资源的增删改查申请,把握以下两个主脉络即可:
- <font color="blue">proto主线</font>:用K8S官网的protobuf定义将各种资源生成java类,用大量API解决这些对象(特点,API极少,每个API都通用,解决所有类型的资源对象);
- <font color="blue">openapi主线</font>:应用openapi工具,将所有资源都主动生成增删改查的API(特点:API极多,每个资源都有本身的API);
明天的文章咱们来学习和理解<font color="red">proto主线</font>;
proto主线的外围类ProtoClient
- 后面曾提到proto主线的特点是API极少,咱们来看看这些大量的API的源头:<font color="blue">ProtoClient类</font>
- 如上图所示,ProtoClient提供了增删改查接口,咱们能够用这些接口实现对K8S资源的操作;
- 有了接口,接下来要搞清楚参数怎么筹备,先看create办法的源码,看它须要什么样的参数:
- 如上图所示,create办法的第一个参数就是<font color="blue">K8S资源类</font>,该类的个性是在泛型中束缚的,必须实现<font color="blue">com.google.protobuf.Message</font>的子接口;
- 这些入参Message的子类从哪里来呢?例如咱们要创立一个NameSpace的时候,是本人写一个Message子类?还是说哪里有现成的?接下来要做的就是搞清楚K8S资源类来自哪里?毕竟所有K8S资源的操作都要用上这些java类;
- 一起去<font color="blue">java客户端</font>的源码寻找线索,这是父子构造的maven工程,在名为<font color="blue">client-java-proto</font>的子工程中,它的README文件给出了线索,地址是:https://github.com/kubernetes... ,如下图:
- 上图红框中的操作向咱们揭示了整个过程:先去下载另一个github仓库,而后此仓库里有脚本generate.sh,该脚本依据protobuf配置生成java类,这些java文件被搁置在<font color="blue">java/proto/src/main/java</font>目录下;
- 本文是学习K8S官网java客户端的文章,无关K8S的protobuf详情不在这里开展,只给出一段要害脚本供您参考,这是依据proto主动生成代码时执行的脚本,用于下载protobuf文件,地址:https://github.com/kubernetes... ,如下图:
- 上图红框中的地址是:https://raw.githubusercontent... ,内容如下,java客户端中的java代码就是依据这些内容生成的:
- 联合后面的剖析,再回到java客户端源码的子工程<font color="blue">client-java-proto</font>,能够找到generate.sh脚本生成的V1.java,这个java文件外面有V1版本的所有protobuf对象,如下图:
- 上图红框中<font color="blue">Namespace</font>类是GeneratedMessageV3的子类,来看下GeneratedMessageV3的继承关系,如下图,该类实现了Message接口,满足ProtoClient.create办法对入参的泛型束缚:
小结
- ProtoClient类提供的操作K8S资源的增删改查办法;
- java客户端的client-java-proto子工程内,有通过K8S官网protobuf生成的对象类,这些类就是ProtoClient的增删查用到的参数;
- 增删改查办法有了,波及的对象也有了,接下来能够实战了;
实战前的筹备
当初还不能马上写代码,还差最初一个筹备步骤:<font color="red">确认API参数</font>;
- 假如实战的内容是查问kube-system这个namespace上面的所有pod列表,那么API相干信息在哪获取:
- 关上API在线文档,我这里K8S版本是1.15,地址是:https://v1-15.docs.kubernetes...
- 如下图,红框1是pod列表的接口文档,红框2显示了该URL,有了这个URL咱们能够编码了:
- 在今后的操作中,所有资源都能够依据该文档找到对应的API信息,辅助咱们编码;
- 终于,能够开始实战了;
源码下载
- 如果您不想编码,能够在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协定 |
- 这个git我的项目中有多个文件夹,本章的利用在<font color="blue">kubernetesclient</font>文件夹下,如下图红框所示:
开始编码
- 关上《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>
- 新增<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@Slf4jpublic 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; }}
- 上述代码展现了ProtoClient的API的用法,一个是获取pod列表,一个是创立namespace;
验证
- 确保K8S环境的config文件在本地能够拜访(代码中kubeConfigPath变量的值);
- 运行ProtobufApplication;
- 先尝试获取<font color="blue">kube-system</font>这个namespace下的所有pod列表,在浏览器拜访:http://localhost:8080/pods/kube-system ,响应如下图,红框中的items_数组就是所有pod信息:
- 上图中的<font color="blue">items_</font>数组,开展一个却name字段是byte数组,没方法看出实在内容:
- 借助IDEA的断点性能,能够看清上述<font color="blue">name_</font>字段的内容,如下图:
- 再来试试创立namespace的性能,浏览器执行:http://localhost:8080/createnamespace/aaabbbccc ,就会创立名为<font color="blue">aaabbbccc</font>的namespace,并将<font color="blue">ProtoClient.create</font>的返回信息展示到浏览器上:
- SSH登录上K8S服务器,查看namespace,如下图红框,能够见到新增的namespace:
- 验证实现,基于ProtoClient的API和K8S官网的在线API文档,咱们能够轻松操作K8S环境;
ProtoClient的短板
- ProtoClient的短板其实在后面曾经提到了,如下图红框4所示,在线API文档中提到查问pod列表的时候能够输出一些参数(例如过滤条件),然而ProtoClient提供的API咱们也看过了,并不反对输出查问参数:
- 来看下ProtoClient申请K8S Api service的外围代码,如下图红框所示,<font color="red">申请参数字段曾经写死</font>,所以里面调用ProtoClient的API时基本没方法把参数传进来:
- 咱们能够参考上述代码本人写一段,把红框地位改为API文档中指定的参数,然而,这样仿佛稍微麻烦,还有更好的方法吗?
- 当然有,敬请期待下一篇,一起学习和实战openapi主线;
你不孤独,欣宸原创一路相伴
- Java系列
- Spring系列
- Docker系列
- kubernetes系列
- 数据库+中间件系列
- DevOps系列
欢送关注公众号:程序员欣宸
微信搜寻「程序员欣宸」,我是欣宸,期待与您一起畅游Java世界...
https://github.com/zq2599/blog_demos