Java Operator SDK

2024-09-02 16:12
文章标签 java sdk operator

本文主要是介绍Java Operator SDK,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Java Operator SDK

  • 生成项目骨架
  • 快速入门
  • 模式和最佳实践
  • 使用示例Operators
    • 实现示例Operator
    • Quarkus
    • Spring Boot

Operators 代表Kubernetes管理集群和非集群资源。这个Java Operator SDK (JOSDK) 旨在通过使用一个对Java开发人员来说应该感觉自然的API,使编写Kubernetes操作员变得尽可能容易,并且不必担心许多低级细节,因为SDK会自动处理。

生成项目骨架

该项目包括一个Maven插件,用于生成项目的骨架:

mvn io.javaoperatorsdk:bootstrapper:[version]:create 
-DprojectGroupId=org.acme 
-DprojectArtifactId=getting-started

这个命令使用了Java Operator SDK的bootstrapper插件来创建一个项目的骨架。具体命令是mvn io.javaoperatorsdk:bootstrapper:[version]:create -DprojectGroupId=org.acme -DprojectArtifactId=getting-started

其中[version]是指Java Operator SDK的版本号,-DprojectGroupId=org.acme指定了项目的groupId为org.acme-DprojectArtifactId=getting-started指定了项目的artifactId为getting-started

运行这个命令后,bootstrapper插件会自动生成一个基本的项目结构,包括Maven的pom.xml文件和一些示例代码,以便你可以开始编写Kubernetes操作员。这个骨架项目可以作为一个起点,你可以根据需要进行修改和扩展。

快速入门

使用SDK的最简单方法是启动并执行我们的示例之一。有一个专门的页面来描述如何开始。

以下是开发代码并将operator部署到Kubernetes集群的主要步骤。在samples/mysql-schema/目录下可以找到更详细和具体的版本。

  • 配置kubectl以与您选择的Kubernetes集群一起使用。
  • 应用自定义资源定义(Custom Resource Definition)。
  • 在根目录下使用mvn install编译整个项目(包括框架和示例)。
  • 运行您选择的示例的主类,并查看示例的README文件以了解其功能。在本地运行时,框架将使用您的Kubernetes客户端配置(在~/.kube/config中)建立与集群的连接。这就是为什么提前设置kubectl非常重要。
  • 您可以在本地开发模式下使用这个代码进行测试。
  • 构建Docker镜像并将其推送到镜像仓库。
  • 应用RBAC配置。
  • 应用部署配置。
  • 验证operator是否正在运行。请不要再在本地运行它,以避免处理来自集群API服务器的事件时发生冲突。

模式和最佳实践

本文档介绍了构建和运行操作员的模式和最佳实践,以及如何使用Java Operator SDK (JOSDK)实现它们。请参阅Operator SDK中的最佳实践。

实现Reconciler

始终协调所有资源

协调可以由多个来源的事件触发。检查事件并只协调控制器管理的相关资源或资源子集可能很诱人。然而,这被认为是操作员的反模式,因为Kubernetes的分布式性质使得很难确保始终接收到所有事件。如果由于某种原因,您的操作员没有接收到一些事件,如果您不协调整个状态,您可能会根据关于集群状态的不适当假设进行操作。这就是为什么始终协调所有资源很重要,无论多么诱人只考虑子集。幸运的是,JOSDK尽可能地使其易于使用和高效,通过提供智能缓存来避免过度访问Kubernetes API服务器,并确保仅在需要时触发您的调和器。

由于在业界对这个话题有共识,JOSDK从框架的第2个版本开始不再提供Reconciler实现中的事件访问。

事件源和缓存

如上所述,在协调期间,最佳实践是协调控制器管理的所有相关资源。这意味着我们希望将期望状态与集群的实际状态进行比较。直接从Kubernetes API服务器读取资源的实际状态意味着会产生很大的负载。因此,通常的做法是为相关资源创建一个监视器,并缓存其最新状态。这是使用Informer模式完成的。在Java Operator SDK中,informer被封装在EventSource中,以将其集成到框架的事件系统中。这是通过InformerEventSource类实现的。

