2021-01-07

Return Homezq2599
CnBlogsHomeNew PostContactAdminSubscription订阅Posts - 134 Articles - 0 Comments - 21
Kubernetes官方java客户端之五:proto基本操作
欢迎访问我的GitHub
https://github.com/zq2599/blog_demos

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

概览
本文是《Kubernetes官方java客户端》系列的第五篇,以下提到的java客户端都是指client-jar.jar;
经过前面四篇文章的准备和尝试,我们对java客户端有了初步了解,也成功运行了hello world,接下来要做的是继续深入学习和实践,掌握这门利器;
两个主要脉络
java客户端的基本功能并不复杂,就是以何种手段发起对K8S资源的增删改查请求,把握以下两个主脉络即可:
proto主线:用K8S官方的protobuf定义将各种资源生成java类,用少量API处理这些对象(特点,API极少,每个API都通用,处理所有类型的资源对象);
openapi主线:使用openapi工具,将所有资源都自动生成增删改查的API(特点:API极多,每个资源都有自身的API);
今天的文章咱们来学习和了解proto主线;

proto主线的核心类ProtoClient
前面曾提到proto主线的特点是API极少,咱们来看看这些少量的API的源头:ProtoClient类
在这里插入图片描述

如上图所示,ProtoClient提供了增删改查接口,我们可以用这些接口实现对K8S资源的操作;

有了接口,接下来要搞清楚参数怎么准备,先看create方法的源码,看它需要什么样的参数:
在这里插入图片描述

如上图所示,create方法的第一个参数就是K8S资源类,该类的特性是在泛型中约束的,必须实现com.google.protobuf.Message的子接口;

这些入参Message的子类从哪里来呢?例如我们要创建一个NameSpace的时候,是自己写一个Message子类?还是说哪里有现成的?接下来要做的就是搞清楚K8S资源类来自哪里?毕竟所有K8S资源的操作都要用上这些java类;

一起去java客户端的源码寻找线索,这是父子结构的maven工程,在名为client-java-proto的子工程中,它的README文件给出了线索,地址是:https://github.com/kubernetes-client/java/tree/master/proto ,如下图:
在这里插入图片描述

上图红框中的操作向我们揭示了整个过程:先去下载另一个github仓库,然后此仓库里有脚本generate.sh,该脚本根据protobuf配置生成java类,这些java文件被放置在java/proto/src/main/java目录下;

本文是学习K8S官方java客户端的文章,有关K8S的protobuf详情不在这里展开,只给出一段关键脚本供您参考,这是根据proto自动生成代码时执行的脚本,用于下载protobuf文件,地址:https://github.com/kubernetes-client/gen/blob/master/proto/dependencies.sh ,如下图:
在这里插入图片描述

上图红框中的地址是:https://raw.githubusercontent.com/kubernetes//api/master/rbac/v1alpha1/generated.proto ,内容如下,java客户端中的java代码就是根据这些内容生成的:
在这里插入图片描述

结合前面的分析,再回到java客户端源码的子工程client-java-proto,可以找到generate.sh脚本生成的V1.java,这个java文件里面有V1版本的所有protobuf对象,如下图:
在这里插入图片描述

上图红框中Namespace类是GeneratedMessageV3的子类,来看下GeneratedMessageV3的继承关系,如下图,该类实现了Message接口,满足ProtoClient.create方法对入参的泛型约束:
在这里插入图片描述

小结
ProtoClient类提供的操作K8S资源的增删改查方法;
java客户端的client-java-proto子工程内,有通过K8S官方protobuf生成的对象类,这些类就是ProtoClient的增删查用到的参数;
增删改查方法有了,涉及的对象也有了,接下来可以实战了;
实战前的准备
现在还不能马上写代码,还差最后一个准备步骤:确认API参数;

假设实战的内容是查询kube-system这个namespace下面的所有pod列表,那么API相关信息在哪获取:
打开API在线文档,我这里K8S版本是1.15,地址是:https://v1-15.docs.kubernetes.io/docs/reference/generated/kubernetes-api/v1.15/

