使用Kubernetes的java-client实现Deployment的部署及更新操作
程序员文章站
2022-07-09 21:38:39
使用Kubernetes的java-client,实现Deployment的代码部署以及更新操作 ......
1. 背景介绍
需求: 针对多种协议sdk
构造探针,测试公司接入机服务状况(每一个探针应对单一接入机,接入机数量可能会动态变化).
难点: 大多数协议sdk
均不支持多实例运行,且部分sdk
通过生成文件保存内部状态;各协议sdk
处于迭代状态,不能对其进行魔改.
分析:
(1) 基于以上原因,无法选择多线程或者多进程,在单一物理机或容器内完成探针相应功能;
(2) 尝试通过kubernetes
部署探针容器,通过容器完成不同协议sdk
的进程隔离乃至文件隔离
;
(3) 通过deployment
设置容器环境参数
的方式,给不同容器设置对应的启动参数;
(4) kubernetes
控制程序通过apollo
动态获取配置,更新相应协议的deployment
,从而更新相关容器镜像.
2. 依赖设置
pom
文件中添加kubernetes
以及apollo
依赖:
<dependency> <groupid>io.kubernetes</groupid> <artifactid>client-java</artifactid> <version>4.0.0</version> <scope>compile</scope> </dependency> <dependency> <groupid>com.ctrip.framework.apollo</groupid> <artifactid>apollo-client</artifactid> <version>1.1.0</version> </dependency>
3. 部署deployment
3.1 获取api client
注意,此处我们使用extensionsv1beta1api
,对应api version: extensions/v1beta1
.
在实际操作中,可以通过kubectl version
获取api server
支持的版本.
apiclient client; try { client = config.defaultclient(); } catch (ioexception ex) { log.error("get k8s default client failed, error: [{}]", ex.getmessage()); throw new userexception(appstatus.internal_server_error, "can not get k8s default client."); } configuration.setdefaultapiclient(client); extensionsv1beta1api api = new extensionsv1beta1api(client);
3.2 创建deployment
deployment
创建需要设置如下内容:
-
api version
; -
kind
; -
meta data
; -
spec info
.
不熟悉以上元素的,可以查阅官方文档,或者通过kubernetes inaction
一书了解.
extensionsv1beta1deployment edpdeployment = new extensionsv1beta1deployment(); edpdeployment.setapiversion("extensions/v1beta1"); edpdeployment.setkind("deployment"); edpdeployment.setmetadata(createdeploymentmeta(namespace, protocoltype.edp, config)); edpdeployment.setspec(createdeploymentspec(protocoltype.edp, config)); try { appsv1api.createnamespaceddeployment(common.inspector_namespace, edpdeployment, false, null, null); } catch (apiexception e) { log.error(e.getmessage()); }
至此,可以通过kubectl
相关命令查看deployment
的创建情况.
4. 更新deployment
deployment
的更新操作比较晦涩,需要先构建arraylist<jsonobject>
存放更新操作以及相应数值(此处使用gson
),进而调用相应接口完成操作.
/** * 构造deployment的更新信息(json格式,需要指定操作类型,更新元素路径,以及更新后的数值) * 此处,仅示范如何更新pod中第一个容器(filebeta)的镜像id * @return json信息 */ public arraylist<jsonobject> getinspectorimagepatchelements() { // k8s java-client官方示例使用gson gson gson = new gson(); arraylist<jsonobject> result = new arraylist<>(); // 更新deployment中的filebeta容器镜像id deploymentpatchjson patchjson = new deploymentpatchjson("replace", "/spec/template/spec/containers/0/image", appconfig.gefilebetaimageid()); result.add((gson.fromjson(gson.tojson(patchjson), jsonelement.class)).getasjsonobject()); return result; } /** * 更新指定的deployment * */ public void patchcurrentdeployment(extensionsv1beta1api api, extensionsv1beta1deployment deployment) { arraylist<jsonobject> patchelements = inspectorservice.getinspectorimagepatchelements(); try { api.patchnamespaceddeployment(deployment.getmetadata().getname(), deployment.getmetadata().getnamespace(), patchelements, "true", null); } catch (apiexception e) { log.error("patch deployment failed, error: [{}]", e.getmessage()); } }