仅当实际资源已经在缓存中时,才会将新事件传播到Reconciler。因此,Reconciler实现只需要将期望状态与由缓存资源提供的观察到的状态进行比较。如果在缓存中找不到资源,则需要创建该资源。如果实际状态与期望状态不匹配,则需要更新该资源。

幂等性

由于在触发Reconciler时应协调所有资源,并且在任何给定资源上可以多次触发协调,特别是在使用重试策略时,因此Reconciler实现必须是幂等的,这意味着相同的观察到的状态应该产生完全相同的结果。这也意味着操作员通常应以无状态方式运行。幸运的是,由于操作员通常管理声明性资源,因此通常很容易确保幂等性。

同步或异步方式处理资源

根据您的用例,您的协调逻辑可能需要等待相当长的时间,而操作员等待资源达到其期望状态。例如,您的Reconciler可能需要等待Pod准备就绪,然后再执行其他操作。可以通过同步或异步方式来解决此问题。

异步方式是仅在Reconciler确定无法在此时完成其全部逻辑时退出协调逻辑。这将释放资源以处理其他主资源事件。但是,这需要放置足够的事件源以监视操作员等待的所有资源的状态更改。当正确执行此操作时,任何状态更改都将再次触发Reconciler,它将有机会完成其处理。

同步方式是定期轮询资源的状态,直到它们达到所需状态。如果在您的Reconciler实现的协调方法的上下文中执行此操作,这将阻止当前线程,可能需要很长时间。因此,通常建议使用异步处理方式。

为什么要自动重试?

默认情况下,自动重试已启用,并且可以根据您的需求进行配置。虽然完全关闭此功能是可能的,但我们建议不要这样做。为您的Reconciler配置自动重试的主要原因是由于Kubernetes的分布式性质,错误经常发生:瞬态网络错误可以通过自动重试轻松处理。同样,当与Kubernetes资源一起工作时,不同的操作者可能会修改资源,因此在处理Kubernetes资源时可能会发生冲突。这样的冲突通常可以通过再次协调资源来自然地解决。如果自动完成,整个过程可以完全透明地进行。

管理状态

由于Kubernetes资源的声明性本质,仅处理Kubernetes资源的操作员可以以无状态方式运行,即它们不需要维护有关这些资源状态的信息,因为应该可以从其表示中完全重建资源状态(毕竟,这就是声明性的含义)。但是,当处理外部资源时,这通常不再成立,可能需要操作员跟踪此外部状态,以便在发生另一个协调时可用。虽然这样的状态可以放在主资源的状态子资源中,但如果需要跟踪大量状态,则可能很难管理。它也违反了最佳实践,即资源的状态应该表示实际资源状态,而其规范表示期望状态。因此,不建议将不严格表示资源实际状态的状态放入其中。相反,建议将这种状态放入用于此目的的单独资源中,例如Kubernetes Secret或ConfigMap甚至是专用的自定义资源,其结构更容易验证。

在Informer错误和缓存同步超时的情况下停止(或不停止)操作员

可以配置,如果任何Informer错误发生在启动时,操作员是否应停止。默认情况下,如果在启动时出现错误,例如informer没有权限列出目标资源(包括主资源或辅助资源),则操作员将立即停止。通过将上述标志设置为false,可以更改此行为,从而操作员即使某些informer未启动也会启动。在这种情况下-与稍后遇到问题的informer启动时一样-将无限期地使用指数回退重试连接。仅当资源无法反序列化时,操作员才会停止,当前。更改此标志的典型用例是监视控制器的名称空间列表。在某些名称空间中某些资源的权限问题可能存在时,最好启动操作员,以便在处理其他名称空间时可以处理其他名称空间。

stopOnInformerErrorDuringStartup对缓存同步超时行为产生影响。如果为true,则操作员将在缓存同步超时时停止。如果为false,则在超时后,即使一个或多个事件源缓存未同步,控制器也将开始协调资源。

使用示例Operators