如下图,红框1是pod列表的接口文档,红框2显示了该URL,有了这个URL我们可以编码了:
在这里插入图片描述

在今后的操作中,所有资源都可以根据该文档找到对应的API信息,辅助我们编码;

终于,可以开始实战了;

源码下载
如果您不想编码,可以在GitHub下载所有源码,地址和链接信息如下表所示(https://github.com/zq2599/blog_demos):
名称 链接 备注
项目主页 https://github.com/zq2599/blog_demos 该项目在GitHub上的主页
git仓库地址(https) https://github.com/zq2599/blog_demos.git 该项目源码的仓库地址,https协议
git仓库地址(ssh) [email protected]:zq2599/blog_demos.git 该项目源码的仓库地址,ssh协议
这个git项目中有多个文件夹,本章的应用在kubernetesclient文件夹下,如下图红框所示:
在这里插入图片描述
开始编码
打开《Kubernetes官方java客户端之一:准备 》中创建的kubernetesclient工程,在里面新建子工程protobufclient,其pom.xml内容如下,要注意的是spring-boot-starter-json已经被排除,因此序列化工具会变为Gson(原本默认是jackson):


4.0.0


    com.bolingcavalry
    kubernetesclient
    1.0-SNAPSHOT
    ../pom.xml


com.bolingcavalry
protobufclient
0.0.1-SNAPSHOT
protobufclient
Demo project for protobuf client
jar


    
        org.springframework.boot
        spring-boot-starter-web
        
            
                org.springframework.boot
                spring-boot-starter-json
            
        
    

    
        org.projectlombok
        lombok
        true
    

    
        io.kubernetes
        client-java
    




    
        
            org.springframework.boot
            spring-boot-maven-plugin
            2.3.0.RELEASE
        
    

新增ProtobufApplication.java,这是新工程的引导类,也有通过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 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 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 pods(@PathVariable("namespace") String namespace) throws Exception {
    // 通过ProtoClient的list接口获取指定namespace下的pod列表
    ObjectOrStatus 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;

先尝试获取kube-system这个namespace下的所有pod列表,在浏览器访问:http://localhost:8080/pods/kube-system ,响应如下图,红框中的items_数组就是所有pod信息:
在这里插入图片描述

上图中的items_数组,展开一个却name字段是byte数组,没办法看出真实内容:
在这里插入图片描述

借助IDEA的断点功能,可以看清上述name_字段的内容,如下图:
在这里插入图片描述

再来试试创建namespace的功能,浏览器执行:http://localhost:8080/createnamespace/aaabbbccc ,就会创建名为aaabbbccc的namespace,并将ProtoClient.create的返回信息展现到浏览器上:
在这里插入图片描述

SSH登录上K8S服务器,查看namespace,如下图红框,可以见到新增的namespace:
在这里插入图片描述

验证完成,基于ProtoClient的API和K8S官方的在线API文档,我们可以轻松操作K8S环境;

ProtoClient的短板
ProtoClient的短板其实在前面已经提到了,如下图红框4所示,在线API文档中提到查询pod列表的时候可以输入一些参数(例如过滤条件),但是ProtoClient提供的API咱们也看过了,并不支持输入查询参数:
在这里插入图片描述

来看下ProtoClient请求K8S Api service的核心代码,如下图红框所示,请求参数字段已经写死,所以外面调用ProtoClient的API时根本没办法把参数传进来:
在这里插入图片描述

咱们可以参考上述代码自己写一段,把红框位置改为API文档中指定的参数,但是,这样似乎略微麻烦,还有更好的办法吗?

当然有,敬请期待下一篇,一起学习和实战openapi主线;
你不孤单,欣宸原创一路相伴
Java系列
Spring系列
Docker系列
kubernetes系列
数据库+中间件系列
DevOps系列
欢迎关注公众号:程序员欣宸
微信搜索「程序员欣宸」,我是欣宸,期待与您一同畅游Java世界…
https://github.com/zq2599/blog_demos

好文要顶 关注我 收藏该文
程序员欣宸
关注 - 4
粉丝 - 17
+加关注
00
« 上一篇: Kubernetes官方java客户端之四:内部应用
posted @ 2021-01-07 07:51 程序员欣宸 Views(30) Comments(0) Edit 收藏
刷新评论刷新页面返回顶部
登录后才能发表评论,立即 登录 或 注册, 访问 网站首页
【推荐】News: 大型组态、工控、仿真、CADGIS 50万行VC++源码免费下载
【推荐】有你助力,更好为你——博客园用户消费观调查,附带小惊喜!
【推荐】AWS携手博客园为开发者送福利,注册立享12个月免费套餐
【推荐】七牛云新老用户同享 1 分钱抢 CDN 1TB流量大礼包!
【推荐】了不起的开发者,挡不住的华为,园子里的品牌专区
【推荐】未知数的距离,毫秒间的传递,声网与你实时互动
【推荐】新一代 NoSQL 数据库,Aerospike专区新鲜入驻

相关博文:
· kubernetes之部署java项目
· Kubernetes
· kubernetes
· Kubernetes Ingress
· Kubernetes Nacos
» 更多推荐…

最新 IT 新闻:
· 互联网新巨头二号位简史
· BAT移动生态战争2021:对生态的研究和发力成为重中之重
· 《绝地求生》续作或正在开发 登陆PC/主机/移动端
· 特斯拉与BBA,必有一战
· 一线|瑞幸郭谨一回应被“逼宫”:举报信是陆正耀等起草,当事员工不知情
» 更多新闻…
昵称: 程序员欣宸
园龄: 8年
粉丝: 17
关注: 4
+加关注
< 2021年1月 >
日 一 二 三 四 五 六
27 28 29 30 31 1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31 1 2 3 4 5 6
Search

My Tags
CI(1)
DevOps(1)
GitLab(1)
java(1)
springboot(1)
PostArchives
2021/1(4)
2020/12(13)
2020/11(23)
2020/10(27)
2020/9(6)
2020/6(7)
2019/11(5)
2019/10(6)
2019/9(41)
2019/8(2)
Recent Comments

  1. Re:群晖DS218+部署GitLab
    大佬,麻烦问下内存是哪个牌子的吗?可以私信连接吗?

–a403828237
2. Re:Flink SQL Client综合实战
老师您好,我是开源中国的内容志愿者李艳,想跟您聊聊内容合作,能否加下您的微信或qq给您详细说明下

–爱吃甜品的女孩
3. Re:K8S的Kafka监控(Prometheus+Grafana)
666呀!

–monkey’s
4. Re:K8S的Kafka监控(Prometheus+Grafana)
@通用C#系统架构 谢谢您的反馈…
–程序员欣宸
5. Re:K8S的Kafka监控(Prometheus+Grafana)
非常好的文章,整套能搭建起来很棒。

–通用C#系统架构
Top Posts

  1. 树莓派4B安装64位Linux(不用显示器键盘鼠标)(12436)
  2. 设置IntelliJ IDEA支持lambda表达式(7473)
  3. Jenkins流水线(pipeline)实战之:从部署到体验(2631)
  4. 树莓派4B安装docker-compose(64位Linux)(2153)
  5. 让docker中的mysql启动时自动执行sql(2141)
    推荐排行榜
  6. Jenkins把GitHub项目做成Docker镜像(3)
  7. GitLab CI构建SpringBoot-2.3应用(2)
  8. springboot的jar为何能独立运行(2)
  9. 设置非root账号不用sudo直接执行docker命令(2)
  10. 群晖DS218+部署mysql(2)
    Copyright © 2021 程序员欣宸
    Powered by .NET 5.0 on Kubernetes

你可能感兴趣的:(2021-01-07)