用Java开发自己的Kubernetes控制器,想试试吗?

作者 | Nicolas Fränkel

译者 | 天道酬勤 责编 | 徐威龙

封图| CSDN 下载于视觉中国

在本文中,我们将开始开发自己的Kubernetes控制器。 

技术栈可以是Python、NodeJS或Ruby。因为这个博客被命名为为“ Java极客”,因此选择Java是很正常的。 

作为一个用例,我们将实现sidecar模式:每当一个pod被调度时,sidecar pod也会随之被调度。如果将前者删除,则后者也必须删除。

选择合适的工具

 

为了用Java执行REST调用,首先需要生成绑定。有几种方法可以做到这些。最繁琐的操作是手动执行此操作:需要仔细掌握所有可能的JSON请求和响应组合,开发相应的Java对象,选择JSON序列化框架以及HTTP客户端。第二个最佳选择是使用专有代码生成器,例如Swagger(https://swagger.io/)或Apiary(https://apiary.io/)。这就要求API提供程序以一种可能的格式提供模型。不利的一面是,需要使用相关工具。有时,格式或多或少是开放的,例如OpenAPI规范(https://swagger.io/specification/)。在这种情况下,可以从实现该格式的工具中选择工具。在最好的情况下,可能已经提供了绑定。

Kubernetes就是这种情况:该项目为各种语言提供了自己的绑定(https://kubernetes.io/docs/reference/using-api/client-libraries/)。问题在于语言包装器与REST API非常接近,对于作者来说太熟悉了。例如,这是列出所有名称空间中所有pod的方式:

ApiClient client = Config.defaultClient();
CoreV1Api core = new CoreV1Api(client);
V1PodList pods =core.listPodForAllNamespaces(null, null, null, null, null, null, null, null);  

注意:所有的null参数需要传递。

这就是“包装器代码非常接近REST API”的意思。幸运的是,还有另一个选择。Fabric8组织在Github上提供了流畅的Java API。与上述代码等效的代码是:

KubernetesClient client = new DefaultKubernetesClient();
PodList pods = client.pods().inAnyNamespace().list();    注意:无需传递无用的null参数。

Fabric8组织在Github上提供了流畅的Java API:

https://github.com/fabric8io/kubernetes-client)

Fabric8快速概述

 

简单来说,使用Fabric8的API,所有Kubernetes资源都可以在KubernetesClient实例上使用,例如:

  • client.namespaces()

  • client.services()

  • client.nodes()

根据资源的性质,它的作用域可以是一个名称空间,也可以不是:

  • client.pods().inAnyNamespace()

  • client.pods().inNamespace("ns")

此时,可以调用这个动作: 

列出所有名称空间中的所有Pod:

client.pods().inAnyNamespace().list();

删除名称空间ns中的所有pod:

client.pods().delete(client.pods().inNamespace("ns").list().getItems());
创建一个名为ns的新名称空间:
client.namespaces().createNew().withApiVersion("v1").withNewMetadata().withName("ns").endMetadata().done();

实现控制循环

注意,Kubernetes控制器只是一个控制循环,它监视集群的状态,并将其与所需状态进行协调。为了能够调度/删除事件,需要使用Observer模式。应用程序将订阅此类事件,当他们发生时,相关回调将被触发。

下图是一个非常简单的API图:       

要真正实现一个监视程序,只需执行以下几行代码:

public class DummyWatcher implements Watcher<Pod> {@Overridepublic void eventReceived(Action action, Pod pod) {switch (action) {case ADDED:    //注意1        break;case MODIFIED: //注意2       break;case DELETED:  //注意3break;case ERROR:    //注意4       break;}}@Overridepublic void onClose(KubernetesClientException cause) {//注意5               }
}client.pods().inAnyNamespace().watch(DummyWatcher());注意:
  1. 添加新pod时起作用

  2. 修改现有pod时起作用

  3. 删除pod时起作用

  4. 发生错误时起作用

  5. 清理任何资源。如果客户端正确关闭,cause将为null

具体细节

 

现在,我们拥有了实现sidecar模式所需的一切。我不会展示全部代码,它可以在GitHub上找到:https://github.com/nfrankel/jvm-controller,但需要重点强调一些关键内容。

1) 标记sidecar

从本质上讲,观察者需要在添加新的pod时添加一个sidecar pod,并在移除它时删除它。这种基本方法行不通:如果安排了sidecar pod,则将触发观察者,并向sidecar添加新的sidecar pod。而且这种情况还会持续下去。因此,标记sidecar pod至关重要。检测到此类pod时,不应触发创建逻辑。

有几种标记sidecar pod的方法:

  • 在sidecar pod的名称后加上特定的字符串,例如sidecar

  • 添加如下特定标签:

client.pods().inNamespace("ns").createNew().withNewMetadata().addToLabels("sidecar", "true").endMetadata().done();

2) 连同pod一起移除sidecar

pod应只有一个sidecar。如上所述,应在添加Pod时创建它,而在删除后者时应删除它。

因此,应将对主pod的引用添加到sidecar中。这样,当pod被删除时,如果它不是一个sidecar,我们应该找到分配的sidecar并将其删除。

第一种简单的方法是在删除主pod时显式删除sidecar。但是,这是一项繁重的工作,需要花很多时间。Kubernetes允许将pod的生命周期绑定到另一个Pod的生命周期。然后,删除逻辑由Kubernetes本身处理。这由ownerReference的概念支持。

该API使其易于实现:

client.pods().inNamespace("ns").createNew().withNewMetadata().addNewOwnerReference().withApiVersion("v1").withKind("Pod").withName(podName).withUid(pod.getMetadata().getUid()).endOwnerReference().endMetadata().done();3) 始终保持一个sidecar

添加一个sidecar并不意味着它将永远保持这种方式。例如,可以删除属于部署的pod。部署的目标是重新创建一个pod,以达到所需的副本数量。

同样,如果在保留主pod的同时删除了sidecar,则应使用正确的引用生成一个新的sidecar。

 

结论

 

在这篇文章中,我们描述了如何在JVM上使用Java语言实现Kubernetes控制器。借助Fabric8的API,实现的操作非常简单。主要问题来自调度/删除逻辑中的极端情况。在本系列的下一篇(也是最后一篇)文章中,我们将最终看到如何部署和运行代码。

这篇文章的完整源代码可以在Github上以Maven格式找到:

https://github.com/nfrankel/jvm-controller

希望这篇文章对你有用,欢迎评论区和我们讨论。

原文:https://blog.frankel.ch/your-own-kubernetes-controller/2/

防疫、复工如何并行?天云数据推出人工智能监测方案!到底如何做到事前预防,而不是事后诸葛亮?本周四晚8点,天云数据VP陈勇为各位揭晓答案!扫描下方二维码免费报名~

今日福利:点击阅读原文,凭优惠码“AIP1510”都可获得价值299元的「2020 AI开发者万人大会」在线直播门票一张。  

推荐阅读:为什么要在油气行业中应用 IoT?这 8 个应用场景告诉你 IoT 在油气行业中可以做什么
生产环境使用HBase,你必须知道的最佳实践
Java 14 来了!
字节跳动武汉招聘 2000  人,距离大厂 Offer,你还差这篇 Java 干货!| 原力计划
数字合约如何将所有权下放?如何使用脚本系统将交易转换为可编程的智能合约?答案就在这篇文章里!
人生苦短,不光要用Python,还要在VSCode里用
真香,朕在看了! 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/518652.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SpringBoot 扫描包

文章目录1. 默认扫描2.指定扫描3.指定扫描21. 默认扫描 默认扫描&#xff1a; 在启动类WikiApplication上的SpringBootApplication注解&#xff0c;默认SpringBoot 扫描范围是当前包(com.gblfy.wiki)以及子包controller包等等 2.指定扫描 扫描项目包但不能扫描第三方的包&a…

揭秘阿里云背后神秘而富有能量的一群人

作为某创业公司CTO兼CTO兼CFO&#xff0c;带领众子弟行走于云端计算&#xff0c;累计犒赏已达757157.09银两&#xff0c;江湖人称紫龙&#xff0c;就是众多阿里云大使中低调内敛的一位。其话不多&#xff0c;一个典型的技术男&#xff0c;但又热心钻研传播推广&#xff0c;不到…

Java-数组下标越界及小结

https://www.bilibili.com/video/BV12J41137hu?p54&spm_id_frompageDriver

如何给女朋友解释什么是撞库、脱库和洗库?

来源 | 漫话编程最近&#xff0c;安全圈又有一个大新闻&#xff0c;微博名为安全_云舒的微博用户在发文称&#xff1a;“很多人的手机号码泄露了&#xff0c;根据微博账号就能查到手机号……已经有人通过微博泄露查到我的手机号码&#xff0c;来加我微信了。”并且&#xff0c;…

OceanBase数据库实践入门——性能测试建议

概述 本文主要分享针对想压测OceanBase时需要了解的一些技术原理。这些建议可以帮助用户对OceanBase做一些调优&#xff0c;再结合测试程序快速找到适合业务的最佳性能。由于OceanBase自身参数很多、部署形态也比较灵活&#xff0c;这里并没有给出具体步骤。 数据库读写特点 …

Istio 在阿里云容器服务的部署及流量治理实践

目标 在阿里云容器服务 Kubernetes 集群上部署 Istio 服务网格实践灰度发布、故障注入、熔断等 Istio 流量管理特性 准备工作 安装和设置 kubectl 客户端&#xff0c;请参考不同的操作系统&#xff0c;如果已经安装请忽略&#xff1a; macOS curl -LO https://kubectl.oss-cn…

mysql创建操作用户

使用root用户创建一个新的数据库wiki 创建一个新的连接 由于新建的用户名下没有表&#xff0c;因此会抛出异常 就好了

Java-数组的使用

public class ArrayDemo03 {public static void main(String[] args) {int[] arrays {1,2,3,4,5};// JDK1.5&#xff0c; 没有下标&#xff0c;增强写法 // for (int array : arrays) { // System.out.println(array); // }printArray(arrays);Syste…

为何你的 SaaS 想法总是失败?没想清楚这 4 个原因可能会继续失败!

作者 | Elliot Bonneville译者 | 天道酬勤 责编 | 徐威龙封图| CSDN 下载于视觉中国最初&#xff0c;作者是准备进行一个”7 天 SaaS 挑战“的&#xff0c;但当他真正坐下来的时候就面临了第一个问题&#xff1a;他还没有决定要做什么。不过幸好的是&#xff0c;作者有一个完整…

重磅开源|AOP for Flutter开发利器——AspectD

问题背景 随着Flutter这一框架的快速发展&#xff0c;有越来越多的业务开始使用Flutter来重构或新建其产品。但在我们的实践过程中发现&#xff0c;一方面Flutter开发效率高&#xff0c;性能优异&#xff0c;跨平台表现好&#xff0c;另一方面Flutter也面临着插件&#xff0c;…

Vue-cli 3.X 构建工具零基础快速上手

文章目录一、环境准备1. 安装node2. 配置镜像二、安装Vue CLI2.1. 查看当前vuecli版本2.2. 安装最新版本2.3. 安装指定版本三、创建web项目3.1. 指定创建的项目名称3.2. 安装序列图3.3. 安装序列图简述一、环境准备 声明&#xff1a;命令均在在cmd窗口执行 1. 安装node 2. 配置…

分布式数据库选型——数据水平拆分方案

概述 水平拆分的概念随着分布式数据库的推广已为大部分人熟知。分库分表、异构索引、小表广播、这些功能几乎是产品功能需求标配。然而有些客户使用分布式数据库后的体验不尽如意。本文尝试从数据的角度总结分布式数据的复制&#xff08;replication&#xff09;和分区&#x…

从代码到 Docker、Kubernetes、Istio、Knative……,或许是时候重新思考从代码到云的编程了...

作者 | Lakmal Warusawithana译者 |弯月 责编 | 徐威龙封图| CSDN 下载于视觉中国早些时候&#xff0c;开发人员只需编写程序、构建&#xff0c;然后运行。如今&#xff0c;开发人员还需要考虑各种运行方式&#xff0c;作为可执行文件在机器上运行&#xff08;很有可能是虚拟机…

容器服务Windows Kubernetes使用阿里云日志服务来收集容器日志

目前&#xff0c;容器服务Windows Kubernetes支持将业务容器产生的stdout输出、日志文件同步到阿里云日志服务&#xff08;SLS&#xff09;进行统一管理。 支撑组件安装 在Windows Kubernetes集群安装界面勾选使用日志服务&#xff0c;集群会安装支持日志收集的必要组件logta…

Java-Arrays类

public class ArrayDemo06 {public static void main(String[] args) {int[] a {1,4,2,6,5,8,7};System.out.println(a); //hashCode [I1b6d3586// 打印数组元素 Arrays.toStringSystem.out.println(Arrays.toString(a)); // [1, 4, 2, 6, 5, 8, 7]// 自己写一个方法去打印…

看完这一篇,你就对 Spring Security 略窥门径了 | 原力计划

作者 | BoCong-Deng来源 | CSDN 博客&#xff0c;责编 | 夕颜头图 | CSDN 下载自东方 IC出品 | CSDN&#xff08;ID:CSDNnews&#xff09;写在前面开发Web应用&#xff0c;对页面的安全控制通常是必须的。比如&#xff1a;对于没有访问权限的用户需要转到登录表单页面。要实现访…

Java-冒泡排序

public class ArrayDemo07 {public static void main(String[] args) {int[] a {3,5,1,7,8,4};int[] sort sort(a);System.out.println(Arrays.toString(sort)); // [1, 3, 4, 5, 7, 8]}/*每次将 最大 或 最小的数 后移*/public static int[] sort(int[] array){// 临时变量…

借助 Cloud Toolkit 快速创建 Dubbo 工程

Cloud Toolkit 是一个 IDE 插件&#xff0c;帮助开发者更高效地开发、测试、诊断并部署应用。在最新版的插件中&#xff0c;提供了快速创建 Dubbo 工程的功能&#xff0c;下面就来快速体验下吧。 Dubbo 采用全 Spring 配置方式&#xff0c;透明化接入应用&#xff0c;对应用没…

vue-cli-service不是内部或外部命令,也不是可运行的程序

报错信息: “不是内部或外部命令&#xff0c;也不是可运行的程序” 步骤一: 检查package.json 中是否有 vue-cli-server,没有则需安装 步骤二 : 执行npm install命令 npm run serve

另一种声音:容器是不是未来?

作者 | Ian Eyberg译者 | 天道酬勤 责编 | 徐威龙封图| CSDN 下载于视觉中国CSDN 云计算旨在为读者提供更多角度的声音&#xff0c;本文仅代表作者个人观点&#xff0c;不代表CSDN云计算任何立场。前几天作者看到了这则推文&#xff0c;可以这么说&#xff0c;是它促使我开始就…