我们在目录下提供了一些示例,旨在演示不同场景下使用不同组件的用法,但主要是更真实的示例:

  • webpage: 简单的示例,创建包含HTML代码的自定义资源的NGINX Web服务器。
  • mysql-schema: 管理MySQL数据库中模式的操作员。演示如何管理非Kubernetes资源。
  • tomcat: 具有两个控制器的操作员,管理Tomcat实例和运行在Tomcat中的Web应用程序。这个示例的目的是展示如何管理多个相关的自定义资源和/或更多的控制器。

实现示例Operator

使用Maven将以下依赖项添加到您的项目中:

<dependency><groupId>io.javaoperatorsdk</groupId><artifactId>operator-framework</artifactId><version>{see https://search.maven.org/search?q=a:operator-framework%20AND%20g:io.javaoperatorsdk for latest version}</version>
</dependency>

或者,您也可以使用Gradle,但是需要将SDK声明为注解处理器,以便生成控制器和自定义资源类之间的映射关系:

dependencies {implementation "io.javaoperatorsdk:operator-framework:${javaOperatorVersion}"annotationProcessor "io.javaoperatorsdk:operator-framework:${javaOperatorVersion}"
}

在添加了依赖项后,定义一个主方法来初始化Operator并注册一个控制器。

public class Runner {public static void main(String[] args) {Operator operator = new Operator();operator.register(new WebPageReconciler());operator.start();}
}

控制器实现业务逻辑,并描述了处理CRD所需的所有类。

@ControllerConfiguration
public class WebPageReconciler implements Reconciler<WebPage> {// Return the changed resource, so it gets updated. See javadoc for details.@Overridepublic UpdateControl<CustomService> reconcile(CustomService resource,Context context) {// ... your logic ...return UpdateControl.patchStatus(resource);}
}

一个示例的自定义资源POJO表示

@Group("sample.javaoperatorsdk")
@Version("v1")
public class WebPage extends CustomResource<WebPageSpec, WebPageStatus> implementsNamespaced {
}public class WebServerSpec {private String html;public String getHtml() {return html;}public void setHtml(String html) {this.html = html;}
}

禁用CustomResource实现的验证

operator默认会查询部署的CRD以检查CustomResource实现是否与集群中已知的匹配。这需要向集群发起额外的查询,并且有时需要提升operator的权限才能从集群中读取CRD。这种验证主要是为了帮助新手operator开发人员入门并避免常见错误。高级用户或生产部署可能希望跳过此步骤。可以通过将CHECK_CRD_ENV_KEY环境变量设置为false来实现。

自动生成CRD
要从您的注解自定义资源类自动生成CRD清单,您只需要将以下依赖项添加到您的项目中(在背景中使用了注解处理器),使用Maven:

<dependency><groupId>io.fabric8</groupId><artifactId>crd-generator-apt</artifactId><scope>provided</scope>
</dependency>

或者使用Gradle:

dependencies {annotationProcessor 'io.fabric8:crd-generator-apt:<version>'...
}

CRD将在target/classes/META-INF/fabric8目录中生成(如果使用测试范围,则在target/test-classes/META-INF/fabric8目录中生成),其中CRD名称后缀为生成的规范版本。例如,

  • mycrs.java-operator-sdk.io-v1.yml
  • mycrs.java-operator-sdk.io-v1beta1.yml

注意:使用quarkus-operator-sdk扩展的Quarkus用户无需添加任何额外的依赖项来生成他们的CRD,因为扩展本身会处理这个过程。

Quarkus

还提供了一个Quarkus扩展,以便于基于Quarkus的操作员开发。
在您的项目中添加以下依赖项:这个依赖项

<dependency><groupId>io.quarkiverse.operatorsdk</groupId><artifactId>quarkus-operator-sdk</artifactId><version>{see https://search.maven.org/search?q=a:quarkus-operator-sdk for latest version}</version>
</dependency>

创建一个应用程序,Quarkus将自动创建和注入一个KubernetesClient(或OpenShiftClient)、Operator、ConfigurationService和ResourceController实例,您的应用程序可以使用它们。下面是您需要编写的最小代码,以使您的操作员和控制器运行起来:

@QuarkusMain
public class QuarkusOperator implements QuarkusApplication {@InjectOperator operator;public static void main(String... args) {Quarkus.run(QuarkusOperator.class, args);}@Overridepublic int run(String... args) throws Exception {operator.start();Quarkus.waitForExit();return 0;}
}

Spring Boot

您还可以让Spring Boot自动连接您的应用程序并自动注册控制器。
将以下依赖项添加到您的项目中:这个依赖项

<dependency><groupId>io.javaoperatorsdk</groupId><artifactId>operator-framework-spring-boot-starter</artifactId><version>{see https://search.maven.org/search?q=a:operator-framework-spring-boot-starter%20AND%20g:io.javaoperatorsdk forlatest version}</version>
</dependency>

创建应用

@SpringBootApplication
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}
}

您还需要一个 @Configuration 来确保您的协调器已注册:

@Configuration
public class Config {@Beanpublic WebPageReconciler customServiceController() {return new WebPageReconciler();}@Bean(initMethod = "start", destroyMethod = "stop")@SuppressWarnings("rawtypes")public Operator operator(List<Reconciler> controllers) {Operator operator = new Operator();controllers.forEach(operator::register);return operator;}
}

Spring Boot 测试支持

添加以下依赖项可以让您模拟需要加载 spring 容器的测试操作员,但不需要真正访问 Kubernetes 集群。

<dependency><groupId>io.javaoperatorsdk</groupId><artifactId>operator-framework-spring-boot-starter-test</artifactId><version>{see https://search.maven.org/search?q=a:operator-framework-spring-boot-starter%20AND%20g:io.javaoperatorsdk forlatest version}</version>
</dependency>

模拟operator:

@SpringBootTest
@EnableMockOperator
public class SpringBootStarterSampleApplicationTest {@Testvoid contextLoads() {}
}

这篇关于Java Operator SDK的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1130440

相关文章

JVM 的类初始化机制

前言 当你在 Java 程序中new对象时,有没有考虑过 JVM 是如何把静态的字节码(byte code)转化为运行时对象的呢,这个问题看似简单,但清楚的同学相信也不会太多,这篇文章首先介绍 JVM 类初始化的机制,然后给出几个易出错的实例来分析,帮助大家更好理解这个知识点。 JVM 将字节码转化为运行时对象分为三个阶段,分别是:loading 、Linking、initialization

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

Spring Security--Architecture Overview

1 核心组件 这一节主要介绍一些在Spring Security中常见且核心的Java类,它们之间的依赖,构建起了整个框架。想要理解整个架构,最起码得对这些类眼熟。 1.1 SecurityContextHolder SecurityContextHolder用于存储安全上下文(security context)的信息。当前操作的用户是谁,该用户是否已经被认证,他拥有哪些角色权限…这些都被保

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

Java架构师知识体认识

源码分析 常用设计模式 Proxy代理模式Factory工厂模式Singleton单例模式Delegate委派模式Strategy策略模式Prototype原型模式Template模板模式 Spring5 beans 接口实例化代理Bean操作 Context Ioc容器设计原理及高级特性Aop设计原理Factorybean与Beanfactory Transaction 声明式事物

Java进阶13讲__第12讲_1/2

多线程、线程池 1.  线程概念 1.1  什么是线程 1.2  线程的好处 2.   创建线程的三种方式 注意事项 2.1  继承Thread类 2.1.1 认识  2.1.2  编码实现  package cn.hdc.oop10.Thread;import org.slf4j.Logger;import org.slf4j.LoggerFactory

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟&nbsp;开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚&nbsp;第一站:海量资源,应有尽有 走进“智听

在cscode中通过maven创建java项目

在cscode中创建java项目 可以通过博客完成maven的导入 建立maven项目 使用快捷键 Ctrl + Shift + P 建立一个 Maven 项目 1 Ctrl + Shift + P 打开输入框2 输入 "> java create"3 选择 maven4 选择 No Archetype5 输入 域名6 输入项目名称7 建立一个文件目录存放项目,文件名一般为项目名8 确定