spring cloud + kubeedge

序言

最近公司在做边缘计算相关的事情,让我负责云平台的开发。云边协同使用的是华为开源的kubeedge,为了更好的支持云平台开发,我开始自己开发基础框架:spring cloud kubeedge。

第一节 :为何要开发这个框架

华为的kubeedge开源的时间并不长,spring cloud 官方还没有集成它。但是spring cloud 家族已经有spring cloud k8s了,该框架封装了io.fabric8。该开源框架对kubernetes的 API server跟随性不强,华为的kubeedge却紧跟kubernetes的版本。所以我决定自己封装另一个开源组件kubernetes client。

第二节  : spring cloud kubeedge 的功能

提供标准接口,屏蔽复杂的函数调用和参数设置。

第三节 : 成果

spring cloud + kubeedge_第1张图片

第四节: 实战使用

子项目spring cloud kubeedge web 实际上是一个测试项目,使用集成的spring-cloud-kubeedge-core来访问搭建好的kubeedge平台。

 部分代码如下:

配置文件:

package com.miller.springcloudkubeedgeweb.config;

import com.miller.springcloudkubeedgeweb.common.StandardNamespaceUtils;
import com.miller.springcloudkubeedgeweb.util.ResourceRenderer;
import io.kubernetes.client.ApiClient;
import io.kubernetes.client.apis.CoreV1Api;
import io.kubernetes.client.util.Config;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Bean;

import io.kubernetes.client.Configuration;

import java.io.IOException;
import java.io.InputStream;

/**
 * @program: spring-cloud-kubeedge
 * @description: cfg
 * @author: Miller.FAN
 * @create: 2019-12-09 15:32
 **/

@org.springframework.context.annotation.Configuration
@EnableAutoConfiguration
public class NeedConfig {

