proto 客户端 JAVA_Kubernetes官方java客户端之五:proto基本操作

欢迎访问我的GitHub

内容:所有原创文章分类汇总及配套源码,涉及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类

355af4033cd98113f0395584c289f385.png

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

有了接口,接下来要搞清楚参数怎么准备,先看create方法的源码,看它需要什么样的参数:

afffdeb2909654fa30f01e28cd7e42e0.png

如上图所示,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 ,如下图:

df5bc80d64f556b42bd5afc8d33dcb41.png

上图红框中的操作向我们揭示了整个过程:先去下载另一个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 ,如下图:

10ccf068416719dd2717d8a00b426cf3.png

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

6bbc8e82df54e690777a5b14676e9795.png

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

a1b5884097079436d9f2bfad3ed8dd02.png

小结ProtoClient类提供的操作K8S资源的增删改查方法;

java客户端的client-java-proto子工程内,有通过K8S官方protobuf生成的对象类,这些类就是ProtoClient的增删查用到的参数;

增删改查方法有了,涉及的对象也有了,接下来可以实战了;

实战前的准备

现在还不能马上写代码,还差最后一个准备步骤:确认API参数;假设实战的内容是查询kube-system这个namespace下面的所有pod列表,那么API相关信息在哪获取:如下图,红框1是pod列表的接口文档,红框2显示了该URL,有了这个URL我们可以编码了:

6057faf69aa4fa9c5e36ff3658a45848.png

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

终于,可以开始实战了;

源码下载如果您不想编码,可以在GitHub下载所有源码,地址和链接信息如下表所示(https://github.com/zq2599/blog_demos):名称链接备注git仓库地址(ssh)git@github.com:zq2599/blog_demos.git该项目源码的仓库地址,ssh协议这个git项目中有多个文件夹,本章的应用在kubernetesclient文件夹下,如下图红框所示:

6b54b3e88012a55bf311dce5dbce8daa.png

开始编码打开《Kubernetes官方java客户端之一:准备 》中创建的kubernetesclient工程,在里面新建子工程protobufclient,其pom.xml内容如下,要注意的是spring-boot-starter-json已经被排除,因此序列化工具会变为Gson(原本默认是jackson):<?xml  version="1.0" encoding="UTF-8"?>

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">

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信息:

7da445459ed2b162941cf5b8e5d8024a.png

上图中的items_数组,展开一个却name字段是byte数组,没办法看出真实内容:

88761fe6ebf687e926380fdd11df5b46.png

借助IDEA的断点功能,可以看清上述name_字段的内容,如下图:

13db1d034882ccdcfe9449535ecc316c.png

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

b2b409c50c0269649c2f1cc2d79618b1.png

SSH登录上K8S服务器,查看namespace,如下图红框,可以见到新增的namespace:

0f12a38cde8e6454154f724793f1e66c.png

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

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

947026f2c566566f12aa0f1afaeb9387.png

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

2d6c5532314cd2f9e29e585f1d5251de.png

咱们可以参考上述代码自己写一段,把红框位置改为API文档中指定的参数,但是,这样似乎略微麻烦,还有更好的办法吗?当然有,敬请期待下一篇,一起学习和实战openapi主线;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值