Fabric8 Kubernetes和Openshift Java DSL

介绍

在首次发行时Fabric8 2版使用的是基于JAX-RS已经Kubernetes这是使用客户ApacheCXF 。 客户端很棒,但是我们一直想提供更薄的东西,更少的依赖(以便更容易采用) 。 我们还想给它一个功能,并围绕它构建一个DSL,以使其更易于使用和阅读。

新客户端当前位于: https : //github.com/fabric8io/kubernetes-client ,它提供以下模块:

  1. Kubernetes客户
  2. 一个Openshift客户。
  3. 以上所有功能的模拟框架(基于EasyMock

乍一看客户

让我们快速了解如何使用客户端创建,列出和删除内容:

//Instantiate the client
        KubernetesClient client = new DefaultKubernetesClient();

        //Create a service
        Service myservice = ...;
        client.services().inNamespace("fabric8").create(myservice);
        
        //Create a service inline
        Service jenkins = client.services().inNamespace("fabric8").createNew()
                .withNewMetadata()
                    .withName("jenkins")
                    .addToLabels("component", "jenkins")
                .endMetadata()
                .done();

        //List services
        ServiceList serviceList = client.services().inNamespace("fabric8").list();
        
        //Watch services
        client.services().inNamespace("fabric8").watch(new Watcher<Service>() {
                @Override
                public void eventReceived(Action action, Service resource) {
                  logger.info("{}: {}", action, resource);
                }
        });

        //Delete by label
        Boolean deleted = client.services().withLabel("component", "jenkins").delete();
        
        //Close client
        client.close();

上面的代码片段几乎可以自我解释(这就是使用DSL的美妙之处),但是我仍然有一个博客文章可以填写,因此我将提供尽可能多的细节。

客户端域模型

您可以将客户视为两件事的结合:

  1. Kubernetes域模型。
  2. 模型周围的DSL。

域模型是一组对象,这些对象表示在客户端与Kubernetes / Openshift之间交换的数据。 数据的原始格式为JSON。 这些JSON对象非常复杂,其结构也很严格,因此手工制作它们并不是一件容易的事。

我们需要一种在Java中操作这些JSON对象的方法(并能够利用代码完成等功能),但还应尽可能地保持原始格式。 使用JSON对象的POJO表示形式可以进行操作,但是感觉不太像JSON,也不能真正用于具有深度嵌套的JSON。 因此,我们决定在那些使用与原始JSON完全相同的结构的POJO之上生成流畅的生成器。

例如,这里是Kubernetes服务的JSON对象:

{
  "kind": "Service",
  "metadata": {
    "name": "kubernetes",
    "namespace": "default",
    "labels": {
      "component": "apiserver",
      "provider": "kubernetes"
    }
  },
  "spec": {
    "ports": [
      {
        "name": "",
        "protocol": "TCP",
        "port": 443,
        "targetPort": 443
      }
    ],
    "selector": null,
    "portalIP": "172.30.17.2",
    "sessionAffinity": "None"
  },
  "status": {}
}

使用Fluent Builders的Java等效项可能是:

Service srv = new ServiceBuilder()
                .withNewMetadata()
                    .withName("kubernetes")
                    .addToLabels("component", "apiserver")
                    .addToLabels("provider", "kubernetes")
                .endMetadata()
                .withNewSpec()
                    .addNewPort()
                        .withProtocol("TCP")
                        .withPort(443)
                        .withNewTargetPort(443)
                    .endPort()
                    .withPortalIP("172.30.17.2")
                    .withSessionAffinity("None")
                .endSpec()
                .build();

域模型依赖于其自己的项目: Fabric8的Kubernetes模型 。 经过很长的过程,该模型是从KubernetesOpenshift代码生成的:

  1. 进行源转换JSON模式
  2. JSON模式转换POJO
  3. 一代流利的建设者

流利的构建者是由一个名为sundrio的小项目生成的,我将在以后的文章中介绍。

获取客户端实例

由于提供了一个空的构造函数,因此获取默认客户端实例的实例非常简单。 使用空的构造函数时,客户端将使用以下默认设置:

  • Kubernetes URL
    1. 系统属性“ kubernetes.master
    2. 环境变量“ KUBERNETES_MASTER
    3. 来自用户主目录中的“ .kube / config ”文件。
    4. 使用DNS:“ https://kubernetes.default.svc
  • 服务帐户路径“ /var/run/secrets/kubernetes.io/serviceaccount/

通过传递Config对象的实例,可以提供更精细的配置

//Client with custom config
Config config = new ConfigBuilder()
        .withMasterUrl(url)
        .withTrustCerts(true)
        .withOauthToken(mytoken)
        .build();
        
KubernetesClient = new DefaultKubernetesClient(config);

客户端扩展和适配器

为了支持Kubernetes扩展(例如Openshift ),客户端使用ExtensionAdapter的概念。 这个想法很简单。 扩展客户端扩展默认客户端并实现Extension 。 只要可以通过Java的ServiceLoader找到一个适配器,每个客户端实例都可以适应该扩展 (请原谅)。

这是一个如何使客户端的任何实例适应OpenshiftClient实例的示例

KubernetesClient client = new DefaultKubernetesClinet();
OpenShiftClient oc = client.adapt(OpenShiftClient.class);

仅当Kubernetes客户端返回的根路径列表中存在/ oapi时,以上代码才有效(即,该客户端指向开放式移位安装)。 如果不是,它将抛出IllegalArugementException。

如果用户正在编写绑定到Openshift的代码,则他总是可以直接实例化默认openshift客户端的实例。

//Openshift client with custom config
OpenshiftConfig config = new OpenshiftConfigBuilder()
          .withMasterUrl(url)
          .withOpenShiftUrl(openshiftUrl)
          .withTrustCerts(true)
          .build();
          
OpenshiftClient client = new DefaultOpenshiftClient(config);

测试和模拟

模拟与外部系统对话的客户端是很常见的情况。 当客户平时
(不支持方法链接)模拟很简单,并且有大量的框架可用于这项工作。 但是,当使用DSL时,事情变得更加复杂,并且需要大量样板代码才能将各个部分连接在一起。 如果原因不明显,我们可以说使用模拟方法定义每次方法调用时模拟方法的行为。 与等效的Flat对象相比,DSL倾向于拥有更多的方法(带有更少的参数)。 仅此一项就增加了定义行为所需的工作。 而且,这些方法通过返回中间对象链接在一起,这意味着它们也需要被模拟,这进一步增加了工作量和复杂性。

为了删除所有样板并简化使用客户端的过程,我们将客户端的DSL与模拟框架EasyMock的DSL相结合。 这意味着该DSL的入口点是Kubernetes客户端DSL本身,但是终端方法已经过修改,因此它们返回“期望设置器”。 一个例子应该使它更容易理解。

KubernetesMockClient mock = new KubernetesMockClient();
 
 //Define the behaviour
 mock.services().inNamespace(or("default","fabric8")).withName("fabric8-console-service").get().andReturn(
                new ServiceBuilder()
                        .withNewMetadata().withName("fabric8-console-service").endMetadata()
                        .withNewSpec()
                            .addNewPort()
                                .withProtocol("TCP")
                                .withPort(80)
                                .withNewTargetPort(9090)
                            .endPort()
                        .endSpec()
                .build()
        ).anyTimes();
        
//Get an instance of the client mock        
KubernetesClient client = mock.replay();

//Use the client
Assert.assertNotNull(client.services().inNamespace("fabric8").withName("fabric8-console-service").get());
Assert.assertNotNull(client.services().inNamespace("default").withName("fabric8-console-service").get());

//Verify the client
EasyMock.verify(client);

该模拟框架可以轻松地与其他Fabric8组件结合,例如CDI扩展 。 您只需要创建@Produces方法即可返回模拟。

请享用!

翻译自: https://www.javacodegeeks.com/2015/08/fabric8-kubernetes-and-openshift-java-dsl.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值