    @Bean
    public CoreV1Api coreV1Api() {
        String fileName = "classpath:/k8s/controller-manager.conf";
        InputStream inputStream = null;
        try {
            inputStream = ResourceRenderer.resourceLoader(fileName);
        } catch (
                IOException e) {
            e.printStackTrace();
        }
        ApiClient client = null;
        try {
            client = Config.fromConfig(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
        client.setConnectTimeout(5 * 60 * 1000);
        Configuration.setDefaultApiClient(client);
        return new CoreV1Api();
    }
    @Bean
    public StandardNamespaceUtils standardNamespaceUtils() {
        return new StandardNamespaceUtils();
    }
    
}

 service层:

package com.miller.springcloudkubeedgeweb.service;

import com.miller.springcloudkubeedgecore.namespace.StandardNamespaceUtils;
import io.kubernetes.client.apis.CoreV1Api;
import io.kubernetes.client.models.V1Namespace;
import io.kubernetes.client.models.V1NamespaceList;
import org.springframework.stereotype.Service;

/**
 * @program: spring-cloud-kubeedge
 * @description: namespace
 * @author: Miller.FAN
 * @create: 2019-12-09 11:58
 **/
@Service
public class NamespaceService implements NamespaceRepository{

/*    @Autowired
    StandardNamespaceUtils standardNamespaceUtils;*/

    private CoreV1Api coreV1Api = new CoreV1Api();

    private StandardNamespaceUtils standardNamespaceUtils = new StandardNamespaceUtils(coreV1Api);

    //返回分区列表
    public V1NamespaceList getNamespace(){
        return standardNamespaceUtils.getNamespaceList();
    }

    //创建分区
    public V1Namespace createNamespace() {
        return standardNamespaceUtils.createNamespace();
    }

    //删除分区
    public Boolean deleteNamespace(String namespace) {
        return standardNamespaceUtils.deleteNamespace(namespace);
    }

    //查询指定的分区信息
    public V1Namespace queryNamespace(String namespace) {
        return standardNamespaceUtils.queryNamespace(namespace);
    }

    //替换分区内容
    public V1Namespace replaceNamespace(String name, V1Namespace body) {
        return standardNamespaceUtils.replaceNamespace(name,body);
    }
}

controller层:

package com.miller.springcloudkubeedgeweb.controller;

import com.miller.springcloudkubeedgeweb.service.NamespaceService;
import io.kubernetes.client.models.V1Namespace;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;

import static com.miller.springcloudkubeedgeweb.common.Commons.SUCCESS;

/**
 * @program: spring-cloud-kubeedge
 * @description: c
 * @author: Miller.FAN
 * @create: 2019-12-09 14:26
 **/
@RestController
@RequestMapping(path = "/namespace")
@Api(value = "NamespaceController", description = "命名空间信息接口")
public class NamespaceController {

    @Autowired
    private NamespaceService namespaceService;

    @RequestMapping(value ="/get/list" , method = RequestMethod.GET)
    @ApiOperation(value = "get/list", notes = "getNamespaceList")
    public HashMap getNamespaceList() {
        HashMap ret = new HashMap<>();
        ret.put(SUCCESS,namespaceService.getNamespace());
        return ret;
    }

    @RequestMapping(value ="/creat" , method = RequestMethod.POST)
    @ApiOperation(value = "creat", notes = "creatNamespace")
    public HashMap creatNamespace() {
        HashMap ret = new HashMap<>();
        ret.put(SUCCESS,namespaceService.createNamespace());
        return ret;
    }

    @RequestMapping(value ="/delete/{namespace}" , method = RequestMethod.DELETE)
    @ApiOperation(value = "delete", notes = "deleteNamespace")
    public HashMap deleteNamespace(@PathVariable String namespace) {
        HashMap ret = new HashMap<>();
        ret.put(SUCCESS,namespaceService.deleteNamespace(namespace));
        return ret;
    }

    @RequestMapping(value ="/query/{namespace}" , method = RequestMethod.GET)
    @ApiOperation(value = "query", notes = "queryNamespace")
    public HashMap queryNamespace(@PathVariable String namespace) {
        HashMap ret = new HashMap<>();
        ret.put(SUCCESS,namespaceService.queryNamespace(namespace));
        return ret;
    }

    @RequestMapping(value ="/update/{namespace}" , method = RequestMethod.PUT)
    @ApiOperation(value = "update", notes = "creatNamespace")
    public HashMap creatNamespace(@PathVariable String namespace, @RequestBody V1Namespace body) {
        HashMap ret = new HashMap<>();
        ret.put(SUCCESS,namespaceService.replaceNamespace(namespace,body));
        return ret;
    }

}

第五节 : 启动项目,测试

spring cloud + kubeedge_第2张图片

在swagger的UI页面测试:

spring cloud + kubeedge_第3张图片

spring cloud + kubeedge_第4张图片

返回的结果:

{
  "ok": {
    "apiVersion": "v1",
    "items": [
      {
        "apiVersion": null,
        "kind": null,
        "metadata": {
          "annotations": null,
          "clusterName": null,
          "creationTimestamp": {
            "year": 2019,
            "dayOfMonth": 10,
            "dayOfWeek": 2,
            "era": 1,
            "dayOfYear": 344,
            "hourOfDay": 19,
            "yearOfCentury": 19,
            "weekyear": 2019,
            "centuryOfEra": 20,
            "yearOfEra": 2019,
            "monthOfYear": 12,
            "minuteOfHour": 0,
            "weekOfWeekyear": 50,
            "millisOfSecond": 0,
            "secondOfMinute": 30,
            "millisOfDay": 68430000,
            "minuteOfDay": 1140,
            "secondOfDay": 68430,
            "millis": 1575975630000,
            "zone": {
              "fixed": false,
              "uncachedZone": {
                "fixed": false,
                "cachable": true,
                "id": "Asia/Shanghai"
              },
              "id": "Asia/Shanghai"
            },
            "chronology": {
              "zone": {
                "fixed": false,
                "uncachedZone": {
                  "fixed": false,
                  "cachable": true,
                  "id": "Asia/Shanghai"
                },
                "id": "Asia/Shanghai"
              }
            },
            "beforeNow": true,
            "equalNow": false,
            "afterNow": false
          },
          "deletionGracePeriodSeconds": null,
          "deletionTimestamp": null,
          "finalizers": null,
          "generateName": null,
          "generation": null,
          "initializers": null,
          "labels": null,
          "managedFields": null,
          "name": "default",
          "namespace": null,
          "ownerReferences": null,
          "resourceVersion": "148",
          "selfLink": "/api/v1/namespaces/default",
          "uid": "9c1a0018-ce47-4229-a32e-b675b33d7056"
        },
        "spec": {
          "finalizers": [
            "kubernetes"
          ]
        },
        "status": {
          "phase": "Active"
        }
      },
      {
        "apiVersion": null,
        "kind": null,
        "metadata": {
          "annotations": null,
          "clusterName": null,
          "creationTimestamp": {
            "year": 2019,
            "dayOfMonth": 10,
            "dayOfWeek": 2,
            "era": 1,
            "dayOfYear": 344,
            "hourOfDay": 19,
            "yearOfCentury": 19,
            "weekyear": 2019,
            "centuryOfEra": 20,
            "yearOfEra": 2019,
            "monthOfYear": 12,
            "minuteOfHour": 0,
            "weekOfWeekyear": 50,
            "millisOfSecond": 0,
            "secondOfMinute": 27,
            "millisOfDay": 68427000,
            "minuteOfDay": 1140,
            "secondOfDay": 68427,
            "millis": 1575975627000,
            "zone": {
              "fixed": false,
              "uncachedZone": {
                "fixed": false,
                "cachable": true,
                "id": "Asia/Shanghai"
              },
              "id": "Asia/Shanghai"
            },
            "chronology": {
              "zone": {
                "fixed": false,
                "uncachedZone": {
                  "fixed": false,
                  "cachable": true,
                  "id": "Asia/Shanghai"
                },
                "id": "Asia/Shanghai"
              }
            },
            "beforeNow": true,
            "equalNow": false,
            "afterNow": false
          },
          "deletionGracePeriodSeconds": null,
          "deletionTimestamp": null,
          "finalizers": null,
          "generateName": null,
          "generation": null,
          "initializers": null,
          "labels": null,
          "managedFields": null,
          "name": "kube-node-lease",
          "namespace": null,
          "ownerReferences": null,
          "resourceVersion": "38",
          "selfLink": "/api/v1/namespaces/kube-node-lease",
          "uid": "2fa58c84-63ed-4b66-9a1b-896da7d8a7d0"
        },
        "spec": {
          "finalizers": [
            "kubernetes"
          ]
        },
        "status": {
          "phase": "Active"
        }
      },
      {
        "apiVersion": null,
        "kind": null,
        "metadata": {
          "annotations": null,
          "clusterName": null,
          "creationTimestamp": {
            "year": 2019,
            "dayOfMonth": 10,
            "dayOfWeek": 2,
            "era": 1,
            "dayOfYear": 344,
            "hourOfDay": 19,
            "yearOfCentury": 19,
            "weekyear": 2019,
            "centuryOfEra": 20,
            "yearOfEra": 2019,
            "monthOfYear": 12,
            "minuteOfHour": 0,
            "weekOfWeekyear": 50,
            "millisOfSecond": 0,
            "secondOfMinute": 27,
            "millisOfDay": 68427000,
            "minuteOfDay": 1140,
            "secondOfDay": 68427,
            "millis": 1575975627000,
            "zone": {
              "fixed": false,
              "uncachedZone": {
                "fixed": false,
                "cachable": true,
                "id": "Asia/Shanghai"
              },
              "id": "Asia/Shanghai"
            },
            "chronology": {
              "zone": {
                "fixed": false,
                "uncachedZone": {
                  "fixed": false,
                  "cachable": true,
                  "id": "Asia/Shanghai"
                },
                "id": "Asia/Shanghai"
              }
            },
            "beforeNow": true,
            "equalNow": false,
            "afterNow": false
          },
          "deletionGracePeriodSeconds": null,
          "deletionTimestamp": null,
          "finalizers": null,
          "generateName": null,
          "generation": null,
          "initializers": null,
          "labels": null,
          "managedFields": null,
          "name": "kube-public",
          "namespace": null,
          "ownerReferences": null,
          "resourceVersion": "37",
          "selfLink": "/api/v1/namespaces/kube-public",
          "uid": "0964a321-07c2-45ff-8ffa-f3438e9d2d4a"
        },
        "spec": {
          "finalizers": [
            "kubernetes"
          ]
        },
        "status": {
          "phase": "Active"
        }
      },
      {
        "apiVersion": null,
        "kind": null,
        "metadata": {
          "annotations": null,
          "clusterName": null,
          "creationTimestamp": {
            "year": 2019,
            "dayOfMonth": 10,
            "dayOfWeek": 2,
            "era": 1,
            "dayOfYear": 344,
            "hourOfDay": 19,
            "yearOfCentury": 19,
            "weekyear": 2019,
            "centuryOfEra": 20,
            "yearOfEra": 2019,
            "monthOfYear": 12,
            "minuteOfHour": 0,
            "weekOfWeekyear": 50,
            "millisOfSecond": 0,
            "secondOfMinute": 27,
            "millisOfDay": 68427000,
            "minuteOfDay": 1140,
            "secondOfDay": 68427,
            "millis": 1575975627000,
            "zone": {
              "fixed": false,
              "uncachedZone": {
                "fixed": false,
                "cachable": true,
                "id": "Asia/Shanghai"
              },
              "id": "Asia/Shanghai"
            },
            "chronology": {
              "zone": {
                "fixed": false,
                "uncachedZone": {
                  "fixed": false,
                  "cachable": true,
                  "id": "Asia/Shanghai"
                },
                "id": "Asia/Shanghai"
              }
            },
            "beforeNow": true,
            "equalNow": false,
            "afterNow": false
          },
          "deletionGracePeriodSeconds": null,
          "deletionTimestamp": null,
          "finalizers": null,
          "generateName": null,
          "generation": null,
          "initializers": null,
          "labels": null,
          "managedFields": null,
          "name": "kube-system",
          "namespace": null,
          "ownerReferences": null,
          "resourceVersion": "36",
          "selfLink": "/api/v1/namespaces/kube-system",
          "uid": "5e6cbd2f-a2b5-4315-a50e-6d2fd52ab8b7"
        },
        "spec": {
          "finalizers": [
            "kubernetes"
          ]
        },
        "status": {
          "phase": "Active"
        }
      }
    ],
    "kind": "NamespaceList",
    "metadata": {
      "resourceVersion": "109495",
      "selfLink": "/api/v1/namespaces",
      "continue": null
    }
  }
}

上面的返回数据是json格式的,包含了kubeedge的所有namespace的信息。

大家看到import com.miller.***这样的导入,不要被误导,这是我自己开发的starter,在自己本地仓库中,网上是没有的,我的英文名:miller,所有我没有成立的公司叫com.miller。欢迎各路神仙来访,留言、讨论、学习。

你可能感兴趣的:(spring,cloud,kubeedge)