• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

Go开发PaaS平台2

武飞扬头像
theo.wu
帮助1

Go开发PaaS平台核心功能

代码仓库地址GitHub - yunixiangfeng/gopaas

第7章 云原生 Go PaaS 平台路由管理功能开发,对外域名映射,动态设置域名

域名能够让我们的服务提供外网访问的能力,让公网也能够访问到集群内部的资源,是我们开放业务的入口。将讲解 Ingress 的核心原理和流量转化流程,熟练掌握如何应用 K8s 中的服务通过域名的方式映射到公网,提供外网访问能力。

7-1 路由ingress 架构详解

Go PaaS 平台服务管理开发

主要内容
路由作用讲解
路由原理和架构说明
开发路由管理功能
为什么要用Ingress?
ClusterlP的方式只能在集群内部访问。
NodePort 当有几十上百的服务在集群中运行时,很难管理。
LoadBalance 方式受限于云平台。

路由 Ingress 简介
Ingress:一个普通资源对象,用来表明具体路由规则
Ingress-controller: 来执行转发规则

路由 Ingress 架构说明

学新通路由Ingress-controller (nginx) 如何运作的? 

学新通学新通

7-2 路由model与repository开发调整

  1.  
    PS C:\Users\Administrator\Desktop\gopaas> .\yu-tool\yu-tool.exe newService github.com/yunixiangfeng/gopaas/route
  2.  
     
  3.  
    cd route
  4.  
     
  5.  
    go mod tidy
  6.  
     
  7.  
    // versions:
  8.  
    // protoc-gen-go v1.27.1
  9.  
    // protoc v3.15.7
  10.  
    // source: proto/svc/svc.proto
  11.  
    protoc --proto_path=. --micro_out=. --go_out=:. ./proto/route/route.proto

C:\Users\Administrator\Desktop\gopaas\route\domain\model\route.go

  1.  
    package model
  2.  
     
  3.  
    type Route struct {
  4.  
    ID int64 `gorm:"primary_key;not_null;auto_increment"`
  5.  
    RouteName string `json:"route_name"`
  6.  
    RouteNamespace string `json:"route_namespace"`
  7.  
    RouteHost string `json:"route_host"`
  8.  
    RoutePath []RoutePath `gorm:"ForeignKey:RouteID" json:"route_path"`
  9.  
    }

C:\Users\Administrator\Desktop\gopaas\route\domain\model\route_path.go

  1.  
    package model
  2.  
     
  3.  
    type RoutePath struct {
  4.  
    ID int64 `gorm:"primary_key;not_null;auto_increment"`
  5.  
    RouteID int64 `json:"route_id"`
  6.  
    RoutePathName string `json:"route_path_name"`
  7.  
    RouteBackendService string `json:"route_backend_service"`
  8.  
    RouteBackendServicePort int32 `json:"route_backend_service_port"`
  9.  
    }

C:\Users\Administrator\Desktop\gopaas\route\domain\repository\route_repository.go

  1.  
    package repository
  2.  
     
  3.  
    import (
  4.  
    "github.com/jinzhu/gorm"
  5.  
    "github.com/yunixiangfeng/gopaas/common"
  6.  
    "github.com/yunixiangfeng/gopaas/route/domain/model"
  7.  
    )
  8.  
     
  9.  
    //创建需要实现的接口
  10.  
    type IRouteRepository interface {
  11.  
    //初始化表
  12.  
    InitTable() error
  13.  
    //根据ID查处找数据
  14.  
    FindRouteByID(int64) (*model.Route, error)
  15.  
    //创建一条 route 数据
  16.  
    CreateRoute(*model.Route) (int64, error)
  17.  
    //根据ID删除一条 route 数据
  18.  
    DeleteRouteByID(int64) error
  19.  
    //修改更新数据
  20.  
    UpdateRoute(*model.Route) error
  21.  
    //查找route所有数据
  22.  
    FindAll() ([]model.Route, error)
  23.  
    }
  24.  
     
  25.  
    //创建routeRepository
  26.  
    func NewRouteRepository(db *gorm.DB) IRouteRepository {
  27.  
    return &RouteRepository{mysqlDb: db}
  28.  
    }
  29.  
     
  30.  
    type RouteRepository struct {
  31.  
    mysqlDb *gorm.DB
  32.  
    }
  33.  
     
  34.  
    //初始化表
  35.  
    func (u *RouteRepository) InitTable() error {
  36.  
    return u.mysqlDb.CreateTable(&model.Route{}, &model.RoutePath{}).Error
  37.  
    }
  38.  
     
  39.  
    //根据ID查找Route信息
  40.  
    func (u *RouteRepository) FindRouteByID(routeID int64) (route *model.Route, err error) {
  41.  
    route = &model.Route{}
  42.  
    return route, u.mysqlDb.Preload("RoutePath").First(route, routeID).Error
  43.  
    }
  44.  
     
  45.  
    //创建Route信息
  46.  
    func (u *RouteRepository) CreateRoute(route *model.Route) (int64, error) {
  47.  
    return route.ID, u.mysqlDb.Create(route).Error
  48.  
    }
  49.  
     
  50.  
    //根据ID删除Route信息
  51.  
    func (u *RouteRepository) DeleteRouteByID(routeID int64) error {
  52.  
    tx := u.mysqlDb.Begin()
  53.  
    //遇到问题回滚
  54.  
    defer func() {
  55.  
    if r := recover(); r != nil {
  56.  
    tx.Rollback()
  57.  
    }
  58.  
    }()
  59.  
    if tx.Error != nil {
  60.  
    common.Error(tx.Error)
  61.  
    return tx.Error
  62.  
    }
  63.  
    //开始删除
  64.  
    if err := u.mysqlDb.Where("id = ?", routeID).Delete(&model.Route{}).Error; err != nil {
  65.  
    tx.Rollback()
  66.  
    common.Error(err)
  67.  
    return err
  68.  
    }
  69.  
    //删除关联表
  70.  
    if err := u.mysqlDb.Where("route_id = ?", routeID).Delete(&model.RoutePath{}).Error; err != nil {
  71.  
    tx.Rollback()
  72.  
    common.Error(err)
  73.  
    return err
  74.  
    }
  75.  
    return tx.Commit().Error
  76.  
    }
  77.  
     
  78.  
    //更新Route信息
  79.  
    func (u *RouteRepository) UpdateRoute(route *model.Route) error {
  80.  
    return u.mysqlDb.Model(route).Update(route).Error
  81.  
    }
  82.  
     
  83.  
    //获取结果集
  84.  
    func (u *RouteRepository) FindAll() (routeAll []model.Route, err error) {
  85.  
    return routeAll, u.mysqlDb.Preload("RoutePath").Find(&routeAll).Error
  86.  
    }

7-3 路由 service 开发 

C:\Users\Administrator\Desktop\gopaas\route\domain\service\route_data_service.go 

  1.  
    package service
  2.  
     
  3.  
    import (
  4.  
    "context"
  5.  
    "errors"
  6.  
    "strconv"
  7.  
     
  8.  
    "github.com/yunixiangfeng/gopaas/common"
  9.  
    "github.com/yunixiangfeng/gopaas/route/domain/model"
  10.  
    "github.com/yunixiangfeng/gopaas/route/domain/repository"
  11.  
    "github.com/yunixiangfeng/gopaas/route/proto/route"
  12.  
    v1 "k8s.io/api/apps/v1"
  13.  
    v12 "k8s.io/api/networking/v1"
  14.  
    v14 "k8s.io/apimachinery/pkg/apis/meta/v1"
  15.  
    "k8s.io/client-go/kubernetes"
  16.  
    )
  17.  
     
  18.  
    //这里是接口类型
  19.  
    type IRouteDataService interface {
  20.  
    AddRoute(*model.Route) (int64, error)
  21.  
    DeleteRoute(int64) error
  22.  
    UpdateRoute(*model.Route) error
  23.  
    FindRouteByID(int64) (*model.Route, error)
  24.  
    FindAllRoute() ([]model.Route, error)
  25.  
     
  26.  
    CreateRouteToK8s(*route.RouteInfo) error
  27.  
    DeleteRouteFromK8s(*model.Route) error
  28.  
    UpdateRouteToK8s(*route.RouteInfo) error
  29.  
    }
  30.  
     
  31.  
    //创建
  32.  
    //注意:返回值 IRouteDataService 接口类型
  33.  
    func NewRouteDataService(routeRepository repository.IRouteRepository, clientSet *kubernetes.Clientset) IRouteDataService {
  34.  
    return &RouteDataService{RouteRepository: routeRepository, K8sClientSet: clientSet, deployment: &v1.Deployment{}}
  35.  
    }
  36.  
     
  37.  
    type RouteDataService struct {
  38.  
    //注意:这里是 IRouteRepository 类型
  39.  
    RouteRepository repository.IRouteRepository
  40.  
    K8sClientSet *kubernetes.Clientset
  41.  
    deployment *v1.Deployment
  42.  
    }
  43.  
     
  44.  
    //创建k8s(把proto 属性补全)
  45.  
    func (u *RouteDataService) CreateRouteToK8s(info *route.RouteInfo) (err error) {
  46.  
    ingress := u.setIngress(info)
  47.  
    //查找是否存在
  48.  
    if _, err = u.K8sClientSet.NetworkingV1().Ingresses(info.RouteNamespace).Get(context.TODO(), info.RouteName, v14.GetOptions{}); err != nil {
  49.  
    if _, err = u.K8sClientSet.NetworkingV1().Ingresses(info.RouteNamespace).Create(context.TODO(), ingress, v14.CreateOptions{}); err != nil {
  50.  
    //创建不成功记录错误
  51.  
    common.Error(err)
  52.  
    return err
  53.  
    }
  54.  
    return nil
  55.  
    } else {
  56.  
    common.Error("路由 " info.RouteName " 已经存在")
  57.  
    return errors.New("路由 " info.RouteName " 已经存在")
  58.  
    }
  59.  
    }
  60.  
     
  61.  
    func (u *RouteDataService) setIngress(info *route.RouteInfo) *v12.Ingress {
  62.  
    route := &v12.Ingress{}
  63.  
    //设置路由
  64.  
    route.TypeMeta = v14.TypeMeta{
  65.  
    Kind: "Ingress",
  66.  
    APIVersion: "v1",
  67.  
    }
  68.  
    //设置路由基础信息
  69.  
    route.ObjectMeta = v14.ObjectMeta{
  70.  
    Name: info.RouteName,
  71.  
    Namespace: info.RouteNamespace,
  72.  
    Labels: map[string]string{
  73.  
    "app-name": info.RouteName,
  74.  
    "author": "wu123",
  75.  
    },
  76.  
    Annotations: map[string]string{
  77.  
    "k8s/generated-by-wu": "由代码创建",
  78.  
    },
  79.  
    }
  80.  
    //使用 ingress-nginx
  81.  
    className := "nginx"
  82.  
    //设置路由 spec 信息
  83.  
    route.Spec = v12.IngressSpec{
  84.  
    IngressClassName: &className,
  85.  
    //默认访问服务
  86.  
    DefaultBackend: nil,
  87.  
    //如果开启https这里要设置
  88.  
    TLS: nil,
  89.  
    Rules: u.getIngressPath(info),
  90.  
    }
  91.  
    return route
  92.  
    }
  93.  
     
  94.  
    //根据info信息获取path路径
  95.  
    func (u *RouteDataService) getIngressPath(info *route.RouteInfo) (path []v12.IngressRule) {
  96.  
    //1.设置host
  97.  
    pathRule := v12.IngressRule{Host: info.RouteHost}
  98.  
    //2.设置Path
  99.  
    ingressPath := []v12.HTTPIngressPath{}
  100.  
    for _, v := range info.RoutePath {
  101.  
    pathType := v12.PathTypePrefix
  102.  
    ingressPath = append(ingressPath, v12.HTTPIngressPath{
  103.  
    Path: v.RoutePathName,
  104.  
    PathType: &pathType,
  105.  
    Backend: v12.IngressBackend{
  106.  
    Service: &v12.IngressServiceBackend{
  107.  
    Name: v.RouteBackendService,
  108.  
    Port: v12.ServiceBackendPort{
  109.  
    Number: v.RouteBackendServicePort,
  110.  
    },
  111.  
    },
  112.  
    },
  113.  
    })
  114.  
    }
  115.  
     
  116.  
    //3.赋值 Path
  117.  
    pathRule.IngressRuleValue = v12.IngressRuleValue{HTTP: &v12.HTTPIngressRuleValue{Paths: ingressPath}}
  118.  
    path = append(path, pathRule)
  119.  
    return
  120.  
    }
  121.  
     
  122.  
    //更新route
  123.  
    func (u *RouteDataService) UpdateRouteToK8s(info *route.RouteInfo) (err error) {
  124.  
    ingress := u.setIngress(info)
  125.  
    if _, err = u.K8sClientSet.NetworkingV1().Ingresses(info.RouteNamespace).Update(context.TODO(), ingress, v14.UpdateOptions{}); err != nil {
  126.  
    common.Error(err)
  127.  
    return err
  128.  
    }
  129.  
    return nil
  130.  
    }
  131.  
     
  132.  
    //删除route
  133.  
    func (u *RouteDataService) DeleteRouteFromK8s(route2 *model.Route) (err error) {
  134.  
    //删除Ingress
  135.  
    if err = u.K8sClientSet.NetworkingV1().Ingresses(route2.RouteNamespace).Delete(context.TODO(), route2.RouteName, v14.DeleteOptions{}); err != nil {
  136.  
    //如果删除失败记录下
  137.  
    common.Error(err)
  138.  
    return err
  139.  
    } else {
  140.  
    if err := u.DeleteRoute(route2.ID); err != nil {
  141.  
    common.Error(err)
  142.  
    return err
  143.  
    }
  144.  
    common.Info("删除 ingress ID:" strconv.FormatInt(route2.ID, 10) " 成功!")
  145.  
    }
  146.  
    return
  147.  
    }
  148.  
     
  149.  
    //插入
  150.  
    func (u *RouteDataService) AddRoute(route *model.Route) (int64, error) {
  151.  
    return u.RouteRepository.CreateRoute(route)
  152.  
    }
  153.  
     
  154.  
    //删除
  155.  
    func (u *RouteDataService) DeleteRoute(routeID int64) error {
  156.  
    return u.RouteRepository.DeleteRouteByID(routeID)
  157.  
    }
  158.  
     
  159.  
    //更新
  160.  
    func (u *RouteDataService) UpdateRoute(route *model.Route) error {
  161.  
    return u.RouteRepository.UpdateRoute(route)
  162.  
    }
  163.  
     
  164.  
    //查找
  165.  
    func (u *RouteDataService) FindRouteByID(routeID int64) (*model.Route, error) {
  166.  
    return u.RouteRepository.FindRouteByID(routeID)
  167.  
    }
  168.  
     
  169.  
    //查找
  170.  
    func (u *RouteDataService) FindAllRoute() ([]model.Route, error) {
  171.  
    return u.RouteRepository.FindAll()
  172.  
    }

C:\Users\Administrator\Desktop\gopaas\route\proto\route\route.proto

  1.  
    syntax = "proto3";
  2.  
     
  3.  
    package route;
  4.  
     
  5.  
    option go_package = "./proto/route;route";
  6.  
     
  7.  
    service Route {
  8.  
    //对外提供添加服务
  9.  
    rpc AddRoute(RouteInfo) returns (Response) {}
  10.  
    rpc DeleteRoute(RouteId) returns (Response) {}
  11.  
    rpc UpdateRoute(RouteInfo) returns (Response) {}
  12.  
    rpc FindRouteByID(RouteId) returns (RouteInfo) {}
  13.  
    rpc FindAllRoute(FindAll) returns (AllRoute) {}
  14.  
    }
  15.  
    message RouteInfo {
  16.  
    int64 id = 1;
  17.  
    string route_name = 2;
  18.  
    string route_namespace =3;
  19.  
    string route_host =4;
  20.  
    repeated RoutePath route_path=5;
  21.  
    }
  22.  
     
  23.  
    message RoutePath {
  24.  
    int64 id = 1;
  25.  
    int64 route_id =2;
  26.  
    string route_path_name=3;
  27.  
    string route_backend_service=4;
  28.  
    int32 route_backend_service_port=5;
  29.  
    }
  30.  
     
  31.  
    message RouteId {
  32.  
    int64 id = 1;
  33.  
    }
  34.  
     
  35.  
    message FindAll {
  36.  
     
  37.  
    }
  38.  
     
  39.  
    message Response {
  40.  
    string msg =1 ;
  41.  
    }
  42.  
     
  43.  
    message AllRoute {
  44.  
    repeated RouteInfo route_info = 1;
  45.  
    }
  46.  
     
  47.  
     

7-4 路由 handler 逻辑开发和注意事项

创建handler对外暴露服务

C:\Users\Administrator\Desktop\gopaas\route\handler\routeHandler.go

  1.  
    package handler
  2.  
     
  3.  
    import (
  4.  
    "context"
  5.  
    "strconv"
  6.  
     
  7.  
    log "github.com/asim/go-micro/v3/logger"
  8.  
    "github.com/yunixiangfeng/gopaas/common"
  9.  
    "github.com/yunixiangfeng/gopaas/route/domain/model"
  10.  
    "github.com/yunixiangfeng/gopaas/route/domain/service"
  11.  
    route "github.com/yunixiangfeng/gopaas/route/proto/route"
  12.  
    )
  13.  
     
  14.  
    type RouteHandler struct {
  15.  
    //注意这里的类型是 IRouteDataService 接口类型
  16.  
    RouteDataService service.IRouteDataService
  17.  
    }
  18.  
     
  19.  
    // 添加路由
  20.  
    func (e *RouteHandler) AddRoute(ctx context.Context, info *route.RouteInfo, rsp *route.Response) error {
  21.  
    log.Info("Received *route.AddRoute request")
  22.  
    route := &model.Route{}
  23.  
    if err := common.SwapTo(info, route); err != nil {
  24.  
    common.Error(err)
  25.  
    rsp.Msg = err.Error()
  26.  
    return err
  27.  
    }
  28.  
    //创建route到k8s
  29.  
    if err := e.RouteDataService.CreateRouteToK8s(info); err != nil {
  30.  
    common.Error(err)
  31.  
    rsp.Msg = err.Error()
  32.  
    return err
  33.  
    } else {
  34.  
    //写入数据库
  35.  
    routeID, err := e.RouteDataService.AddRoute(route)
  36.  
    if err != nil {
  37.  
    common.Error(err)
  38.  
    rsp.Msg = err.Error()
  39.  
    return err
  40.  
    }
  41.  
    common.Info("Route 添加成功 ID 号为:" strconv.FormatInt(routeID, 10))
  42.  
    rsp.Msg = "Route 添加成功 ID 号为:" strconv.FormatInt(routeID, 10)
  43.  
    }
  44.  
    return nil
  45.  
    }
  46.  
     
  47.  
    //删除route
  48.  
    func (e *RouteHandler) DeleteRoute(ctx context.Context, req *route.RouteId, rsp *route.Response) error {
  49.  
    log.Info("Received *route.DeleteRoute request")
  50.  
    routeModel, err := e.RouteDataService.FindRouteByID(req.Id)
  51.  
    if err != nil {
  52.  
    common.Error(err)
  53.  
    return err
  54.  
    }
  55.  
    //从k8s中删除,并且删除数据库中数据
  56.  
    if err := e.RouteDataService.DeleteRouteFromK8s(routeModel); err != nil {
  57.  
    common.Error(err)
  58.  
    return err
  59.  
    }
  60.  
    return nil
  61.  
    }
  62.  
     
  63.  
    //更新route
  64.  
    func (e *RouteHandler) UpdateRoute(ctx context.Context, req *route.RouteInfo, rsp *route.Response) error {
  65.  
    log.Info("Received *route.UpdateRoute request")
  66.  
    if err := e.RouteDataService.UpdateRouteToK8s(req); err != nil {
  67.  
    common.Error(err)
  68.  
    return err
  69.  
    }
  70.  
    //查询数据库的信息
  71.  
    routeModel, err := e.RouteDataService.FindRouteByID(req.Id)
  72.  
    if err != nil {
  73.  
    common.Error(err)
  74.  
    return err
  75.  
    }
  76.  
    //数据更新
  77.  
    if err := common.SwapTo(req, routeModel); err != nil {
  78.  
    common.Error(err)
  79.  
    return err
  80.  
    }
  81.  
    return e.RouteDataService.UpdateRoute(routeModel)
  82.  
    }
  83.  
     
  84.  
    //根据ID查询route信息
  85.  
    func (e *RouteHandler) FindRouteByID(ctx context.Context, req *route.RouteId, rsp *route.RouteInfo) error {
  86.  
    log.Info("Received *route.FindRouteByID request")
  87.  
    routeModel, err := e.RouteDataService.FindRouteByID(req.Id)
  88.  
    if err != nil {
  89.  
    common.Error(err)
  90.  
    return err
  91.  
    }
  92.  
    //数据转化
  93.  
    if err := common.SwapTo(routeModel, rsp); err != nil {
  94.  
    common.Error(err)
  95.  
    return err
  96.  
    }
  97.  
    return nil
  98.  
    }
  99.  
     
  100.  
    func (e *RouteHandler) FindAllRoute(ctx context.Context, req *route.FindAll, rsp *route.AllRoute) error {
  101.  
    log.Info("Received *route.FindAllRoute request")
  102.  
    allRoute, err := e.RouteDataService.FindAllRoute()
  103.  
    if err != nil {
  104.  
    common.Error(err)
  105.  
    return err
  106.  
    }
  107.  
    //整理下格式
  108.  
    for _, v := range allRoute {
  109.  
    //创建实例
  110.  
    routeInfo := &route.RouteInfo{}
  111.  
    //把查询出来的数据进行转化
  112.  
    if err := common.SwapTo(v, routeInfo); err != nil {
  113.  
    common.Error(err)
  114.  
    return err
  115.  
    }
  116.  
    //数据合并
  117.  
    rsp.RouteInfo = append(rsp.RouteInfo, routeInfo)
  118.  
    }
  119.  
    return nil
  120.  
    }

C:\Users\Administrator\Desktop\gopaas\route\main.go

  1.  
    package main
  2.  
     
  3.  
    import (
  4.  
    "flag"
  5.  
    "fmt"
  6.  
    "path/filepath"
  7.  
     
  8.  
    "github.com/yunixiangfeng/gopaas/common"
  9.  
    "github.com/yunixiangfeng/gopaas/route/domain/repository"
  10.  
     
  11.  
    //"github.com/afex/hystrix-go/hystrix"
  12.  
    "github.com/asim/go-micro/plugins/registry/consul/v3"
  13.  
    ratelimit "github.com/asim/go-micro/plugins/wrapper/ratelimiter/uber/v3"
  14.  
    opentracing2 "github.com/asim/go-micro/plugins/wrapper/trace/opentracing/v3"
  15.  
    "github.com/asim/go-micro/v3"
  16.  
    "github.com/asim/go-micro/v3/registry"
  17.  
    "github.com/asim/go-micro/v3/server"
  18.  
    "github.com/jinzhu/gorm"
  19.  
    _ "github.com/jinzhu/gorm/dialects/mysql"
  20.  
    "github.com/opentracing/opentracing-go"
  21.  
    service2 "github.com/yunixiangfeng/gopaas/route/domain/service"
  22.  
    "github.com/yunixiangfeng/gopaas/route/handler"
  23.  
     
  24.  
    //hystrix2 "github.com/yunixiangfeng/gopaas/route/plugin/hystrix"
  25.  
    "strconv"
  26.  
     
  27.  
    route "github.com/yunixiangfeng/gopaas/route/proto/route"
  28.  
    "k8s.io/client-go/kubernetes"
  29.  
    "k8s.io/client-go/tools/clientcmd"
  30.  
    "k8s.io/client-go/util/homedir"
  31.  
    )
  32.  
     
  33.  
    var (
  34.  
    //服务地址
  35.  
    hostIp = "192.168.204.130"
  36.  
    //服务地址
  37.  
    serviceHost = hostIp
  38.  
    //服务端口
  39.  
    servicePort = "8085"
  40.  
     
  41.  
    //注册中心配置
  42.  
    consulHost = hostIp
  43.  
    consulPort int64 = 8500
  44.  
    //链路追踪
  45.  
    tracerHost = hostIp
  46.  
    tracerPort = 6831
  47.  
    //熔断端口,每个服务不能重复
  48.  
    //hystrixPort = 9095
  49.  
    //监控端口,每个服务不能重复
  50.  
    prometheusPort = 9195
  51.  
    )
  52.  
     
  53.  
    func main() {
  54.  
    //需要本地启动,mysql,consul中间件服务
  55.  
    //1.注册中心
  56.  
    consul := consul.NewRegistry(func(options *registry.Options) {
  57.  
    options.Addrs = []string{
  58.  
    consulHost ":" strconv.FormatInt(consulPort, 10),
  59.  
    }
  60.  
    })
  61.  
    //2.配置中心,存放经常变动的变量
  62.  
    consulConfig, err := common.GetConsulConfig(consulHost, consulPort, "/micro/config")
  63.  
    if err != nil {
  64.  
    common.Error(err)
  65.  
    }
  66.  
    //3.使用配置中心连接 mysql
  67.  
    mysqlInfo := common.GetMysqlFromConsul(consulConfig, "mysql")
  68.  
    //初始化数据库
  69.  
    db, err := gorm.Open("mysql", mysqlInfo.User ":" mysqlInfo.Pwd "@(" mysqlInfo.Host ":3306)/" mysqlInfo.Database "?charset=utf8&parseTime=True&loc=Local")
  70.  
    if err != nil {
  71.  
    //命令行输出下,方便查看错误
  72.  
    fmt.Println(err)
  73.  
    common.Fatal(err)
  74.  
    }
  75.  
    defer db.Close()
  76.  
    //禁止复表
  77.  
    db.SingularTable(true)
  78.  
     
  79.  
    //4.添加链路追踪
  80.  
    t, io, err := common.NewTracer("go.micro.service.route", tracerHost ":" strconv.Itoa(tracerPort))
  81.  
    if err != nil {
  82.  
    common.Error(err)
  83.  
    }
  84.  
    defer io.Close()
  85.  
    opentracing.SetGlobalTracer(t)
  86.  
     
  87.  
    //添加熔断器,作为客户端需要启用
  88.  
    //hystrixStreamHandler := hystrix.NewStreamHandler()
  89.  
    //hystrixStreamHandler.Start()
  90.  
     
  91.  
    //添加日志中心
  92.  
    //1)需要程序日志打入到日志文件中
  93.  
    //2)在程序中添加filebeat.yml 文件
  94.  
    //3) 启动filebeat,启动命令 ./filebeat -e -c filebeat.yml
  95.  
    fmt.Println("日志统一记录在根目录 micro.log 文件中,请点击查看日志!")
  96.  
     
  97.  
    //启动监听程序
  98.  
    //go func() {
  99.  
    // //http://192.168.204.130:9092/turbine/turbine.stream
  100.  
    // //看板访问地址 http://127.0.0.1:9002/hystrix,url后面一定要带 /hystrix
  101.  
    // err = http.ListenAndServe(net.JoinHostPort("0.0.0.0",strconv.Itoa(hystrixPort)),hystrixStreamHandler)
  102.  
    // if err !=nil {
  103.  
    // common.Error(err)
  104.  
    // }
  105.  
    //}()
  106.  
     
  107.  
    //5.添加监控
  108.  
    common.PrometheusBoot(prometheusPort)
  109.  
     
  110.  
    //下载kubectl:https://kubernetes.io/docs/tasks/tools/#tabset-2
  111.  
    //macos:
  112.  
    // 1.curl -LO "https://dl.k8s.io/release/v1.21.0/bin/darwin/amd64/kubectl"
  113.  
    // 2.chmod x ./kubectl
  114.  
    // 3.sudo mv ./kubectl /usr/local/bin/kubectl
  115.  
    // sudo chown root: /usr/local/bin/kubectl
  116.  
    // 5.kubectl version --client
  117.  
    // 6.集群模式下直接拷贝服务端~/.kube/config 文件到本机 ~/.kube/confg 中
  118.  
    // 注意:- config中的域名要能解析正确
  119.  
    // - 生产环境可以创建另一个证书
  120.  
    // 7.kubectl get ns 查看是否正常
  121.  
    //
  122.  
    //6.创建k8s连接
  123.  
    //在集群外面连接
  124.  
    var kubeconfig *string
  125.  
    if home := homedir.HomeDir(); home != "" {
  126.  
    kubeconfig = flag.String("kubeconfig", filepath.Join(home, ".kube", "config"), "(optional) absolute path to the kubeconfig file")
  127.  
    } else {
  128.  
    kubeconfig = flag.String("kubeconfig", "", "absolute path to the kubeconfig file")
  129.  
    }
  130.  
    flag.Parse()
  131.  
    config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
  132.  
    if err != nil {
  133.  
    common.Fatal(err.Error())
  134.  
    }
  135.  
     
  136.  
    //在集群中外的配置
  137.  
    //config, err := rest.InClusterConfig()
  138.  
    //if err != nil {
  139.  
    // panic(err.Error())
  140.  
    //}
  141.  
     
  142.  
    // create the clientset
  143.  
    clientset, err := kubernetes.NewForConfig(config)
  144.  
    if err != nil {
  145.  
    common.Fatal(err.Error())
  146.  
    }
  147.  
     
  148.  
    //7.创建服务
  149.  
    service := micro.NewService(
  150.  
    //自定义服务地址,且必须写在其它参数前面
  151.  
    micro.Server(server.NewServer(func(options *server.Options) {
  152.  
    options.Advertise = serviceHost ":" servicePort
  153.  
    })),
  154.  
    micro.Name("go.micro.service.route"),
  155.  
    micro.Version("latest"),
  156.  
    //指定服务端口
  157.  
    micro.Address(":" servicePort),
  158.  
    //添加注册中心
  159.  
    micro.Registry(consul),
  160.  
    //添加链路追踪
  161.  
    micro.WrapHandler(opentracing2.NewHandlerWrapper(opentracing.GlobalTracer())),
  162.  
    micro.WrapClient(opentracing2.NewClientWrapper(opentracing.GlobalTracer())),
  163.  
    //只作为客户端的时候起作用,如果存在调用别人的情况,原则上不去主动调用
  164.  
    //micro.WrapClient(hystrix2.NewClientHystrixWrapper()),
  165.  
    //添加限流
  166.  
    micro.WrapHandler(ratelimit.NewHandlerWrapper(1000)),
  167.  
    )
  168.  
     
  169.  
    service.Init()
  170.  
     
  171.  
    //只能执行一遍
  172.  
    err = repository.NewRouteRepository(db).InitTable()
  173.  
    if err != nil {
  174.  
    common.Fatal(err)
  175.  
    }
  176.  
     
  177.  
    // 注册句柄,可以快速操作已开发的服务
  178.  
    routeDataService := service2.NewRouteDataService(repository.NewRouteRepository(db), clientset)
  179.  
    route.RegisterRouteHandler(service.Server(), &handler.RouteHandler{RouteDataService: routeDataService})
  180.  
     
  181.  
    // 启动服务
  182.  
    if err := service.Run(); err != nil {
  183.  
    //输出启动失败信息
  184.  
    common.Fatal(err)
  185.  
    }
  186.  
    }

7-5 route 对外API的开发

  1.  
    PS C:\Users\Administrator\Desktop\gopaas> .\yu-tool\yu-tool.exe createApi github.com/yunixiangfeng/gopaas/routeApi
  2.  
     
  3.  
    yu-v3 --proto_path=. --micro_out=. --go_out=:. ./proto/routeApi/routeApi.proto
  4.  
     
  5.  
    go mod tidy

C:\Users\Administrator\Desktop\gopaas\routeapi\main.go

  1.  
    package main
  2.  
     
  3.  
    import (
  4.  
    "fmt"
  5.  
     
  6.  
    "github.com/afex/hystrix-go/hystrix"
  7.  
    "github.com/asim/go-micro/plugins/registry/consul/v3"
  8.  
    ratelimit "github.com/asim/go-micro/plugins/wrapper/ratelimiter/uber/v3"
  9.  
    "github.com/asim/go-micro/plugins/wrapper/select/roundrobin/v3"
  10.  
    opentracing2 "github.com/asim/go-micro/plugins/wrapper/trace/opentracing/v3"
  11.  
    "github.com/asim/go-micro/v3"
  12.  
    "github.com/asim/go-micro/v3/registry"
  13.  
    "github.com/asim/go-micro/v3/server"
  14.  
    "github.com/yunixiangfeng/gopaas/common"
  15.  
    go_micro_service_route "github.com/yunixiangfeng/gopaas/route/proto/route"
  16.  
     
  17.  
    "net"
  18.  
    "net/http"
  19.  
    "strconv"
  20.  
     
  21.  
    _ "github.com/jinzhu/gorm/dialects/mysql"
  22.  
    "github.com/opentracing/opentracing-go"
  23.  
    "github.com/yunixiangfeng/gopaas/routeApi/handler"
  24.  
    hystrix2 "github.com/yunixiangfeng/gopaas/routeApi/plugin/hystrix"
  25.  
     
  26.  
    routeApi "github.com/yunixiangfeng/gopaas/routeApi/proto/routeApi"
  27.  
    )
  28.  
     
  29.  
    var (
  30.  
    //服务地址
  31.  
    hostIp = "192.168.204.130"
  32.  
    //服务地址
  33.  
    serviceHost = hostIp
  34.  
    //服务端口
  35.  
    servicePort = "8086"
  36.  
    //注册中心配置
  37.  
    consulHost = hostIp
  38.  
    consulPort int64 = 8500
  39.  
    //链路追踪
  40.  
    tracerHost = hostIp
  41.  
    tracerPort = 6831
  42.  
    //熔断端口,每个服务不能重复
  43.  
    hystrixPort = 9096
  44.  
    //监控端口,每个服务不能重复
  45.  
    prometheusPort = 9196
  46.  
    )
  47.  
     
  48.  
    func main() {
  49.  
    //需要本地启动,mysql,consul中间件服务
  50.  
    //1.注册中心
  51.  
    consul := consul.NewRegistry(func(options *registry.Options) {
  52.  
    options.Addrs = []string{
  53.  
    consulHost ":" strconv.FormatInt(consulPort, 10),
  54.  
    }
  55.  
    })
  56.  
     
  57.  
    //2.添加链路追踪
  58.  
    t, io, err := common.NewTracer("go.micro.api.routeApi", tracerHost ":" strconv.Itoa(tracerPort))
  59.  
    if err != nil {
  60.  
    common.Error(err)
  61.  
    }
  62.  
    defer io.Close()
  63.  
    opentracing.SetGlobalTracer(t)
  64.  
     
  65.  
    //3.添加熔断器
  66.  
    hystrixStreamHandler := hystrix.NewStreamHandler()
  67.  
    hystrixStreamHandler.Start()
  68.  
     
  69.  
    //添加日志中心
  70.  
    //1)需要程序日志打入到日志文件中
  71.  
    //2)在程序中添加filebeat.yml 文件
  72.  
    //3) 启动filebeat,启动命令 ./filebeat -e -c filebeat.yml
  73.  
    fmt.Println("日志统一记录在根目录 micro.log 文件中,请点击查看日志!")
  74.  
     
  75.  
    //启动监听程序
  76.  
    go func() {
  77.  
    //http://192.168.204.130:9092/turbine/turbine.stream
  78.  
    //看板访问地址 http://127.0.0.1:9002/hystrix,url后面一定要带 /hystrix
  79.  
    err = http.ListenAndServe(net.JoinHostPort("0.0.0.0", strconv.Itoa(hystrixPort)), hystrixStreamHandler)
  80.  
    if err != nil {
  81.  
    common.Error(err)
  82.  
    }
  83.  
    }()
  84.  
     
  85.  
    //4.添加监控
  86.  
    common.PrometheusBoot(prometheusPort)
  87.  
     
  88.  
    //5.创建服务
  89.  
    service := micro.NewService(
  90.  
    //自定义服务地址,且必须写在其它参数前面
  91.  
    micro.Server(server.NewServer(func(opts *server.Options) {
  92.  
    opts.Advertise = serviceHost ":" servicePort
  93.  
     
  94.  
    })),
  95.  
    micro.Name("go.micro.api.routeApi"),
  96.  
    micro.Version("latest"),
  97.  
    //指定服务端口
  98.  
    micro.Address(":" servicePort),
  99.  
    //添加注册中心
  100.  
    micro.Registry(consul),
  101.  
    //添加链路追踪
  102.  
    micro.WrapHandler(opentracing2.NewHandlerWrapper(opentracing.GlobalTracer())),
  103.  
    micro.WrapClient(opentracing2.NewClientWrapper(opentracing.GlobalTracer())),
  104.  
    //只作为客户端的时候起作用
  105.  
    micro.WrapClient(hystrix2.NewClientHystrixWrapper()),
  106.  
    //添加限流
  107.  
    micro.WrapHandler(ratelimit.NewHandlerWrapper(1000)),
  108.  
    //增加负载均衡
  109.  
    micro.WrapClient(roundrobin.NewClientWrapper()),
  110.  
    )
  111.  
     
  112.  
    service.Init()
  113.  
     
  114.  
    // 指定需要访问的服务,可以快速操作已开发的服务,
  115.  
    // 默认API服务名称带有"Api",程序会自动替换
  116.  
    // 如果不带有特定字符会使用默认"XXX" 请自行替换
  117.  
    routeService := go_micro_service_route.NewRouteService("go.micro.service.route", service.Client())
  118.  
    // 注册控制器
  119.  
    if err := routeApi.RegisterRouteApiHandler(service.Server(), &handler.RouteApi{RouteService: routeService}); err != nil {
  120.  
    common.Error(err)
  121.  
    }
  122.  
     
  123.  
    // 启动服务
  124.  
    if err := service.Run(); err != nil {
  125.  
    //输出启动失败信息
  126.  
    common.Fatal(err)
  127.  
    }
  128.  
    }

C:\Users\Administrator\Desktop\gopaas\routeapi\handler\routeApiHandler.go

  1.  
    package handler
  2.  
     
  3.  
    import (
  4.  
    "context"
  5.  
    "encoding/json"
  6.  
    "errors"
  7.  
    "strconv"
  8.  
     
  9.  
    log "github.com/asim/go-micro/v3/logger"
  10.  
    "github.com/yunixiangfeng/gopaas/common"
  11.  
    route "github.com/yunixiangfeng/gopaas/route/proto/route"
  12.  
    routeApi "github.com/yunixiangfeng/gopaas/routeApi/proto/routeApi"
  13.  
    )
  14.  
     
  15.  
    type RouteApi struct {
  16.  
    RouteService route.RouteService
  17.  
    }
  18.  
     
  19.  
    // routeApi.FindRouteById 通过API向外暴露为/routeApi/findRouteById,接收http请求
  20.  
    // 即:/routeApi/FindRouteById 请求会调用go.micro.api.routeApi 服务的routeApi.FindRouteById 方法
  21.  
    func (e *RouteApi) FindRouteById(ctx context.Context, req *routeApi.Request, rsp *routeApi.Response) error {
  22.  
    log.Info("Received routeApi.FindRouteById request")
  23.  
    if _, ok := req.Get["route_id"]; !ok {
  24.  
    rsp.StatusCode = 500
  25.  
    return errors.New("参数异常")
  26.  
    }
  27.  
    //获取 route id
  28.  
    routeIdString := req.Get["route_id"].Values[0]
  29.  
    routeId, err := strconv.ParseInt(routeIdString, 10, 64)
  30.  
    if err != nil {
  31.  
    common.Error(err)
  32.  
    return err
  33.  
    }
  34.  
    //获取route信息
  35.  
    routeInfo, err := e.RouteService.FindRouteByID(ctx, &route.RouteId{
  36.  
    Id: routeId,
  37.  
    })
  38.  
    if err != nil {
  39.  
    common.Error(err)
  40.  
    return err
  41.  
    }
  42.  
    //返回route结果
  43.  
    rsp.StatusCode = 200
  44.  
    b, _ := json.Marshal(routeInfo)
  45.  
    rsp.Body = string(b)
  46.  
    return nil
  47.  
    }
  48.  
     
  49.  
    // routeApi.AddRoute 通过API向外暴露为/routeApi/AddRoute,接收http请求
  50.  
    // 即:/routeApi/AddRoute 请求会调用go.micro.api.routeApi 服务的routeApi.AddRoute 方法
  51.  
    func (e *RouteApi) AddRoute(ctx context.Context, req *routeApi.Request, rsp *routeApi.Response) error {
  52.  
    log.Info("Received routeApi.AddRoute request")
  53.  
    addRouteInfo := &route.RouteInfo{}
  54.  
    routePathName, ok := req.Post["route_path_name"]
  55.  
    if ok && len(routePathName.Values) > 0 {
  56.  
    port, err := strconv.ParseInt(req.Post["route_backend_service_port"].Values[0], 10, 32)
  57.  
    if err != nil {
  58.  
    common.Error(err)
  59.  
    return err
  60.  
    }
  61.  
    //这里如果有多个Path需要处理多个
  62.  
    routePath := &route.RoutePath{
  63.  
    RoutePathName: req.Post["route_path_name"].Values[0],
  64.  
    RouteBackendService: req.Post["route_backend_service"].Values[0],
  65.  
    RouteBackendServicePort: int32(port),
  66.  
    }
  67.  
    //合并
  68.  
    addRouteInfo.RoutePath = append(addRouteInfo.RoutePath, routePath)
  69.  
    }
  70.  
    form.FormToSvcStruct(req.Post, addRouteInfo)
  71.  
    response, err := e.RouteService.AddRoute(ctx, addRouteInfo)
  72.  
    if err != nil {
  73.  
    common.Error(err)
  74.  
    return err
  75.  
    }
  76.  
    rsp.StatusCode = 200
  77.  
    b, _ := json.Marshal(response)
  78.  
    rsp.Body = string(b)
  79.  
    return nil
  80.  
    }
  81.  
     
  82.  
    // routeApi.DeleteRouteById 通过API向外暴露为/routeApi/DeleteRouteById,接收http请求
  83.  
    // 即:/routeApi/DeleteRouteById 请求会调用go.micro.api.routeApi 服务的 routeApi.DeleteRouteById 方法
  84.  
    func (e *RouteApi) DeleteRouteById(ctx context.Context, req *routeApi.Request, rsp *routeApi.Response) error {
  85.  
    log.Info("Received routeApi.DeleteRouteById request")
  86.  
    if _, ok := req.Get["route_id"]; !ok {
  87.  
    rsp.StatusCode = 500
  88.  
    return errors.New("参数异常")
  89.  
    }
  90.  
    //获取 route id
  91.  
    routeIdString := req.Get["route_id"].Values[0]
  92.  
    routeId, err := strconv.ParseInt(routeIdString, 10, 64)
  93.  
    if err != nil {
  94.  
    common.Error(err)
  95.  
    return err
  96.  
    }
  97.  
    //调用route 删除服务
  98.  
    response, err := e.RouteService.DeleteRoute(ctx, &route.RouteId{
  99.  
    Id: routeId,
  100.  
    })
  101.  
    if err != nil {
  102.  
    common.Error(err)
  103.  
    return err
  104.  
    }
  105.  
    rsp.StatusCode = 200
  106.  
    b, _ := json.Marshal(response)
  107.  
    rsp.Body = string(b)
  108.  
    return nil
  109.  
    }
  110.  
     
  111.  
    // routeApi.UpdateRoute 通过API向外暴露为/routeApi/UpdateRoute,接收http请求
  112.  
    // 即:/routeApi/UpdateRoute 请求会调用go.micro.api.routeApi 服务的routeApi.UpdateRoute 方法
  113.  
    func (e *RouteApi) UpdateRoute(ctx context.Context, req *routeApi.Request, rsp *routeApi.Response) error {
  114.  
    log.Info("Received routeApi.UpdateRoute request")
  115.  
    rsp.StatusCode = 200
  116.  
    b, _ := json.Marshal("{success:'成功访问/routeApi/UpdateRoute'}")
  117.  
    rsp.Body = string(b)
  118.  
    return nil
  119.  
    }
  120.  
     
  121.  
    // 默认的方法routeApi.Call 通过API向外暴露为/routeApi/call,接收http请求
  122.  
    // 即:/routeApi/call或/routeApi/ 请求会调用go.micro.api.routeApi 服务的routeApi.FindRouteById 方法
  123.  
    func (e *RouteApi) Call(ctx context.Context, req *routeApi.Request, rsp *routeApi.Response) error {
  124.  
    log.Info("Received routeApi.Call request")
  125.  
    allRoute, err := e.RouteService.FindAllRoute(ctx, &route.FindAll{})
  126.  
    if err != nil {
  127.  
    common.Error(err)
  128.  
    return err
  129.  
    }
  130.  
    rsp.StatusCode = 200
  131.  
    b, _ := json.Marshal(allRoute)
  132.  
    rsp.Body = string(b)
  133.  
    return nil
  134.  
    }

C:\Users\Administrator\Desktop\gopaas\routeapi\plugin\form\form.go

  1.  
    package form
  2.  
     
  3.  
    import (
  4.  
    "errors"
  5.  
    "reflect"
  6.  
    "strconv"
  7.  
    "strings"
  8.  
    "time"
  9.  
     
  10.  
    "github.com/yunixiangfeng/gopaas/common"
  11.  
    "github.com/yunixiangfeng/gopaas/routeApi/proto/routeApi"
  12.  
    )
  13.  
     
  14.  
    //根据结构体中name标签映射数据到结构体中并且转换类型
  15.  
    func FormToSvcStruct(data map[string]*routeApi.Pair, obj interface{}) {
  16.  
    objValue := reflect.ValueOf(obj).Elem()
  17.  
    for i := 0; i < objValue.NumField(); i {
  18.  
    //获取sql对应的值
  19.  
    dataTag := strings.Replace(objValue.Type().Field(i).Tag.Get("json"), ",omitempty", "", -1)
  20.  
    dataSlice, ok := data[dataTag]
  21.  
    if !ok {
  22.  
    continue
  23.  
    }
  24.  
    valueSlice := dataSlice.Values
  25.  
    if len(valueSlice) <= 0 {
  26.  
    continue
  27.  
    }
  28.  
    //排除port和env
  29.  
    if dataTag == "route_path" {
  30.  
    continue
  31.  
    }
  32.  
    value := valueSlice[0]
  33.  
    //端口,环境变量的单独处理
  34.  
    //获取对应字段的名称
  35.  
    name := objValue.Type().Field(i).Name
  36.  
    //获取对应字段类型
  37.  
    structFieldType := objValue.Field(i).Type()
  38.  
    //获取变量类型,也可以直接写"string类型"
  39.  
    val := reflect.ValueOf(value)
  40.  
    var err error
  41.  
    if structFieldType != val.Type() {
  42.  
    //类型转换
  43.  
    val, err = TypeConversion(value, structFieldType.Name()) //类型转换
  44.  
    if err != nil {
  45.  
    common.Error(err)
  46.  
    }
  47.  
    }
  48.  
    //设置类型值
  49.  
    objValue.FieldByName(name).Set(val)
  50.  
    }
  51.  
    }
  52.  
     
  53.  
    //类型转换
  54.  
    func TypeConversion(value string, ntype string) (reflect.Value, error) {
  55.  
    if ntype == "string" {
  56.  
    return reflect.ValueOf(value), nil
  57.  
    } else if ntype == "time.Time" {
  58.  
    t, err := time.ParseInLocation("2006-01-02 15:04:05", value, time.Local)
  59.  
    return reflect.ValueOf(t), err
  60.  
    } else if ntype == "Time" {
  61.  
    t, err := time.ParseInLocation("2006-01-02 15:04:05", value, time.Local)
  62.  
    return reflect.ValueOf(t), err
  63.  
    } else if ntype == "int" {
  64.  
    i, err := strconv.Atoi(value)
  65.  
    return reflect.ValueOf(i), err
  66.  
    } else if ntype == "int32" {
  67.  
    i, err := strconv.ParseInt(value, 10, 32)
  68.  
    if err != nil {
  69.  
    return reflect.ValueOf(int32(i)), err
  70.  
    }
  71.  
    return reflect.ValueOf(int32(i)), err
  72.  
    } else if ntype == "int64" {
  73.  
    i, err := strconv.ParseInt(value, 10, 64)
  74.  
    return reflect.ValueOf(i), err
  75.  
    } else if ntype == "float32" {
  76.  
    i, err := strconv.ParseFloat(value, 64)
  77.  
    return reflect.ValueOf(float32(i)), err
  78.  
    } else if ntype == "float64" {
  79.  
    i, err := strconv.ParseFloat(value, 64)
  80.  
    return reflect.ValueOf(i), err
  81.  
    }
  82.  
     
  83.  
    //else if .......增加其他一些类型的转换
  84.  
     
  85.  
    return reflect.ValueOf(value), errors.New("未知的类型:" ntype)
  86.  
    }

7-6 在k8s 中创建 nginx-controller 资源对象

C:\Users\Administrator\Desktop\gopaas\ingress\deploy.yml

  1.  
    apiVersion: v1
  2.  
    kind: Namespace
  3.  
    metadata:
  4.  
    labels:
  5.  
    app.kubernetes.io/instance: ingress-nginx
  6.  
    app.kubernetes.io/name: ingress-nginx
  7.  
    name: default
  8.  
    ---
  9.  
    apiVersion: v1
  10.  
    automountServiceAccountToken: true
  11.  
    kind: ServiceAccount
  12.  
    metadata:
  13.  
    labels:
  14.  
    app.kubernetes.io/component: controller
  15.  
    app.kubernetes.io/instance: ingress-nginx
  16.  
    app.kubernetes.io/name: ingress-nginx
  17.  
    app.kubernetes.io/part-of: ingress-nginx
  18.  
    app.kubernetes.io/version: 1.2.0
  19.  
    name: ingress-nginx
  20.  
    namespace: default
  21.  
    ---
  22.  
    apiVersion: v1
  23.  
    kind: ServiceAccount
  24.  
    metadata:
  25.  
    labels:
  26.  
    app.kubernetes.io/component: admission-webhook
  27.  
    app.kubernetes.io/instance: ingress-nginx
  28.  
    app.kubernetes.io/name: ingress-nginx
  29.  
    app.kubernetes.io/part-of: ingress-nginx
  30.  
    app.kubernetes.io/version: 1.2.0
  31.  
    name: ingress-nginx-admission
  32.  
    namespace: default
  33.  
    ---
  34.  
    apiVersion: rbac.authorization.k8s.io/v1
  35.  
    kind: Role
  36.  
    metadata:
  37.  
    labels:
  38.  
    app.kubernetes.io/component: controller
  39.  
    app.kubernetes.io/instance: ingress-nginx
  40.  
    app.kubernetes.io/name: ingress-nginx
  41.  
    app.kubernetes.io/part-of: ingress-nginx
  42.  
    app.kubernetes.io/version: 1.2.0
  43.  
    name: ingress-nginx
  44.  
    namespace: default
  45.  
    rules:
  46.  
    - apiGroups:
  47.  
    - ""
  48.  
    resources:
  49.  
    - namespaces
  50.  
    verbs:
  51.  
    - get
  52.  
    - apiGroups:
  53.  
    - ""
  54.  
    resources:
  55.  
    - configmaps
  56.  
    - pods
  57.  
    - secrets
  58.  
    - endpoints
  59.  
    verbs:
  60.  
    - get
  61.  
    - list
  62.  
    - watch
  63.  
    - apiGroups:
  64.  
    - ""
  65.  
    resources:
  66.  
    - services
  67.  
    verbs:
  68.  
    - get
  69.  
    - list
  70.  
    - watch
  71.  
    - apiGroups:
  72.  
    - networking.k8s.io
  73.  
    resources:
  74.  
    - ingresses
  75.  
    verbs:
  76.  
    - get
  77.  
    - list
  78.  
    - watch
  79.  
    - apiGroups:
  80.  
    - networking.k8s.io
  81.  
    resources:
  82.  
    - ingresses/status
  83.  
    verbs:
  84.  
    - update
  85.  
    - apiGroups:
  86.  
    - networking.k8s.io
  87.  
    resources:
  88.  
    - ingressclasses
  89.  
    verbs:
  90.  
    - get
  91.  
    - list
  92.  
    - watch
  93.  
    - apiGroups:
  94.  
    - ""
  95.  
    resourceNames:
  96.  
    - ingress-controller-leader
  97.  
    resources:
  98.  
    - configmaps
  99.  
    verbs:
  100.  
    - get
  101.  
    - update
  102.  
    - apiGroups:
  103.  
    - ""
  104.  
    resources:
  105.  
    - configmaps
  106.  
    verbs:
  107.  
    - create
  108.  
    - apiGroups:
  109.  
    - ""
  110.  
    resources:
  111.  
    - events
  112.  
    verbs:
  113.  
    - create
  114.  
    - patch
  115.  
    ---
  116.  
    apiVersion: rbac.authorization.k8s.io/v1
  117.  
    kind: Role
  118.  
    metadata:
  119.  
    labels:
  120.  
    app.kubernetes.io/component: admission-webhook
  121.  
    app.kubernetes.io/instance: ingress-nginx
  122.  
    app.kubernetes.io/name: ingress-nginx
  123.  
    app.kubernetes.io/part-of: ingress-nginx
  124.  
    app.kubernetes.io/version: 1.2.0
  125.  
    name: ingress-nginx-admission
  126.  
    namespace: default
  127.  
    rules:
  128.  
    - apiGroups:
  129.  
    - ""
  130.  
    resources:
  131.  
    - secrets
  132.  
    verbs:
  133.  
    - get
  134.  
    - create
  135.  
    ---
  136.  
    apiVersion: rbac.authorization.k8s.io/v1
  137.  
    kind: ClusterRole
  138.  
    metadata:
  139.  
    labels:
  140.  
    app.kubernetes.io/instance: ingress-nginx
  141.  
    app.kubernetes.io/name: ingress-nginx
  142.  
    app.kubernetes.io/part-of: ingress-nginx
  143.  
    app.kubernetes.io/version: 1.2.0
  144.  
    name: ingress-nginx
  145.  
    rules:
  146.  
    - apiGroups:
  147.  
    - ""
  148.  
    resources:
  149.  
    - configmaps
  150.  
    - endpoints
  151.  
    - nodes
  152.  
    - pods
  153.  
    - secrets
  154.  
    - namespaces
  155.  
    verbs:
  156.  
    - list
  157.  
    - watch
  158.  
    - apiGroups:
  159.  
    - ""
  160.  
    resources:
  161.  
    - nodes
  162.  
    verbs:
  163.  
    - get
  164.  
    - apiGroups:
  165.  
    - ""
  166.  
    resources:
  167.  
    - services
  168.  
    verbs:
  169.  
    - get
  170.  
    - list
  171.  
    - watch
  172.  
    - apiGroups:
  173.  
    - networking.k8s.io
  174.  
    resources:
  175.  
    - ingresses
  176.  
    verbs:
  177.  
    - get
  178.  
    - list
  179.  
    - watch
  180.  
    - apiGroups:
  181.  
    - ""
  182.  
    resources:
  183.  
    - events
  184.  
    verbs:
  185.  
    - create
  186.  
    - patch
  187.  
    - apiGroups:
  188.  
    - networking.k8s.io
  189.  
    resources:
  190.  
    - ingresses/status
  191.  
    verbs:
  192.  
    - update
  193.  
    - apiGroups:
  194.  
    - networking.k8s.io
  195.  
    resources:
  196.  
    - ingressclasses
  197.  
    verbs:
  198.  
    - get
  199.  
    - list
  200.  
    - watch
  201.  
    ---
  202.  
    apiVersion: rbac.authorization.k8s.io/v1
  203.  
    kind: ClusterRole
  204.  
    metadata:
  205.  
    labels:
  206.  
    app.kubernetes.io/component: admission-webhook
  207.  
    app.kubernetes.io/instance: ingress-nginx
  208.  
    app.kubernetes.io/name: ingress-nginx
  209.  
    app.kubernetes.io/part-of: ingress-nginx
  210.  
    app.kubernetes.io/version: 1.2.0
  211.  
    name: ingress-nginx-admission
  212.  
    rules:
  213.  
    - apiGroups:
  214.  
    - admissionregistration.k8s.io
  215.  
    resources:
  216.  
    - validatingwebhookconfigurations
  217.  
    verbs:
  218.  
    - get
  219.  
    - update
  220.  
    ---
  221.  
    apiVersion: rbac.authorization.k8s.io/v1
  222.  
    kind: RoleBinding
  223.  
    metadata:
  224.  
    labels:
  225.  
    app.kubernetes.io/component: controller
  226.  
    app.kubernetes.io/instance: ingress-nginx
  227.  
    app.kubernetes.io/name: ingress-nginx
  228.  
    app.kubernetes.io/part-of: ingress-nginx
  229.  
    app.kubernetes.io/version: 1.2.0
  230.  
    name: ingress-nginx
  231.  
    namespace: default
  232.  
    roleRef:
  233.  
    apiGroup: rbac.authorization.k8s.io
  234.  
    kind: Role
  235.  
    name: ingress-nginx
  236.  
    subjects:
  237.  
    - kind: ServiceAccount
  238.  
    name: ingress-nginx
  239.  
    namespace: default
  240.  
    ---
  241.  
    apiVersion: rbac.authorization.k8s.io/v1
  242.  
    kind: RoleBinding
  243.  
    metadata:
  244.  
    labels:
  245.  
    app.kubernetes.io/component: admission-webhook
  246.  
    app.kubernetes.io/instance: ingress-nginx
  247.  
    app.kubernetes.io/name: ingress-nginx
  248.  
    app.kubernetes.io/part-of: ingress-nginx
  249.  
    app.kubernetes.io/version: 1.2.0
  250.  
    name: ingress-nginx-admission
  251.  
    namespace: default
  252.  
    roleRef:
  253.  
    apiGroup: rbac.authorization.k8s.io
  254.  
    kind: Role
  255.  
    name: ingress-nginx-admission
  256.  
    subjects:
  257.  
    - kind: ServiceAccount
  258.  
    name: ingress-nginx-admission
  259.  
    namespace: default
  260.  
    ---
  261.  
    apiVersion: rbac.authorization.k8s.io/v1
  262.  
    kind: ClusterRoleBinding
  263.  
    metadata:
  264.  
    labels:
  265.  
    app.kubernetes.io/instance: ingress-nginx
  266.  
    app.kubernetes.io/name: ingress-nginx
  267.  
    app.kubernetes.io/part-of: ingress-nginx
  268.  
    app.kubernetes.io/version: 1.2.0
  269.  
    name: ingress-nginx
  270.  
    roleRef:
  271.  
    apiGroup: rbac.authorization.k8s.io
  272.  
    kind: ClusterRole
  273.  
    name: ingress-nginx
  274.  
    subjects:
  275.  
    - kind: ServiceAccount
  276.  
    name: ingress-nginx
  277.  
    namespace: default
  278.  
    ---
  279.  
    apiVersion: rbac.authorization.k8s.io/v1
  280.  
    kind: ClusterRoleBinding
  281.  
    metadata:
  282.  
    labels:
  283.  
    app.kubernetes.io/component: admission-webhook
  284.  
    app.kubernetes.io/instance: ingress-nginx
  285.  
    app.kubernetes.io/name: ingress-nginx
  286.  
    app.kubernetes.io/part-of: ingress-nginx
  287.  
    app.kubernetes.io/version: 1.2.0
  288.  
    name: ingress-nginx-admission
  289.  
    roleRef:
  290.  
    apiGroup: rbac.authorization.k8s.io
  291.  
    kind: ClusterRole
  292.  
    name: ingress-nginx-admission
  293.  
    subjects:
  294.  
    - kind: ServiceAccount
  295.  
    name: ingress-nginx-admission
  296.  
    namespace: default
  297.  
    ---
  298.  
    apiVersion: v1
  299.  
    data:
  300.  
    allow-snippet-annotations: "true"
  301.  
    kind: ConfigMap
  302.  
    metadata:
  303.  
    labels:
  304.  
    app.kubernetes.io/component: controller
  305.  
    app.kubernetes.io/instance: ingress-nginx
  306.  
    app.kubernetes.io/name: ingress-nginx
  307.  
    app.kubernetes.io/part-of: ingress-nginx
  308.  
    app.kubernetes.io/version: 1.2.0
  309.  
    name: ingress-nginx-controller
  310.  
    namespace: default
  311.  
    ---
  312.  
    apiVersion: v1
  313.  
    kind: Service
  314.  
    metadata:
  315.  
    labels:
  316.  
    app.kubernetes.io/component: controller
  317.  
    app.kubernetes.io/instance: ingress-nginx
  318.  
    app.kubernetes.io/name: ingress-nginx
  319.  
    app.kubernetes.io/part-of: ingress-nginx
  320.  
    app.kubernetes.io/version: 1.2.0
  321.  
    name: ingress-nginx-controller
  322.  
    namespace: default
  323.  
    spec:
  324.  
    #externalTrafficPolicy: Local
  325.  
    ports:
  326.  
    - appProtocol: http
  327.  
    name: http
  328.  
    port: 80
  329.  
    protocol: TCP
  330.  
    targetPort: http
  331.  
    - appProtocol: https
  332.  
    name: https
  333.  
    port: 443
  334.  
    protocol: TCP
  335.  
    targetPort: https
  336.  
    selector:
  337.  
    app.kubernetes.io/component: controller
  338.  
    app.kubernetes.io/instance: ingress-nginx
  339.  
    app.kubernetes.io/name: ingress-nginx
  340.  
    # type: LoadBalancer
  341.  
    ---
  342.  
    apiVersion: v1
  343.  
    kind: Service
  344.  
    metadata:
  345.  
    labels:
  346.  
    app.kubernetes.io/component: controller
  347.  
    app.kubernetes.io/instance: ingress-nginx
  348.  
    app.kubernetes.io/name: ingress-nginx
  349.  
    app.kubernetes.io/part-of: ingress-nginx
  350.  
    app.kubernetes.io/version: 1.2.0
  351.  
    name: ingress-nginx-controller-admission
  352.  
    namespace: default
  353.  
    spec:
  354.  
    ports:
  355.  
    - appProtocol: https
  356.  
    name: https-webhook
  357.  
    port: 443
  358.  
    targetPort: webhook
  359.  
    selector:
  360.  
    app.kubernetes.io/component: controller
  361.  
    app.kubernetes.io/instance: ingress-nginx
  362.  
    app.kubernetes.io/name: ingress-nginx
  363.  
    type: ClusterIP
  364.  
    ---
  365.  
    apiVersion: apps/v1
  366.  
    #kind: Deployment
  367.  
    kind: DaemonSet
  368.  
    metadata:
  369.  
    labels:
  370.  
    app.kubernetes.io/component: controller
  371.  
    app.kubernetes.io/instance: ingress-nginx
  372.  
    app.kubernetes.io/name: ingress-nginx
  373.  
    app.kubernetes.io/part-of: ingress-nginx
  374.  
    app.kubernetes.io/version: 1.2.0
  375.  
    name: ingress-nginx-controller
  376.  
    namespace: default
  377.  
    spec:
  378.  
    minReadySeconds: 0
  379.  
    revisionHistoryLimit: 10
  380.  
    selector:
  381.  
    matchLabels:
  382.  
    app.kubernetes.io/component: controller
  383.  
    app.kubernetes.io/instance: ingress-nginx
  384.  
    app.kubernetes.io/name: ingress-nginx
  385.  
    template:
  386.  
    metadata:
  387.  
    labels:
  388.  
    app.kubernetes.io/component: controller
  389.  
    app.kubernetes.io/instance: ingress-nginx
  390.  
    app.kubernetes.io/name: ingress-nginx
  391.  
    spec:
  392.  
    containers:
  393.  
    - args:
  394.  
    - /nginx-ingress-controller
  395.  
    - --publish-service=$(POD_NAMESPACE)/ingress-nginx-controller
  396.  
    - --election-id=ingress-controller-leader
  397.  
    - --controller-class=k8s.io/ingress-nginx
  398.  
    - --ingress-class=nginx
  399.  
    - --configmap=$(POD_NAMESPACE)/ingress-nginx-controller
  400.  
    - --validating-webhook=:8443
  401.  
    - --validating-webhook-certificate=/usr/local/certificates/cert
  402.  
    - --validating-webhook-key=/usr/local/certificates/key
  403.  
    env:
  404.  
    - name: POD_NAME
  405.  
    valueFrom:
  406.  
    fieldRef:
  407.  
    fieldPath: metadata.name
  408.  
    - name: POD_NAMESPACE
  409.  
    valueFrom:
  410.  
    fieldRef:
  411.  
    fieldPath: metadata.namespace
  412.  
    - name: LD_PRELOAD
  413.  
    value: /usr/local/lib/libmimalloc.so
  414.  
    image: k8s.gcr.io/ingress-nginx/controller:v1.2.0@sha256:d8196e3bc1e72547c5dec66d6556c0ff92a23f6d0919b206be170bc90d5f9185
  415.  
    imagePullPolicy: IfNotPresent
  416.  
    lifecycle:
  417.  
    preStop:
  418.  
    exec:
  419.  
    command:
  420.  
    - /wait-shutdown
  421.  
    livenessProbe:
  422.  
    failureThreshold: 5
  423.  
    httpGet:
  424.  
    path: /healthz
  425.  
    port: 10254
  426.  
    scheme: HTTP
  427.  
    initialDelaySeconds: 10
  428.  
    periodSeconds: 10
  429.  
    successThreshold: 1
  430.  
    timeoutSeconds: 1
  431.  
    name: controller
  432.  
    ports:
  433.  
    - containerPort: 80
  434.  
    name: http
  435.  
    protocol: TCP
  436.  
    - containerPort: 443
  437.  
    name: https
  438.  
    protocol: TCP
  439.  
    - containerPort: 8443
  440.  
    name: webhook
  441.  
    protocol: TCP
  442.  
    readinessProbe:
  443.  
    failureThreshold: 3
  444.  
    httpGet:
  445.  
    path: /healthz
  446.  
    port: 10254
  447.  
    scheme: HTTP
  448.  
    initialDelaySeconds: 10
  449.  
    periodSeconds: 10
  450.  
    successThreshold: 1
  451.  
    timeoutSeconds: 1
  452.  
    resources:
  453.  
    requests:
  454.  
    cpu: 100m
  455.  
    memory: 90Mi
  456.  
    securityContext:
  457.  
    allowPrivilegeEscalation: true
  458.  
    capabilities:
  459.  
    add:
  460.  
    - NET_BIND_SERVICE
  461.  
    drop:
  462.  
    - ALL
  463.  
    runAsUser: 101
  464.  
    volumeMounts:
  465.  
    - mountPath: /usr/local/certificates/
  466.  
    name: webhook-cert
  467.  
    readOnly: true
  468.  
    # dnsPolicy: ClusterFirst
  469.  
    dnsPolicy: ClusterFirstWithHostNet
  470.  
    hostNetwork: true
  471.  
    nodeSelector:
  472.  
    kubernetes.io/os: linux
  473.  
    serviceAccountName: ingress-nginx
  474.  
    terminationGracePeriodSeconds: 300
  475.  
    volumes:
  476.  
    - name: webhook-cert
  477.  
    secret:
  478.  
    secretName: ingress-nginx-admission
  479.  
    ---
  480.  
    apiVersion: batch/v1
  481.  
    kind: Job
  482.  
    metadata:
  483.  
    labels:
  484.  
    app.kubernetes.io/component: admission-webhook
  485.  
    app.kubernetes.io/instance: ingress-nginx
  486.  
    app.kubernetes.io/name: ingress-nginx
  487.  
    app.kubernetes.io/part-of: ingress-nginx
  488.  
    app.kubernetes.io/version: 1.2.0
  489.  
    name: ingress-nginx-admission-create
  490.  
    namespace: default
  491.  
    spec:
  492.  
    template:
  493.  
    metadata:
  494.  
    labels:
  495.  
    app.kubernetes.io/component: admission-webhook
  496.  
    app.kubernetes.io/instance: ingress-nginx
  497.  
    app.kubernetes.io/name: ingress-nginx
  498.  
    app.kubernetes.io/part-of: ingress-nginx
  499.  
    app.kubernetes.io/version: 1.2.0
  500.  
    name: ingress-nginx-admission-create
  501.  
    spec:
  502.  
    containers:
  503.  
    - args:
  504.  
    - create
  505.  
    - --host=ingress-nginx-controller-admission,ingress-nginx-controller-admission.$(POD_NAMESPACE).svc
  506.  
    - --namespace=$(POD_NAMESPACE)
  507.  
    - --secret-name=ingress-nginx-admission
  508.  
    env:
  509.  
    - name: POD_NAMESPACE
  510.  
    valueFrom:
  511.  
    fieldRef:
  512.  
    fieldPath: metadata.namespace
  513.  
    image: k8s.gcr.io/ingress-nginx/kube-webhook-certgen:v1.1.1@sha256:64d8c73dca984af206adf9d6d7e46aa550362b1d7a01f3a0a91b20cc67868660
  514.  
    imagePullPolicy: IfNotPresent
  515.  
    name: create
  516.  
    securityContext:
  517.  
    allowPrivilegeEscalation: false
  518.  
    nodeSelector:
  519.  
    kubernetes.io/os: linux
  520.  
    restartPolicy: OnFailure
  521.  
    securityContext:
  522.  
    fsGroup: 2000
  523.  
    runAsNonRoot: true
  524.  
    runAsUser: 2000
  525.  
    serviceAccountName: ingress-nginx-admission
  526.  
    ---
  527.  
    apiVersion: batch/v1
  528.  
    kind: Job
  529.  
    metadata:
  530.  
    labels:
  531.  
    app.kubernetes.io/component: admission-webhook
  532.  
    app.kubernetes.io/instance: ingress-nginx
  533.  
    app.kubernetes.io/name: ingress-nginx
  534.  
    app.kubernetes.io/part-of: ingress-nginx
  535.  
    app.kubernetes.io/version: 1.2.0
  536.  
    name: ingress-nginx-admission-patch
  537.  
    namespace: default
  538.  
    spec:
  539.  
    template:
  540.  
    metadata:
  541.  
    labels:
  542.  
    app.kubernetes.io/component: admission-webhook
  543.  
    app.kubernetes.io/instance: ingress-nginx
  544.  
    app.kubernetes.io/name: ingress-nginx
  545.  
    app.kubernetes.io/part-of: ingress-nginx
  546.  
    app.kubernetes.io/version: 1.2.0
  547.  
    name: ingress-nginx-admission-patch
  548.  
    spec:
  549.  
    containers:
  550.  
    - args:
  551.  
    - patch
  552.  
    - --webhook-name=ingress-nginx-admission
  553.  
    - --namespace=$(POD_NAMESPACE)
  554.  
    - --patch-mutating=false
  555.  
    - --secret-name=ingress-nginx-admission
  556.  
    - --patch-failure-policy=Fail
  557.  
    env:
  558.  
    - name: POD_NAMESPACE
  559.  
    valueFrom:
  560.  
    fieldRef:
  561.  
    fieldPath: metadata.namespace
  562.  
    image: k8s.gcr.io/ingress-nginx/kube-webhook-certgen:v1.1.1@sha256:64d8c73dca984af206adf9d6d7e46aa550362b1d7a01f3a0a91b20cc67868660
  563.  
    imagePullPolicy: IfNotPresent
  564.  
    name: patch
  565.  
    securityContext:
  566.  
    allowPrivilegeEscalation: false
  567.  
    nodeSelector:
  568.  
    kubernetes.io/os: linux
  569.  
    restartPolicy: OnFailure
  570.  
    securityContext:
  571.  
    fsGroup: 2000
  572.  
    runAsNonRoot: true
  573.  
    runAsUser: 2000
  574.  
    serviceAccountName: ingress-nginx-admission
  575.  
    ---
  576.  
    apiVersion: networking.k8s.io/v1
  577.  
    kind: IngressClass
  578.  
    metadata:
  579.  
    labels:
  580.  
    app.kubernetes.io/component: controller
  581.  
    app.kubernetes.io/instance: ingress-nginx
  582.  
    app.kubernetes.io/name: ingress-nginx
  583.  
    app.kubernetes.io/part-of: ingress-nginx
  584.  
    app.kubernetes.io/version: 1.2.0
  585.  
    name: nginx
  586.  
    spec:
  587.  
    controller: k8s.io/ingress-nginx
  588.  
    ---
  589.  
    apiVersion: admissionregistration.k8s.io/v1
  590.  
    kind: ValidatingWebhookConfiguration
  591.  
    metadata:
  592.  
    labels:
  593.  
    app.kubernetes.io/component: admission-webhook
  594.  
    app.kubernetes.io/instance: ingress-nginx
  595.  
    app.kubernetes.io/name: ingress-nginx
  596.  
    app.kubernetes.io/part-of: ingress-nginx
  597.  
    app.kubernetes.io/version: 1.2.0
  598.  
    name: ingress-nginx-admission
  599.  
    webhooks:
  600.  
    - admissionReviewVersions:
  601.  
    - v1
  602.  
    clientConfig:
  603.  
    service:
  604.  
    name: ingress-nginx-controller-admission
  605.  
    namespace: default
  606.  
    path: /networking/v1/ingresses
  607.  
    failurePolicy: Fail
  608.  
    matchPolicy: Equivalent
  609.  
    name: validate.nginx.ingress.kubernetes.io
  610.  
    rules:
  611.  
    - apiGroups:
  612.  
    - networking.k8s.io
  613.  
    apiVersions:
  614.  
    - v1
  615.  
    operations:
  616.  
    - CREATE
  617.  
    - UPDATE
  618.  
    resources:
  619.  
    - ingresses
  620.  
    sideEffects: None
  1.  
    #### 在master节点执行命令
  2.  
    kubectl apply -f deploy.yml
  3.  
     
  4.  
    [root@k8s-master01 k8s]# kubectl apply -f ingress-deploy.yml
  5.  
    [root@k8s-master01 k8s]# kubectl get svc
  6.  
    NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
  7.  
    go-test ClusterIP 10.100.201.177 <none> 9099/TCP 13h
  8.  
    ingress-nginx-controller ClusterIP 10.106.55.124 <none> 80/TCP,443/TCP 21s
  9.  
    ingress-nginx-controller-admission ClusterIP 10.111.49.109 <none> 443/TCP 21s
  10.  
    kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 94d
  11.  
    [root@k8s-master01 k8s]# kubectl get daemonset
  12.  
    NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
  13.  
    ingress-nginx-controller 2 2 0 2 0 kubernetes.io/os=linux 2m51s
  14.  
     

7-7 route 前端管理页面及效果演示

C:\Users\Administrator\Desktop\gopaas\go-paas-front\route-create.html

  1.  
    <!DOCTYPE html>
  2.  
    <html lang="en">
  3.  
    <head>
  4.  
    <meta charset="utf-8">
  5.  
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
  6.  
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
  7.  
    <meta name="description" content="">
  8.  
    <meta name="author" content="">
  9.  
    <link rel="shortcut icon" href="assets/img/logo-fav.png">
  10.  
    <title>CPaaS</title>
  11.  
    <link rel="stylesheet" type="text/css" href="assets/lib/perfect-scrollbar/css/perfect-scrollbar.min.css"/>
  12.  
    <link rel="stylesheet" type="text/css" href="assets/lib/material-design-icons/css/material-design-iconic-font.min.css"/><!--[if lt IE 9]>
  13.  
    <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
  14.  
    <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
  15.  
    <![endif]-->
  16.  
    <link rel="stylesheet" href="assets/css/style.css" type="text/css"/>
  17.  
    </head>
  18.  
    <body>
  19.  
    <div class="be-wrapper">
  20.  
    <nav class="navbar navbar-default navbar-fixed-top be-top-header">
  21.  
    <div class="container-fluid">
  22.  
    <div class="navbar-header"><a href="index.html" class="navbar-brand"></a>
  23.  
    </div>
  24.  
    <div class="be-right-navbar">
  25.  
    <ul class="nav navbar-nav navbar-right be-user-nav">
  26.  
    <li class="dropdown"><a href="#" data-toggle="dropdown" role="button" aria-expanded="false" class="dropdown-toggle"><img src="assets/img/avatar.png" alt="Avatar"><span class="user-name">Túpac Amaru</span></a>
  27.  
    <ul role="menu" class="dropdown-menu">
  28.  
    <li>
  29.  
    <div class="user-info">
  30.  
    <div class="user-name">Túpac Amaru</div>
  31.  
    <div class="user-position online">Available</div>
  32.  
    </div>
  33.  
    </li>
  34.  
    <li><a href="#"><span class="icon mdi mdi-face"></span> Account</a></li>
  35.  
    <li><a href="#"><span class="icon mdi mdi-settings"></span> Settings</a></li>
  36.  
    <li><a href="#"><span class="icon mdi mdi-power"></span> Logout</a></li>
  37.  
    </ul>
  38.  
    </li>
  39.  
    </ul>
  40.  
    <div class="page-title"><span>Form Validation</span></div>
  41.  
    <ul class="nav navbar-nav navbar-right be-icons-nav">
  42.  
    <li class="dropdown"><a href="#" role="button" aria-expanded="false" class="be-toggle-right-sidebar"><span class="icon mdi mdi-settings"></span></a></li>
  43.  
    <li class="dropdown"><a href="#" data-toggle="dropdown" role="button" aria-expanded="false" class="dropdown-toggle"><span class="icon mdi mdi-notifications"></span><span class="indicator"></span></a>
  44.  
    <ul class="dropdown-menu be-notifications">
  45.  
    <li>
  46.  
    <div class="title">Notifications<span class="badge">3</span></div>
  47.  
    <div class="list">
  48.  
    <div class="be-scroller">
  49.  
    <div class="content">
  50.  
    <ul>
  51.  
    <li class="notification notification-unread"><a href="#">
  52.  
    <div class="image"><img src="assets/img/avatar2.png" alt="Avatar"></div>
  53.  
    <div class="notification-info">
  54.  
    <div class="text"><span class="user-name">Jessica Caruso</span> accepted your invitation to join the team.</div><span class="date">2 min ago</span>
  55.  
    </div></a></li>
  56.  
    <li class="notification"><a href="#">
  57.  
    <div class="image"><img src="assets/img/avatar3.png" alt="Avatar"></div>
  58.  
    <div class="notification-info">
  59.  
    <div class="text"><span class="user-name">Joel King</span> is now following you</div><span class="date">2 days ago</span>
  60.  
    </div></a></li>
  61.  
    <li class="notification"><a href="#">
  62.  
    <div class="image"><img src="assets/img/avatar4.png" alt="Avatar"></div>
  63.  
    <div class="notification-info">
  64.  
    <div class="text"><span class="user-name">John Doe</span> is watching your main repository</div><span class="date">2 days ago</span>
  65.  
    </div></a></li>
  66.  
    <li class="notification"><a href="#">
  67.  
    <div class="image"><img src="assets/img/avatar5.png" alt="Avatar"></div>
  68.  
    <div class="notification-info"><span class="text"><span class="user-name">Emily Carter</span> is now following you</span><span class="date">5 days ago</span></div></a></li>
  69.  
    </ul>
  70.  
    </div>
  71.  
    </div>
  72.  
    </div>
  73.  
    <div class="footer"> <a href="#">View all notifications</a></div>
  74.  
    </li>
  75.  
    </ul>
  76.  
    </li>
  77.  
    <li class="dropdown"><a href="#" data-toggle="dropdown" role="button" aria-expanded="false" class="dropdown-toggle"><span class="icon mdi mdi-apps"></span></a>
  78.  
    <ul class="dropdown-menu be-connections">
  79.  
    <li>
  80.  
    <div class="list">
  81.  
    <div class="content">
  82.  
    <div class="row">
  83.  
    <div class="col-xs-4"><a href="#" class="connection-item"><img src="assets/img/github.png" alt="Github"><span>GitHub</span></a></div>
  84.  
    <div class="col-xs-4"><a href="#" class="connection-item"><img src="assets/img/bitbucket.png" alt="Bitbucket"><span>Bitbucket</span></a></div>
  85.  
    <div class="col-xs-4"><a href="#" class="connection-item"><img src="assets/img/slack.png" alt="Slack"><span>Slack</span></a></div>
  86.  
    </div>
  87.  
    <div class="row">
  88.  
    <div class="col-xs-4"><a href="#" class="connection-item"><img src="assets/img/dribbble.png" alt="Dribbble"><span>Dribbble</span></a></div>
  89.  
    <div class="col-xs-4"><a href="#" class="connection-item"><img src="assets/img/mail_chimp.png" alt="Mail Chimp"><span>Mail Chimp</span></a></div>
  90.  
    <div class="col-xs-4"><a href="#" class="connection-item"><img src="assets/img/dropbox.png" alt="Dropbox"><span>Dropbox</span></a></div>
  91.  
    </div>
  92.  
    </div>
  93.  
    </div>
  94.  
    <div class="footer"> <a href="#">More</a></div>
  95.  
    </li>
  96.  
    </ul>
  97.  
    </li>
  98.  
    </ul>
  99.  
    </div>
  100.  
    </div>
  101.  
    </nav>
  102.  
    <!--
  103.  
    侧边栏-开始
  104.  
    -->
  105.  
    <div class="be-left-sidebar">
  106.  
    <div class="left-sidebar-wrapper"><a href="#" class="left-sidebar-toggle">看版</a>
  107.  
    <div class="left-sidebar-spacer">
  108.  
    <div class="left-sidebar-scroll">
  109.  
    <div class="left-sidebar-content">
  110.  
    <ul class="sidebar-elements">
  111.  
    <li class="divider">菜单</li>
  112.  
    <li class="parent"><a href="#"><i class="icon mdi mdi-home"></i><span>控制台</span></a>
  113.  
    </li>
  114.  
    <li class="parent"><a href="#"><i class="icon mdi mdi-face"></i><span>应用管理</span></a>
  115.  
    <ul class="sub-menu">
  116.  
    <li ><a href="pod-index.html">添加应用</a>
  117.  
    </li>
  118.  
    </ul>
  119.  
    </li>
  120.  
    <li class="parent"><a href="charts.html"><i class="icon mdi mdi-chart-donut"></i><span>服务管理</span></a>
  121.  
    <ul class="sub-menu">
  122.  
    <li ><a href="svc-index.html">添加服务</a>
  123.  
    </li>
  124.  
    </ul>
  125.  
    </li>
  126.  
    <li class="parent"><a href="#"><i class="icon mdi mdi-dot-circle"></i><span>域名管理</span></a>
  127.  
    <ul class="sub-menu">
  128.  
    <li class="active"><a href="route-index.html">添加路由</a>
  129.  
    </li>
  130.  
    </ul>
  131.  
    </li>
  132.  
    <li class="parent"><a href="#"><i class="icon mdi mdi-border-all"></i><span>中间件</span></a>
  133.  
    <ul class="sub-menu">
  134.  
    <li><a href="tables-general.html">General</a>
  135.  
    </li>
  136.  
    <li><a href="tables-datatables.html">Data Tables</a>
  137.  
    </li>
  138.  
    <li><a href="tables-filters.html"><span class="label label-primary pull-right">New</span>Table Filters</a>
  139.  
    </li>
  140.  
    </ul>
  141.  
    </li>
  142.  
    <li class="parent"><a href="#"><i class="icon mdi mdi-layers"></i><span>应用市场</span></a>
  143.  
    <ul class="sub-menu">
  144.  
    <li><a href="pages-blank.html">Blank Page</a>
  145.  
    </li>
  146.  
    <li><a href="pages-blank-header.html">Blank Page Header</a>
  147.  
    </li>
  148.  
    <li><a href="pages-login.html">Login</a>
  149.  
    </li>
  150.  
    <li><a href="pages-login2.html">Login v2</a>
  151.  
    </li>
  152.  
    <li><a href="pages-404.html">404 Page</a>
  153.  
    </li>
  154.  
    <li><a href="pages-sign-up.html">Sign Up</a>
  155.  
    </li>
  156.  
    <li><a href="pages-forgot-password.html">Forgot Password</a>
  157.  
    </li>
  158.  
    <li><a href="pages-profile.html">Profile</a>
  159.  
    </li>
  160.  
    <li><a href="pages-pricing-tables.html">Pricing Tables</a>
  161.  
    </li>
  162.  
    <li><a href="pages-pricing-tables2.html">Pricing Tables v2</a>
  163.  
    </li>
  164.  
    <li><a href="pages-timeline.html">Timeline</a>
  165.  
    </li>
  166.  
    <li><a href="pages-timeline2.html">Timeline v2</a>
  167.  
    </li>
  168.  
    <li><a href="pages-invoice.html"><span class="label label-primary pull-right">New</span>Invoice</a>
  169.  
    </li>
  170.  
    <li><a href="pages-calendar.html">Calendar</a>
  171.  
    </li>
  172.  
    <li><a href="pages-gallery.html">Gallery</a>
  173.  
    </li>
  174.  
    <li><a href="pages-code-editor.html"><span class="label label-primary pull-right">New </span>Code Editor</a>
  175.  
    </li>
  176.  
    <li><a href="pages-booking.html"><span class="label label-primary pull-right">New</span>Booking</a>
  177.  
    </li>
  178.  
    <li><a href="pages-loaders.html"><span class="label label-primary pull-right">New</span>Loaders</a>
  179.  
    </li>
  180.  
    </ul>
  181.  
    </li>
  182.  
     
  183.  
    </ul>
  184.  
    </div>
  185.  
    </div>
  186.  
    </div>
  187.  
    <div class="progress-widget">
  188.  
    <div class="progress-data"><span class="progress-value">60%</span><span class="name">Current Project</span></div>
  189.  
    <div class="progress">
  190.  
    <div style="width: 60%;" class="progress-bar progress-bar-primary"></div>
  191.  
    </div>
  192.  
    </div>
  193.  
    </div>
  194.  
    </div>
  195.  
    <!--
  196.  
    侧边栏-结束
  197.  
    -->
  198.  
    <div class="be-content">
  199.  
    <div class="main-content container-fluid">
  200.  
    <div class="row">
  201.  
    <div class="col-md-12">
  202.  
    <div class="panel panel-default panel-border-color panel-border-color-primary">
  203.  
    <div class="panel-heading panel-heading-divider">添加路由<span class="panel-subtitle"></span></div>
  204.  
    <div class="panel-body">
  205.  
    <form action="http://localhost:8080/routeApi/addRoute" class="form-horizontal group-border-dashed" method="post" >
  206.  
    <div class="form-group">
  207.  
    <label class="col-sm-3 control-label">路由名称:</label>
  208.  
    <div class="col-sm-6">
  209.  
    <input type="text" required="" class="form-control" id="route_name" name="route_name">
  210.  
    </div>
  211.  
    </div>
  212.  
    <div class="form-group">
  213.  
    <label class="col-sm-3 control-label">命名空间:</label>
  214.  
    <div class="col-sm-6">
  215.  
    <input type="text" required="" class="form-control" id="route_namespace" name="route_namespace" value="default">
  216.  
    </div>
  217.  
    </div>
  218.  
    <div class="form-group">
  219.  
    <label class="col-sm-3 control-label">设置域名:</label>
  220.  
    <div class="col-sm-6">
  221.  
    <input type="text" required="" class="form-control" id="route_host" name="route_host" >
  222.  
    </div>
  223.  
    </div>
  224.  
    <div class="form-group">
  225.  
    <label class="col-sm-3 control-label">设置路径:</label>
  226.  
    <div class="col-sm-6">
  227.  
    <input type="text" required="" class="form-control" name="route_path_name" id="route_path_name">
  228.  
    </div>
  229.  
    </div>
  230.  
    <div class="form-group">
  231.  
    <label class="col-sm-3 control-label">后端服务:</label>
  232.  
    <div class="col-sm-6">
  233.  
    <input type="text" required="" class="form-control" id="" name="route_backend_service" id="route_backend_service">
  234.  
    </div>
  235.  
    </div>
  236.  
     
  237.  
    <div class="form-group">
  238.  
    <label class="col-sm-3 control-label">后端服务端口:</label>
  239.  
    <div class="col-sm-6">
  240.  
    <input type="text" required="" class="form-control" name="route_backend_service_port" id="route_backend_service_port">
  241.  
    </div>
  242.  
    </div>
  243.  
     
  244.  
    <div class="form-group">
  245.  
    <div class="col-sm-2 col-sm-10">
  246.  
    <button type="submit" class="btn btn-space btn-primary">添加路由</button>
  247.  
    <button class="btn btn-space btn-default">Cancel</button>
  248.  
    </div>
  249.  
    </div>
  250.  
    </form>
  251.  
    </div>
  252.  
    </div>
  253.  
    </div>
  254.  
    </div>
  255.  
    </div>
  256.  
    </div>
  257.  
     
  258.  
    </div>
  259.  
    <script src="assets/lib/jquery/jquery.min.js" type="text/javascript"></script>
  260.  
    <script src="assets/lib/perfect-scrollbar/js/perfect-scrollbar.jquery.min.js" type="text/javascript"></script>
  261.  
    <script src="assets/js/main.js" type="text/javascript"></script>
  262.  
    <script src="assets/lib/bootstrap/dist/js/bootstrap.min.js" type="text/javascript"></script>
  263.  
    <script src="assets/lib/parsley/parsley.min.js" type="text/javascript"></script>
  264.  
     
  265.  
    <script type="text/javascript">
  266.  
    $(document).ready(function(){
  267.  
    App.init();
  268.  
    });
  269.  
     
  270.  
    //获取url中的参数
  271.  
    function getUrlParam(name) {
  272.  
    var reg = new RegExp("(^|&)" name "=([^&]*)(&|$)"); //构造一个含有目标参数的正则表达式对象
  273.  
    var r = window.location.search.substr(1).match(reg); //匹配目标参数
  274.  
    if (r != null) return unescape(r[2]); return null; //返回参数值
  275.  
    }
  276.  
     
  277.  
    </script>
  278.  
     
  279.  
    </body>
  280.  
    </html>

C:\Users\Administrator\Desktop\gopaas\go-paas-front\route-detail.html

  1.  
    <!DOCTYPE html>
  2.  
    <html lang="en">
  3.  
    <head>
  4.  
    <meta charset="utf-8">
  5.  
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
  6.  
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
  7.  
    <meta name="description" content="">
  8.  
    <meta name="author" content="">
  9.  
    <link rel="shortcut icon" href="assets/img/logo-fav.png">
  10.  
    <title>CPaaS</title>
  11.  
    <link rel="stylesheet" type="text/css" href="assets/lib/perfect-scrollbar/css/perfect-scrollbar.min.css"/>
  12.  
    <link rel="stylesheet" type="text/css" href="assets/lib/material-design-icons/css/material-design-iconic-font.min.css"/><!--[if lt IE 9]>
  13.  
    <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
  14.  
    <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
  15.  
    <![endif]-->
  16.  
    <link rel="stylesheet" href="assets/css/style.css" type="text/css"/>
  17.  
    </head>
  18.  
    <body>
  19.  
    <div class="be-wrapper">
  20.  
    <nav class="navbar navbar-default navbar-fixed-top be-top-header">
  21.  
    <div class="container-fluid">
  22.  
    <div class="navbar-header"><a href="index.html" class="navbar-brand"></a>
  23.  
    </div>
  24.  
    <div class="be-right-navbar">
  25.  
    <ul class="nav navbar-nav navbar-right be-user-nav">
  26.  
    <li class="dropdown"><a href="#" data-toggle="dropdown" role="button" aria-expanded="false" class="dropdown-toggle"><img src="assets/img/avatar.png" alt="Avatar"><span class="user-name">Túpac Amaru</span></a>
  27.  
    <ul role="menu" class="dropdown-menu">
  28.  
    <li>
  29.  
    <div class="user-info">
  30.  
    <div class="user-name">Túpac Amaru</div>
  31.  
    <div class="user-position online">Available</div>
  32.  
    </div>
  33.  
    </li>
  34.  
    <li><a href="#"><span class="icon mdi mdi-face"></span> Account</a></li>
  35.  
    <li><a href="#"><span class="icon mdi mdi-settings"></span> Settings</a></li>
  36.  
    <li><a href="#"><span class="icon mdi mdi-power"></span> Logout</a></li>
  37.  
    </ul>
  38.  
    </li>
  39.  
    </ul>
  40.  
    <div class="page-title"><span>Form Validation</span></div>
  41.  
    <ul class="nav navbar-nav navbar-right be-icons-nav">
  42.  
    <li class="dropdown"><a href="#" role="button" aria-expanded="false" class="be-toggle-right-sidebar"><span class="icon mdi mdi-settings"></span></a></li>
  43.  
    <li class="dropdown"><a href="#" data-toggle="dropdown" role="button" aria-expanded="false" class="dropdown-toggle"><span class="icon mdi mdi-notifications"></span><span class="indicator"></span></a>
  44.  
    <ul class="dropdown-menu be-notifications">
  45.  
    <li>
  46.  
    <div class="title">Notifications<span class="badge">3</span></div>
  47.  
    <div class="list">
  48.  
    <div class="be-scroller">
  49.  
    <div class="content">
  50.  
    <ul>
  51.  
    <li class="notification notification-unread"><a href="#">
  52.  
    <div class="image"><img src="assets/img/avatar2.png" alt="Avatar"></div>
  53.  
    <div class="notification-info">
  54.  
    <div class="text"><span class="user-name">Jessica Caruso</span> accepted your invitation to join the team.</div><span class="date">2 min ago</span>
  55.  
    </div></a></li>
  56.  
    <li class="notification"><a href="#">
  57.  
    <div class="image"><img src="assets/img/avatar3.png" alt="Avatar"></div>
  58.  
    <div class="notification-info">
  59.  
    <div class="text"><span class="user-name">Joel King</span> is now following you</div><span class="date">2 days ago</span>
  60.  
    </div></a></li>
  61.  
    <li class="notification"><a href="#">
  62.  
    <div class="image"><img src="assets/img/avatar4.png" alt="Avatar"></div>
  63.  
    <div class="notification-info">
  64.  
    <div class="text"><span class="user-name">John Doe</span> is watching your main repository</div><span class="date">2 days ago</span>
  65.  
    </div></a></li>
  66.  
    <li class="notification"><a href="#">
  67.  
    <div class="image"><img src="assets/img/avatar5.png" alt="Avatar"></div>
  68.  
    <div class="notification-info"><span class="text"><span class="user-name">Emily Carter</span> is now following you</span><span class="date">5 days ago</span></div></a></li>
  69.  
    </ul>
  70.  
    </div>
  71.  
    </div>
  72.  
    </div>
  73.  
    <div class="footer"> <a href="#">View all notifications</a></div>
  74.  
    </li>
  75.  
    </ul>
  76.  
    </li>
  77.  
    <li class="dropdown"><a href="#" data-toggle="dropdown" role="button" aria-expanded="false" class="dropdown-toggle"><span class="icon mdi mdi-apps"></span></a>
  78.  
    <ul class="dropdown-menu be-connections">
  79.  
    <li>
  80.  
    <div class="list">
  81.  
    <div class="content">
  82.  
    <div class="row">
  83.  
    <div class="col-xs-4"><a href="#" class="connection-item"><img src="assets/img/github.png" alt="Github"><span>GitHub</span></a></div>
  84.  
    <div class="col-xs-4"><a href="#" class="connection-item"><img src="assets/img/bitbucket.png" alt="Bitbucket"><span>Bitbucket</span></a></div>
  85.  
    <div class="col-xs-4"><a href="#" class="connection-item"><img src="assets/img/slack.png" alt="Slack"><span>Slack</span></a></div>
  86.  
    </div>
  87.  
    <div class="row">
  88.  
    <div class="col-xs-4"><a href="#" class="connection-item"><img src="assets/img/dribbble.png" alt="Dribbble"><span>Dribbble</span></a></div>
  89.  
    <div class="col-xs-4"><a href="#" class="connection-item"><img src="assets/img/mail_chimp.png" alt="Mail Chimp"><span>Mail Chimp</span></a></div>
  90.  
    <div class="col-xs-4"><a href="#" class="connection-item"><img src="assets/img/dropbox.png" alt="Dropbox"><span>Dropbox</span></a></div>
  91.  
    </div>
  92.  
    </div>
  93.  
    </div>
  94.  
    <div class="footer"> <a href="#">More</a></div>
  95.  
    </li>
  96.  
    </ul>
  97.  
    </li>
  98.  
    </ul>
  99.  
    </div>
  100.  
    </div>
  101.  
    </nav>
  102.  
    <!--
  103.  
    侧边栏-开始
  104.  
    -->
  105.  
    <div class="be-left-sidebar">
  106.  
    <div class="left-sidebar-wrapper"><a href="#" class="left-sidebar-toggle">看版</a>
  107.  
    <div class="left-sidebar-spacer">
  108.  
    <div class="left-sidebar-scroll">
  109.  
    <div class="left-sidebar-content">
  110.  
    <ul class="sidebar-elements">
  111.  
    <li class="divider">菜单</li>
  112.  
    <li class="parent"><a href="#"><i class="icon mdi mdi-home"></i><span>控制台</span></a>
  113.  
    </li>
  114.  
    <li class="parent"><a href="#"><i class="icon mdi mdi-face"></i><span>应用管理</span></a>
  115.  
    <ul class="sub-menu">
  116.  
    <li ><a href="pod-index.html">添加应用</a>
  117.  
    </li>
  118.  
    </ul>
  119.  
    </li>
  120.  
    <li class="parent"><a href="charts.html"><i class="icon mdi mdi-chart-donut"></i><span>服务管理</span></a>
  121.  
    <ul class="sub-menu">
  122.  
    <li ><a href="svc-index.html">添加服务</a>
  123.  
    </li>
  124.  
    </ul>
  125.  
    </li>
  126.  
    <li class="parent"><a href="#"><i class="icon mdi mdi-dot-circle"></i><span>域名管理</span></a>
  127.  
    <ul class="sub-menu">
  128.  
    <li class="active"><a href="route-index.html">添加路由</a>
  129.  
    </li>
  130.  
    </ul>
  131.  
    </li>
  132.  
    <li class="parent"><a href="#"><i class="icon mdi mdi-border-all"></i><span>中间件</span></a>
  133.  
    <ul class="sub-menu">
  134.  
    <li><a href="tables-general.html">General</a>
  135.  
    </li>
  136.  
    <li><a href="tables-datatables.html">Data Tables</a>
  137.  
    </li>
  138.  
    <li><a href="tables-filters.html"><span class="label label-primary pull-right">New</span>Table Filters</a>
  139.  
    </li>
  140.  
    </ul>
  141.  
    </li>
  142.  
    <li class="parent"><a href="#"><i class="icon mdi mdi-layers"></i><span>应用市场</span></a>
  143.  
    <ul class="sub-menu">
  144.  
    <li><a href="pages-blank.html">Blank Page</a>
  145.  
    </li>
  146.  
    <li><a href="pages-blank-header.html">Blank Page Header</a>
  147.  
    </li>
  148.  
    <li><a href="pages-login.html">Login</a>
  149.  
    </li>
  150.  
    <li><a href="pages-login2.html">Login v2</a>
  151.  
    </li>
  152.  
    <li><a href="pages-404.html">404 Page</a>
  153.  
    </li>
  154.  
    <li><a href="pages-sign-up.html">Sign Up</a>
  155.  
    </li>
  156.  
    <li><a href="pages-forgot-password.html">Forgot Password</a>
  157.  
    </li>
  158.  
    <li><a href="pages-profile.html">Profile</a>
  159.  
    </li>
  160.  
    <li><a href="pages-pricing-tables.html">Pricing Tables</a>
  161.  
    </li>
  162.  
    <li><a href="pages-pricing-tables2.html">Pricing Tables v2</a>
  163.  
    </li>
  164.  
    <li><a href="pages-timeline.html">Timeline</a>
  165.  
    </li>
  166.  
    <li><a href="pages-timeline2.html">Timeline v2</a>
  167.  
    </li>
  168.  
    <li><a href="pages-invoice.html"><span class="label label-primary pull-right">New</span>Invoice</a>
  169.  
    </li>
  170.  
    <li><a href="pages-calendar.html">Calendar</a>
  171.  
    </li>
  172.  
    <li><a href="pages-gallery.html">Gallery</a>
  173.  
    </li>
  174.  
    <li><a href="pages-code-editor.html"><span class="label label-primary pull-right">New </span>Code Editor</a>
  175.  
    </li>
  176.  
    <li><a href="pages-booking.html"><span class="label label-primary pull-right">New</span>Booking</a>
  177.  
    </li>
  178.  
    <li><a href="pages-loaders.html"><span class="label label-primary pull-right">New</span>Loaders</a>
  179.  
    </li>
  180.  
    </ul>
  181.  
    </li>
  182.  
     
  183.  
    </ul>
  184.  
    </div>
  185.  
    </div>
  186.  
    </div>
  187.  
    <div class="progress-widget">
  188.  
    <div class="progress-data"><span class="progress-value">60%</span><span class="name">Current Project</span></div>
  189.  
    <div class="progress">
  190.  
    <div style="width: 60%;" class="progress-bar progress-bar-primary"></div>
  191.  
    </div>
  192.  
    </div>
  193.  
    </div>
  194.  
    </div>
  195.  
    <!--
  196.  
    侧边栏-结束
  197.  
    -->
  198.  
    <div class="be-content">
  199.  
    <div class="main-content container-fluid">
  200.  
    <div class="row">
  201.  
    <div class="col-md-12">
  202.  
    <div class="panel panel-default panel-border-color panel-border-color-primary">
  203.  
    <div class="panel-heading panel-heading-divider">路由详情<span class="panel-subtitle">查看路由详情信息</span></div>
  204.  
    <div class="panel-body">
  205.  
    <form action="#" class="form-horizontal group-border-dashed">
  206.  
    <div class="form-group">
  207.  
    <label class="col-sm-3 control-label">路由ID:</label>
  208.  
    <div class="col-sm-6">
  209.  
    <input type="text" required="" readonly class="form-control" id="route_id" name="route_id">
  210.  
    </div>
  211.  
    </div>
  212.  
    <div class="form-group">
  213.  
    <label class="col-sm-3 control-label">路由名称:</label>
  214.  
    <div class="col-sm-6">
  215.  
    <input type="text" required="" readonly class="form-control" id="route_name" name="route_name">
  216.  
    </div>
  217.  
    </div>
  218.  
    <div class="form-group">
  219.  
    <label class="col-sm-3 control-label">命名空间:</label>
  220.  
    <div class="col-sm-6">
  221.  
    <input type="text" required="" readonly class="form-control" id="route_namespace" name="route_namespace">
  222.  
    </div>
  223.  
    </div>
  224.  
    <div class="form-group">
  225.  
    <label class="col-sm-3 control-label">设置域名:</label>
  226.  
    <div class="col-sm-6">
  227.  
    <input type="text" required="" class="form-control" id="route_host" name="route_host" >
  228.  
    </div>
  229.  
    </div>
  230.  
    <div class="form-group">
  231.  
    <label class="col-sm-3 control-label">设置路径:</label>
  232.  
    <div class="col-sm-6">
  233.  
    <input type="text" required="" class="form-control" name="route_path_name" id="route_path_name">
  234.  
    </div>
  235.  
    </div>
  236.  
    <div class="form-group">
  237.  
    <label class="col-sm-3 control-label">后端服务:</label>
  238.  
    <div class="col-sm-6">
  239.  
    <input type="text" required="" class="form-control" name="route_backend_service" id="route_backend_service">
  240.  
    </div>
  241.  
    </div>
  242.  
     
  243.  
    <div class="form-group">
  244.  
    <label class="col-sm-3 control-label">后端服务端口:</label>
  245.  
    <div class="col-sm-6">
  246.  
    <input type="text" required="" class="form-control" name="route_backend_service_port" id="route_backend_service_port">
  247.  
    </div>
  248.  
    </div>
  249.  
     
  250.  
     
  251.  
     
  252.  
    </form>
  253.  
    </div>
  254.  
    </div>
  255.  
    </div>
  256.  
    </div>
  257.  
    </div>
  258.  
    </div>
  259.  
     
  260.  
    </div>
  261.  
    <script src="assets/lib/jquery/jquery.min.js" type="text/javascript"></script>
  262.  
    <script src="assets/lib/perfect-scrollbar/js/perfect-scrollbar.jquery.min.js" type="text/javascript"></script>
  263.  
    <script src="assets/js/main.js" type="text/javascript"></script>
  264.  
    <script src="assets/lib/bootstrap/dist/js/bootstrap.min.js" type="text/javascript"></script>
  265.  
    <script src="assets/lib/parsley/parsley.min.js" type="text/javascript"></script>
  266.  
    <script type="text/javascript">
  267.  
    $(document).ready(function(){
  268.  
    App.init();
  269.  
    $('form').parsley();
  270.  
    $.ajax({
  271.  
    type:"get",
  272.  
    url:"http://127.0.0.1:8080/routeApi/findRouteById?route_id=" getUrlParam('route_id'),
  273.  
    success: function(data){
  274.  
    console.log(data);
  275.  
    if(data.id != "" || data.id != null || data.id != undefined){
  276.  
    $('#route_id').val(data.id);
  277.  
    $("#route_name").val(data.route_name);
  278.  
    $('#route_namespace').val(data.route_namespace);
  279.  
    $('#route_host').val(data.route_host);
  280.  
    //这里有多个要循环
  281.  
    $('#route_path_name').val(data.route_path[0]['route_path_name']);
  282.  
    $('#route_backend_service').val(data.route_path[0]['route_backend_service']);
  283.  
    $('#route_backend_service_port').val(data.route_path[0]['route_backend_service_port']);
  284.  
     
  285.  
    }else{
  286.  
    console.log(data);
  287.  
    }
  288.  
    },
  289.  
    error: function(result){
  290.  
    console.log(result);
  291.  
    }
  292.  
    });
  293.  
    });
  294.  
     
  295.  
    //获取url中的参数
  296.  
    function getUrlParam(name) {
  297.  
    var reg = new RegExp("(^|&)" name "=([^&]*)(&|$)"); //构造一个含有目标参数的正则表达式对象
  298.  
    var r = window.location.search.substr(1).match(reg); //匹配目标参数
  299.  
    if (r != null) return unescape(r[2]); return null; //返回参数值
  300.  
    }
  301.  
     
  302.  
    </script>
  303.  
     
  304.  
    </body>
  305.  
    </html>

C:\Users\Administrator\Desktop\gopaas\go-paas-front\route-index.html

  1.  
    <!DOCTYPE html>
  2.  
    <html lang="en">
  3.  
    <head>
  4.  
    <meta charset="utf-8">
  5.  
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
  6.  
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
  7.  
    <meta name="description" content="">
  8.  
    <meta name="author" content="">
  9.  
    <link rel="shortcut icon" href="assets/img/logo-fav.png">
  10.  
    <title>CPaaS</title>
  11.  
    <link rel="stylesheet" type="text/css" href="assets/lib/perfect-scrollbar/css/perfect-scrollbar.min.css"/>
  12.  
    <link rel="stylesheet" type="text/css" href="assets/lib/material-design-icons/css/material-design-iconic-font.min.css"/><!--[if lt IE 9]>
  13.  
    <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
  14.  
    <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
  15.  
    <![endif]-->
  16.  
    <link rel="stylesheet" type="text/css" href="assets/lib/datatables/css/dataTables.bootstrap.min.css"/>
  17.  
    <link rel="stylesheet" href="assets/css/style.css" type="text/css"/>
  18.  
    </head>
  19.  
    <body>
  20.  
    <div class="be-wrapper">
  21.  
    <nav class="navbar navbar-default navbar-fixed-top be-top-header">
  22.  
    <div class="container-fluid">
  23.  
    <div class="navbar-header"><a href="index.html" class="navbar-brand"></a>
  24.  
    </div>
  25.  
    <div class="be-right-navbar">
  26.  
    <ul class="nav navbar-nav navbar-right be-user-nav">
  27.  
    <li class="dropdown"><a href="#" data-toggle="dropdown" role="button" aria-expanded="false" class="dropdown-toggle"><img src="assets/img/avatar.png" alt="Avatar"><span class="user-name">Túpac Amaru</span></a>
  28.  
    <ul role="menu" class="dropdown-menu">
  29.  
    <li>
  30.  
    <div class="user-info">
  31.  
    <div class="user-name">wu123</div>
  32.  
    <div class="user-position online">在线</div>
  33.  
    </div>
  34.  
    </li>
  35.  
    <li><a href="#"><span class="icon mdi mdi-face"></span> 账户</a></li>
  36.  
    <li><a href="#"><span class="icon mdi mdi-settings"></span> 设置</a></li>
  37.  
    <li><a href="#"><span class="icon mdi mdi-power"></span> 推出登录</a></li>
  38.  
    </ul>
  39.  
    </li>
  40.  
    </ul>
  41.  
    <div class="page-title"></div>
  42.  
    <ul class="nav navbar-nav navbar-right be-icons-nav">
  43.  
    <li class="dropdown"><a href="#" role="button" aria-expanded="false" class="be-toggle-right-sidebar"><span class="icon mdi mdi-settings"></span></a></li>
  44.  
    <li class="dropdown"><a href="#" data-toggle="dropdown" role="button" aria-expanded="false" class="dropdown-toggle"><span class="icon mdi mdi-notifications"></span><span class="indicator"></span></a>
  45.  
    <ul class="dropdown-menu be-notifications">
  46.  
    <li>
  47.  
    <div class="title">消息提醒<span class="badge">3</span></div>
  48.  
    <div class="list">
  49.  
    <div class="be-scroller">
  50.  
    <div class="content">
  51.  
    <ul>
  52.  
    <li class="notification notification-unread"><a href="#">
  53.  
    <div class="image"><img src="assets/img/avatar2.png" alt="Avatar"></div>
  54.  
    <div class="notification-info">
  55.  
    <div class="text"><span class="user-name">Jessica Caruso</span> accepted your invitation to join the team.</div><span class="date">2 min ago</span>
  56.  
    </div></a></li>
  57.  
    <li class="notification"><a href="#">
  58.  
    <div class="image"><img src="assets/img/avatar3.png" alt="Avatar"></div>
  59.  
    <div class="notification-info">
  60.  
    <div class="text"><span class="user-name">Joel King</span> is now following you</div><span class="date">2 days ago</span>
  61.  
    </div></a></li>
  62.  
    <li class="notification"><a href="#">
  63.  
    <div class="image"><img src="assets/img/avatar4.png" alt="Avatar"></div>
  64.  
    <div class="notification-info">
  65.  
    <div class="text"><span class="user-name">John Doe</span> is watching your main repository</div><span class="date">2 days ago</span>
  66.  
    </div></a></li>
  67.  
    <li class="notification"><a href="#">
  68.  
    <div class="image"><img src="assets/img/avatar5.png" alt="Avatar"></div>
  69.  
    <div class="notification-info"><span class="text"><span class="user-name">Emily Carter</span> is now following you</span><span class="date">5 days ago</span></div></a></li>
  70.  
    </ul>
  71.  
    </div>
  72.  
    </div>
  73.  
    </div>
  74.  
    <div class="footer"> <a href="#">View all notifications</a></div>
  75.  
    </li>
  76.  
    </ul>
  77.  
    </li>
  78.  
    <li class="dropdown"><a href="#" data-toggle="dropdown" role="button" aria-expanded="false" class="dropdown-toggle"><span class="icon mdi mdi-apps"></span></a>
  79.  
    <ul class="dropdown-menu be-connections">
  80.  
    <li>
  81.  
    <div class="list">
  82.  
    <div class="content">
  83.  
    <div class="row">
  84.  
    <div class="col-xs-4"><a href="#" class="connection-item"><img src="assets/img/github.png" alt="Github"><span>GitHub</span></a></div>
  85.  
    <div class="col-xs-4"><a href="#" class="connection-item"><img src="assets/img/bitbucket.png" alt="Bitbucket"><span>Bitbucket</span></a></div>
  86.  
    <div class="col-xs-4"><a href="#" class="connection-item"><img src="assets/img/slack.png" alt="Slack"><span>Slack</span></a></div>
  87.  
    </div>
  88.  
    <div class="row">
  89.  
    <div class="col-xs-4"><a href="#" class="connection-item"><img src="assets/img/dribbble.png" alt="Dribbble"><span>Dribbble</span></a></div>
  90.  
    <div class="col-xs-4"><a href="#" class="connection-item"><img src="assets/img/mail_chimp.png" alt="Mail Chimp"><span>Mail Chimp</span></a></div>
  91.  
    <div class="col-xs-4"><a href="#" class="connection-item"><img src="assets/img/dropbox.png" alt="Dropbox"><span>Dropbox</span></a></div>
  92.  
    </div>
  93.  
    </div>
  94.  
    </div>
  95.  
    <div class="footer"> <a href="#">More</a></div>
  96.  
    </li>
  97.  
    </ul>
  98.  
    </li>
  99.  
    </ul>
  100.  
    </div>
  101.  
    </div>
  102.  
    </nav>
  103.  
    <!--
  104.  
    侧边栏-开始
  105.  
    -->
  106.  
    <div class="be-left-sidebar">
  107.  
    <div class="left-sidebar-wrapper"><a href="#" class="left-sidebar-toggle">看版</a>
  108.  
    <div class="left-sidebar-spacer">
  109.  
    <div class="left-sidebar-scroll">
  110.  
    <div class="left-sidebar-content">
  111.  
    <ul class="sidebar-elements">
  112.  
    <li class="divider">菜单</li>
  113.  
    <li class="parent"><a href="#"><i class="icon mdi mdi-home"></i><span>控制台</span></a>
  114.  
    </li>
  115.  
    <li class="parent"><a href="#"><i class="icon mdi mdi-face"></i><span>应用管理</span></a>
  116.  
    <ul class="sub-menu">
  117.  
    <li ><a href="pod-index.html">添加应用</a>
  118.  
    </li>
  119.  
    </ul>
  120.  
    </li>
  121.  
    <li class="parent"><a href="charts.html"><i class="icon mdi mdi-chart-donut"></i><span>服务管理</span></a>
  122.  
    <ul class="sub-menu">
  123.  
    <li ><a href="svc-index.html">添加服务</a>
  124.  
    </li>
  125.  
    </ul>
  126.  
    </li>
  127.  
    <li class="parent"><a href="#"><i class="icon mdi mdi-dot-circle"></i><span>域名管理</span></a>
  128.  
    <ul class="sub-menu">
  129.  
    <li class="active"><a href="route-index.html">添加路由</a>
  130.  
    </li>
  131.  
    </ul>
  132.  
    </li>
  133.  
    <li class="parent"><a href="#"><i class="icon mdi mdi-border-all"></i><span>中间件</span></a>
  134.  
    <ul class="sub-menu">
  135.  
    <li><a href="tables-general.html">General</a>
  136.  
    </li>
  137.  
    <li><a href="tables-datatables.html">Data Tables</a>
  138.  
    </li>
  139.  
    <li><a href="tables-filters.html"><span class="label label-primary pull-right">New</span>Table Filters</a>
  140.  
    </li>
  141.  
    </ul>
  142.  
    </li>
  143.  
    <li class="parent"><a href="#"><i class="icon mdi mdi-layers"></i><span>应用市场</span></a>
  144.  
    <ul class="sub-menu">
  145.  
    <li><a href="pages-blank.html">Blank Page</a>
  146.  
    </li>
  147.  
    <li><a href="pages-blank-header.html">Blank Page Header</a>
  148.  
    </li>
  149.  
    <li><a href="pages-login.html">Login</a>
  150.  
    </li>
  151.  
    <li><a href="pages-login2.html">Login v2</a>
  152.  
    </li>
  153.  
    <li><a href="pages-404.html">404 Page</a>
  154.  
    </li>
  155.  
    <li><a href="pages-sign-up.html">Sign Up</a>
  156.  
    </li>
  157.  
    <li><a href="pages-forgot-password.html">Forgot Password</a>
  158.  
    </li>
  159.  
    <li><a href="pages-profile.html">Profile</a>
  160.  
    </li>
  161.  
    <li><a href="pages-pricing-tables.html">Pricing Tables</a>
  162.  
    </li>
  163.  
    <li><a href="pages-pricing-tables2.html">Pricing Tables v2</a>
  164.  
    </li>
  165.  
    <li><a href="pages-timeline.html">Timeline</a>
  166.  
    </li>
  167.  
    <li><a href="pages-timeline2.html">Timeline v2</a>
  168.  
    </li>
  169.  
    <li><a href="pages-invoice.html"><span class="label label-primary pull-right">New</span>Invoice</a>
  170.  
    </li>
  171.  
    <li><a href="pages-calendar.html">Calendar</a>
  172.  
    </li>
  173.  
    <li><a href="pages-gallery.html">Gallery</a>
  174.  
    </li>
  175.  
    <li><a href="pages-code-editor.html"><span class="label label-primary pull-right">New </span>Code Editor</a>
  176.  
    </li>
  177.  
    <li><a href="pages-booking.html"><span class="label label-primary pull-right">New</span>Booking</a>
  178.  
    </li>
  179.  
    <li><a href="pages-loaders.html"><span class="label label-primary pull-right">New</span>Loaders</a>
  180.  
    </li>
  181.  
    </ul>
  182.  
    </li>
  183.  
     
  184.  
    </ul>
  185.  
    </div>
  186.  
    </div>
  187.  
    </div>
  188.  
    <div class="progress-widget">
  189.  
    <div class="progress-data"><span class="progress-value">60%</span><span class="name">Current Project</span></div>
  190.  
    <div class="progress">
  191.  
    <div style="width: 60%;" class="progress-bar progress-bar-primary"></div>
  192.  
    </div>
  193.  
    </div>
  194.  
    </div>
  195.  
    </div>
  196.  
    <!--
  197.  
    侧边栏-结束
  198.  
    -->
  199.  
    <div class="be-content">
  200.  
    <div class="page-head">
  201.  
    <h2 class="page-head-title">路由管理</h2>
  202.  
    <ol class="breadcrumb page-head-nav">
  203.  
    <li><a href="#">控制台</a></li>
  204.  
    <li><a href="#">路由管理</a></li>
  205.  
    <li class="active">路由列表</li>
  206.  
    </ol>
  207.  
    </div>
  208.  
    <div class="main-content container-fluid">
  209.  
    <div class="row">
  210.  
    <div class="col-sm-12">
  211.  
    <div class="panel panel-default panel-table">
  212.  
    <div class="panel-heading">
  213.  
    <a href="route-create.html"><button class="btn btn-space btn-primary">添加路由</button></a>
  214.  
    <div class="tools dropdown"><span class="icon mdi mdi-download"></span><a href="#" type="button" data-toggle="dropdown" class="dropdown-toggle"><span class="icon mdi mdi-more-vert"></span></a>
  215.  
    <ul role="menu" class="dropdown-menu pull-right">
  216.  
    <li><a href="#">Action</a></li>
  217.  
    <li><a href="#">Another action</a></li>
  218.  
    <li><a href="#">Something else here</a></li>
  219.  
    <li class="divider"></li>
  220.  
    <li><a href="#">Separated link</a></li>
  221.  
    </ul>
  222.  
    </div>
  223.  
    </div>
  224.  
    <div class="panel-body">
  225.  
    <table id="table1" class="table table-striped table-hover table-fw-widget">
  226.  
    <thead>
  227.  
    <tr>
  228.  
    <th>ID</th>
  229.  
    <th>域名</th>
  230.  
    <th>命名空间</th>
  231.  
    <th>路径</th>
  232.  
    <th>操作</th>
  233.  
    </tr>
  234.  
    </thead>
  235.  
    <tbody id="table-data">
  236.  
    </tbody>
  237.  
    </table>
  238.  
    </div>
  239.  
    </div>
  240.  
    </div>
  241.  
    </div>
  242.  
     
  243.  
    </div>
  244.  
    </div>
  245.  
    <nav class="be-right-sidebar">
  246.  
    <div class="sb-content">
  247.  
    <div class="tab-navigation">
  248.  
    <ul role="tablist" class="nav nav-tabs nav-justified">
  249.  
    <li role="presentation" class="active"><a href="#tab1" aria-controls="tab1" role="tab" data-toggle="tab">Chat</a></li>
  250.  
    <li role="presentation"><a href="#tab2" aria-controls="tab2" role="tab" data-toggle="tab">Todo</a></li>
  251.  
    <li role="presentation"><a href="#tab3" aria-controls="tab3" role="tab" data-toggle="tab">Settings</a></li>
  252.  
    </ul>
  253.  
    </div>
  254.  
    <div class="tab-panel">
  255.  
    <div class="tab-content">
  256.  
    <div id="tab1" role="tabpanel" class="tab-pane tab-chat active">
  257.  
    <div class="chat-contacts">
  258.  
    <div class="chat-sections">
  259.  
    <div class="be-scroller">
  260.  
    <div class="content">
  261.  
    <h2>Recent</h2>
  262.  
    <div class="contact-list contact-list-recent">
  263.  
    <div class="user"><a href="#"><img src="assets/img/avatar1.png" alt="Avatar">
  264.  
    <div class="user-data"><span class="status away"></span><span class="name">Claire Sassu</span><span class="message">Can you share the...</span></div></a></div>
  265.  
    <div class="user"><a href="#"><img src="assets/img/avatar2.png" alt="Avatar">
  266.  
    <div class="user-data"><span class="status"></span><span class="name">Maggie jackson</span><span class="message">I confirmed the info.</span></div></a></div>
  267.  
    <div class="user"><a href="#"><img src="assets/img/avatar3.png" alt="Avatar">
  268.  
    <div class="user-data"><span class="status offline"></span><span class="name">Joel King </span><span class="message">Ready for the meeti...</span></div></a></div>
  269.  
    </div>
  270.  
    <h2>Contacts</h2>
  271.  
    <div class="contact-list">
  272.  
    <div class="user"><a href="#"><img src="assets/img/avatar4.png" alt="Avatar">
  273.  
    <div class="user-data2"><span class="status"></span><span class="name">Mike Bolthort</span></div></a></div>
  274.  
    <div class="user"><a href="#"><img src="assets/img/avatar5.png" alt="Avatar">
  275.  
    <div class="user-data2"><span class="status"></span><span class="name">Maggie jackson</span></div></a></div>
  276.  
    <div class="user"><a href="#"><img src="assets/img/avatar6.png" alt="Avatar">
  277.  
    <div class="user-data2"><span class="status offline"></span><span class="name">Jhon Voltemar</span></div></a></div>
  278.  
    </div>
  279.  
    </div>
  280.  
    </div>
  281.  
    </div>
  282.  
    <div class="bottom-input">
  283.  
    <input type="text" placeholder="Search..." name="q"><span class="mdi mdi-search"></span>
  284.  
    </div>
  285.  
    </div>
  286.  
    <div class="chat-window">
  287.  
    <div class="title">
  288.  
    <div class="user"><img src="assets/img/avatar2.png" alt="Avatar">
  289.  
    <h2>Maggie jackson</h2><span>Active 1h ago</span>
  290.  
    </div><span class="icon return mdi mdi-chevron-left"></span>
  291.  
    </div>
  292.  
    <div class="chat-messages">
  293.  
    <div class="be-scroller">
  294.  
    <div class="content">
  295.  
    <ul>
  296.  
    <li class="friend">
  297.  
    <div class="msg">Hello</div>
  298.  
    </li>
  299.  
    <li class="self">
  300.  
    <div class="msg">Hi, how are you?</div>
  301.  
    </li>
  302.  
    <li class="friend">
  303.  
    <div class="msg">Good, I'll need support with my pc</div>
  304.  
    </li>
  305.  
    <li class="self">
  306.  
    <div class="msg">Sure, just tell me what is going on with your computer?</div>
  307.  
    </li>
  308.  
    <li class="friend">
  309.  
    <div class="msg">I don't know it just turns off suddenly</div>
  310.  
    </li>
  311.  
    </ul>
  312.  
    </div>
  313.  
    </div>
  314.  
    </div>
  315.  
    <div class="chat-input">
  316.  
    <div class="input-wrapper"><span class="photo mdi mdi-camera"></span>
  317.  
    <input type="text" placeholder="Message..." name="q" autocomplete="off"><span class="send-msg mdi mdi-mail-send"></span>
  318.  
    </div>
  319.  
    </div>
  320.  
    </div>
  321.  
    </div>
  322.  
    <div id="tab2" role="tabpanel" class="tab-pane tab-todo">
  323.  
    <div class="todo-container">
  324.  
    <div class="todo-wrapper">
  325.  
    <div class="be-scroller">
  326.  
    <div class="todo-content"><span class="category-title">Today</span>
  327.  
    <ul class="todo-list">
  328.  
    <li>
  329.  
    <div class="be-checkbox be-checkbox-sm"><span class="delete mdi mdi-delete"></span>
  330.  
    <input id="todo1" type="checkbox" checked="">
  331.  
    <label for="todo1">Initialize the project</label>
  332.  
    </div>
  333.  
    </li>
  334.  
    <li>
  335.  
    <div class="be-checkbox be-checkbox-sm"><span class="delete mdi mdi-delete"></span>
  336.  
    <input id="todo2" type="checkbox">
  337.  
    <label for="todo2">Create the main structure</label>
  338.  
    </div>
  339.  
    </li>
  340.  
    <li>
  341.  
    <div class="be-checkbox be-checkbox-sm"><span class="delete mdi mdi-delete"></span>
  342.  
    <input id="todo3" type="checkbox">
  343.  
    <label for="todo3">Updates changes to GitHub</label>
  344.  
    </div>
  345.  
    </li>
  346.  
    </ul><span class="category-title">Tomorrow</span>
  347.  
    <ul class="todo-list">
  348.  
    <li>
  349.  
    <div class="be-checkbox be-checkbox-sm"><span class="delete mdi mdi-delete"></span>
  350.  
    <input id="todo4" type="checkbox">
  351.  
    <label for="todo4">Initialize the project</label>
  352.  
    </div>
  353.  
    </li>
  354.  
    <li>
  355.  
    <div class="be-checkbox be-checkbox-sm"><span class="delete mdi mdi-delete"></span>
  356.  
    <input id="todo5" type="checkbox">
  357.  
    <label for="todo5">Create the main structure</label>
  358.  
    </div>
  359.  
    </li>
  360.  
    <li>
  361.  
    <div class="be-checkbox be-checkbox-sm"><span class="delete mdi mdi-delete"></span>
  362.  
    <input id="todo6" type="checkbox">
  363.  
    <label for="todo6">Updates changes to GitHub</label>
  364.  
    </div>
  365.  
    </li>
  366.  
    <li>
  367.  
    <div class="be-checkbox be-checkbox-sm"><span class="delete mdi mdi-delete"></span>
  368.  
    <input id="todo7" type="checkbox">
  369.  
    <label for="todo7" title="This task is too long to be displayed in a normal space!">This task is too long to be displayed in a normal space!</label>
  370.  
    </div>
  371.  
    </li>
  372.  
    </ul>
  373.  
    </div>
  374.  
    </div>
  375.  
    </div>
  376.  
    <div class="bottom-input">
  377.  
    <input type="text" placeholder="Create new task..." name="q"><span class="mdi mdi-plus"></span>
  378.  
    </div>
  379.  
    </div>
  380.  
    </div>
  381.  
    <div id="tab3" role="tabpanel" class="tab-pane tab-settings">
  382.  
    <div class="settings-wrapper">
  383.  
    <div class="be-scroller"><span class="category-title">General</span>
  384.  
    <ul class="settings-list">
  385.  
    <li>
  386.  
    <div class="switch-button switch-button-sm">
  387.  
    <input type="checkbox" checked="" name="st1" id="st1"><span>
  388.  
    <label for="st1"></label></span>
  389.  
    </div><span class="name">Available</span>
  390.  
    </li>
  391.  
    <li>
  392.  
    <div class="switch-button switch-button-sm">
  393.  
    <input type="checkbox" checked="" name="st2" id="st2"><span>
  394.  
    <label for="st2"></label></span>
  395.  
    </div><span class="name">Enable notifications</span>
  396.  
    </li>
  397.  
    <li>
  398.  
    <div class="switch-button switch-button-sm">
  399.  
    <input type="checkbox" checked="" name="st3" id="st3"><span>
  400.  
    <label for="st3"></label></span>
  401.  
    </div><span class="name">Login with Facebook</span>
  402.  
    </li>
  403.  
    </ul><span class="category-title">Notifications</span>
  404.  
    <ul class="settings-list">
  405.  
    <li>
  406.  
    <div class="switch-button switch-button-sm">
  407.  
    <input type="checkbox" name="st4" id="st4"><span>
  408.  
    <label for="st4"></label></span>
  409.  
    </div><span class="name">Email notifications</span>
  410.  
    </li>
  411.  
    <li>
  412.  
    <div class="switch-button switch-button-sm">
  413.  
    <input type="checkbox" checked="" name="st5" id="st5"><span>
  414.  
    <label for="st5"></label></span>
  415.  
    </div><span class="name">Project updates</span>
  416.  
    </li>
  417.  
    <li>
  418.  
    <div class="switch-button switch-button-sm">
  419.  
    <input type="checkbox" checked="" name="st6" id="st6"><span>
  420.  
    <label for="st6"></label></span>
  421.  
    </div><span class="name">New comments</span>
  422.  
    </li>
  423.  
    <li>
  424.  
    <div class="switch-button switch-button-sm">
  425.  
    <input type="checkbox" name="st7" id="st7"><span>
  426.  
    <label for="st7"></label></span>
  427.  
    </div><span class="name">Chat messages</span>
  428.  
    </li>
  429.  
    </ul><span class="category-title">Workflow</span>
  430.  
    <ul class="settings-list">
  431.  
    <li>
  432.  
    <div class="switch-button switch-button-sm">
  433.  
    <input type="checkbox" name="st8" id="st8"><span>
  434.  
    <label for="st8"></label></span>
  435.  
    </div><span class="name">Deploy on commit</span>
  436.  
    </li>
  437.  
    </ul>
  438.  
    </div>
  439.  
    </div>
  440.  
    </div>
  441.  
    </div>
  442.  
    </div>
  443.  
    </div>
  444.  
    </nav>
  445.  
    </div>
  446.  
    <script src="assets/lib/jquery/jquery.min.js" type="text/javascript"></script>
  447.  
    <script src="assets/lib/perfect-scrollbar/js/perfect-scrollbar.jquery.min.js" type="text/javascript"></script>
  448.  
    <script src="assets/js/main.js" type="text/javascript"></script>
  449.  
    <script src="assets/lib/bootstrap/dist/js/bootstrap.min.js" type="text/javascript"></script>
  450.  
    <script src="assets/lib/datatables/js/jquery.dataTables.min.js" type="text/javascript"></script>
  451.  
    <script src="assets/lib/datatables/js/dataTables.bootstrap.min.js" type="text/javascript"></script>
  452.  
    <script src="assets/lib/datatables/plugins/buttons/js/dataTables.buttons.js" type="text/javascript"></script>
  453.  
    <script src="assets/lib/datatables/plugins/buttons/js/buttons.html5.js" type="text/javascript"></script>
  454.  
    <script src="assets/lib/datatables/plugins/buttons/js/buttons.flash.js" type="text/javascript"></script>
  455.  
    <script src="assets/lib/datatables/plugins/buttons/js/buttons.print.js" type="text/javascript"></script>
  456.  
    <script src="assets/lib/datatables/plugins/buttons/js/buttons.colVis.js" type="text/javascript"></script>
  457.  
    <script src="assets/lib/datatables/plugins/buttons/js/buttons.bootstrap.js" type="text/javascript"></script>
  458.  
    <script src="assets/js/app-tables-datatables.js" type="text/javascript"></script>
  459.  
     
  460.  
    <script type="text/javascript">
  461.  
    $(document).ready(function(){
  462.  
     
  463.  
    //initialize the javascript
  464.  
    App.init();
  465.  
     
  466.  
    App.dataTables();
  467.  
     
  468.  
    $.ajax({
  469.  
    type:"get",
  470.  
    url:"http://127.0.0.1:8080/routeApi/",
  471.  
    success: function(data){
  472.  
    console.log(data);
  473.  
    $("#table-data").html("");
  474.  
    $.each(data['route_info'],function (i,item) {
  475.  
    $("#table-data").append(' <tr class="gradeA">\
  476.  
    <td>' item.id '</td>\
  477.  
    <td>' item.route_name '</td>\
  478.  
    <td>' item.route_namespace '</td>\
  479.  
    <td class="center">' item.route_host '</td>\
  480.  
    <td class="center"><a href="https://blog.csdn.net/niwoxiangyu/article/details/route-detail.html?route_id=' item.id '">详情</a> <a href="http://localhost:8080/routeApi/deleteRouteById?route_id=' item.id '" style="color:red;" >删除</a></td>\
  481.  
    </tr>'
  482.  
    );
  483.  
    })
  484.  
    },
  485.  
    error: function(result){
  486.  
    console.log(result);
  487.  
    }
  488.  
    });
  489.  
    });
  490.  
     
  491.  
     
  492.  
     
  493.  
    </script>
  494.  
     
  495.  
    </body>
  496.  
    </html>

学新通

7-8 总结&思考 

主要内容
介绍了ingress的以及ingress-controller的作用
说明ingress-controller的运行原理
ingress-controller (nginx)的代码功能开发

经验之谈
Ingress controller 的类型一般采用daemonset模式
路由管理要审核不然管理起来非常复杂。

Route-controller 其它模式的用法?
除去nginx以外 还有哪些是常用的类型?

7-9 【扩展阅读】Kubernetes 使用 ingress 配置 https 集群

第8章 云原生Go PaaS 平台后台监控能力建设,总览集群资源使用

集群的状态需要有强有力的全局视图,监控系统应运而生,通过强大的监控系统能够窥探整个 PaaS 的运行状态,实施反馈集群信息轻松掌握使用 Promethus 对整个 PaaS 平台应用和组件的监控能力,可以通过监控结合不同的业务逻辑适应企业多变的业务需求。

8-1 Go PaaS 平台监控系统 Prometheus 架构介绍

GO PaaS 平台监控系统建立

主要内容
主流监控 Promethus监控讲解
在 K8s 中安装监控
Promethus 监控维度效果展示

Promethus 架构介绍
监控可以监控哪些方面的信息
监控的核心组件
监控的核心架构

Go PaaS平台监控模块建立

监控的目标
发现已经存在的问题
预防即将出现的问题

监控哪些内容
系统基础指标(内存、CPU、IO、Disk、Network等)服务基础信息(存活,占用的系统资源等)
服务个性化(接口、固定返回值等) ;
日志内容(从日志中获取报错信息 );

K8s 中的监控内容
节点
服务
K8s自身的组件

如何监控?
数据采集:要先配置采集什么内容
数据存储:采集完数据之后,需要有数据库来进行存储定义报警规则:设置报警红线,满足条件进行报警
配置报警方式:设置短信,邮件,微信等报警:

(普罗米修斯)监控Prometheus
是一套开源的监控&报警&时间序列数据库的组合
由metric名称和 kv 标识的多维数据模型
支持 pull、push 两种方式添加数据

Prometheus(普罗米修斯)架构

学新通

(普罗米修斯)数据来源rometheus

服务器指标来源
容器指标来源
组件指标来源 

学新通

学新通学新通

8-2 Go PaaS 平台Prometheus 监控安装

C:\Users\Administrator\Desktop\gopaas\promethues\README.md

  1.  
    ### Prometheus 安装说明
  2.  
     
  3.  
    #### 1.解压 zip 包
  4.  
    ```cassandraql
  5.  
    unzip v0.9.0.zip
  6.  
    ```
  7.  
     
  8.  
    #### 2.进入目录
  9.  
    ```cassandraql
  10.  
    cd kube-prometheus-0.9.0
  11.  
    ```
  12.  
     
  13.  
    #### 3.执行安装命令
  14.  
    ```cassandraql
  15.  
    //创建命名空间和CRD
  16.  
    kubectl create -f manifests/setup
  17.  
     
  18.  
    //等待创建结束
  19.  
    until kubectl get servicemonitors --all-namespaces ; do date; sleep 1; echo ""; done
  20.  
     
  21.  
    //创建监控组件
  22.  
    kubectl create -f manifests/
  23.  
     
  24.  
    //查看 monitoring 内的 pod
  25.  
    kubectl get pods -n monitoring
  26.  
    ```
  27.  
     
  28.  
    #### 4.添加路由外网访问
  29.  
    通过前一章开发的 route 功能添加 monitoring 命名空间下
  30.  
    grafana.wu123.com 域名
  31.  
    第一次登录默认账号:admin 密码:admin
  1.  
    [root@k8s-worker01 kube-prometheus-0.9.0]# kubectl get pods -n monitoring
  2.  
    NAME READY STATUS RESTARTS AGE
  3.  
    alertmanager-main-0 2/2 Running 0 4m52s
  4.  
    alertmanager-main-1 2/2 Running 0 4m41s
  5.  
    blackbox-exporter-589d9b456-zs74d 3/3 Running 0 4m52s
  6.  
    grafana-6767dc8755-sl48b 1/1 Running 0 4m55s
  7.  
    kube-state-metrics-8fc46689b-hgh9w 2/3 Running 0 4m52s
  8.  
    node-exporter-5h2vw 2/2 Running 0 4m52s
  9.  
    node-exporter-6gp27 2/2 Running 0 4m52s
  10.  
    node-exporter-j6phd 2/2 Running 0 4m52s
  11.  
    prometheus-adapter-58cd975bff-9rvj8 1/1 Running 0 4m52s
  12.  
    prometheus-adapter-58cd975bff-lwjhl 1/1 Running 0 4m52s
  13.  
    prometheus-k8s-0 2/2 Running 0 4m52s
  14.  
    prometheus-k8s-1 2/2 Running 0 4m52s
  15.  
    prometheus-operator-6cdd8db9f7-7mp6q 2/2 Running 0 9m6s

学新通学新通

学新通

学新通

8-3 Go PaaS 平台 监控 Grafana 图标使用说明

学新通

8-4 总结&思考

主要内容
介绍了 Prometheus的基础组件与架构在 k8s 中安装Promethues 与监控看板
grafana功能展示

经验之谈
监控为GOPaaS平台不或缺的能力,数据需要近一步保存
PaaS 平台的监控扩展基于 Prometheus
监控更多要考虑业务属性和决策目标

还有哪些决策需要监控数据的支持
监控能够给 PaaS运营带来哪些场景

8-5 【扩展阅读】Prometheus Operator 安装配置详细文档

第9章 云原生 Go PaaS 平台分布式存储管理功能开发,提供数据落盘方案

数据是非常宝贵的财富,业务运行过程中产生的数据是无形的资产,分布式存储系统能够提供多种数据保存方案。深度解读 Ceph 分布式系统的原理、架构、核心组件等知识

9-1 Go PaaS 平台分布式存储 Ceph 架构介绍

GO PaaS 平台分布式存储开发

主要内容
Ceph 基础概念介绍
Ceph 架构说明及安装
服务后端功能开发

Ceph 集群基础介绍
Ceph 特性
Ceph 存储类型
Ceph 核心组件

Ceph 特性
高性能:支持上千个节点,支持TP到PB及的数据。
高可用:故障域分离,强一致性,自动修复。

高扩性:去中心化,扩展灵活。

Ceph 存储支持的类型
块存储:类比传统的存储硬盘,磁盘阵列
文件存储:类比FTP 服务
对象存储:类比大容量硬盘里面附带文件服务

学新通

Ceph 存储架构及核心组件

学新通

Ceph 基础存储系统 RADOS
全称: Reliable Autonomic Distributed Object Store
RADOS是ceph存储集群的基础
所有数据都以对象的形式存储

Ceph 基础库LIBRADOS
LIBRADOS层的功能是对 RADOS 进行抽象和封装
向上层提供 API以便直接基于 RADOS 进行应用开发
支持多种编程语言,比如GO、C、C 、Python 等

上层接口RADOSGW、RBD和CEPHFS
RADOSGW:基于RESTFUL协议,兼容S3和Swift
RBD提供分布式的块存储设备接口,像磁盘一样挂载使用
CephFS 是一个POSIX 兼容的分布式文件系统

9-2 Go PaaS 平台 Ceph 核心组件介绍 

Ceph 核心组件简介 OSD(ceph-osd)
object storage daemon,用于集群中所有数据与对象的存储。
负责处理集群数据的复制、恢复、回填、再均衡。
Ceph 集群通过管理 OSD 来管理物理硬盘

Ceph 核心组件简介 Manager (ceph-mgr)
收集 Ceph 集群状态,运行指标(存储利用率、系统负载等)
外提供 ceph dashboard (ceph ui)和 resetful api。
Manager组件开启高可用时,至少2个实现高可用性。

Ceph 核心组件简介 MDSceph-mds):
Metadata server,元数据服务
为 Ceph 文件系统提供元数据计算、缓存与同步服务
MDS类似于元数据的代理缓存服务器

Ceph 核心组件简介 Monitor (ceph-mon)
维护集群Cluster Map的状态
维护集群的Cluster MAP二进制表,保证集群数据的一致性monitor组件信息,manger 组件信息,osd 组件信息,mds组件信息,crush 算法信息

9-3 Go PaaS 平台 Ceph 存储过程及核心概念介绍

RADOS的系统逻辑结构

学新通

RADOS存储过程

学新通

逻辑概念说明
File:用户需要存储或者访问的文件
Objects: RADOS的基本存储单元,即对象。
PG(Placement Group): 这里PG作用是对object的存储进行组织和位置映射 

逻辑概念说明
OSD (object storage device 
oid : 每个object都会有一个唯一的OID,由ino和ono生成
pgid: 使用静态hash函数对OID做hash去除特征码

存储过程中各层次之间的映射关系
file -> object
object -> PG
PG -> OSD

为什么引入 PG 概念?
因为 Obiect 对象的 size 很小,并不会直接存储进 OSD 中
多对象如果遍历寻址,速度很缓慢
直接映射到 OSD上当单个OSD 损坏后无法迁移数据

9-4 Go PaaS 平台Ceph 资源购买注意事项

Ceph 集群安装
3台 2C 4G 20G系统盘,20G数据盘
操作系统为 Centos 8.3
采用 Cephadm 方式安装 ceph 16 版本

9-5 Go PaaS 平台Ceph 安全机器初始化

  1.  
    ### 基于 Centos8 系统通过 Cephadm 快速部署 Ceph16(pacific)版本
  2.  
     
  3.  
    #### 前期准备
  4.  
     
  5.  
    ##### 1. 安装依赖
  6.  
    lvm因为系统自带的都有,所以就不用单独安装了,
  7.  
    ```cassandraql
  8.  
    dnf install epel-release -y
  9.  
    dnf install python3 -y
  10.  
    dnf install podman -y
  11.  
    dnf install -y chrony
  12.  
    systemctl start chronyd && systemctl enable chronyd
  13.  
    ```
  14.  
    chrony时间服务为必须安装,具体有2点原因:1为不安装在添加主机的时候会报错,2为即使安装成功ceph -s会也提示时间不同步!
  15.  
    ##### 2.关闭防火墙和selinux (每台都执行)
  16.  
    ```cassandraql
  17.  
    systemctl disable firewalld && systemctl stop firewalld
  18.  
    setenforce 0
  19.  
    sed -i "s/SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config
  20.  
    ```
  21.  
     
  22.  
    ##### 3.分别在三个节点设置主机名
  23.  
    ```cassandraql
  24.  
    hostnamectl set-hostname ceph01
  25.  
    hostnamectl set-hostname ceph02
  26.  
    hostnamectl set-hostname ceph03
  27.  
    ```
  28.  
    重启机器 reboot
  29.  
    cephadm需要主机名为短主机名,不能为FQDN,否者在添加主机会报错!
  30.  
     
  31.  
    ##### 4.添加hosts文件中的主机名和IP关系,主机名需要和上面一致
  32.  
    172.31.96.70 ceph01 2Cpu 4G内存 20G系统盘,20G数据盘
  33.  
    172.31.96.71 ceph02 2Cpu 4G内存 20G系统盘,20G数据盘
  34.  
    172.31.96.72 ceph03 2Cpu 4G内存 20G系统盘,20G数据盘
  35.  
    ```cassandraql
  36.  
    cat >> /etc/hosts <<EOF
  37.  
    172.31.96.70 ceph01
  38.  
    172.31.96.71 ceph02
  39.  
    172.31.96.72 ceph03
  40.  
    EOF
  41.  
    ```

9-6 Go PaaS 平台cephadm 安装基础集群(上)

C:\Users\Administrator\Desktop\gopaas\ceph\1.ceph 安装.md

  1.  
    #### 安装 cephadm
  2.  
    cephadm 命令可以
  3.  
    1. 引导新集群
  4.  
    2. 使用有效的Ceph CLI启动容器化的Shell
  5.  
    3. 帮助调试容器化的Ceph守护进程。
  6.  
    以下操作只在一台节点执行就可以
  7.  
    ##### 1.使用curl获取独立脚本的最新版本。网络不好的话可直接去GitHub复制
  8.  
     
  9.  
    ```cassandraql
  10.  
    curl --silent --remote-name --location https://github.com/ceph/ceph/raw/pacific/src/cephadm/cephadm
  11.  
    chmod x cephadm
  12.  
    ./cephadm add-repo --release pacific
  13.  
    ./cephadm install
  14.  
    ./cephadm install ceph-common
  15.  
    ```
  16.  
    官方文档中还提到了另一种安装cephadm方式,就是通过dnf install -y cephadm安装,实践证明最好不要使用这种方式,这种方式安装的cephadm可能不是最新版本的,但cephadm去拉的容器版本又是最新的,会导致两个版本不一致!
  17.  
     
  18.  
     
  19.  
     
  20.  
     
  21.  
    #### 引导新群集
  22.  
    ##### 1.先创建一个目录:/etc/ceph
  23.  
    ```cassandraql
  24.  
    mkdir -p /etc/ceph
  25.  
    ```
  26.  
     
  27.  
    ##### 2.运行该命令:ceph bootstrap
  28.  
    ```cassandraql
  29.  
    cephadm bootstrap --mon-ip 172.31.96.70
  30.  
    ```
  31.  
    此命令将会进行以下操作:
  32.  
    - 为本地主机上的新群集创建monitor和manager守护程序。
  33.  
    - 为 Ceph 群集生成新的 SSH 密钥,并将其添加到root用户的文件/root/.ssh/authorized_keys
  34.  
    - 将与新群集通信所需的最小配置文件保存到 /etc/ceph/ceph.conf
  35.  
    - 将client.admin管理(特权!)密钥的副本写入/etc/ceph/ceph.client.admin.keyring
  36.  
    - 将公钥的副本写入/etc/ceph/ceph.pub
  37.  
     
  38.  
    安装日志如下为成功
  39.  
    ```cassandraql
  40.  
    [root@ceph01 ~]# cephadm bootstrap --mon-ip 172.31.96.70
  41.  
    Verifying podman|docker is present...
  42.  
    Verifying lvm2 is present...
  43.  
    Verifying time synchronization is in place...
  44.  
    Unit chronyd.service is enabled and running
  45.  
    Repeating the final host check...
  46.  
    podman (/usr/bin/podman) version 3.3.1 is present
  47.  
    systemctl is present
  48.  
    lvcreate is present
  49.  
    Unit chronyd.service is enabled and running
  50.  
    Host looks OK
  51.  
    Cluster fsid: ba25aef4-19f6-11ed-867d-00163e005933
  52.  
    Verifying IP 172.31.96.71 port 3300 ...
  53.  
    ERROR: [Errno 99] Cannot assign requested address
  54.  
    [root@ceph01 ~]# cephadm bootstrap --mon-ip 172.31.96.70
  55.  
    Verifying podman|docker is present...
  56.  
    Verifying lvm2 is present...
  57.  
    Verifying time synchronization is in place...
  58.  
    Unit chronyd.service is enabled and running
  59.  
    Repeating the final host check...
  60.  
    podman (/usr/bin/podman) version 3.3.1 is present
  61.  
    systemctl is present
  62.  
    lvcreate is present
  63.  
    Unit chronyd.service is enabled and running
  64.  
    Host looks OK
  65.  
    Cluster fsid: c32ff766-19f6-11ed-aa17-00163e005933
  66.  
    Verifying IP 172.31.96.70 port 3300 ...
  67.  
    Verifying IP 172.31.96.70 port 6789 ...
  68.  
    Mon IP `172.31.96.70` is in CIDR network `172.31.96.0/20`
  69.  
    - internal network (--cluster-network) has not been provided, OSD replication will default to the public_network
  70.  
    Pulling container image quay.io/ceph/ceph:v16...
  71.  
    Ceph version: ceph version 16.2.10 (45fa1a083152e41a408d15505f594ec5f1b4fe17) pacific (stable)
  72.  
    Extracting ceph user uid/gid from container image...
  73.  
    Creating initial keys...
  74.  
    Creating initial monmap...
  75.  
    Creating mon...
  76.  
    Waiting for mon to start...
  77.  
    Waiting for mon...
  78.  
    mon is available
  79.  
    Assimilating anything we can from ceph.conf...
  80.  
    Generating new minimal ceph.conf...
  81.  
    Restarting the monitor...
  82.  
    Setting mon public_network to 172.31.96.0/20
  83.  
    Wrote config to /etc/ceph/ceph.conf
  84.  
    Wrote keyring to /etc/ceph/ceph.client.admin.keyring
  85.  
    Creating mgr...
  86.  
    Verifying port 9283 ...
  87.  
    Waiting for mgr to start...
  88.  
    Waiting for mgr...
  89.  
    mgr not available, waiting (1/15)...
  90.  
    mgr not available, waiting (2/15)...
  91.  
    mgr not available, waiting (3/15)...
  92.  
    mgr not available, waiting (4/15)...
  93.  
    mgr is available
  94.  
    Enabling cephadm module...
  95.  
    Waiting for the mgr to restart...
  96.  
    Waiting for mgr epoch 5...
  97.  
    mgr epoch 5 is available
  98.  
    Setting orchestrator backend to cephadm...
  99.  
    Generating ssh key...
  100.  
    Wrote public SSH key to /etc/ceph/ceph.pub
  101.  
    Adding key to root@localhost authorized_keys...
  102.  
    Adding host ceph01...
  103.  
    Deploying mon service with default placement...
  104.  
    Deploying mgr service with default placement...
  105.  
    Deploying crash service with default placement...
  106.  
    Deploying prometheus service with default placement...
  107.  
    Deploying grafana service with default placement...
  108.  
    Deploying node-exporter service with default placement...
  109.  
    Deploying alertmanager service with default placement...
  110.  
    Enabling the dashboard module...
  111.  
    Waiting for the mgr to restart...
  112.  
    Waiting for mgr epoch 9...
  113.  
    mgr epoch 9 is available
  114.  
    Generating a dashboard self-signed certificate...
  115.  
    Creating initial admin user...
  116.  
    Fetching dashboard port number...
  117.  
    Ceph Dashboard is now available at:
  118.  
     
  119.  
    URL: https://ceph01:8443/
  120.  
    User: admin
  121.  
    Password: 9ro6qdzyel
  122.  
     
  123.  
    Enabling client.admin keyring and conf on hosts with "admin" label
  124.  
    Enabling autotune for osd_memory_target
  125.  
    You can access the Ceph CLI as following in case of multi-cluster or non-default config:
  126.  
     
  127.  
    sudo /usr/sbin/cephadm shell --fsid c32ff766-19f6-11ed-aa17-00163e005933 -c /etc/ceph/ceph.conf -k /etc/ceph/ceph.client.admin.keyring
  128.  
     
  129.  
    Or, if you are only running a single cluster on this host:
  130.  
     
  131.  
    sudo /usr/sbin/cephcadm shell
  132.  
     
  133.  
    Please consider enabling telemetry to help improve Ceph:
  134.  
     
  135.  
    ceph telemetry on
  136.  
     
  137.  
    For more information see:
  138.  
     
  139.  
    https://docs.ceph.com/en/pacific/mgr/telemetry/
  140.  
     
  141.  
    Bootstrap complete.
  142.  
    ```
  143.  
     
  144.  
    完成后记录以上了IP以及用户和密码,打开Ceph Dashboard并根据提示修改密码,打开后提示要激活统计模块。
  145.  
    如果错过使用命令
  146.  
    ```cassandraql
  147.  
    如果Ceph Dashboard中错过了启用,也可以使用命令启用,命令是“ceph telemetry on --license sharing-1-0”。
  148.  
    ```
  149.  
     
  150.  
    如果忘记记录密码可以通过以下方法重置密码(将密码写入password文件中,通过命令导入密码)
  151.  
    ```cassandraql
  152.  
    ceph dashboard ac-user-set-password admin -i password
  153.  
    {"username": "admin", "password": "$2b$12$6oFrEpssXCzLnKTWQy5fM.YZwlHjn8CuQRdeSSJR9hBGgVuwGCxoa", "roles": ["administrator"], "name": null, "email": null, "lastUpdate": 1620495653, "enabled": true, "pwdExpirationDate": null, "pwdUpdateRequired": false}
  154.  
    ```

9-7 Go PaaS 平台cephadm 安装基础集群(下)

  1.  
    ##### 3.添加主机
  2.  
    在引导成功单节点Ceph群集后会引导程序会将public key的副本写入/etc/ceph/ceph.pub,在添加主机节点前需要讲该key分发到要加入群集的主机上
  3.  
     
  4.  
    拷贝到ceph02
  5.  
    ```cassandraql
  6.  
    ssh-copy-id -f -i /etc/ceph/ceph.pub root@ceph02
  7.  
    ```
  8.  
     
  9.  
    拷贝到ceph03
  10.  
    ```cassandraql
  11.  
    ssh-copy-id -f -i /etc/ceph/ceph.pub root@ceph03
  12.  
    ```
  13.  
     
  14.  
    添加ceph 02 节点
  15.  
    ```cassandraql
  16.  
    ceph orch host add ceph02 172.31.96.71
  17.  
    ```
  18.  
    添加ceph 03 节点
  19.  
    ```cassandraql
  20.  
    ceph orch host add ceph03 172.31.96.72
  21.  
    ```
  22.  
     
  23.  
    查看节点
  24.  
    ```cassandraql
  25.  
    [root@ceph01 ~]# ceph orch host ls
  26.  
    HOST ADDR LABELS STATUS
  27.  
    ceph01 172.31.96.70 _admin
  28.  
    ceph02 172.31.96.71
  29.  
    ceph03 172.31.96.72
  30.  
    3 hosts in cluster
  31.  
    ```
  32.  
     
  33.  
    ##### 4.添加OSD
  34.  
    添加OSD需求满足以下所有条件:
  35.  
    - 设备必须没有分区。
  36.  
    - 设备不得具有任何LVM状态。
  37.  
    - 不得安装设备。
  38.  
    - 该设备不得包含文件系统。
  39.  
    - 该设备不得包含Ceph BlueStore OSD。
  40.  
    - 设备必须大于 5 GB。
  41.  
    添加OSD有2种方式,
  42.  
    1.为自动添加所有满足条件的OSD。
  43.  
    ```
  44.  
    ceph orch apply osd --all-available-devices
  45.  
    ```
  46.  
    2.为通过手工指定的方式添加OSD。
  47.  
    ```cassandraql
  48.  
    ceph orch daemon add osd ceph1:/dev/sdb
  49.  
    ```
  50.  
    本次使用第一种自动部署的方式,部署完成后查看设备列表,显示为NO就完成了。
  51.  
    ```cassandraql
  52.  
    [root@ceph01 ~]# ceph orch device ls
  53.  
    HOST PATH TYPE DEVICE ID SIZE AVAILABLE REFRESHED REJECT REASONS
  54.  
    ceph01 /dev/vdb hdd j6c3xd1a6qug5beqk71y 21.4G 9s ago Insufficient space (<10 extents) on vgs, LVM detected, locked
  55.  
    ceph02 /dev/vdb hdd j6c3xd1a6qug5beqk720 21.4G 14s ago Insufficient space (<10 extents) on vgs, LVM detected, locked
  56.  
    ceph03 /dev/vdb hdd j6c3xd1a6qug5beqk71z 21.4G 14s ago Insufficient space (<10 extents) on vgs, LVM detected, locked
  57.  
    ```
  58.  
     
  59.  
    #### 5.查看Ceph部署服务
  60.  
    ```cassandraql
  61.  
    [root@ceph01 ~]# ceph -s
  62.  
    cluster:
  63.  
    id: c32ff766-19f6-11ed-aa17-00163e005933
  64.  
    health: HEALTH_OK
  65.  
     
  66.  
    services:
  67.  
    mon: 3 daemons, quorum ceph01,ceph02,ceph03 (age 4m)
  68.  
    mgr: ceph01.sdapbz(active, since 30m), standbys: ceph02.njhkgr
  69.  
    osd: 3 osds: 3 up (since 96s), 3 in (since 114s)
  70.  
     
  71.  
    data:
  72.  
    pools: 1 pools, 1 pgs
  73.  
    objects: 0 objects, 0 B
  74.  
    usage: 15 MiB used, 60 GiB / 60 GiB avail
  75.  
    pgs: 1 active clean
  76.  
     
  77.  
    ```
  78.  
     
  79.  
    打开 dashboard 看监控数据

9-8 Go PaaS 平台ceph 核心组件安装

  1.  
    #### 6.部署RGW
  2.  
    使用指定数量匹配模式部署。
  3.  
    ```
  4.  
    ceph orch apply rgw rgw --placement=3
  5.  
    ```
  6.  
    通过Service查看命令ceph orch ls查看该服务状态。
  7.  
    ```cassandraql
  8.  
    [root@ceph01 ~]# ceph orch ls
  9.  
    NAME PORTS RUNNING REFRESHED AGE PLACEMENT
  10.  
    alertmanager ?:9093,9094 1/1 10s ago 40m count:1
  11.  
    crash 3/3 15s ago 40m *
  12.  
    grafana ?:3000 1/1 10s ago 40m count:1
  13.  
    mgr 2/2 14s ago 40m count:2
  14.  
    mon 3/5 15s ago 40m count:5
  15.  
    node-exporter ?:9100 3/3 15s ago 40m *
  16.  
    osd.all-available-devices 3 15s ago 9m *
  17.  
    prometheus ?:9095 1/1 10s ago 40m count:1
  18.  
    rgw.rgw ?:80 3/3 15s ago 30s count:3
  19.  
    ```
  20.  
    通过Deamon查看命令ceph orch ps查看该进程状态。
  21.  
    ```cassandraql
  22.  
    [root@ceph01 ~]# ceph orch ps
  23.  
    NAME HOST PORTS STATUS REFRESHED AGE MEM USE MEM LIM VERSION IMAGE ID CONTAINER ID
  24.  
    alertmanager.ceph01 ceph01 *:9093,9094 running (12m) 41s ago 39m 27.9M - ba2b418f427c b6fbf7382136
  25.  
    crash.ceph01 ceph01 running (39m) 41s ago 39m 7717k - 16.2.10 0d668911f040 9660dd933bd2
  26.  
    crash.ceph02 ceph02 running (14m) 44s ago 14m 9713k - 16.2.10 0d668911f040 35cac443b75c
  27.  
    crash.ceph03 ceph03 running (13m) 45s ago 13m 8632k - 16.2.10 0d668911f040 3135f2560d98
  28.  
    grafana.ceph01 ceph01 *:3000 running (38m) 41s ago 39m 67.9M - 8.3.5 dad864ee21e9 7f47d88ad676
  29.  
    mgr.ceph01.sdapbz ceph01 *:9283 running (41m) 41s ago 41m 499M - 16.2.10 0d668911f040 9e001eab3a53
  30.  
    mgr.ceph02.njhkgr ceph02 *:8443,9283 running (14m) 44s ago 14m 409M - 16.2.10 0d668911f040 146058cf2aea
  31.  
    mon.ceph01 ceph01 running (41m) 41s ago 41m 147M 2048M 16.2.10 0d668911f040 5896f4b2a014
  32.  
    mon.ceph02 ceph02 running (14m) 44s ago 14m 85.3M 2048M 16.2.10 0d668911f040 7fd0c2c36613
  33.  
    mon.ceph03 ceph03 running (13m) 45s ago 13m 82.1M 2048M 16.2.10 0d668911f040 db5a5b5039d5
  34.  
    node-exporter.ceph01 ceph01 *:9100 running (38m) 41s ago 38m 16.5M - 1dbe0e931976 2d7d68e3a0da
  35.  
    node-exporter.ceph02 ceph02 *:9100 running (14m) 44s ago 14m 18.2M - 1dbe0e931976 083f26d39f07
  36.  
    node-exporter.ceph03 ceph03 *:9100 running (12m) 45s ago 12m 14.4M - 1dbe0e931976 c3b21c79b2f4
  37.  
    osd.0 ceph03 running (9m) 45s ago 9m 40.4M 4096M 16.2.10 0d668911f040 2210df27e314
  38.  
    osd.1 ceph02 running (9m) 44s ago 9m 44.7M 4096M 16.2.10 0d668911f040 9ab8967c65b9
  39.  
    osd.2 ceph01 running (9m) 41s ago 9m 47.6M 4096M 16.2.10 0d668911f040 78a2000670f7
  40.  
    prometheus.ceph01 ceph01 *:9095 running (12m) 41s ago 38m 69.2M - 514e6a882f6e 06de63766e30
  41.  
    rgw.rgw.ceph01.bvcnos ceph01 *:80 running (58s) 41s ago 57s 43.7M - 16.2.10 0d668911f040 96c4d8963d47
  42.  
    rgw.rgw.ceph02.awygjp ceph02 *:80 running (54s) 44s ago 53s 46.2M - 16.2.10 0d668911f040 9d0bd0b0b060
  43.  
    rgw.rgw.ceph03.iiixeq ceph03 *:80 running (50s) 45s ago 49s 21.2M - 16.2.10 0d668911f040 a5d6e8a8983a
  44.  
    ```
  45.  
    集成到dashboard
  46.  
    ```cassandraql
  47.  
    [root@ceph01 ~]# radosgw-admin user create --uid=rgw --display-name=rgw --system
  48.  
     
  49.  
    以下是输出结果
  50.  
     
  51.  
    "keys": [
  52.  
    {
  53.  
    "user": "rgw",
  54.  
    "access_key": "M0XRR80H4AGGE4PP0A5B",
  55.  
    "secret_key": "Tbln48sfIceDGNill5muCrX0oMCHrQcl2oC9OURe"
  56.  
    }
  57.  
    ],{
  58.  
    "user_id": "rgw",
  59.  
    "display_name": "rgw",
  60.  
    "email": "",
  61.  
    "suspended": 0,
  62.  
    "max_buckets": 1000,
  63.  
    "subusers": [],
  64.  
    "keys": [
  65.  
    {
  66.  
    "user": "rgw",
  67.  
    "access_key": "43DTMZ3EY02B10QNTJSS",
  68.  
    "secret_key": "4d3qzY1A7uqVk3LWVMsGJY0negbcxg95d8QJYuzi"
  69.  
    }
  70.  
    ],
  71.  
    "swift_keys": [],
  72.  
    "caps": [],
  73.  
    "op_mask": "read, write, delete",
  74.  
    "system": "true",
  75.  
    "default_placement": "",
  76.  
    "default_storage_class": "",
  77.  
    "placement_tags": [],
  78.  
    "bucket_quota": {
  79.  
    "enabled": false,
  80.  
    "check_on_raw": false,
  81.  
    "max_size": -1,
  82.  
    "max_size_kb": 0,
  83.  
    "max_objects": -1
  84.  
    },
  85.  
    "user_quota": {
  86.  
    "enabled": false,
  87.  
    "check_on_raw": false,
  88.  
    "max_size": -1,
  89.  
    "max_size_kb": 0,
  90.  
    "max_objects": -1
  91.  
    },
  92.  
    "temp_url_keys": [],
  93.  
    "type": "rgw",
  94.  
    "mfa_ids": []
  95.  
    }
  96.  
     
  97.  
    ```
  98.  
    查看 Dashboard 是否集成成功
  99.  
     
  100.  
    #### 7.部署Cephfs
  101.  
    部署cephfs服务并创建cepfs,创建cephfs有两种方式,一种是使用的是ceph fs命令该命令会自动创建相应的池,另一种手工创建池并创建Service,下面方法任选一种。
  102.  
    方法一:
  103.  
    ```cassandraql
  104.  
    ceph fs volume create cephfs --placement=3
  105.  
    ```
  106.  
    方法二:
  107.  
    ```cassandraql
  108.  
    #ceph osd pool create cephfs_data 32
  109.  
    #ceph osd pool create cephfs_metadata 32
  110.  
    #ceph fs new cephfs cephfs_metadata cephfs_data
  111.  
    #ceph orch apply mds cephfs --placement=3
  112.  
    ```
  113.  
    我们采用方法一
  114.  
    查看Service状态。
  115.  
    ```cassandraql
  116.  
    [root@ceph01 ~]# ceph fs volume create cephfs --placement=3
  117.  
    [root@ceph01 ~]# ceph orch ls
  118.  
    NAME PORTS RUNNING REFRESHED AGE PLACEMENT
  119.  
    alertmanager ?:9093,9094 1/1 9s ago 48m count:1
  120.  
    crash 3/3 13s ago 48m *
  121.  
    grafana ?:3000 1/1 9s ago 48m count:1
  122.  
    mds.cephfs 3/3 13s ago 29s count:3
  123.  
    mgr 2/2 13s ago 48m count:2
  124.  
    mon 3/5 13s ago 48m count:5
  125.  
    node-exporter ?:9100 3/3 13s ago 48m *
  126.  
    osd.all-available-devices 3 13s ago 17m *
  127.  
    prometheus ?:9095 1/1 9s ago 48m count:1
  128.  
    rgw.rgw ?:80 3/3 13s ago 8m count:3
  129.  
    ```
  130.  
    查看Deamon状态。
  131.  
    ```cassandraql
  132.  
    [root@ceph01 ~]# ceph orch ps
  133.  
    NAME HOST PORTS STATUS REFRESHED AGE MEM USE MEM LIM VERSION IMAGE ID CONTAINER ID
  134.  
    alertmanager.ceph01 ceph01 *:9093,9094 running (20m) 59s ago 48m 29.5M - ba2b418f427c b6fbf7382136
  135.  
    crash.ceph01 ceph01 running (48m) 59s ago 48m 7587k - 16.2.10 0d668911f040 9660dd933bd2
  136.  
    crash.ceph02 ceph02 running (22m) 63s ago 22m 9667k - 16.2.10 0d668911f040 35cac443b75c
  137.  
    crash.ceph03 ceph03 running (21m) 63s ago 21m 8606k - 16.2.10 0d668911f040 3135f2560d98
  138.  
    grafana.ceph01 ceph01 *:3000 running (46m) 59s ago 47m 77.2M - 8.3.5 dad864ee21e9 7f47d88ad676
  139.  
    mds.cephfs.ceph01.uwclzo ceph01 running (74s) 59s ago 74s 28.2M - 16.2.10 0d668911f040 e7ead0c130a6
  140.  
    mds.cephfs.ceph02.zqmpyt ceph02 running (71s) 63s ago 70s 23.7M - 16.2.10 0d668911f040 06ed8fd3bc1a
  141.  
    mds.cephfs.ceph03.glufpl ceph03 running (67s) 63s ago 67s 22.9M - 16.2.10 0d668911f040 a3e497cb8a85
  142.  
    mgr.ceph01.sdapbz ceph01 *:9283 running (49m) 59s ago 49m 508M - 16.2.10 0d668911f040 9e001eab3a53
  143.  
    mgr.ceph02.njhkgr ceph02 *:8443,9283 running (22m) 63s ago 22m 410M - 16.2.10 0d668911f040 146058cf2aea
  144.  
    mon.ceph01 ceph01 running (50m) 59s ago 50m 177M 2048M 16.2.10 0d668911f040 5896f4b2a014
  145.  
    mon.ceph02 ceph02 running (22m) 63s ago 22m 115M 2048M 16.2.10 0d668911f040 7fd0c2c36613
  146.  
    mon.ceph03 ceph03 running (21m) 63s ago 21m 111M 2048M 16.2.10 0d668911f040 db5a5b5039d5
  147.  
    node-exporter.ceph01 ceph01 *:9100 running (47m) 59s ago 47m 17.4M - 1dbe0e931976 2d7d68e3a0da
  148.  
    node-exporter.ceph02 ceph02 *:9100 running (22m) 63s ago 22m 18.0M - 1dbe0e931976 083f26d39f07
  149.  
    node-exporter.ceph03 ceph03 *:9100 running (21m) 63s ago 21m 14.7M - 1dbe0e931976 c3b21c79b2f4
  150.  
    osd.0 ceph03 running (17m) 63s ago 17m 69.7M 4096M 16.2.10 0d668911f040 2210df27e314
  151.  
    osd.1 ceph02 running (17m) 63s ago 17m 72.6M 4096M 16.2.10 0d668911f040 9ab8967c65b9
  152.  
    osd.2 ceph01 running (17m) 59s ago 17m 72.4M 4096M 16.2.10 0d668911f040 78a2000670f7
  153.  
    prometheus.ceph01 ceph01 *:9095 running (20m) 59s ago 46m 73.6M - 514e6a882f6e 06de63766e30
  154.  
    rgw.rgw.ceph01.bvcnos ceph01 *:80 running (9m) 59s ago 9m 73.3M - 16.2.10 0d668911f040 96c4d8963d47
  155.  
    rgw.rgw.ceph02.awygjp ceph02 *:80 running (9m) 63s ago 9m 80.8M - 16.2.10 0d668911f040 9d0bd0b0b060
  156.  
    rgw.rgw.ceph03.iiixeq ceph03 *:80 running (9m) 63s ago 8m 57.4M - 16.2.10 0d668911f040 a5d6e8a8983a
  157.  
    ```
  158.  
     
  159.  
    查看 Dashboard
  160.  
     
  161.  
    #### 8.部署NFS
  162.  
    先创建nfs所需求的池。
  163.  
    ```cassandraql
  164.  
    #ceph osd pool create ganesha_data 32
  165.  
    #ceph osd pool application enable ganesha_data nfs
  166.  
    ```
  167.  
    部署nfs Service。
  168.  
    ```cassandraql
  169.  
    #ceph orch apply nfs nfs ganesha_data --placement=3
  170.  
    ```
  171.  
    查看Service状态。
  172.  
    ```cassandraql
  173.  
    [root@ceph01 ~]# ceph orch ls
  174.  
    NAME PORTS RUNNING REFRESHED AGE PLACEMENT
  175.  
    alertmanager ?:9093,9094 1/1 8s ago 52m count:1
  176.  
    crash 3/3 13s ago 52m *
  177.  
    grafana ?:3000 1/1 8s ago 52m count:1
  178.  
    mds.cephfs 3/3 13s ago 4m count:3
  179.  
    mgr 2/2 13s ago 52m count:2
  180.  
    mon 3/5 13s ago 52m count:5
  181.  
    nfs.nfs 3/3 13s ago 36s count:3
  182.  
    node-exporter ?:9100 3/3 13s ago 52m *
  183.  
    osd.all-available-devices 3 13s ago 21m *
  184.  
    prometheus ?:9095 1/1 8s ago 52m count:1
  185.  
    rgw.rgw ?:80 3/3 13s ago 12m count:3
  186.  
    ```
  187.  
     
  188.  
    查看Deamon状态。
  189.  
    ```cassandraql
  190.  
    [root@ceph01 ~]# ceph orch ls
  191.  
    NAME PORTS RUNNING REFRESHED AGE PLACEMENT
  192.  
    alertmanager ?:9093,9094 1/1 8s ago 52m count:1
  193.  
    crash 3/3 13s ago 52m *
  194.  
    grafana ?:3000 1/1 8s ago 52m count:1
  195.  
    mds.cephfs 3/3 13s ago 4m count:3
  196.  
    mgr 2/2 13s ago 52m count:2
  197.  
    mon 3/5 13s ago 52m count:5
  198.  
    nfs.nfs 3/3 13s ago 36s count:3
  199.  
    node-exporter ?:9100 3/3 13s ago 52m *
  200.  
    osd.all-available-devices 3 13s ago 21m *
  201.  
    prometheus ?:9095 1/1 8s ago 52m count:1
  202.  
    rgw.rgw ?:80 3/3 13s ago 12m count:3
  203.  
     
  204.  
    ```
  205.  
     
  206.  
    #### 9.部署iSCSi
  207.  
    创建iscsi所需求的池。
  208.  
    ```cassandraql
  209.  
    #ceph osd pool create iscsi_pool 16 16
  210.  
    #ceph osd pool application enable iscsi_pool iscsi
  211.  
    ```
  212.  
     
  213.  
    部署iscsi我们换YAM方式
  214.  
    ```cassandraql
  215.  
    #vi iscsi.yaml
  216.  
    service_type: iscsi
  217.  
    service_id: gw
  218.  
    placement:
  219.  
    hosts:
  220.  
    - ceph01
  221.  
    - ceph02
  222.  
    - ceph03
  223.  
    spec:
  224.  
    pool: iscsi_pool
  225.  
    trusted_ip_list: "172.31.96.70,172.31.96.71,172.31.96.72"
  226.  
    api_user: admin
  227.  
    api_password: admin
  228.  
    api_secure: false
  229.  
     
  230.  
    ```
  231.  
    通过apply命令部署,cephadm也是声明式的,所以如果想修改配置参数只需要直接修改YAML文件。
  232.  
     
  233.  
    ```cassandraql
  234.  
    [root@ceph01 ~]# ceph orch apply -i iscsi.yaml
  235.  
    Scheduled iscsi.gw update...
  236.  
    ```
  237.  
    查看Service状态。
  238.  
    ```cassandraql
  239.  
    [root@ceph01 ~]# ceph orch ls
  240.  
    NAME PORTS RUNNING REFRESHED AGE PLACEMENT
  241.  
    alertmanager ?:9093,9094 1/1 9s ago 67m count:1
  242.  
    crash 3/3 21s ago 67m *
  243.  
    grafana ?:3000 1/1 9s ago 67m count:1
  244.  
    iscsi.gw 3/3 21s ago 40s ceph01;ceph02;ceph03
  245.  
    mds.cephfs 3/3 21s ago 19m count:3
  246.  
    mgr 2/2 20s ago 67m count:2
  247.  
    mon 3/5 21s ago 67m count:5
  248.  
    nfs.nfs 3/3 21s ago 16m count:3
  249.  
    node-exporter ?:9100 3/3 21s ago 67m *
  250.  
    osd.all-available-devices 3 21s ago 36m *
  251.  
    prometheus ?:9095 1/1 9s ago 67m count:1
  252.  
    rgw.rgw ?:80 3/3 21s ago 27m count:3
  253.  
    ```
  254.  
    查看Deamon状态。
  255.  
    ```cassandraql
  256.  
    [root@ceph01 ~]# ceph orch ps
  257.  
    NAME HOST PORTS STATUS REFRESHED AGE MEM USE MEM LIM VERSION IMAGE ID CONTAINER ID
  258.  
    alertmanager.ceph01 ceph01 *:9093,9094 running (39m) 33s ago 67m 35.2M - ba2b418f427c b6fbf7382136
  259.  
    crash.ceph01 ceph01 running (67m) 33s ago 67m 7386k - 16.2.10 0d668911f040 9660dd933bd2
  260.  
    crash.ceph02 ceph02 running (41m) 44s ago 41m 10.5M - 16.2.10 0d668911f040 35cac443b75c
  261.  
    crash.ceph03 ceph03 running (40m) 45s ago 40m 10.8M - 16.2.10 0d668911f040 3135f2560d98
  262.  
    grafana.ceph01 ceph01 *:3000 running (65m) 33s ago 66m 80.2M - 8.3.5 dad864ee21e9 7f47d88ad676
  263.  
    iscsi.gw.ceph01.mqjxqu ceph01 running (60s) 33s ago 59s 76.1M - 3.5 0d668911f040 e712bdbb2d80
  264.  
    iscsi.gw.ceph02.xeggjo ceph02 running (56s) 44s ago 56s 52.9M - 3.5 0d668911f040 04c7f5263155
  265.  
    iscsi.gw.ceph03.xykglu ceph03 running (52s) 45s ago 52s 76.9M - 3.5 0d668911f040 59cb4c7bbfd5
  266.  
    mds.cephfs.ceph01.uwclzo ceph01 running (20m) 33s ago 20m 27.6M - 16.2.10 0d668911f040 e7ead0c130a6
  267.  
    mds.cephfs.ceph02.zqmpyt ceph02 running (20m) 44s ago 20m 26.8M - 16.2.10 0d668911f040 06ed8fd3bc1a
  268.  
    mds.cephfs.ceph03.glufpl ceph03 running (20m) 45s ago 20m 26.5M - 16.2.10 0d668911f040 a3e497cb8a85
  269.  
    mgr.ceph01.sdapbz ceph01 *:9283 running (68m) 33s ago 68m 495M - 16.2.10 0d668911f040 9e001eab3a53
  270.  
    mgr.ceph02.njhkgr ceph02 *:8443,9283 running (41m) 44s ago 41m 411M - 16.2.10 0d668911f040 146058cf2aea
  271.  
    mon.ceph01 ceph01 running (68m) 33s ago 69m 237M 2048M 16.2.10 0d668911f040 5896f4b2a014
  272.  
    mon.ceph02 ceph02 running (41m) 44s ago 41m 164M 2048M 16.2.10 0d668911f040 7fd0c2c36613
  273.  
    mon.ceph03 ceph03 running (40m) 45s ago 40m 146M 2048M 16.2.10 0d668911f040 db5a5b5039d5
  274.  
    nfs.nfs.0.0.ceph01.ijxnwe ceph01 *:2049 running (16m) 33s ago 16m 72.4M - 3.5 0d668911f040 f9b0609cbe7b
  275.  
    nfs.nfs.1.0.ceph02.pedadk ceph02 *:2049 running (16m) 44s ago 16m 75.8M - 3.5 0d668911f040 54d58b785ed6
  276.  
    nfs.nfs.2.0.ceph03.daqdkw ceph03 *:2049 running (16m) 45s ago 16m 73.0M - 3.5 0d668911f040 c1bebe7782d4
  277.  
    node-exporter.ceph01 ceph01 *:9100 running (66m) 33s ago 66m 17.7M - 1dbe0e931976 2d7d68e3a0da
  278.  
    node-exporter.ceph02 ceph02 *:9100 running (41m) 44s ago 41m 18.3M - 1dbe0e931976 083f26d39f07
  279.  
    node-exporter.ceph03 ceph03 *:9100 running (40m) 45s ago 40m 15.5M - 1dbe0e931976 c3b21c79b2f4
  280.  
    osd.0 ceph03 running (36m) 45s ago 36m 77.8M 4096M 16.2.10 0d668911f040 2210df27e314
  281.  
    osd.1 ceph02 running (36m) 44s ago 36m 80.1M 4096M 16.2.10 0d668911f040 9ab8967c65b9
  282.  
    osd.2 ceph01 running (36m) 33s ago 36m 79.3M 4096M 16.2.10 0d668911f040 78a2000670f7
  283.  
    prometheus.ceph01 ceph01 *:9095 running (39m) 33s ago 65m 97.3M - 514e6a882f6e 06de63766e30
  284.  
    rgw.rgw.ceph01.bvcnos ceph01 *:80 running (28m) 33s ago 28m 61.8M - 16.2.10 0d668911f040 96c4d8963d47
  285.  
    rgw.rgw.ceph02.awygjp ceph02 *:80 running (28m) 44s ago 28m 81.6M - 16.2.10 0d668911f040 9d0bd0b0b060
  286.  
    rgw.rgw.ceph03.iiixeq ceph03 *:80 running (27m) 45s ago 27m 60.0M - 16.2.10 0d668911f040 a5d6e8a8983a
  287.  
    ```

学新通

9-9 Go PaaS 平台 k8s 通过CSI方式添加外部Ceph 系统(上)

C:\Users\Administrator\Desktop\gopaas\ceph\2.k8s 使用 CSI 添加 ceph 为存储.md

  1.  
    ### k8s 1.21.5 CSI 模式添加 ceph 16 为为外部存储(动态存储卷)
  2.  
     
  3.  
    #### 1.动态持久卷
  4.  
    不需要存储管理员干预,使k8s使用的存储image创建自动化,即根据使用需要可以动态申请存储空间并自动创建。需要先定义一个或者多个StorageClass,每个StorageClass都必须配置一个provisioner,用来决定使用哪个卷插件分配PV。然后,StorageClass资源指定持久卷声明请求StorageClass时使用哪个provisioner来在对应存储创建持久卷。
  5.  
     
  6.  
    #### 2.创建一个普通用户来给k8s做rdb的映射
  7.  
    在ceph集群中创建一个k8s专用的pool和用户:
  8.  
    ```cassandraql
  9.  
    ceph osd pool create kubernetes 16 16
  10.  
    ceph auth get-or-create client.kubernetes mon 'profile rbd' osd 'profile rbd pool=kubernetes' mgr 'profile rbd pool=kubernetes'
  11.  
     
  12.  
    初始化
  13.  
    rbd pool init kubernetes
  14.  
     
  15.  
    查看 pool
  16.  
    ceph osd pool ls
  17.  
    rados lspools
  18.  
    ```
  19.  
    得到
  20.  
    ```cassandraql
  21.  
    [client.kubernetes]
  22.  
    key = AQC2Q/ZiecM/MBAA2nwfDPKgfReHxz/o4kQV3A==
  23.  
    ```
  24.  
    后面的配置需要用到这里的 key,如果忘了可以通过以下命令来获取:
  25.  
    ```cassandraql
  26.  
    ceph auth get client.kubernetes
  27.  
    ```
  28.  
    得到
  29.  
    ```cassandraql
  30.  
    [client.kubernetes]
  31.  
    key = AQC2Q/ZiecM/MBAA2nwfDPKgfReHxz/o4kQV3A==
  32.  
    caps mgr = "profile rbd pool=kubernetes"
  33.  
    caps mon = "profile rbd"
  34.  
    caps osd = "profile rbd pool=kubernetes"
  35.  
    exported keyring for client.kubernetes
  36.  
    ```
  37.  
    #### 3. 部署 ceph-csi 在k8s master 集群上
  38.  
    拉取 ceph-csi 的 最新 release 分支(v3.6.2)
  39.  
    ```cassandraql
  40.  
    git clone --depth 1 --branch v3.6.2 https://github.com/ceph/ceph-csi
  41.  
    ```
  42.  
    ##### 修改 Configmap
  43.  
    获取 Ceph 集群的信息:
  44.  
    ```cassandraql
  45.  
    [root@ceph01 ~]# ceph mon dump
  46.  
    epoch 3
  47.  
    fsid c32ff766-19f6-11ed-aa17-00163e005933
  48.  
    last_changed 2022-08-12T04:55:22.875422 0000
  49.  
    created 2022-08-12T04:26:27.658334 0000
  50.  
    min_mon_release 16 (pacific)
  51.  
    election_strategy: 1
  52.  
    0: [v2:172.31.96.70:3300/0,v1:172.31.96.70:6789/0] mon.ceph01
  53.  
    1: [v2:172.31.96.71:3300/0,v1:172.31.96.71:6789/0] mon.ceph02
  54.  
    2: [v2:172.31.96.72:3300/0,v1:172.31.96.72:6789/0] mon.ceph03
  55.  
    dumped monmap epoch 3
  56.  
    ```
  57.  
     
  58.  
    这里需要用到两个信息:
  59.  
    - fsid : 这个是 Ceph 的集群 ID。
  60.  
    - 监控节点信息。目前 ceph-csi 只支持 v1 版本的协议,所以监控节点那里我们只能用 v1 的那个 IP 和端口号(例如,172.31.96.70:6789)。
  61.  
     
  62.  
    进入 ceph-csi 的 deploy/rbd/kubernetes 目录:
  63.  
    ```cassandraql
  64.  
    [root@master ~]# cd ceph-csi/deploy/rbd/kubernetes
  65.  
    [root@master kubernetes]# ls -l ./
  66.  
    total 40
  67.  
    -rw-r--r-- 1 root root 309 Aug 12 20:18 csi-config-map.yaml
  68.  
    -rw-r--r-- 1 root root 435 Aug 12 20:18 csidriver.yaml
  69.  
    -rw-r--r-- 1 root root 1776 Aug 12 20:18 csi-nodeplugin-psp.yaml
  70.  
    -rw-r--r-- 1 root root 1110 Aug 12 20:18 csi-nodeplugin-rbac.yaml
  71.  
    -rw-r--r-- 1 root root 1199 Aug 12 20:18 csi-provisioner-psp.yaml
  72.  
    -rw-r--r-- 1 root root 3264 Aug 12 20:18 csi-provisioner-rbac.yaml
  73.  
    -rw-r--r-- 1 root root 8021 Aug 12 20:18 csi-rbdplugin-provisioner.yaml
  74.  
    -rw-r--r-- 1 root root 7242 Aug 12 20:18 csi-rbdplugin.yaml
  75.  
    ```
  76.  
    将以上获取的信息写入 csi-config-map.yaml:
  77.  
    vi csi-config-map.yaml
  78.  
    ```cassandraql
  79.  
    apiVersion: v1
  80.  
    kind: ConfigMap
  81.  
    data:
  82.  
    config.json: |-
  83.  
    [
  84.  
    {
  85.  
    "clusterID": "c32ff766-19f6-11ed-aa17-00163e005933",
  86.  
    "monitors": [
  87.  
    "172.31.96.70:6789",
  88.  
    "172.31.96.71:6789",
  89.  
    "172.31.96.72:6789"
  90.  
    ]
  91.  
    }
  92.  
    ]
  93.  
    metadata:
  94.  
    name: ceph-csi-config
  95.  
    ```
  96.  
    将此 Configmap 存储到 Kubernetes 集群中:
  97.  
    ```cassandraql
  98.  
    kubectl apply -f csi-config-map.yaml
  99.  
    ```
  100.  
     
  101.  
    创建ceph-config
  102.  
    ```cassandraql
  103.  
    cat <<EOF > ceph-config-map.yaml
  104.  
    ---
  105.  
    apiVersion: v1
  106.  
    kind: ConfigMap
  107.  
    data:
  108.  
    ceph.conf: |
  109.  
    [global]
  110.  
    auth_cluster_required = cephx
  111.  
    auth_service_required = cephx
  112.  
    auth_client_required = cephx
  113.  
    # keyring is a required key and its value should be empty
  114.  
    keyring: |
  115.  
    metadata:
  116.  
    name: ceph-config
  117.  
    EOF
  118.  
    ```
  119.  
    创建
  120.  
    ```cassandraql
  121.  
    kubectl apply -f ceph-config-map.yaml
  122.  
    ```
  123.  
     
  124.  
    创建 ceph-csi-encryption-kms-config
  125.  
    ```cassandraql
  126.  
    cat <<EOF > csi-kms-config-map.yaml
  127.  
    ---
  128.  
    apiVersion: v1
  129.  
    kind: ConfigMap
  130.  
    data:
  131.  
    config.json: |-
  132.  
    {}
  133.  
    metadata:
  134.  
    name: ceph-csi-encryption-kms-config
  135.  
    EOF
  136.  
    ```
  137.  
    启用
  138.  
    ```cassandraql
  139.  
    kubectl apply -f csi-kms-config-map.yaml
  140.  
    ```

9-10 Go PaaS 平台 k8s 通过CSI方式添加外部Ceph 系统(下)

  1.  
    ##### 新建 Secret
  2.  
    使用创建的 kubernetes 用户 ID 和 cephx 密钥生成 Secret:
  3.  
    ```cassandraql
  4.  
    cat <<EOF > csi-rbd-secret.yaml
  5.  
    apiVersion: v1
  6.  
    kind: Secret
  7.  
    metadata:
  8.  
    name: csi-rbd-secret
  9.  
    namespace: default
  10.  
    stringData:
  11.  
    userID: kubernetes
  12.  
    userKey: AQC2Q/ZiecM/MBAA2nwfDPKgfReHxz/o4kQV3A==
  13.  
    EOF
  14.  
    ```
  15.  
    部署 Secret:
  16.  
    ```cassandraql
  17.  
    kubectl apply -f csi-rbd-secret.yaml
  18.  
    ```
  19.  
    ##### RBAC 授权
  20.  
    创建必须的 ServiceAccount 和 RBAC ClusterRole/ClusterRoleBinding 资源对象:
  21.  
    ```cassandraql
  22.  
    kubectl create -f csi-provisioner-rbac.yaml
  23.  
    kubectl create -f csi-nodeplugin-rbac.yaml
  24.  
    ```
  25.  
     
  26.  
    创建 PodSecurityPolicy:
  27.  
    ```cassandraql
  28.  
    kubectl create -f csi-provisioner-psp.yaml
  29.  
    kubectl create -f csi-nodeplugin-psp.yaml
  30.  
    ```
  31.  
     
  32.  
    ##### 部署 CSI sidecar
  33.  
    将 csi-rbdplugin-provisioner.yaml 和 csi-rbdplugin.yaml 中的 kms 部分配置注释掉:
  34.  
    ```cassandraql
  35.  
    # - name: ceph-csi-encryption-kms-config
  36.  
    # mountPath: /etc/ceph-csi-encryption-kms-config/
  37.  
     
  38.  
    ....
  39.  
    #- name: ceph-csi-encryption-kms-config
  40.  
    # configMap:
  41.  
    # name: ceph-csi-encryption-kms-config
  42.  
     
  43.  
    ```
  44.  
    注释掉pod亲和性
  45.  
    ```cassandraql
  46.  
    # affinity:
  47.  
    # podAntiAffinity:
  48.  
    # requiredDuringSchedulingIgnoredDuringExecution:
  49.  
    # - labelSelector:
  50.  
    # matchExpressions:
  51.  
    # - key: app
  52.  
    # operator: In
  53.  
    # values:
  54.  
    # - csi-rbdplugin-provisioner
  55.  
    # topologyKey: "kubernetes.io/hostname"
  56.  
    ```
  57.  
     
  58.  
    改为一个副本
  59.  
    ```cassandraql
  60.  
    spec:
  61.  
    replicas: 1
  62.  
    ```
  63.  
     
  64.  
    部署 csi-rbdplugin-provisioner:
  65.  
    ```
  66.  
    kubectl create -f csi-rbdplugin-provisioner.yaml
  67.  
    ```
  68.  
    这里面包含了 6 个 Sidecar 容器,包括 external-provisioner、external-attacher、csi-resizer 和 csi-rbdplugin。
  69.  
     
  70.  
    ##### 部署 RBD CSI driver
  71.  
    最后部署 RBD CSI Driver:
  72.  
    ```
  73.  
    kubectl create -f csi-rbdplugin.yaml
  74.  
    ```
  75.  
    Pod 中包含两个容器:CSI node-driver-registrar 和 CSI RBD driver。
  76.  
    ##### 创建 Storageclass
  77.  
    ```cassandraql
  78.  
    cat <<EOF > storageclass.yaml
  79.  
    ---
  80.  
    apiVersion: storage.k8s.io/v1
  81.  
    kind: StorageClass
  82.  
    metadata:
  83.  
    name: csi-rbd-sc
  84.  
    provisioner: rbd.csi.ceph.com
  85.  
    parameters:
  86.  
    clusterID: c32ff766-19f6-11ed-aa17-00163e005933
  87.  
    pool: kubernetes
  88.  
    imageFeatures: layering
  89.  
    csi.storage.k8s.io/provisioner-secret-name: csi-rbd-secret
  90.  
    csi.storage.k8s.io/provisioner-secret-namespace: default
  91.  
    csi.storage.k8s.io/controller-expand-secret-name: csi-rbd-secret
  92.  
    csi.storage.k8s.io/controller-expand-secret-namespace: default
  93.  
    csi.storage.k8s.io/node-stage-secret-name: csi-rbd-secret
  94.  
    csi.storage.k8s.io/node-stage-secret-namespace: default
  95.  
    csi.storage.k8s.io/fstype: ext4
  96.  
    reclaimPolicy: Delete
  97.  
    allowVolumeExpansion: true
  98.  
    mountOptions:
  99.  
    - discard
  100.  
    EOF
  101.  
    ```
  102.  
    创建 storageclass
  103.  
    ```cassandraql
  104.  
    kubectl apply -f storageclass.yaml
  105.  
    ```
  106.  
     
  107.  
    - 这里的 clusterID 对应之前步骤中的 fsid。
  108.  
    - imageFeatures 用来确定创建的 image 特征,如果不指定,就会使用 RBD 内核中的特征列表,但 Linux 不一定支持所有特征,所以这里需要限制一下。
  109.  
     
  110.  
    #### 4.试用 ceph-csi
  111.  
    Kubernetes 通过 PersistentVolume 子系统为用户和管理员提供了一组 API,将存储如何供应的细节从其如何被使用中抽象出来,其中 PV(PersistentVolume) 是实际的存储,PVC(PersistentVolumeClaim) 是用户对存储的请求。
  112.  
     
  113.  
    下面通过官方仓库的示例来演示如何使用 ceph-csi。
  114.  
     
  115.  
    先进入 ceph-csi 项目的 example/rbd 目录,然后直接创建 PVC:
  116.  
    ```cassandraql
  117.  
    kubectl apply -f pvc.yaml
  118.  
    ```
  119.  
    查看 PVC 和申请成功的 PV:
  120.  
    ```cassandraql
  121.  
    $ kubectl get pvc
  122.  
    NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
  123.  
    rbd-pvc Bound pvc-44b89f0e-4efd-4396-9316-10a04d289d7f 1Gi RWO csi-rbd-sc 8m21s
  124.  
     
  125.  
    $ kubectl get pv
  126.  
    NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
  127.  
    pvc-44b89f0e-4efd-4396-9316-10a04d289d7f 1Gi RWO Delete Bound default/rbd-pvc csi-rbd-sc 8m18s
  128.  
    ```
  129.  
    再创建示例 Pod:
  130.  
    ```
  131.  
    kubectl apply -f pod.yaml
  132.  
    ```
  133.  
     
  134.  
    进入 Pod 里面测试读写数据:
  135.  
    ```cassandraql
  136.  
    kubectl apply -f pod.yaml
  137.  
    ```
  138.  
    进入 Pod 里面测试读写数据:
  139.  
    ```cassandraql
  140.  
     
  141.  
    kubectl exec -it csi-rbd-demo-pod bash
  142.  
    root@csi-rbd-demo-pod:/# cd /var/lib/www/
  143.  
    root@csi-rbd-demo-pod:/var/lib/www# ls -l
  144.  
    total 4
  145.  
    drwxrwxrwx 3 root root 4096 Sep 14 09:09 html
  146.  
    root@csi-rbd-demo-pod:/var/lib/www# echo "你好!" > wu123.txt
  147.  
    wu123
  148.  
    ```
  149.  
    列出 kubernetes pool 中的 rbd images:
  150.  
    ```cassandraql
  151.  
    rbd ls -p kubernetes
  152.  
    csi-vol-fe40eb16-1a4e-11ed-bb7c-0eb2f382cefd
  153.  
    ```
  154.  
     
  155.  
    查看该 image 的特征:
  156.  
     
  157.  
    ```cassandraql
  158.  
    [root@ceph01 ceph]# rbd info csi-vol-fe40eb16-1a4e-11ed-bb7c-0eb2f382cefd -p kubernetes
  159.  
    rbd image 'csi-vol-fe40eb16-1a4e-11ed-bb7c-0eb2f382cefd':
  160.  
    size 1 GiB in 256 objects
  161.  
    order 22 (4 MiB objects)
  162.  
    snapshot_count: 0
  163.  
    id: d50f18182e6b
  164.  
    block_name_prefix: rbd_data.d50f18182e6b
  165.  
    format: 2
  166.  
    features: layering
  167.  
    op_features:
  168.  
    flags:
  169.  
    create_timestamp: Fri Aug 12 22:56:49 2022
  170.  
    access_timestamp: Fri Aug 12 22:56:49 2022
  171.  
    modify_timestamp: Fri Aug 12 22:56:49 2022
  172.  
    ```
  173.  
     
  174.  
    到此,k8s 使用外部 ceph 存储配置结束

9-11 Go PaaS 平台PVC 模型开发 

  1.  
    yu-tool.exe  newService github.com/yunixiangfeng/gopaas/volume
  2.  
     
  3.  
    yu-v3 --proto_path=. --micro_out=. --go_out=:. ./proto/volume/volume.proto
  4.  
    go mod tidy

C:\Users\Administrator\Desktop\gopaas\volume\domain\model\volume.go

  1.  
    package model
  2.  
     
  3.  
    type Volume struct{
  4.  
    ID int64 `gorm:"primary_key;not_null;auto_increment"`
  5.  
    //存储的名称
  6.  
    VolumeName string `json:"volume_name"`
  7.  
    //存储的所属的命名空间
  8.  
    VolumeNamespace string `json:"volume_namespace"`
  9.  
    //存储的访问模式,RWO,ROX,RWX
  10.  
    VolumeAccessMode string `json:"volume_access_mode"`
  11.  
    //sc 的 class name
  12.  
    VolumeStorageClassName string `json:"volume_storage_class_name"`
  13.  
    //请求资源的大小
  14.  
    VolumeRequest float32 `json:"volume_request"`
  15.  
    //存储类型 Block,filesystem
  16.  
    VolumePersistentVolumeMode string `json:"volume_persistent_volume_mode"`
  17.  
    }
  18.  
     

 C:\Users\Administrator\Desktop\gopaas\volume\proto\volume\volume.proto

  1.  
    syntax = "proto3";
  2.  
     
  3.  
    package volume;
  4.  
     
  5.  
    option go_package = "./proto/volume;volume";
  6.  
     
  7.  
    service Volume {
  8.  
    //对外提供添加服务
  9.  
    rpc AddVolume(VolumeInfo) returns (Response) {}
  10.  
    rpc DeleteVolume(VolumeId) returns (Response) {}
  11.  
    rpc UpdateVolume(VolumeInfo) returns (Response) {}
  12.  
    rpc FindVolumeByID(VolumeId) returns (VolumeInfo) {}
  13.  
    rpc FindAllVolume(FindAll) returns (AllVolume) {}
  14.  
    }
  15.  
    message VolumeInfo {
  16.  
    int64 id = 1;
  17.  
    string volume_name=2;
  18.  
    string volume_namespace=3;
  19.  
    string volume_access_mode=4;
  20.  
    string volume_storage_class_name=5;
  21.  
    float volume_request=6;
  22.  
    string volume_persistent_volume_mode=7;
  23.  
    }
  24.  
     
  25.  
    message VolumeId {
  26.  
    int64 id = 1;
  27.  
    }
  28.  
     
  29.  
    message FindAll {
  30.  
     
  31.  
    }
  32.  
     
  33.  
    message Response {
  34.  
    string msg =1 ;
  35.  
    }
  36.  
     
  37.  
    message AllVolume {
  38.  
    repeated VolumeInfo volume_info = 1;
  39.  
    }
  40.  
     
  41.  
     

9-12 Go PaaS 平台 Service 开发(上) 

C:\Users\Administrator\Desktop\gopaas\volume\domain\service\volume_data_service.go

  1.  
    package service
  2.  
     
  3.  
    import (
  4.  
    "context"
  5.  
    "errors"
  6.  
    "strconv"
  7.  
     
  8.  
    "github.com/yunixiangfeng/gopaas/common"
  9.  
    "github.com/yunixiangfeng/gopaas/volume/domain/model"
  10.  
    "github.com/yunixiangfeng/gopaas/volume/domain/repository"
  11.  
    "github.com/yunixiangfeng/gopaas/volume/proto/volume"
  12.  
    "k8s.io/api/apps/v1"
  13.  
    v12 "k8s.io/api/core/v1"
  14.  
    "k8s.io/apimachinery/pkg/api/resource"
  15.  
    v13 "k8s.io/apimachinery/pkg/apis/meta/v1"
  16.  
    "k8s.io/client-go/kubernetes"
  17.  
    )
  18.  
     
  19.  
    //这里是接口类型
  20.  
    type IVolumeDataService interface {
  21.  
    AddVolume(*model.Volume) (int64 , error)
  22.  
    DeleteVolume(int64) error
  23.  
    UpdateVolume(*model.Volume) error
  24.  
    FindVolumeByID(int64) (*model.Volume, error)
  25.  
    FindAllVolume() ([]model.Volume, error)
  26.  
     
  27.  
    CreateVolumeToK8s(*volume.VolumeInfo) error
  28.  
    DeleteVolumeFromK8s(*model.Volume) error
  29.  
    }
  30.  
     
  31.  
     
  32.  
    //创建
  33.  
    //注意:返回值 IVolumeDataService 接口类型
  34.  
    func NewVolumeDataService(volumeRepository repository.IVolumeRepository,clientSet *kubernetes.Clientset) IVolumeDataService{
  35.  
    return &VolumeDataService{ VolumeRepository:volumeRepository, K8sClientSet: clientSet,deployment:&v1.Deployment{}}
  36.  
    }
  37.  
     
  38.  
    type VolumeDataService struct {
  39.  
    //注意:这里是 IVolumeRepository 类型
  40.  
    VolumeRepository repository.IVolumeRepository
  41.  
    K8sClientSet *kubernetes.Clientset
  42.  
    deployment *v1.Deployment
  43.  
    }
  44.  
    //从 k8s 删除一个 pvc
  45.  
    func (u *VolumeDataService) DeleteVolumeFromK8s(volume *model.Volume) (err error) {
  46.  
    //先从K8s 中删除
  47.  
    if err = u.K8sClientSet.CoreV1().PersistentVolumeClaims(volume.VolumeNamespace).Delete(context.TODO(),volume.VolumeName, v13.DeleteOptions{});err!=nil {
  48.  
    common.Error(err)
  49.  
    return err
  50.  
    } else {
  51.  
    //从数据表中删除
  52.  
    if err := u.DeleteVolume(volume.ID);err !=nil {
  53.  
    common.Error(err)
  54.  
    return err
  55.  
    }
  56.  
    common.Info("删除存储ID" strconv.FormatInt(volume.ID,10) " 成功!")
  57.  
    }
  58.  
    return
  59.  
    }
  60.  
     
  61.  
    //创建存储到 k8s 中
  62.  
    func (u *VolumeDataService) CreateVolumeToK8s(info *volume.VolumeInfo)(err error) {
  63.  
    volume := u.setVolume(info)
  64.  
    if _,err = u.K8sClientSet.CoreV1().PersistentVolumeClaims(info.VolumeNamespace).Get(context.TODO(),info.VolumeName,v13.GetOptions{});err !=nil {
  65.  
    //如果存储不存在
  66.  
    if _,err = u.K8sClientSet.CoreV1().PersistentVolumeClaims(info.VolumeNamespace).Create(context.TODO(),volume,v13.CreateOptions{});err !=nil{
  67.  
    common.Error(err)
  68.  
    return err
  69.  
    }
  70.  
    common.Info("存储创建成功")
  71.  
    return nil
  72.  
    }else {
  73.  
    common.Error("存储空间" info.VolumeName " 已经存在")
  74.  
    return errors.New("存储空间" info.VolumeName " 已经存在")
  75.  
    }
  76.  
    }
  77.  
    //设置 pvc 的详情信息
  78.  
    func (u *VolumeDataService) setVolume(info *volume.VolumeInfo) *v12.PersistentVolumeClaim {
  79.  
    pvc := &v12.PersistentVolumeClaim{}
  80.  
    //设置接口类型
  81.  
    pvc.TypeMeta = v13.TypeMeta{
  82.  
    Kind: "PersistentVolumeClaim",
  83.  
    APIVersion: "v1",
  84.  
    }
  85.  
    //设置存储基础信息
  86.  
    pvc.ObjectMeta = v13.ObjectMeta{
  87.  
    Name: info.VolumeName,
  88.  
    Namespace: info.VolumeNamespace,
  89.  
    Annotations: map[string]string{
  90.  
    "pv.kubernetes.io/bound-by-controller":"yes",
  91.  
    "volume.beta.kubernetes.io/storage-provisioner":"rbd.csi.ceph.com",
  92.  
    "wu":"wu123",
  93.  
    },
  94.  
    }
  95.  
    //设置存储动态信息
  96.  
    pvc.Spec = v12.PersistentVolumeClaimSpec{
  97.  
    AccessModes: u.getAccessModes(info),
  98.  
    Resources: u.getResource(info),
  99.  
    StorageClassName: &info.VolumeStorageClassName,
  100.  
    VolumeMode: u.getVolumeMode(info),
  101.  
    }
  102.  
    return pvc
  103.  
     
  104.  
    }
  105.  
     
  106.  
    //获取存储类型
  107.  
    func (u *VolumeDataService) getVolumeMode(info *volume.VolumeInfo) *v12.PersistentVolumeMode {
  108.  
    var pvm v12.PersistentVolumeMode
  109.  
    switch info.VolumePersistentVolumeMode {
  110.  
    case "Block":
  111.  
    pvm = v12.PersistentVolumeBlock
  112.  
    case "Filesystem":
  113.  
    pvm = v12.PersistentVolumeFilesystem
  114.  
    default:
  115.  
    pvm = v12.PersistentVolumeFilesystem
  116.  
    }
  117.  
    return &pvm
  118.  
    }
  119.  
     
  120.  
    //插入
  121.  
    func (u *VolumeDataService) AddVolume(volume *model.Volume) (int64 ,error) {
  122.  
    return u.VolumeRepository.CreateVolume(volume)
  123.  
    }
  124.  
     
  125.  
    //删除
  126.  
    func (u *VolumeDataService) DeleteVolume(volumeID int64) error {
  127.  
    return u.VolumeRepository.DeleteVolumeByID(volumeID)
  128.  
    }
  129.  
     
  130.  
    //更新
  131.  
    func (u *VolumeDataService) UpdateVolume(volume *model.Volume) error {
  132.  
    return u.VolumeRepository.UpdateVolume(volume)
  133.  
    }
  134.  
     
  135.  
    //查找
  136.  
    func (u *VolumeDataService) FindVolumeByID(volumeID int64) (*model.Volume, error) {
  137.  
    return u.VolumeRepository.FindVolumeByID(volumeID)
  138.  
    }
  139.  
     
  140.  
    //查找
  141.  
    func (u *VolumeDataService) FindAllVolume() ([]model.Volume, error) {
  142.  
    return u.VolumeRepository.FindAll()
  143.  
    }
  144.  
     

9-13 Go PaaS 平台 Service 开发(下) 

C:\Users\Administrator\Desktop\gopaas\volume\domain\service\volume_data_service.go

  1.  
    //获取资源配置
  2.  
    func (u *VolumeDataService) getResource (info *volume.VolumeInfo)(source v12.ResourceRequirements) {
  3.  
    source.Requests = v12.ResourceList{
  4.  
    "storage": resource.MustParse(strconv.FormatFloat(float64(info.VolumeRequest),'f',6,64) "Gi"),
  5.  
    }
  6.  
    return
  7.  
    }
  8.  
     
  9.  
    //获取访问模式
  10.  
    func (u *VolumeDataService) getAccessModes(info *volume.VolumeInfo)(pvam []v12.PersistentVolumeAccessMode) {
  11.  
    var pm v12.PersistentVolumeAccessMode
  12.  
    switch info.VolumeAccessMode {
  13.  
    case "ReadWriteOnce":
  14.  
    pm = v12.ReadWriteOnce
  15.  
    case "ReadOnlyMany":
  16.  
    pm = v12.ReadOnlyMany
  17.  
    case "ReadWriteMany":
  18.  
    pm = v12.ReadWriteMany
  19.  
    case "ReadWriteOncePod":
  20.  
    pm = v12.ReadWriteOncePod
  21.  
    default:
  22.  
    pm = v12.ReadWriteOnce
  23.  
    }
  24.  
    pvam = append(pvam,pm)
  25.  
    return pvam
  26.  
     
  27.  
    }

9-14 Go PaaS 平台 PV与PVC 的关系和原理说明 

PV和PVC的关系
PV (Persistent Volume): 持久化卷的意思,是对底层的共享存储的一种抽象
PVC (Persistent Volume Claim): 用户存储的请求

学新通

PV的访问模式(accessModes
ReadWriteOnce(RWO): 可读可写,单挂载
ReadOnlyMany(ROX): 只读,多挂载
ReadWriteMany(RWX): 可读可写,多挂载

PV 的回收策略(persistentVolumeReclaimPolicy)
Retain:不清理,保留Volume(需要手动清理
Recycle:会删除数据,类似 rm -rf /xxx/*
Delete:删除存储资源

PV的状态
Available :可用
Bound :已经分配给PVC
Released:PVC 解绑但是还未执行回收策略
Failed:存储异常

PVC的关键参数
访问模式(accessModes):标明访问权限选择器(selector):label选择筛选绑定PV
存储类别 (storageClassName): 设置用来自动创建PV
请求资源 (Resources) :标明需要的存储大小

PV与PVC的生命周期:Provisioning 配置阶段
静态:管理员创建多个PV,属性确定,绑定了真实的存储设。
动态:通过StorageClass,k8s 会创建动态的为PVC 创建PV好处时候资源能够除非利用。创建模式自动。

PV与PVC的生命周期:Binding
在动态配置的情况下,用户创建了PVC后,标明PVC与PV绑
定过程
如果没有满足PVC请求的PV,PVC将无法被创建。
如果绑定了PVC 绑定了Pod,pod将无法创建

PV与PVC的生命周期
Using:PVC与PV绑定后,Pod对存储空间正常使用
Releasing:当Pod被删除或者PV的资源使用结束后
Reclaiming:PV的回收策略对被释放的PV的处理
Recycling: PV被执行擦除后再被分配 

9-15 Go PaaS 平台 Service Handler 开发 

C:\Users\Administrator\Desktop\gopaas\volume\handler\volumeHandler.go

  1.  
    package handler
  2.  
     
  3.  
    import (
  4.  
    "context"
  5.  
    "strconv"
  6.  
     
  7.  
    log "github.com/asim/go-micro/v3/logger"
  8.  
    "github.com/yunixiangfeng/gopaas/common"
  9.  
    "github.com/yunixiangfeng/gopaas/volume/domain/model"
  10.  
    "github.com/yunixiangfeng/gopaas/volume/domain/service"
  11.  
    volume "github.com/yunixiangfeng/gopaas/volume/proto/volume"
  12.  
    )
  13.  
     
  14.  
    type VolumeHandler struct {
  15.  
    //注意这里的类型是 IVolumeDataService 接口类型
  16.  
    VolumeDataService service.IVolumeDataService
  17.  
    }
  18.  
     
  19.  
    // Call is a single request handler called via client.Call or the generated client code
  20.  
    func (e *VolumeHandler) AddVolume(ctx context.Context, info *volume.VolumeInfo, rsp *volume.Response) error {
  21.  
    log.Info("Received *volume.AddVolume request")
  22.  
    volume := &model.Volume{}
  23.  
    if err := common.SwapTo(info, volume); err != nil {
  24.  
    common.Error(err)
  25.  
    rsp.Msg = err.Error()
  26.  
    return err
  27.  
    }
  28.  
    //创建volume
  29.  
    if err := e.VolumeDataService.CreateVolumeToK8s(info); err != nil {
  30.  
    common.Error(err)
  31.  
    rsp.Msg = err.Error()
  32.  
    return err
  33.  
    } else {
  34.  
    //写入数据库
  35.  
    volumeID, err := e.VolumeDataService.AddVolume(volume)
  36.  
    if err != nil {
  37.  
    common.Error(err)
  38.  
    rsp.Msg = err.Error()
  39.  
    return err
  40.  
    }
  41.  
    rsp.Msg = "volume 添加成功 ID 号为:" strconv.FormatInt(volumeID, 10)
  42.  
    }
  43.  
    return nil
  44.  
    }
  45.  
     
  46.  
    //删除
  47.  
    func (e *VolumeHandler) DeleteVolume(ctx context.Context, req *volume.VolumeId, rsp *volume.Response) error {
  48.  
    log.Info("Received *volume.DeleteVolume request")
  49.  
    volumModel, err := e.VolumeDataService.FindVolumeByID(req.Id)
  50.  
    if err != nil {
  51.  
    common.Error(err)
  52.  
    return err
  53.  
    }
  54.  
    //从k8s中删除,并且删除数据库
  55.  
    if err := e.VolumeDataService.DeleteVolumeFromK8s(volumModel); err != nil {
  56.  
    common.Error(err)
  57.  
    return err
  58.  
    }
  59.  
    return nil
  60.  
    }
  61.  
     
  62.  
    func (e *VolumeHandler) UpdateVolume(ctx context.Context, req *volume.VolumeInfo, rsp *volume.Response) error {
  63.  
    log.Info("Received *volume.UpdateVolume request")
  64.  
    return nil
  65.  
    }
  66.  
     
  67.  
    //根据 ID 查找 volume
  68.  
    func (e *VolumeHandler) FindVolumeByID(ctx context.Context, req *volume.VolumeId, rsp *volume.VolumeInfo) error {
  69.  
    log.Info("Received *volume.FindVolumeByID request")
  70.  
    volumeModel, err := e.VolumeDataService.FindVolumeByID(req.Id)
  71.  
    if err != nil {
  72.  
    common.Error(err)
  73.  
    return err
  74.  
    }
  75.  
    //数据转化
  76.  
    if err := common.SwapTo(volumeModel, rsp); err != nil {
  77.  
    common.Error(err)
  78.  
    return err
  79.  
    }
  80.  
    return nil
  81.  
    }
  82.  
     
  83.  
    func (e *VolumeHandler) FindAllVolume(ctx context.Context, req *volume.FindAll, rsp *volume.AllVolume) error {
  84.  
    log.Info("Received *volume.FindAllVolume request")
  85.  
    allVolume, err := e.VolumeDataService.FindAllVolume()
  86.  
    if err != nil {
  87.  
    common.Error(err)
  88.  
    return err
  89.  
    }
  90.  
    //整理格式
  91.  
    for _, v := range allVolume {
  92.  
    //创建实例
  93.  
    volumeInfo := &volume.VolumeInfo{}
  94.  
    //数据转化
  95.  
    if err := common.SwapTo(v, volumeInfo); err != nil {
  96.  
    common.Error(err)
  97.  
    return err
  98.  
    }
  99.  
    //数据合并
  100.  
    rsp.VolumeInfo = append(rsp.VolumeInfo, volumeInfo)
  101.  
    }
  102.  
    return nil
  103.  
    }

C:\Users\Administrator\Desktop\gopaas\volume\main.go

  1.  
    package main
  2.  
     
  3.  
    import (
  4.  
    "flag"
  5.  
    "fmt"
  6.  
    "path/filepath"
  7.  
     
  8.  
    "github.com/yunixiangfeng/gopaas/common"
  9.  
    "github.com/yunixiangfeng/gopaas/volume/domain/repository"
  10.  
     
  11.  
    //"github.com/afex/hystrix-go/hystrix"
  12.  
    "github.com/asim/go-micro/plugins/registry/consul/v3"
  13.  
    ratelimit "github.com/asim/go-micro/plugins/wrapper/ratelimiter/uber/v3"
  14.  
    opentracing2 "github.com/asim/go-micro/plugins/wrapper/trace/opentracing/v3"
  15.  
    "github.com/asim/go-micro/v3"
  16.  
    "github.com/asim/go-micro/v3/registry"
  17.  
    "github.com/asim/go-micro/v3/server"
  18.  
    "github.com/jinzhu/gorm"
  19.  
    _ "github.com/jinzhu/gorm/dialects/mysql"
  20.  
    "github.com/opentracing/opentracing-go"
  21.  
    service2 "github.com/yunixiangfeng/gopaas/volume/domain/service"
  22.  
    "github.com/yunixiangfeng/gopaas/volume/handler"
  23.  
     
  24.  
    //hystrix2 "github.com/yunixiangfeng/gopaas/volume/plugin/hystrix"
  25.  
    "strconv"
  26.  
     
  27.  
    volume "github.com/yunixiangfeng/gopaas/volume/proto/volume"
  28.  
    "k8s.io/client-go/kubernetes"
  29.  
    "k8s.io/client-go/tools/clientcmd"
  30.  
    "k8s.io/client-go/util/homedir"
  31.  
    )
  32.  
     
  33.  
    var (
  34.  
    //服务地址
  35.  
    hostIp = "192.168.204.130"
  36.  
    //服务地址
  37.  
    serviceHost = hostIp
  38.  
    //服务端口
  39.  
    servicePort = "8087"
  40.  
     
  41.  
    //注册中心配置
  42.  
    consulHost = hostIp
  43.  
    consulPort int64 = 8500
  44.  
    //链路追踪
  45.  
    tracerHost = hostIp
  46.  
    tracerPort = 6831
  47.  
    //熔断端口,每个服务不能重复
  48.  
    //hystrixPort = 9097
  49.  
    //监控端口,每个服务不能重复
  50.  
    prometheusPort = 9197
  51.  
    )
  52.  
     
  53.  
    func main() {
  54.  
    //需要本地启动,mysql,consul中间件服务
  55.  
    //1.注册中心
  56.  
    consul := consul.NewRegistry(func(options *registry.Options) {
  57.  
    options.Addrs = []string{
  58.  
    consulHost ":" strconv.FormatInt(consulPort, 10),
  59.  
    }
  60.  
    })
  61.  
    //2.配置中心,存放经常变动的变量
  62.  
    consulConfig, err := common.GetConsulConfig(consulHost, consulPort, "/micro/config")
  63.  
    if err != nil {
  64.  
    common.Error(err)
  65.  
    }
  66.  
    //3.使用配置中心连接 mysql
  67.  
    mysqlInfo := common.GetMysqlFromConsul(consulConfig, "mysql")
  68.  
    //初始化数据库
  69.  
    db, err := gorm.Open("mysql", mysqlInfo.User ":" mysqlInfo.Pwd "@(" mysqlInfo.Host ":3306)/" mysqlInfo.Database "?charset=utf8&parseTime=True&loc=Local")
  70.  
    if err != nil {
  71.  
    //命令行输出下,方便查看错误
  72.  
    fmt.Println(err)
  73.  
    common.Fatal(err)
  74.  
    }
  75.  
    defer db.Close()
  76.  
    //禁止复表
  77.  
    db.SingularTable(true)
  78.  
     
  79.  
    //4.添加链路追踪
  80.  
    t, io, err := common.NewTracer("go.micro.service.volume", tracerHost ":" strconv.Itoa(tracerPort))
  81.  
    if err != nil {
  82.  
    common.Error(err)
  83.  
    }
  84.  
    defer io.Close()
  85.  
    opentracing.SetGlobalTracer(t)
  86.  
     
  87.  
    //添加熔断器,作为客户端需要启用
  88.  
    //hystrixStreamHandler := hystrix.NewStreamHandler()
  89.  
    //hystrixStreamHandler.Start()
  90.  
     
  91.  
    //添加日志中心
  92.  
    //1)需要程序日志打入到日志文件中
  93.  
    //2)在程序中添加filebeat.yml 文件
  94.  
    //3) 启动filebeat,启动命令 ./filebeat -e -c filebeat.yml
  95.  
    fmt.Println("日志统一记录在根目录 micro.log 文件中,请点击查看日志!")
  96.  
     
  97.  
    //启动监听程序
  98.  
    //go func() {
  99.  
    // //http://192.168.204.130:9092/turbine/turbine.stream
  100.  
    // //看板访问地址 http://127.0.0.1:9002/hystrix,url后面一定要带 /hystrix
  101.  
    // err = http.ListenAndServe(net.JoinHostPort("0.0.0.0",strconv.Itoa(hystrixPort)),hystrixStreamHandler)
  102.  
    // if err !=nil {
  103.  
    // common.Error(err)
  104.  
    // }
  105.  
    //}()
  106.  
     
  107.  
    //5.添加监控
  108.  
    common.PrometheusBoot(prometheusPort)
  109.  
     
  110.  
    //下载kubectl:https://kubernetes.io/docs/tasks/tools/#tabset-2
  111.  
    //macos:
  112.  
    // 1.curl -LO "https://dl.k8s.io/release/v1.21.0/bin/darwin/amd64/kubectl"
  113.  
    // 2.chmod x ./kubectl
  114.  
    // 3.sudo mv ./kubectl /usr/local/bin/kubectl
  115.  
    // sudo chown root: /usr/local/bin/kubectl
  116.  
    // 5.kubectl version --client
  117.  
    // 6.集群模式下直接拷贝服务端~/.kube/config 文件到本机 ~/.kube/confg 中
  118.  
    // 注意:- config中的域名要能解析正确
  119.  
    // - 生产环境可以创建另一个证书
  120.  
    // 7.kubectl get ns 查看是否正常
  121.  
    //
  122.  
    //6.创建k8s连接
  123.  
    //在集群外面连接
  124.  
    var kubeconfig *string
  125.  
    if home := homedir.HomeDir(); home != "" {
  126.  
    kubeconfig = flag.String("kubeconfig", filepath.Join(home, ".kube", "config"), "(optional) absolute path to the kubeconfig file")
  127.  
    } else {
  128.  
    kubeconfig = flag.String("kubeconfig", "", "absolute path to the kubeconfig file")
  129.  
    }
  130.  
    flag.Parse()
  131.  
    config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
  132.  
    if err != nil {
  133.  
    common.Fatal(err.Error())
  134.  
    }
  135.  
     
  136.  
    //在集群中外的配置
  137.  
    //config, err := rest.InClusterConfig()
  138.  
    //if err != nil {
  139.  
    // panic(err.Error())
  140.  
    //}
  141.  
     
  142.  
    // create the clientset
  143.  
    clientset, err := kubernetes.NewForConfig(config)
  144.  
    if err != nil {
  145.  
    common.Fatal(err.Error())
  146.  
    }
  147.  
     
  148.  
    //7.创建服务
  149.  
    service := micro.NewService(
  150.  
    //自定义服务地址,且必须写在其它参数前面
  151.  
    micro.Server(server.NewServer(func(options *server.Options) {
  152.  
    options.Advertise = serviceHost ":" servicePort
  153.  
    })),
  154.  
    micro.Name("go.micro.service.volume"),
  155.  
    micro.Version("latest"),
  156.  
    //指定服务端口
  157.  
    micro.Address(":" servicePort),
  158.  
    //添加注册中心
  159.  
    micro.Registry(consul),
  160.  
    //添加链路追踪
  161.  
    micro.WrapHandler(opentracing2.NewHandlerWrapper(opentracing.GlobalTracer())),
  162.  
    micro.WrapClient(opentracing2.NewClientWrapper(opentracing.GlobalTracer())),
  163.  
    //只作为客户端的时候起作用,如果存在调用别人的情况,原则上不去主动调用
  164.  
    //micro.WrapClient(hystrix2.NewClientHystrixWrapper()),
  165.  
    //添加限流
  166.  
    micro.WrapHandler(ratelimit.NewHandlerWrapper(1000)),
  167.  
    )
  168.  
     
  169.  
    service.Init()
  170.  
     
  171.  
    //只能执行一遍
  172.  
    //err = repository.NewVolumeRepository(db).InitTable()
  173.  
    //if err != nil {
  174.  
    // common.Fatal(err)
  175.  
    //}
  176.  
     
  177.  
    // 注册句柄,可以快速操作已开发的服务
  178.  
    volumeDataService := service2.NewVolumeDataService(repository.NewVolumeRepository(db), clientset)
  179.  
    volume.RegisterVolumeHandler(service.Server(), &handler.VolumeHandler{VolumeDataService: volumeDataService})
  180.  
     
  181.  
    // 启动服务
  182.  
    if err := service.Run(); err != nil {
  183.  
    //输出启动失败信息
  184.  
    common.Fatal(err)
  185.  
    }
  186.  
    }

9-16 Go PaaS 平台 volume api 开发 

  1.  
    PS C:\Users\Administrator\Desktop\gopaas> .\yu-tool\yu-tool.exe createApi github.com/yunixiangfeng/gopaas/volumeApi
  2.  
     
  3.  
    yu-v3 --proto_path=. --micro_out=. --go_out=:. ./proto/volumeApi/volumeApi.proto
  4.  
     
  5.  
    go mod tidy

C:\Users\Administrator\Desktop\gopaas\volumeapi\handler\volumeApiHandler.go

  1.  
    package handler
  2.  
     
  3.  
    import (
  4.  
    "context"
  5.  
    "encoding/json"
  6.  
    "errors"
  7.  
    "strconv"
  8.  
     
  9.  
    log "github.com/asim/go-micro/v3/logger"
  10.  
    "github.com/yunixiangfeng/gopaas/common"
  11.  
    volume "github.com/yunixiangfeng/gopaas/volume/proto/volume"
  12.  
    "github.com/yunixiangfeng/gopaas/volumeApi/plugin/form"
  13.  
    volumeApi "github.com/yunixiangfeng/gopaas/volumeApi/proto/volumeApi"
  14.  
    )
  15.  
     
  16.  
    type VolumeApi struct {
  17.  
    VolumeService volume.VolumeService
  18.  
    }
  19.  
     
  20.  
    // volumeApi.FindVolumeById 通过API向外暴露为/volumeApi/findVolumeById,接收http请求
  21.  
    // 即:/volumeApi/FindVolumeById 请求会调用go.micro.api.volumeApi 服务的volumeApi.FindVolumeById 方法
  22.  
    func (e *VolumeApi) FindVolumeById(ctx context.Context, req *volumeApi.Request, rsp *volumeApi.Response) error {
  23.  
    log.Info("Received volumeApi.FindVolumeById request")
  24.  
    if _, ok := req.Get["volume_id"]; !ok {
  25.  
    rsp.StatusCode = 500
  26.  
    return errors.New("参数有异常")
  27.  
    }
  28.  
    //获取 volume_id
  29.  
    volumeIdString := req.Get["volume_id"].Values[0]
  30.  
    volumeId, err := strconv.ParseInt(volumeIdString, 10, 64)
  31.  
    if err != nil {
  32.  
    common.Error(err)
  33.  
    return err
  34.  
    }
  35.  
    //获取 volume 信息
  36.  
    volumeInfo, err := e.VolumeService.FindVolumeByID(ctx, &volume.VolumeId{
  37.  
    Id: volumeId,
  38.  
    })
  39.  
    if err != nil {
  40.  
    common.Error(err)
  41.  
    return err
  42.  
    }
  43.  
    rsp.StatusCode = 200
  44.  
    b, _ := json.Marshal(volumeInfo)
  45.  
    rsp.Body = string(b)
  46.  
    return nil
  47.  
    }
  48.  
     
  49.  
    // volumeApi.AddVolume 通过API向外暴露为/volumeApi/AddVolume,接收http请求
  50.  
    // 即:/volumeApi/AddVolume 请求会调用go.micro.api.volumeApi 服务的volumeApi.AddVolume 方法
  51.  
    func (e *VolumeApi) AddVolume(ctx context.Context, req *volumeApi.Request, rsp *volumeApi.Response) error {
  52.  
    log.Info("Received volumeApi.AddVolume request")
  53.  
    addVolumeInfo := &volume.VolumeInfo{}
  54.  
    form.FormToSvcStruct(req.Post, addVolumeInfo)
  55.  
    response, err := e.VolumeService.AddVolume(ctx, addVolumeInfo)
  56.  
    if err != nil {
  57.  
    common.Error(err)
  58.  
    return err
  59.  
    }
  60.  
    rsp.StatusCode = 200
  61.  
    b, _ := json.Marshal(response)
  62.  
    rsp.Body = string(b)
  63.  
    return nil
  64.  
    }
  65.  
     
  66.  
    // volumeApi.DeleteVolumeById 通过API向外暴露为/volumeApi/DeleteVolumeById,接收http请求
  67.  
    // 即:/volumeApi/DeleteVolumeById 请求会调用go.micro.api.volumeApi 服务的 volumeApi.DeleteVolumeById 方法
  68.  
    func (e *VolumeApi) DeleteVolumeById(ctx context.Context, req *volumeApi.Request, rsp *volumeApi.Response) error {
  69.  
    log.Info("Received volumeApi.DeleteVolumeById request")
  70.  
    if _, ok := req.Get["volume_id"]; !ok {
  71.  
    rsp.StatusCode = 500
  72.  
    return errors.New("参数异常")
  73.  
    }
  74.  
    //获取 volume_id
  75.  
    volumeIdString := req.Get["volume_id"].Values[0]
  76.  
    volumeId, err := strconv.ParseInt(volumeIdString, 10, 64)
  77.  
    if err != nil {
  78.  
    common.Error(err)
  79.  
    return err
  80.  
    }
  81.  
    //调用 volume 删除服务
  82.  
    response, err := e.VolumeService.DeleteVolume(ctx, &volume.VolumeId{
  83.  
    Id: volumeId,
  84.  
    })
  85.  
    if err != nil {
  86.  
    common.Error(err)
  87.  
    return err
  88.  
    }
  89.  
    rsp.StatusCode = 200
  90.  
    b, _ := json.Marshal(response)
  91.  
    rsp.Body = string(b)
  92.  
    return nil
  93.  
    }
  94.  
     
  95.  
    // volumeApi.UpdateVolume 通过API向外暴露为/volumeApi/UpdateVolume,接收http请求
  96.  
    // 即:/volumeApi/UpdateVolume 请求会调用go.micro.api.volumeApi 服务的volumeApi.UpdateVolume 方法
  97.  
    func (e *VolumeApi) UpdateVolume(ctx context.Context, req *volumeApi.Request, rsp *volumeApi.Response) error {
  98.  
    log.Info("Received volumeApi.UpdateVolume request")
  99.  
    rsp.StatusCode = 200
  100.  
    b, _ := json.Marshal("{success:'成功访问/volumeApi/UpdateVolume'}")
  101.  
    rsp.Body = string(b)
  102.  
    return nil
  103.  
    }
  104.  
     
  105.  
    // 默认的方法volumeApi.Call 通过API向外暴露为/volumeApi/call,接收http请求
  106.  
    // 即:/volumeApi/call或/volumeApi/ 请求会调用go.micro.api.volumeApi 服务的volumeApi.FindVolumeById 方法
  107.  
    func (e *VolumeApi) Call(ctx context.Context, req *volumeApi.Request, rsp *volumeApi.Response) error {
  108.  
    log.Info("Received volumeApi.Call request")
  109.  
    allVolume, err := e.VolumeService.FindAllVolume(ctx, &volume.FindAll{})
  110.  
    if err != nil {
  111.  
    common.Error(err)
  112.  
    return err
  113.  
    }
  114.  
    rsp.StatusCode = 200
  115.  
    b, _ := json.Marshal(allVolume)
  116.  
    rsp.Body = string(b)
  117.  
    return nil
  118.  
    }

C:\Users\Administrator\Desktop\gopaas\volumeapi\plugin\form\form.go

  1.  
    package form
  2.  
     
  3.  
    import (
  4.  
    "errors"
  5.  
    "reflect"
  6.  
    "strconv"
  7.  
    "strings"
  8.  
    "time"
  9.  
     
  10.  
    "github.com/yunixiangfeng/gopaas/common"
  11.  
    "github.com/yunixiangfeng/gopaas/volumeApi/proto/volumeApi"
  12.  
    )
  13.  
     
  14.  
    //根据结构体中name标签映射数据到结构体中并且转换类型
  15.  
    func FormToSvcStruct(data map[string]*volumeApi.Pair, obj interface{}) {
  16.  
    objValue := reflect.ValueOf(obj).Elem()
  17.  
    for i := 0; i < objValue.NumField(); i {
  18.  
    //获取sql对应的值
  19.  
    dataTag := strings.Replace(objValue.Type().Field(i).Tag.Get("json"), ",omitempty", "", -1)
  20.  
    dataSlice, ok := data[dataTag]
  21.  
    if !ok {
  22.  
    continue
  23.  
    }
  24.  
    valueSlice := dataSlice.Values
  25.  
    if len(valueSlice) <= 0 {
  26.  
    continue
  27.  
    }
  28.  
    //排除port和env
  29.  
    if dataTag == "route_path" {
  30.  
    continue
  31.  
    }
  32.  
    value := valueSlice[0]
  33.  
    //端口,环境变量的单独处理
  34.  
    //获取对应字段的名称
  35.  
    name := objValue.Type().Field(i).Name
  36.  
    //获取对应字段类型
  37.  
    structFieldType := objValue.Field(i).Type()
  38.  
    //获取变量类型,也可以直接写"string类型"
  39.  
    val := reflect.ValueOf(value)
  40.  
    var err error
  41.  
    if structFieldType != val.Type() {
  42.  
    //类型转换
  43.  
    val, err = TypeConversion(value, structFieldType.Name()) //类型转换
  44.  
    if err != nil {
  45.  
    common.Error(err)
  46.  
    }
  47.  
    }
  48.  
    //设置类型值
  49.  
    objValue.FieldByName(name).Set(val)
  50.  
    }
  51.  
    }
  52.  
     
  53.  
    //类型转换
  54.  
    func TypeConversion(value string, ntype string) (reflect.Value, error) {
  55.  
    if ntype == "string" {
  56.  
    return reflect.ValueOf(value), nil
  57.  
    } else if ntype == "time.Time" {
  58.  
    t, err := time.ParseInLocation("2006-01-02 15:04:05", value, time.Local)
  59.  
    return reflect.ValueOf(t), err
  60.  
    } else if ntype == "Time" {
  61.  
    t, err := time.ParseInLocation("2006-01-02 15:04:05", value, time.Local)
  62.  
    return reflect.ValueOf(t), err
  63.  
    } else if ntype == "int" {
  64.  
    i, err := strconv.Atoi(value)
  65.  
    return reflect.ValueOf(i), err
  66.  
    } else if ntype == "int32" {
  67.  
    i, err := strconv.ParseInt(value, 10, 32)
  68.  
    if err != nil {
  69.  
    return reflect.ValueOf(int32(i)), err
  70.  
    }
  71.  
    return reflect.ValueOf(int32(i)), err
  72.  
    } else if ntype == "int64" {
  73.  
    i, err := strconv.ParseInt(value, 10, 64)
  74.  
    return reflect.ValueOf(i), err
  75.  
    } else if ntype == "float32" {
  76.  
    i, err := strconv.ParseFloat(value, 64)
  77.  
    return reflect.ValueOf(float32(i)), err
  78.  
    } else if ntype == "float64" {
  79.  
    i, err := strconv.ParseFloat(value, 64)
  80.  
    return reflect.ValueOf(i), err
  81.  
    }
  82.  
     
  83.  
    //else if .......增加其他一些类型的转换
  84.  
     
  85.  
    return reflect.ValueOf(value), errors.New("未知的类型:" ntype)
  86.  
    }

 C:\Users\Administrator\Desktop\gopaas\volumeapi\main.go

  1.  
    package main
  2.  
     
  3.  
    import (
  4.  
    "fmt"
  5.  
     
  6.  
    "github.com/afex/hystrix-go/hystrix"
  7.  
    "github.com/asim/go-micro/plugins/registry/consul/v3"
  8.  
    ratelimit "github.com/asim/go-micro/plugins/wrapper/ratelimiter/uber/v3"
  9.  
    "github.com/asim/go-micro/plugins/wrapper/select/roundrobin/v3"
  10.  
    opentracing2 "github.com/asim/go-micro/plugins/wrapper/trace/opentracing/v3"
  11.  
    "github.com/asim/go-micro/v3"
  12.  
    "github.com/asim/go-micro/v3/registry"
  13.  
    "github.com/asim/go-micro/v3/server"
  14.  
    "github.com/yunixiangfeng/gopaas/common"
  15.  
    go_micro_service_volume "github.com/yunixiangfeng/gopaas/volume/proto/volume"
  16.  
     
  17.  
    "net"
  18.  
    "net/http"
  19.  
    "strconv"
  20.  
     
  21.  
    _ "github.com/jinzhu/gorm/dialects/mysql"
  22.  
    "github.com/opentracing/opentracing-go"
  23.  
    "github.com/yunixiangfeng/gopaas/volumeApi/handler"
  24.  
    hystrix2 "github.com/yunixiangfeng/gopaas/volumeApi/plugin/hystrix"
  25.  
     
  26.  
    volumeApi "github.com/yunixiangfeng/gopaas/volumeApi/proto/volumeApi"
  27.  
    )
  28.  
     
  29.  
    var (
  30.  
    //服务地址
  31.  
    hostIp = "192.168.204.130"
  32.  
    //服务地址
  33.  
    serviceHost = hostIp
  34.  
    //服务端口
  35.  
    servicePort = "8087"
  36.  
    //注册中心配置
  37.  
    consulHost = hostIp
  38.  
    consulPort int64 = 8500
  39.  
    //链路追踪
  40.  
    tracerHost = hostIp
  41.  
    tracerPort = 6831
  42.  
    //熔断端口,每个服务不能重复
  43.  
    hystrixPort = 9097
  44.  
    //监控端口,每个服务不能重复
  45.  
    prometheusPort = 9197
  46.  
    )
  47.  
     
  48.  
    func main() {
  49.  
    //需要本地启动,mysql,consul中间件服务
  50.  
    //1.注册中心
  51.  
    consul := consul.NewRegistry(func(options *registry.Options) {
  52.  
    options.Addrs = []string{
  53.  
    consulHost ":" strconv.FormatInt(consulPort, 10),
  54.  
    }
  55.  
    })
  56.  
     
  57.  
    //2.添加链路追踪
  58.  
    t, io, err := common.NewTracer("go.micro.api.volumeApi", tracerHost ":" strconv.Itoa(tracerPort))
  59.  
    if err != nil {
  60.  
    common.Error(err)
  61.  
    }
  62.  
    defer io.Close()
  63.  
    opentracing.SetGlobalTracer(t)
  64.  
     
  65.  
    //3.添加熔断器
  66.  
    hystrixStreamHandler := hystrix.NewStreamHandler()
  67.  
    hystrixStreamHandler.Start()
  68.  
     
  69.  
    //添加日志中心
  70.  
    //1)需要程序日志打入到日志文件中
  71.  
    //2)在程序中添加filebeat.yml 文件
  72.  
    //3) 启动filebeat,启动命令 ./filebeat -e -c filebeat.yml
  73.  
    fmt.Println("日志统一记录在根目录 micro.log 文件中,请点击查看日志!")
  74.  
     
  75.  
    //启动监听程序
  76.  
    go func() {
  77.  
    //http://192.168.204.130:9092/turbine/turbine.stream
  78.  
    //看板访问地址 http://127.0.0.1:9002/hystrix,url后面一定要带 /hystrix
  79.  
    err = http.ListenAndServe(net.JoinHostPort("0.0.0.0", strconv.Itoa(hystrixPort)), hystrixStreamHandler)
  80.  
    if err != nil {
  81.  
    common.Error(err)
  82.  
    }
  83.  
    }()
  84.  
     
  85.  
    //4.添加监控
  86.  
    common.PrometheusBoot(prometheusPort)
  87.  
     
  88.  
    //5.创建服务
  89.  
    service := micro.NewService(
  90.  
    //自定义服务地址,且必须写在其它参数前面
  91.  
    micro.Server(server.NewServer(func(opts *server.Options) {
  92.  
    opts.Advertise = serviceHost ":" servicePort
  93.  
     
  94.  
    })),
  95.  
    micro.Name("go.micro.api.volumeApi"),
  96.  
    micro.Version("latest"),
  97.  
    //指定服务端口
  98.  
    micro.Address(":" servicePort),
  99.  
    //添加注册中心
  100.  
    micro.Registry(consul),
  101.  
    //添加链路追踪
  102.  
    micro.WrapHandler(opentracing2.NewHandlerWrapper(opentracing.GlobalTracer())),
  103.  
    micro.WrapClient(opentracing2.NewClientWrapper(opentracing.GlobalTracer())),
  104.  
    //只作为客户端的时候起作用
  105.  
    micro.WrapClient(hystrix2.NewClientHystrixWrapper()),
  106.  
    //添加限流
  107.  
    micro.WrapHandler(ratelimit.NewHandlerWrapper(1000)),
  108.  
    //增加负载均衡
  109.  
    micro.WrapClient(roundrobin.NewClientWrapper()),
  110.  
    )
  111.  
     
  112.  
    service.Init()
  113.  
     
  114.  
    // 指定需要访问的服务,可以快速操作已开发的服务,
  115.  
    // 默认API服务名称带有"Api",程序会自动替换
  116.  
    // 如果不带有特定字符会使用默认"XXX" 请自行替换
  117.  
    volumeService := go_micro_service_volume.NewVolumeService("go.micro.service.volume", service.Client())
  118.  
    // 注册控制器
  119.  
    if err := volumeApi.RegisterVolumeApiHandler(service.Server(), &handler.VolumeApi{VolumeService: volumeService}); err != nil {
  120.  
    common.Error(err)
  121.  
    }
  122.  
     
  123.  
    // 启动服务
  124.  
    if err := service.Run(); err != nil {
  125.  
    //输出启动失败信息
  126.  
    common.Fatal(err)
  127.  
    }
  128.  
    }

学新通

file:///home/gopath/src/gopaas/go-paas-front/volume-create.html 

9-17 总结&思考

主要内容
Ceph 基础概念介绍
Ceph 架构说明及安装
服务后端功能开发

经验之谈
Ceph 在创建支出需要规划好 PG 数量
分布式存储为了数据不丢失和高可用建议最小保留2个副本

运行过程中重要的数据操作前打快照

Ceph 单个节点宕机数据恢复过程是什么?
Ceph 的监控有哪些维度是要关心的?

9-18 【扩展阅读】基于kubernetes-1.21.5使用Rook方式部署Ceph

第10章 云原生 Go PaaS 平台中间件后端管理服务,动态创建中间件

研发过程中通常有创建不同中间件的需求,能够提供开箱即用的提供中间件资源,是一件非常高效的方式,学习mysql 的中间件的创建和管理,并且通过中间件挂载分布式存储来满足数据落盘的需求。

10-1 Go 云原生PaaS平台中间件model–middleware创建

GO PaaS 平台中间件创建与管理

  1.  
    PS C:\Users\Administrator\Desktop\gopaas> .\yu-tool\yu-tool.exe newService github.com/yunixiangfeng/gopaas/middleware
  2.  
     
  3.  
    yu-v3 --proto_path=. --micro_out=. --go_out=:. ./proto/middleware/middleware.proto
  4.  
     
  5.  
    go mod tidy

 middleware\domain\model\middleware.go

  1.  
    package model
  2.  
     
  3.  
    type Middleware struct {
  4.  
    ID int64 `gorm:"primary_key;not_null;auto_increment"`
  5.  
    //中间件的名称
  6.  
    MiddleName string `json:"middle_name"`
  7.  
    //中间件创建的命名空间
  8.  
    MiddleNamespace string `json:"middle_namespace"`
  9.  
    //中间件的类型
  10.  
    MiddleTypeID int64 `json:"middle_type_id"`
  11.  
    //中间件的版本
  12.  
    MiddleVersionID int64 `json:"middle_version_id"`
  13.  
    //中间件的端口
  14.  
    MiddlePort []MiddlePort `gorm:"ForeignKey:MiddleID" json:"middle_port"`
  15.  
    //默认生成的账号密码
  16.  
    MiddleConfig MiddleConfig `gorm:"ForeignKey:MiddleID" json:"middle_config"`
  17.  
    //环境变量
  18.  
    MiddleEnv []MiddleEnv `gorm:"ForeignKey:MiddleID" json:"middle_env"`
  19.  
    //中间件的CPU
  20.  
    MiddleCpu float32 `json:"middle_cpu"`
  21.  
    //中间件内存
  22.  
    MiddleMemory float32 `json:"middle_memory"`
  23.  
    //中间件存储
  24.  
    MiddleStorage []MiddleStorage `gorm:"ForeignKey:MiddleID" json:"middle_storage"`
  25.  
    //中间件副本
  26.  
    MiddleReplicas int32 `json:"middle_replicas"`
  27.  
    }

10-2 Go PAAS平台中间件model-middle_port创建 

C:\Users\Administrator\Desktop\gopaas\middleware\domain\model\middle_port.go

  1.  
    package model
  2.  
     
  3.  
    type MiddlePort struct {
  4.  
    ID int64 `gorm:"primary_key;not_null;auto_increment" json:"id"`
  5.  
    //主要用来关联中间件的ID
  6.  
    MiddleID int64 `json:"middle_id"`
  7.  
    //中间件开放的端口
  8.  
    MiddlePort int32 `json:"middle_port"`
  9.  
    //中间件开放的端口协议
  10.  
    MiddleProtocol string `json:"middle_protocol"`
  11.  
    }

10-3 中间件model-middle_env创建

C:\Users\Administrator\Desktop\gopaas\middleware\domain\model\middle_env.go

  1.  
    package model
  2.  
     
  3.  
    //中间件的变量
  4.  
    type MiddleEnv struct {
  5.  
    ID int64 `gorm:"primary_key;not_null;auto_increment" json:"id"`
  6.  
    //关联的环境变量ID
  7.  
    MiddleID int64 `json:"middle_id"`
  8.  
    //环境变量key
  9.  
    EnvKey string `json:"env_key"`
  10.  
    //环境变量Value
  11.  
    EnvValue string `json:"env_value"`
  12.  
    }

10-4 中间件model-MiddleConfig创建

C:\Users\Administrator\Desktop\gopaas\middleware\domain\model\middle_config.go

  1.  
    package model
  2.  
     
  3.  
    //中间件配置的结构体
  4.  
    type MiddleConfig struct {
  5.  
    ID int64 `gorm:"primary_key;not_null;auto_increment" json:"id"`
  6.  
    //关联的中间件ID
  7.  
    MiddleID int64 `json:"middle_id"`
  8.  
    //可能存在的root 用户
  9.  
    MiddleConfigRootUser string `json:"middle_config_root_user"`
  10.  
    //可能存在的root 密码
  11.  
    MiddleConfigRootPwd string `json:"middle_config_root_pwd"`
  12.  
    //可能存在的普通用户
  13.  
    MiddleConfigUser string `json:"middle_config_user"`
  14.  
    //普通用户的密码
  15.  
    MiddleConfigPwd string `json:"middle_config_pwd"`
  16.  
    //预置数据库名称
  17.  
    MiddleConfigDataBase string `json:"middle_config_data_base"`
  18.  
    //其它设置
  19.  
    }

10-5 中间件model-MiddleStorage创建 

C:\Users\Administrator\Desktop\gopaas\middleware\domain\model\middle_storage.go

  1.  
    package model
  2.  
     
  3.  
    //中间件的存储盘
  4.  
    type MiddleStorage struct {
  5.  
    ID int64 `gorm:"primary_key;not_null;auto_increment" json:"id"`
  6.  
    //关联的中间件ID
  7.  
    MiddleID int64 `json:"middle_id"`
  8.  
    //存储名称
  9.  
    MiddleStorageName string `json:"middle_storage_name"`
  10.  
    //存储的大小
  11.  
    MiddleStorageSize float32 `json:"middle_storage_size"`
  12.  
    //存储需要挂载的目录
  13.  
    MiddleStoragePath string `json:"middle_storage_path"`
  14.  
    //存储创建的类型
  15.  
    MiddleStorageClass string `json:"middle_storage_class"`
  16.  
    //存储的权限
  17.  
    MiddleStorageAccessMode string `json:"middle_storage_access_mode"`
  18.  
    }

10-6 中间件类型type 和 version创建

C:\Users\Administrator\Desktop\gopaas\middleware\domain\model\middle_type.go

  1.  
    package model
  2.  
     
  3.  
    //中间件类型
  4.  
    type MiddleType struct {
  5.  
    ID int64 `gorm:"primary_key;not_null;auto_increment" json:"id"`
  6.  
    //中间件类型名称
  7.  
    MiddleTypeName string `json:"middle_type_name"`
  8.  
    //中间件图片地址
  9.  
    MiddleTypeImageSrc string `json:"middle_type_image_src"`
  10.  
    //中间件的版本
  11.  
    MiddleVersion[] MiddleVersion `gorm:"ForeignKey:MiddleTypeID" json:"middle_version"`
  12.  
    }

C:\Users\Administrator\Desktop\gopaas\middleware\domain\model\middle_version.go

  1.  
    package model
  2.  
     
  3.  
    type MiddleVersion struct {
  4.  
    ID int64 `gorm:"primary_key;not_null;auto_increment" json:"id"`
  5.  
    MiddleTypeID int64 `json:"middle_type_id"`
  6.  
    //镜像地址
  7.  
    MiddleDockerImage string `json:"middle_docker_image"`
  8.  
    //镜像版本
  9.  
    MiddleVS string `json:"middle_vs"`
  10.  
    //MiddleDockerImage:MiddleVS
  11.  
    //其它
  12.  
    }

10-7 中间件 middleware repository开发 

C:\Users\Administrator\Desktop\gopaas\middleware\domain\repository\middleware_repository.go

  1.  
    package repository
  2.  
     
  3.  
    import (
  4.  
    "github.com/jinzhu/gorm"
  5.  
    "github.com/yunixiangfeng/gopaas/middleware/domain/model"
  6.  
    )
  7.  
     
  8.  
    //创建需要实现的接口
  9.  
    type IMiddlewareRepository interface {
  10.  
    //初始化表
  11.  
    InitTable() error
  12.  
    //根据ID查处找数据
  13.  
    FindMiddlewareByID(int64) (*model.Middleware, error)
  14.  
    //创建一条 middleware 数据
  15.  
    CreateMiddleware(*model.Middleware) (int64, error)
  16.  
    //根据ID删除一条 middleware 数据
  17.  
    DeleteMiddlewareByID(int64) error
  18.  
    //修改更新数据
  19.  
    UpdateMiddleware(*model.Middleware) error
  20.  
    //查找middleware所有数据
  21.  
    FindAll() ([]model.Middleware, error)
  22.  
     
  23.  
    //根据类型查找所有中间件
  24.  
    FindAllByTypeID(int64) ([]model.Middleware, error)
  25.  
    }
  26.  
     
  27.  
    //创建middlewareRepository
  28.  
    func NewMiddlewareRepository(db *gorm.DB) IMiddlewareRepository {
  29.  
    return &MiddlewareRepository{mysqlDb: db}
  30.  
    }
  31.  
     
  32.  
    type MiddlewareRepository struct {
  33.  
    mysqlDb *gorm.DB
  34.  
    }
  35.  
     
  36.  
    //初始化表
  37.  
    func (u *MiddlewareRepository) InitTable() error {
  38.  
    return u.mysqlDb.CreateTable(&model.Middleware{}, &model.MiddleConfig{}, &model.MiddlePort{}, &model.MiddleEnv{}, &model.MiddleStorage{}).Error
  39.  
    }
  40.  
     
  41.  
    //根据ID查找Middleware信息
  42.  
    func (u *MiddlewareRepository) FindMiddlewareByID(middlewareID int64) (middleware *model.Middleware, err error) {
  43.  
    middleware = &model.Middleware{}
  44.  
    //要多个则添加 Preload
  45.  
    return middleware, u.mysqlDb.First(middleware, middlewareID).Error
  46.  
    }
  47.  
     
  48.  
    //创建Middleware信息
  49.  
    func (u *MiddlewareRepository) CreateMiddleware(middleware *model.Middleware) (int64, error) {
  50.  
    return middleware.ID, u.mysqlDb.Create(middleware).Error
  51.  
    }
  52.  
     
  53.  
    //根据ID删除Middleware信息
  54.  
    func (u *MiddlewareRepository) DeleteMiddlewareByID(middlewareID int64) error {
  55.  
    //开启事物
  56.  
    tx := u.mysqlDb.Begin()
  57.  
    //遇到问题回滚
  58.  
    defer func() {
  59.  
    if r := recover(); r != nil {
  60.  
    tx.Rollback()
  61.  
    }
  62.  
    }()
  63.  
    //遇到错误返回
  64.  
    if tx.Error != nil {
  65.  
    return tx.Error
  66.  
    }
  67.  
    //删除中间件
  68.  
    if err := u.mysqlDb.Where("id = ?", middlewareID).Delete(&model.Middleware{}).Error; err != nil {
  69.  
    tx.Rollback()
  70.  
    return err
  71.  
    }
  72.  
    //删除中间件的配置
  73.  
    if err := u.mysqlDb.Where("middle_id = ?", middlewareID).Delete(&model.MiddleConfig{}).Error; err != nil {
  74.  
    tx.Rollback()
  75.  
    return err
  76.  
    }
  77.  
    //删除端口
  78.  
    if err := u.mysqlDb.Where("middle_id = ?", middlewareID).Delete(&model.MiddlePort{}).Error; err != nil {
  79.  
    tx.Rollback()
  80.  
    return err
  81.  
    }
  82.  
    //删除中间件环境变量
  83.  
    if err := u.mysqlDb.Where("middle_id = ?", middlewareID).Delete(&model.MiddleEnv{}).Error; err != nil {
  84.  
    tx.Rollback()
  85.  
    return err
  86.  
    }
  87.  
    //删除中间件存储
  88.  
    if err := u.mysqlDb.Where("middle_id = ?", middlewareID).Delete(&model.MiddleStorage{}).Error; err != nil {
  89.  
    tx.Rollback()
  90.  
    return err
  91.  
    }
  92.  
    return tx.Commit().Error
  93.  
    }
  94.  
     
  95.  
    //更新Middleware信息
  96.  
    func (u *MiddlewareRepository) UpdateMiddleware(middleware *model.Middleware) error {
  97.  
    return u.mysqlDb.Model(middleware).Update(middleware).Error
  98.  
    }
  99.  
     
  100.  
    //获取结果集
  101.  
    func (u *MiddlewareRepository) FindAll() (middlewareAll []model.Middleware, err error) {
  102.  
    //要多个则添加 Preload
  103.  
    return middlewareAll, u.mysqlDb.Find(&middlewareAll).Error
  104.  
    }
  105.  
     
  106.  
    func (u *MiddlewareRepository) FindAllByTypeID(typeID int64) (middlewareAll []model.Middleware, err error) {
  107.  
    //要多个则添加 Preload
  108.  
    return middlewareAll, u.mysqlDb.Where("middle_type_id = ?", typeID).Find(&middlewareAll).Error
  109.  
    }

10-8 中间件类型type和verison repository开发 

C:\Users\Administrator\Desktop\gopaas\middleware\domain\repository\middle_type_repository.go

  1.  
    package repository
  2.  
     
  3.  
    import (
  4.  
    "github.com/jinzhu/gorm"
  5.  
    "github.com/yunixiangfeng/gopaas/middleware/domain/model"
  6.  
    )
  7.  
     
  8.  
    //创建需要实现的接口
  9.  
    type IMiddleTypeRepository interface {
  10.  
    //初始化表
  11.  
    InitTable() error
  12.  
    //根据ID查处找数据
  13.  
    FindTypeByID(int64) (*model.MiddleType, error)
  14.  
    //创建一条 middleware 数据
  15.  
    CreateMiddleType(*model.MiddleType) (int64, error)
  16.  
    //根据ID删除一条 middleware 数据
  17.  
    DeleteMiddleTypeByID(int64) error
  18.  
    //修改更新数据
  19.  
    UpdateMiddleType(*model.MiddleType) error
  20.  
    //查找middleware所有数据
  21.  
    FindAll() ([]model.MiddleType, error)
  22.  
     
  23.  
    FindVersionByID(int64) (*model.MiddleVersion, error)
  24.  
    FindAllVersionByTypeID(int64) ([]model.MiddleVersion, error)
  25.  
    }
  26.  
     
  27.  
    //创建MiddleTypeRepository
  28.  
    func NewMiddleTypeRepository(db *gorm.DB) IMiddleTypeRepository {
  29.  
    return &MiddleTypeRepository{mysqlDb: db}
  30.  
    }
  31.  
     
  32.  
    type MiddleTypeRepository struct {
  33.  
    mysqlDb *gorm.DB
  34.  
    }
  35.  
     
  36.  
    //初始化表
  37.  
    func (u *MiddleTypeRepository) InitTable() error {
  38.  
    return u.mysqlDb.CreateTable(&model.MiddleType{}, &model.MiddleVersion{}).Error
  39.  
    }
  40.  
     
  41.  
    //按照 ID 查找中间件类型
  42.  
    func (u *MiddleTypeRepository) FindTypeByID(middleTypeID int64) (middleType *model.MiddleType, err error) {
  43.  
    middleType = &model.MiddleType{}
  44.  
    return middleType, u.mysqlDb.Preload("MiddleVersion").First(middleType, middleTypeID).Error
  45.  
    }
  46.  
     
  47.  
    //创建中间件
  48.  
    func (u *MiddleTypeRepository) CreateMiddleType(middleType *model.MiddleType) (int64, error) {
  49.  
    return middleType.ID, u.mysqlDb.Create(middleType).Error
  50.  
    }
  51.  
     
  52.  
    //删除中间件
  53.  
    func (u *MiddleTypeRepository) DeleteMiddleTypeByID(middleTypeID int64) error {
  54.  
    tx := u.mysqlDb.Begin()
  55.  
    //遇到问题回滚
  56.  
    defer func() {
  57.  
    if r := recover(); r != nil {
  58.  
    tx.Rollback()
  59.  
    }
  60.  
    }()
  61.  
    //遇到错误返回
  62.  
    if tx.Error != nil {
  63.  
    return tx.Error
  64.  
    }
  65.  
    //删除中间件类型
  66.  
    if err := u.mysqlDb.Where("id = ?", middleTypeID).Delete(&model.MiddleType{}).Error; err != nil {
  67.  
    tx.Rollback()
  68.  
    return err
  69.  
    }
  70.  
    //开始删除版本
  71.  
    if err := u.mysqlDb.Where("middle_type_id = ?", middleTypeID).Delete(&model.MiddleVersion{}).Error; err != nil {
  72.  
    tx.Rollback()
  73.  
    return err
  74.  
    }
  75.  
    return tx.Commit().Error
  76.  
    }
  77.  
     
  78.  
    //更新middleware 信息
  79.  
    func (u *MiddleTypeRepository) UpdateMiddleType(middleType *model.MiddleType) error {
  80.  
    return u.mysqlDb.Model(middleType).Update(middleType).Error
  81.  
    }
  82.  
     
  83.  
    //获取类型的结果集
  84.  
    func (u *MiddleTypeRepository) FindAll() (middleTypeAll []model.MiddleType, err error) {
  85.  
    return middleTypeAll, u.mysqlDb.Find(&middleTypeAll).Error
  86.  
    }
  87.  
     
  88.  
    //根据ID查找单个版本
  89.  
    func (u *MiddleTypeRepository) FindVersionByID(middleVersionID int64) (middleVersion *model.MiddleVersion, err error) {
  90.  
    middleVersion = &model.MiddleVersion{}
  91.  
    return middleVersion, u.mysqlDb.First(middleVersion, middleVersionID).Error
  92.  
    }
  93.  
     
  94.  
    //根据中间件类型查找所有版本
  95.  
    func (u *MiddleTypeRepository) FindAllVersionByTypeID(middleTypeID int64) (middleVersionAll []model.MiddleVersion, err error) {
  96.  
    return middleVersionAll, u.mysqlDb.Where("middle_type_id = ?", middleTypeID).Find(&middleVersionAll).Error
  97.  
    }

10-9 中间件 proto 文件开发 

C:\Users\Administrator\Desktop\gopaas\middleware\proto\middleware\middleware.proto

  1.  
    syntax = "proto3";
  2.  
     
  3.  
    package middleware;
  4.  
     
  5.  
    option go_package = "./proto/middleware;middleware";
  6.  
     
  7.  
    service Middleware {
  8.  
    //对外提供添加服务
  9.  
    rpc AddMiddleware(MiddlewareInfo) returns (Response) {}
  10.  
    rpc DeleteMiddleware(MiddlewareId) returns (Response) {}
  11.  
    rpc UpdateMiddleware(MiddlewareInfo) returns (Response) {}
  12.  
    rpc FindMiddlewareByID(MiddlewareId) returns (MiddlewareInfo) {}
  13.  
    rpc FindAllMiddleware(FindAll) returns (AllMiddleware) {}
  14.  
    //根据中间件的类型查找所有中间件
  15.  
    rpc FindAllMiddlewareByTypeID(FindAllByTypeId) returns (AllMiddleware){}
  16.  
    //获取中间件类型
  17.  
    rpc FindMiddleTypeByID(MiddleTypeId) returns (MiddleTypeInfo){}
  18.  
    rpc AddMiddleType(MiddleTypeInfo) returns (Response){}
  19.  
    rpc DeleteMiddleTypeByID(MiddleTypeId) returns (Response){}
  20.  
    rpc UpdateMiddleType(MiddleTypeInfo) returns(Response){}
  21.  
    rpc FindAllMiddleType(FindAll) returns (AllMiddleType){}
  22.  
    }
  23.  
     
  24.  
    message MiddlewareInfo {
  25.  
    int64 id = 1;
  26.  
    string middle_name = 2;
  27.  
    string middle_namespace =3;
  28.  
    int64 middle_type_id = 4;
  29.  
    int64 middle_version_id =5;
  30.  
    repeated MiddlePort middle_port=6;
  31.  
    MiddleConfig middle_config=7;
  32.  
    repeated MiddleEnv middle_env=8;
  33.  
    float middle_cpu=9;
  34.  
    float middle_memory=10;
  35.  
    repeated MiddleStorage middle_storage =11;
  36.  
    int32 middle_replicas = 12;
  37.  
    //添加需要的镜像版本
  38.  
    string middle_docker_image_version=13;
  39.  
    }
  40.  
    //中间件的端口
  41.  
    message MiddlePort {
  42.  
    int64 middle_id=1;
  43.  
    int32 middle_port=2;
  44.  
    string middle_protocol=3;
  45.  
    }
  46.  
    //中间的配置
  47.  
    message MiddleConfig{
  48.  
    int64 middle_id =1;
  49.  
    string middle_config_root_user =2;
  50.  
    string middle_config_root_pwd =3;
  51.  
    string middle_config_user =4;
  52.  
    string middle_config_pwd =5;
  53.  
    string middle_config_data_base =6;
  54.  
    }
  55.  
    //中间件环境变量
  56.  
    message MiddleEnv {
  57.  
    int64 middle_id=1;
  58.  
    string env_key=2;
  59.  
    string env_value=3;
  60.  
    }
  61.  
     
  62.  
    //中间件存储
  63.  
    message MiddleStorage{
  64.  
    int64 middle_id =1;
  65.  
    string middle_storage_name=2;
  66.  
    float middle_storage_size=3;
  67.  
    string middle_storage_path=4;
  68.  
    string middle_storage_class=5;
  69.  
    string middle_storage_access_mode=6;
  70.  
    }
  71.  
     
  72.  
    message FindAllByTypeId {
  73.  
    int64 type_id =1;
  74.  
    }
  75.  
     
  76.  
    message MiddleTypeId {
  77.  
    int64 id=1;
  78.  
    }
  79.  
     
  80.  
    message MiddlewareId {
  81.  
    int64 id = 1;
  82.  
    }
  83.  
     
  84.  
    message FindAll {
  85.  
     
  86.  
    }
  87.  
     
  88.  
    message Response {
  89.  
    string msg =1 ;
  90.  
    }
  91.  
     
  92.  
    message AllMiddleware {
  93.  
    repeated MiddlewareInfo middleware_info = 1;
  94.  
    }
  95.  
     
  96.  
    message MiddleTypeInfo {
  97.  
    int64 id =1;
  98.  
    string middle_type_name=2;
  99.  
    string middle_type_image_src=3;
  100.  
    repeated MiddleVersion middle_version=4;
  101.  
    }
  102.  
     
  103.  
    message MiddleVersion{
  104.  
    int64 middle_type_id =1;
  105.  
    string middle_docker_image=2;
  106.  
    string middle_vs=3;
  107.  
    }
  108.  
     
  109.  
    message AllMiddleType{
  110.  
    repeated MiddleTypeInfo middle_type_info =1;
  111.  
    }
  112.  
     
  113.  
     

 yu-v3 --proto_path=. --micro_out=. --go_out=:. ./proto/middleware/middleware.proto  

10-10 中间件 service 开发(1) 

C:\Users\Administrator\Desktop\gopaas\middleware\domain\service\middleware_data_service.go

  1.  
    package service
  2.  
     
  3.  
    import (
  4.  
    "context"
  5.  
    "errors"
  6.  
    "strconv"
  7.  
     
  8.  
    "github.com/yunixiangfeng/gopaas/common"
  9.  
    "github.com/yunixiangfeng/gopaas/middleware/domain/model"
  10.  
    "github.com/yunixiangfeng/gopaas/middleware/domain/repository"
  11.  
    "github.com/yunixiangfeng/gopaas/middleware/proto/middleware"
  12.  
    v1 "k8s.io/api/apps/v1"
  13.  
    v13 "k8s.io/api/core/v1"
  14.  
    "k8s.io/apimachinery/pkg/api/resource"
  15.  
    v12 "k8s.io/apimachinery/pkg/apis/meta/v1"
  16.  
    "k8s.io/client-go/kubernetes"
  17.  
    )
  18.  
     
  19.  
    //这里是接口类型
  20.  
    type IMiddlewareDataService interface {
  21.  
    AddMiddleware(*model.Middleware) (int64, error)
  22.  
    DeleteMiddleware(int64) error
  23.  
    UpdateMiddleware(*model.Middleware) error
  24.  
    FindMiddlewareByID(int64) (*model.Middleware, error)
  25.  
    FindAllMiddleware() ([]model.Middleware, error)
  26.  
    //根据类型查找中间件
  27.  
    FindAllMiddlewareByTypeID(int64) ([]model.Middleware, error)
  28.  
    //操作中间件s
  29.  
    CreateToK8s(*middleware.MiddlewareInfo) error
  30.  
    DeleteFromK8s(*model.Middleware) error
  31.  
    UpdateToK8s(*middleware.MiddlewareInfo) error
  32.  
    }
  33.  
     
  34.  
    //创建
  35.  
    //注意:返回值 IMiddlewareDataService 接口类型
  36.  
    func NewMiddlewareDataService(middlewareRepository repository.IMiddlewareRepository, clientSet *kubernetes.Clientset) IMiddlewareDataService {
  37.  
    return &MiddlewareDataService{MiddlewareRepository: middlewareRepository, K8sClientSet: clientSet}
  38.  
    }
  39.  
     
  40.  
    type MiddlewareDataService struct {
  41.  
    //注意:这里是 IMiddlewareRepository 类型
  42.  
    MiddlewareRepository repository.IMiddlewareRepository
  43.  
    K8sClientSet *kubernetes.Clientset
  44.  
    }
  45.  
     
  46.  
    //更新中间件到k8s
  47.  
    func (u *MiddlewareDataService) UpdateToK8s(info *middleware.MiddlewareInfo) error {
  48.  
    statefulSet := u.setStatefulSet(info)
  49.  
    if _, err := u.K8sClientSet.AppsV1().StatefulSets(info.MiddleNamespace).Get(context.TODO(), info.MiddleName, v12.GetOptions{}); err != nil {
  50.  
    common.Error(err)
  51.  
    return errors.New("中间件 " info.MiddleName " 不存在请先创建")
  52.  
    } else {
  53.  
    if _, err = u.K8sClientSet.AppsV1().StatefulSets(info.MiddleNamespace).Update(context.TODO(), statefulSet, v12.UpdateOptions{}); err != nil {
  54.  
    common.Error(err)
  55.  
    return err
  56.  
    }
  57.  
    common.Info("中间件 " info.MiddleName " 更新成功!")
  58.  
    return nil
  59.  
    }
  60.  
     
  61.  
    }
  62.  
     
  63.  
    //删除中间件
  64.  
    func (u *MiddlewareDataService) DeleteFromK8s(middleware *model.Middleware) (err error) {
  65.  
    if err := u.K8sClientSet.AppsV1().StatefulSets(middleware.MiddleNamespace).Delete(context.TODO(), middleware.MiddleName, v12.DeleteOptions{}); err != nil {
  66.  
    common.Error(err)
  67.  
    return err
  68.  
    } else {
  69.  
    if err := u.DeleteMiddleware(middleware.ID); err != nil {
  70.  
    common.Error(err)
  71.  
    return err
  72.  
    }
  73.  
    common.Info("删除中间件:" middleware.MiddleName "成功!")
  74.  
    return nil
  75.  
     
  76.  
    }
  77.  
     
  78.  
    }
  79.  
     
  80.  
    //在k8s中创建中间件
  81.  
    func (u *MiddlewareDataService) CreateToK8s(info *middleware.MiddlewareInfo) error {
  82.  
    statefulSet := u.setStatefulSet(info)
  83.  
    if _, err := u.K8sClientSet.AppsV1().StatefulSets(info.MiddleNamespace).Get(context.TODO(), info.MiddleName, v12.GetOptions{}); err != nil {
  84.  
    //如果没有获取到
  85.  
    if _, err = u.K8sClientSet.AppsV1().StatefulSets(info.MiddleNamespace).Create(context.TODO(), statefulSet, v12.CreateOptions{}); err != nil {
  86.  
    common.Error(err)
  87.  
    return err
  88.  
    }
  89.  
    common.Info("中间件:" info.MiddleName "创建成功")
  90.  
    return nil
  91.  
    } else {
  92.  
    common.Error("中间件:" info.MiddleName "创建失败")
  93.  
    return errors.New("中间件:" info.MiddleName "创建失败")
  94.  
    }
  95.  
    }
  96.  
     
  97.  
    //根据info信息设置值
  98.  
    func (u *MiddlewareDataService) setStatefulSet(info *middleware.MiddlewareInfo) *v1.StatefulSet {
  99.  
    statefulSet := &v1.StatefulSet{}
  100.  
    statefulSet.TypeMeta = v12.TypeMeta{
  101.  
    Kind: "StatefulSet",
  102.  
    APIVersion: "v1",
  103.  
    }
  104.  
    //设置详情
  105.  
    statefulSet.ObjectMeta = v12.ObjectMeta{
  106.  
    Name: info.MiddleName,
  107.  
    Namespace: info.MiddleNamespace,
  108.  
    //设置label标签
  109.  
    Labels: map[string]string{
  110.  
    "app-name": info.MiddleName,
  111.  
    "author": "wu123",
  112.  
    },
  113.  
    }
  114.  
    statefulSet.Name = info.MiddleName
  115.  
    statefulSet.Spec = v1.StatefulSetSpec{
  116.  
    //副本数
  117.  
    Replicas: &info.MiddleReplicas,
  118.  
    Selector: &v12.LabelSelector{
  119.  
    MatchLabels: map[string]string{
  120.  
    "app-name": info.MiddleName,
  121.  
    },
  122.  
    },
  123.  
    //设置容器模版
  124.  
    Template: v13.PodTemplateSpec{
  125.  
    ObjectMeta: v12.ObjectMeta{
  126.  
    Labels: map[string]string{
  127.  
    "app-name": info.MiddleName,
  128.  
    },
  129.  
    },
  130.  
    //设置容器详情
  131.  
    Spec: v13.PodSpec{
  132.  
    Containers: []v13.Container{
  133.  
    {
  134.  
    Name: info.MiddleName,
  135.  
    Image: info.MiddleDockerImageVersion,
  136.  
    //获取容器的端口
  137.  
    Ports: u.getContainerPort(info),
  138.  
    //获取环境变量
  139.  
    Env: u.getEnv(info),
  140.  
    //获取容器CPU,内存
  141.  
    Resources: u.getResources(info),
  142.  
    //设置挂载目录
  143.  
    VolumeMounts: u.setMounts(info),
  144.  
    },
  145.  
    },
  146.  
    //不能设置为0,这样不安全
  147.  
    //https://kubernetes.io/docs/tasks/run-application/force-delete-stateful-set-pod/
  148.  
    TerminationGracePeriodSeconds: u.getTime("10"),
  149.  
    //私有仓库设置密钥
  150.  
    ImagePullSecrets: nil,
  151.  
    },
  152.  
    },
  153.  
    VolumeClaimTemplates: u.getPVC(info),
  154.  
    ServiceName: info.MiddleName,
  155.  
    }
  156.  
    return statefulSet
  157.  
     
  158.  
    }
  159.  
     
  160.  
    func (u *MiddlewareDataService) getTime(stringTime string) *int64 {
  161.  
    b, err := strconv.ParseInt(stringTime, 10, 64)
  162.  
    if err != nil {
  163.  
    common.Error(err)
  164.  
    return nil
  165.  
    }
  166.  
    return &b
  167.  
    }
  168.  
     
  169.  
    //设置存储路径
  170.  
    func (u *MiddlewareDataService) setMounts(info *middleware.MiddlewareInfo) (mount []v13.VolumeMount) {
  171.  
    if len(info.MiddleStorage) == 0 {
  172.  
    return
  173.  
    }
  174.  
    for _, v := range info.MiddleStorage {
  175.  
    mt := &v13.VolumeMount{
  176.  
    Name: v.MiddleStorageName,
  177.  
    MountPath: v.MiddleStoragePath,
  178.  
    }
  179.  
    mount = append(mount, *mt)
  180.  
    }
  181.  
    return
  182.  
    }
  183.  
     
  184.  
    //获取pvc
  185.  
    func (u *MiddlewareDataService) getPVC(info *middleware.MiddlewareInfo) (pvcAll []v13.PersistentVolumeClaim) {
  186.  
    if len(info.MiddleStorage) == 0 {
  187.  
    return
  188.  
    }
  189.  
    for _, v := range info.MiddleStorage {
  190.  
    pvc := &v13.PersistentVolumeClaim{
  191.  
    TypeMeta: v12.TypeMeta{
  192.  
    Kind: "PersistentVolumeClaim",
  193.  
    APIVersion: "v1",
  194.  
    },
  195.  
    ObjectMeta: v12.ObjectMeta{
  196.  
    Name: v.MiddleStorageName,
  197.  
    Namespace: info.MiddleNamespace,
  198.  
    Annotations: map[string]string{
  199.  
    "pv.kubernetes.io/bound-by-controller": "yes",
  200.  
    "volume.beta.kubernetes.io/storage-provisioner": "rbd.csi.ceph.com",
  201.  
    },
  202.  
    },
  203.  
    Spec: v13.PersistentVolumeClaimSpec{
  204.  
    AccessModes: u.getAccessModes(v.MiddleStorageAccessMode),
  205.  
    Resources: u.getPvcResource(v.MiddleStorageSize),
  206.  
    VolumeName: v.MiddleStorageName,
  207.  
    StorageClassName: &v.MiddleStorageClass,
  208.  
    },
  209.  
    }
  210.  
    pvcAll = append(pvcAll, *pvc)
  211.  
    }
  212.  
    return
  213.  
    }
  214.  
     
  215.  
    //获取大小
  216.  
    func (u *MiddlewareDataService) getPvcResource(size float32) (source v13.ResourceRequirements) {
  217.  
    source.Requests = v13.ResourceList{
  218.  
    "storage": resource.MustParse(strconv.FormatFloat(float64(size), 'f', 6, 64) "Gi"),
  219.  
    }
  220.  
    return
  221.  
    }
  222.  
     
  223.  
    //获取权限的
  224.  
    func (u *MiddlewareDataService) getAccessModes(accessMode string) (pvam []v13.PersistentVolumeAccessMode) {
  225.  
    var pm v13.PersistentVolumeAccessMode
  226.  
    switch accessMode {
  227.  
    case "ReadWriteOnce":
  228.  
    pm = v13.ReadWriteOnce
  229.  
    case "ReadOnlyMany":
  230.  
    pm = v13.ReadOnlyMany
  231.  
    case "ReadWriteMany":
  232.  
    pm = v13.ReadWriteMany
  233.  
    case "ReadWriteOncePod":
  234.  
    pm = v13.ReadWriteOncePod
  235.  
    default:
  236.  
    pm = v13.ReadWriteOnce
  237.  
    }
  238.  
    pvam = append(pvam, pm)
  239.  
    return pvam
  240.  
    }
  241.  
     
  242.  
    //获取容器的端口
  243.  
    func (u *MiddlewareDataService) getContainerPort(info *middleware.MiddlewareInfo) (containerPort []v13.ContainerPort) {
  244.  
    for _, v := range info.MiddlePort {
  245.  
    containerPort = append(containerPort, v13.ContainerPort{
  246.  
    Name: "middle-port-" strconv.FormatInt(int64(v.MiddlePort), 10),
  247.  
    ContainerPort: v.MiddlePort,
  248.  
    Protocol: u.getProtocol(v.MiddleProtocol),
  249.  
    })
  250.  
    }
  251.  
    return
  252.  
    }
  253.  
     
  254.  
    //获取protocol 协议
  255.  
    func (u *MiddlewareDataService) getProtocol(protocol string) v13.Protocol {
  256.  
    switch protocol {
  257.  
    case "TCP":
  258.  
    return "TCP"
  259.  
    case "UDP":
  260.  
    return "UDP"
  261.  
    case "SCTP":
  262.  
    return "SCTP"
  263.  
    default:
  264.  
    return "TCP"
  265.  
    }
  266.  
     
  267.  
    }

10-11 中间件 service 开发(2) 

C:\Users\Administrator\Desktop\gopaas\middleware\domain\service\middleware_data_service.go

  1.  
    package service
  2.  
     
  3.  
    import (
  4.  
    "context"
  5.  
    "errors"
  6.  
    "strconv"
  7.  
     
  8.  
    "github.com/yunixiangfeng/gopaas/common"
  9.  
    "github.com/yunixiangfeng/gopaas/middleware/domain/model"
  10.  
    "github.com/yunixiangfeng/gopaas/middleware/domain/repository"
  11.  
    "github.com/yunixiangfeng/gopaas/middleware/proto/middleware"
  12.  
    v1 "k8s.io/api/apps/v1"
  13.  
    v13 "k8s.io/api/core/v1"
  14.  
    "k8s.io/apimachinery/pkg/api/resource"
  15.  
    v12 "k8s.io/apimachinery/pkg/apis/meta/v1"
  16.  
    "k8s.io/client-go/kubernetes"
  17.  
    )
  18.  
     
  19.  
    //这里是接口类型
  20.  
    type IMiddlewareDataService interface {
  21.  
    AddMiddleware(*model.Middleware) (int64, error)
  22.  
    DeleteMiddleware(int64) error
  23.  
    UpdateMiddleware(*model.Middleware) error
  24.  
    FindMiddlewareByID(int64) (*model.Middleware, error)
  25.  
    FindAllMiddleware() ([]model.Middleware, error)
  26.  
    //根据类型查找中间件
  27.  
    FindAllMiddlewareByTypeID(int64) ([]model.Middleware, error)
  28.  
    //操作中间件s
  29.  
    CreateToK8s(*middleware.MiddlewareInfo) error
  30.  
    DeleteFromK8s(*model.Middleware) error
  31.  
    UpdateToK8s(*middleware.MiddlewareInfo) error
  32.  
    }
  33.  
     
  34.  
    //创建
  35.  
    //注意:返回值 IMiddlewareDataService 接口类型
  36.  
    func NewMiddlewareDataService(middlewareRepository repository.IMiddlewareRepository, clientSet *kubernetes.Clientset) IMiddlewareDataService {
  37.  
    return &MiddlewareDataService{MiddlewareRepository: middlewareRepository, K8sClientSet: clientSet}
  38.  
    }
  39.  
     
  40.  
    type MiddlewareDataService struct {
  41.  
    //注意:这里是 IMiddlewareRepository 类型
  42.  
    MiddlewareRepository repository.IMiddlewareRepository
  43.  
    K8sClientSet *kubernetes.Clientset
  44.  
    }
  45.  
     
  46.  
    //更新中间件到k8s
  47.  
    func (u *MiddlewareDataService) UpdateToK8s(info *middleware.MiddlewareInfo) error {
  48.  
    statefulSet := u.setStatefulSet(info)
  49.  
    if _, err := u.K8sClientSet.AppsV1().StatefulSets(info.MiddleNamespace).Get(context.TODO(), info.MiddleName, v12.GetOptions{}); err != nil {
  50.  
    common.Error(err)
  51.  
    return errors.New("中间件 " info.MiddleName " 不存在请先创建")
  52.  
    } else {
  53.  
    if _, err = u.K8sClientSet.AppsV1().StatefulSets(info.MiddleNamespace).Update(context.TODO(), statefulSet, v12.UpdateOptions{}); err != nil {
  54.  
    common.Error(err)
  55.  
    return err
  56.  
    }
  57.  
    common.Info("中间件 " info.MiddleName " 更新成功!")
  58.  
    return nil
  59.  
    }
  60.  
     
  61.  
    }
  62.  
     
  63.  
    //删除中间件
  64.  
    func (u *MiddlewareDataService) DeleteFromK8s(middleware *model.Middleware) (err error) {
  65.  
    if err := u.K8sClientSet.AppsV1().StatefulSets(middleware.MiddleNamespace).Delete(context.TODO(), middleware.MiddleName, v12.DeleteOptions{}); err != nil {
  66.  
    common.Error(err)
  67.  
    return err
  68.  
    } else {
  69.  
    if err := u.DeleteMiddleware(middleware.ID); err != nil {
  70.  
    common.Error(err)
  71.  
    return err
  72.  
    }
  73.  
    common.Info("删除中间件:" middleware.MiddleName "成功!")
  74.  
    return nil
  75.  
     
  76.  
    }
  77.  
     
  78.  
    }
  79.  
     
  80.  
    //在k8s中创建中间件
  81.  
    func (u *MiddlewareDataService) CreateToK8s(info *middleware.MiddlewareInfo) error {
  82.  
    statefulSet := u.setStatefulSet(info)
  83.  
    if _, err := u.K8sClientSet.AppsV1().StatefulSets(info.MiddleNamespace).Get(context.TODO(), info.MiddleName, v12.GetOptions{}); err != nil {
  84.  
    //如果没有获取到
  85.  
    if _, err = u.K8sClientSet.AppsV1().StatefulSets(info.MiddleNamespace).Create(context.TODO(), statefulSet, v12.CreateOptions{}); err != nil {
  86.  
    common.Error(err)
  87.  
    return err
  88.  
    }
  89.  
    common.Info("中间件:" info.MiddleName "创建成功")
  90.  
    return nil
  91.  
    } else {
  92.  
    common.Error("中间件:" info.MiddleName "创建失败")
  93.  
    return errors.New("中间件:" info.MiddleName "创建失败")
  94.  
    }
  95.  
    }
  96.  
     
  97.  
    //根据info信息设置值
  98.  
    func (u *MiddlewareDataService) setStatefulSet(info *middleware.MiddlewareInfo) *v1.StatefulSet {
  99.  
    statefulSet := &v1.StatefulSet{}
  100.  
    statefulSet.TypeMeta = v12.TypeMeta{
  101.  
    Kind: "StatefulSet",
  102.  
    APIVersion: "v1",
  103.  
    }
  104.  
    //设置详情
  105.  
    statefulSet.ObjectMeta = v12.ObjectMeta{
  106.  
    Name: info.MiddleName,
  107.  
    Namespace: info.MiddleNamespace,
  108.  
    //设置label标签
  109.  
    Labels: map[string]string{
  110.  
    "app-name": info.MiddleName,
  111.  
    "author": "wu123",
  112.  
    },
  113.  
    }
  114.  
    statefulSet.Name = info.MiddleName
  115.  
    statefulSet.Spec = v1.StatefulSetSpec{
  116.  
    //副本数
  117.  
    Replicas: &info.MiddleReplicas,
  118.  
    Selector: &v12.LabelSelector{
  119.  
    MatchLabels: map[string]string{
  120.  
    "app-name": info.MiddleName,
  121.  
    },
  122.  
    },
  123.  
    //设置容器模版
  124.  
    Template: v13.PodTemplateSpec{
  125.  
    ObjectMeta: v12.ObjectMeta{
  126.  
    Labels: map[string]string{
  127.  
    "app-name": info.MiddleName,
  128.  
    },
  129.  
    },
  130.  
    //设置容器详情
  131.  
    Spec: v13.PodSpec{
  132.  
    Containers: []v13.Container{
  133.  
    {
  134.  
    Name: info.MiddleName,
  135.  
    Image: info.MiddleDockerImageVersion,
  136.  
    //获取容器的端口
  137.  
    Ports: u.getContainerPort(info),
  138.  
    //获取环境变量
  139.  
    Env: u.getEnv(info),
  140.  
    //获取容器CPU,内存
  141.  
    Resources: u.getResources(info),
  142.  
    //设置挂载目录
  143.  
    VolumeMounts: u.setMounts(info),
  144.  
    },
  145.  
    },
  146.  
    //不能设置为0,这样不安全
  147.  
    //https://kubernetes.io/docs/tasks/run-application/force-delete-stateful-set-pod/
  148.  
    TerminationGracePeriodSeconds: u.getTime("10"),
  149.  
    //私有仓库设置密钥
  150.  
    ImagePullSecrets: nil,
  151.  
    },
  152.  
    },
  153.  
    VolumeClaimTemplates: u.getPVC(info),
  154.  
    ServiceName: info.MiddleName,
  155.  
    }
  156.  
    return statefulSet
  157.  
     
  158.  
    }
  159.  
     
  160.  
    func (u *MiddlewareDataService) getTime(stringTime string) *int64 {
  161.  
    b, err := strconv.ParseInt(stringTime, 10, 64)
  162.  
    if err != nil {
  163.  
    common.Error(err)
  164.  
    return nil
  165.  
    }
  166.  
    return &b
  167.  
    }
  168.  
     
  169.  
    //设置存储路径
  170.  
    func (u *MiddlewareDataService) setMounts(info *middleware.MiddlewareInfo) (mount []v13.VolumeMount) {
  171.  
    if len(info.MiddleStorage) == 0 {
  172.  
    return
  173.  
    }
  174.  
    for _, v := range info.MiddleStorage {
  175.  
    mt := &v13.VolumeMount{
  176.  
    Name: v.MiddleStorageName,
  177.  
    MountPath: v.MiddleStoragePath,
  178.  
    }
  179.  
    mount = append(mount, *mt)
  180.  
    }
  181.  
    return
  182.  
    }
  183.  
     
  184.  
    //获取pvc
  185.  
    func (u *MiddlewareDataService) getPVC(info *middleware.MiddlewareInfo) (pvcAll []v13.PersistentVolumeClaim) {
  186.  
    if len(info.MiddleStorage) == 0 {
  187.  
    return
  188.  
    }
  189.  
    for _, v := range info.MiddleStorage {
  190.  
    pvc := &v13.PersistentVolumeClaim{
  191.  
    TypeMeta: v12.TypeMeta{
  192.  
    Kind: "PersistentVolumeClaim",
  193.  
    APIVersion: "v1",
  194.  
    },
  195.  
    ObjectMeta: v12.ObjectMeta{
  196.  
    Name: v.MiddleStorageName,
  197.  
    Namespace: info.MiddleNamespace,
  198.  
    Annotations: map[string]string{
  199.  
    "pv.kubernetes.io/bound-by-controller": "yes",
  200.  
    "volume.beta.kubernetes.io/storage-provisioner": "rbd.csi.ceph.com",
  201.  
    },
  202.  
    },
  203.  
    Spec: v13.PersistentVolumeClaimSpec{
  204.  
    AccessModes: u.getAccessModes(v.MiddleStorageAccessMode),
  205.  
    Resources: u.getPvcResource(v.MiddleStorageSize),
  206.  
    VolumeName: v.MiddleStorageName,
  207.  
    StorageClassName: &v.MiddleStorageClass,
  208.  
    },
  209.  
    }
  210.  
    pvcAll = append(pvcAll, *pvc)
  211.  
    }
  212.  
    return
  213.  
    }
  214.  
     
  215.  
    //获取大小
  216.  
    func (u *MiddlewareDataService) getPvcResource(size float32) (source v13.ResourceRequirements) {
  217.  
    source.Requests = v13.ResourceList{
  218.  
    "storage": resource.MustParse(strconv.FormatFloat(float64(size), 'f', 6, 64) "Gi"),
  219.  
    }
  220.  
    return
  221.  
    }
  222.  
     
  223.  
    //获取权限的
  224.  
    func (u *MiddlewareDataService) getAccessModes(accessMode string) (pvam []v13.PersistentVolumeAccessMode) {
  225.  
    var pm v13.PersistentVolumeAccessMode
  226.  
    switch accessMode {
  227.  
    case "ReadWriteOnce":
  228.  
    pm = v13.ReadWriteOnce
  229.  
    case "ReadOnlyMany":
  230.  
    pm = v13.ReadOnlyMany
  231.  
    case "ReadWriteMany":
  232.  
    pm = v13.ReadWriteMany
  233.  
    case "ReadWriteOncePod":
  234.  
    pm = v13.ReadWriteOncePod
  235.  
    default:
  236.  
    pm = v13.ReadWriteOnce
  237.  
    }
  238.  
    pvam = append(pvam, pm)
  239.  
    return pvam
  240.  
    }
  241.  
     
  242.  
    //获取容器的端口
  243.  
    func (u *MiddlewareDataService) getContainerPort(info *middleware.MiddlewareInfo) (containerPort []v13.ContainerPort) {
  244.  
    for _, v := range info.MiddlePort {
  245.  
    containerPort = append(containerPort, v13.ContainerPort{
  246.  
    Name: "middle-port-" strconv.FormatInt(int64(v.MiddlePort), 10),
  247.  
    ContainerPort: v.MiddlePort,
  248.  
    Protocol: u.getProtocol(v.MiddleProtocol),
  249.  
    })
  250.  
    }
  251.  
    return
  252.  
    }
  253.  
     
  254.  
    //获取protocol 协议
  255.  
    func (u *MiddlewareDataService) getProtocol(protocol string) v13.Protocol {
  256.  
    switch protocol {
  257.  
    case "TCP":
  258.  
    return "TCP"
  259.  
    case "UDP":
  260.  
    return "UDP"
  261.  
    case "SCTP":
  262.  
    return "SCTP"
  263.  
    default:
  264.  
    return "TCP"
  265.  
    }
  266.  
     
  267.  
    }
  268.  
     
  269.  
    //获取中间件的环境变量
  270.  
    func (u *MiddlewareDataService) getEnv(info *middleware.MiddlewareInfo) (envVar []v13.EnvVar) {
  271.  
    for _, v := range info.MiddleEnv {
  272.  
    envVar = append(envVar, v13.EnvVar{
  273.  
    Name: v.EnvKey,
  274.  
    Value: v.EnvValue,
  275.  
    ValueFrom: nil,
  276.  
    })
  277.  
    }
  278.  
    return
  279.  
    }
  280.  
     
  281.  
    //获取中间件需要的资源
  282.  
    func (u *MiddlewareDataService) getResources(info *middleware.MiddlewareInfo) (source v13.ResourceRequirements) {
  283.  
    //最大能够使用的资源
  284.  
    source.Limits = v13.ResourceList{
  285.  
    "cpu": resource.MustParse(strconv.FormatFloat(float64(info.MiddleCpu), 'f', 6, 64)),
  286.  
    "memory": resource.MustParse(strconv.FormatFloat(float64(info.MiddleMemory), 'f', 6, 64)),
  287.  
    }
  288.  
    //最小请求资源
  289.  
    source.Requests = v13.ResourceList{
  290.  
    "cpu": resource.MustParse(strconv.FormatFloat(float64(info.MiddleCpu), 'f', 6, 64)),
  291.  
    "memory": resource.MustParse(strconv.FormatFloat(float64(info.MiddleMemory), 'f', 6, 64)),
  292.  
    }
  293.  
    return
  294.  
    }
  295.  
     
  296.  
    //插入
  297.  
    func (u *MiddlewareDataService) AddMiddleware(middleware *model.Middleware) (int64, error) {
  298.  
    return u.MiddlewareRepository.CreateMiddleware(middleware)
  299.  
    }
  300.  
     
  301.  
    //删除
  302.  
    func (u *MiddlewareDataService) DeleteMiddleware(middlewareID int64) error {
  303.  
    return u.MiddlewareRepository.DeleteMiddlewareByID(middlewareID)
  304.  
    }
  305.  
     
  306.  
    //更新
  307.  
    func (u *MiddlewareDataService) UpdateMiddleware(middleware *model.Middleware) error {
  308.  
    return u.MiddlewareRepository.UpdateMiddleware(middleware)
  309.  
    }
  310.  
     
  311.  
    //查找
  312.  
    func (u *MiddlewareDataService) FindMiddlewareByID(middlewareID int64) (*model.Middleware, error) {
  313.  
    return u.MiddlewareRepository.FindMiddlewareByID(middlewareID)
  314.  
    }
  315.  
     
  316.  
    //查找
  317.  
    func (u *MiddlewareDataService) FindAllMiddleware() ([]model.Middleware, error) {
  318.  
    return u.MiddlewareRepository.FindAll()
  319.  
    }
  320.  
     
  321.  
    //根据类型查找所有的中间件
  322.  
    func (u *MiddlewareDataService) FindAllMiddlewareByTypeID(typeID int64) ([]model.Middleware, error) {
  323.  
    return u.MiddlewareRepository.FindAllByTypeID(typeID)
  324.  
    }

10-12 中间件middleware service开发(3)

C:\Users\Administrator\Desktop\gopaas\middleware\domain\service\middleware_data_service.go

  1.  
    package service
  2.  
     
  3.  
    import (
  4.  
    "context"
  5.  
    "errors"
  6.  
    "strconv"
  7.  
     
  8.  
    "github.com/yunixiangfeng/gopaas/common"
  9.  
    "github.com/yunixiangfeng/gopaas/middleware/domain/model"
  10.  
    "github.com/yunixiangfeng/gopaas/middleware/domain/repository"
  11.  
    "github.com/yunixiangfeng/gopaas/middleware/proto/middleware"
  12.  
    v1 "k8s.io/api/apps/v1"
  13.  
    v13 "k8s.io/api/core/v1"
  14.  
    "k8s.io/apimachinery/pkg/api/resource"
  15.  
    v12 "k8s.io/apimachinery/pkg/apis/meta/v1"
  16.  
    "k8s.io/client-go/kubernetes"
  17.  
    )
  18.  
     
  19.  
    //这里是接口类型
  20.  
    type IMiddlewareDataService interface {
  21.  
    AddMiddleware(*model.Middleware) (int64, error)
  22.  
    DeleteMiddleware(int64) error
  23.  
    UpdateMiddleware(*model.Middleware) error
  24.  
    FindMiddlewareByID(int64) (*model.Middleware, error)
  25.  
    FindAllMiddleware() ([]model.Middleware, error)
  26.  
    //根据类型查找中间件
  27.  
    FindAllMiddlewareByTypeID(int64) ([]model.Middleware, error)
  28.  
    //操作中间件s
  29.  
    CreateToK8s(*middleware.MiddlewareInfo) error
  30.  
    DeleteFromK8s(*model.Middleware) error
  31.  
    UpdateToK8s(*middleware.MiddlewareInfo) error
  32.  
    }
  33.  
     
  34.  
    //创建
  35.  
    //注意:返回值 IMiddlewareDataService 接口类型
  36.  
    func NewMiddlewareDataService(middlewareRepository repository.IMiddlewareRepository, clientSet *kubernetes.Clientset) IMiddlewareDataService {
  37.  
    return &MiddlewareDataService{MiddlewareRepository: middlewareRepository, K8sClientSet: clientSet}
  38.  
    }
  39.  
     
  40.  
    type MiddlewareDataService struct {
  41.  
    //注意:这里是 IMiddlewareRepository 类型
  42.  
    MiddlewareRepository repository.IMiddlewareRepository
  43.  
    K8sClientSet *kubernetes.Clientset
  44.  
    }
  45.  
     
  46.  
    //更新中间件到k8s
  47.  
    func (u *MiddlewareDataService) UpdateToK8s(info *middleware.MiddlewareInfo) error {
  48.  
    statefulSet := u.setStatefulSet(info)
  49.  
    if _, err := u.K8sClientSet.AppsV1().StatefulSets(info.MiddleNamespace).Get(context.TODO(), info.MiddleName, v12.GetOptions{}); err != nil {
  50.  
    common.Error(err)
  51.  
    return errors.New("中间件 " info.MiddleName " 不存在请先创建")
  52.  
    } else {
  53.  
    if _, err = u.K8sClientSet.AppsV1().StatefulSets(info.MiddleNamespace).Update(context.TODO(), statefulSet, v12.UpdateOptions{}); err != nil {
  54.  
    common.Error(err)
  55.  
    return err
  56.  
    }
  57.  
    common.Info("中间件 " info.MiddleName " 更新成功!")
  58.  
    return nil
  59.  
    }
  60.  
     
  61.  
    }
  62.  
     
  63.  
    //删除中间件
  64.  
    func (u *MiddlewareDataService) DeleteFromK8s(middleware *model.Middleware) (err error) {
  65.  
    if err := u.K8sClientSet.AppsV1().StatefulSets(middleware.MiddleNamespace).Delete(context.TODO(), middleware.MiddleName, v12.DeleteOptions{}); err != nil {
  66.  
    common.Error(err)
  67.  
    return err
  68.  
    } else {
  69.  
    if err := u.DeleteMiddleware(middleware.ID); err != nil {
  70.  
    common.Error(err)
  71.  
    return err
  72.  
    }
  73.  
    common.Info("删除中间件:" middleware.MiddleName "成功!")
  74.  
    return nil
  75.  
     
  76.  
    }
  77.  
     
  78.  
    }
  79.  
     
  80.  
    //在k8s中创建中间件
  81.  
    func (u *MiddlewareDataService) CreateToK8s(info *middleware.MiddlewareInfo) error {
  82.  
    statefulSet := u.setStatefulSet(info)
  83.  
    if _, err := u.K8sClientSet.AppsV1().StatefulSets(info.MiddleNamespace).Get(context.TODO(), info.MiddleName, v12.GetOptions{}); err != nil {
  84.  
    //如果没有获取到
  85.  
    if _, err = u.K8sClientSet.AppsV1().StatefulSets(info.MiddleNamespace).Create(context.TODO(), statefulSet, v12.CreateOptions{}); err != nil {
  86.  
    common.Error(err)
  87.  
    return err
  88.  
    }
  89.  
    common.Info("中间件:" info.MiddleName "创建成功")
  90.  
    return nil
  91.  
    } else {
  92.  
    common.Error("中间件:" info.MiddleName "创建失败")
  93.  
    return errors.New("中间件:" info.MiddleName "创建失败")
  94.  
    }
  95.  
    }
  96.  
     
  97.  
    //根据info信息设置值
  98.  
    func (u *MiddlewareDataService) setStatefulSet(info *middleware.MiddlewareInfo) *v1.StatefulSet {
  99.  
    statefulSet := &v1.StatefulSet{}
  100.  
    statefulSet.TypeMeta = v12.TypeMeta{
  101.  
    Kind: "StatefulSet",
  102.  
    APIVersion: "v1",
  103.  
    }
  104.  
    //设置详情
  105.  
    statefulSet.ObjectMeta = v12.ObjectMeta{
  106.  
    Name: info.MiddleName,
  107.  
    Namespace: info.MiddleNamespace,
  108.  
    //设置label标签
  109.  
    Labels: map[string]string{
  110.  
    "app-name": info.MiddleName,
  111.  
    "author": "wu123",
  112.  
    },
  113.  
    }
  114.  
    statefulSet.Name = info.MiddleName
  115.  
    statefulSet.Spec = v1.StatefulSetSpec{
  116.  
    //副本数
  117.  
    Replicas: &info.MiddleReplicas,
  118.  
    Selector: &v12.LabelSelector{
  119.  
    MatchLabels: map[string]string{
  120.  
    "app-name": info.MiddleName,
  121.  
    },
  122.  
    },
  123.  
    //设置容器模版
  124.  
    Template: v13.PodTemplateSpec{
  125.  
    ObjectMeta: v12.ObjectMeta{
  126.  
    Labels: map[string]string{
  127.  
    "app-name": info.MiddleName,
  128.  
    },
  129.  
    },
  130.  
    //设置容器详情
  131.  
    Spec: v13.PodSpec{
  132.  
    Containers: []v13.Container{
  133.  
    {
  134.  
    Name: info.MiddleName,
  135.  
    Image: info.MiddleDockerImageVersion,
  136.  
    //获取容器的端口
  137.  
    Ports: u.getContainerPort(info),
  138.  
    //获取环境变量
  139.  
    Env: u.getEnv(info),
  140.  
    //获取容器CPU,内存
  141.  
    Resources: u.getResources(info),
  142.  
    //设置挂载目录
  143.  
    VolumeMounts: u.setMounts(info),
  144.  
    },
  145.  
    },
  146.  
    //不能设置为0,这样不安全
  147.  
    //https://kubernetes.io/docs/tasks/run-application/force-delete-stateful-set-pod/
  148.  
    TerminationGracePeriodSeconds: u.getTime("10"),
  149.  
    //私有仓库设置密钥
  150.  
    ImagePullSecrets: nil,
  151.  
    },
  152.  
    },
  153.  
    VolumeClaimTemplates: u.getPVC(info),
  154.  
    ServiceName: info.MiddleName,
  155.  
    }
  156.  
    return statefulSet
  157.  
     
  158.  
    }
  159.  
     
  160.  
    func (u *MiddlewareDataService) getTime(stringTime string) *int64 {
  161.  
    b, err := strconv.ParseInt(stringTime, 10, 64)
  162.  
    if err != nil {
  163.  
    common.Error(err)
  164.  
    return nil
  165.  
    }
  166.  
    return &b
  167.  
    }
  168.  
     
  169.  
    //设置存储路径
  170.  
    func (u *MiddlewareDataService) setMounts(info *middleware.MiddlewareInfo) (mount []v13.VolumeMount) {
  171.  
    if len(info.MiddleStorage) == 0 {
  172.  
    return
  173.  
    }
  174.  
    for _, v := range info.MiddleStorage {
  175.  
    mt := &v13.VolumeMount{
  176.  
    Name: v.MiddleStorageName,
  177.  
    MountPath: v.MiddleStoragePath,
  178.  
    }
  179.  
    mount = append(mount, *mt)
  180.  
    }
  181.  
    return
  182.  
    }
  183.  
     
  184.  
    //获取pvc
  185.  
    func (u *MiddlewareDataService) getPVC(info *middleware.MiddlewareInfo) (pvcAll []v13.PersistentVolumeClaim) {
  186.  
    if len(info.MiddleStorage) == 0 {
  187.  
    return
  188.  
    }
  189.  
    for _, v := range info.MiddleStorage {
  190.  
    pvc := &v13.PersistentVolumeClaim{
  191.  
    TypeMeta: v12.TypeMeta{
  192.  
    Kind: "PersistentVolumeClaim",
  193.  
    APIVersion: "v1",
  194.  
    },
  195.  
    ObjectMeta: v12.ObjectMeta{
  196.  
    Name: v.MiddleStorageName,
  197.  
    Namespace: info.MiddleNamespace,
  198.  
    Annotations: map[string]string{
  199.  
    "pv.kubernetes.io/bound-by-controller": "yes",
  200.  
    "volume.beta.kubernetes.io/storage-provisioner": "rbd.csi.ceph.com",
  201.  
    },
  202.  
    },
  203.  
    Spec: v13.PersistentVolumeClaimSpec{
  204.  
    AccessModes: u.getAccessModes(v.MiddleStorageAccessMode),
  205.  
    Resources: u.getPvcResource(v.MiddleStorageSize),
  206.  
    VolumeName: v.MiddleStorageName,
  207.  
    StorageClassName: &v.MiddleStorageClass,
  208.  
    },
  209.  
    }
  210.  
    pvcAll = append(pvcAll, *pvc)
  211.  
    }
  212.  
    return
  213.  
    }
  214.  
     
  215.  
    //获取大小
  216.  
    func (u *MiddlewareDataService) getPvcResource(size float32) (source v13.ResourceRequirements) {
  217.  
    source.Requests = v13.ResourceList{
  218.  
    "storage": resource.MustParse(strconv.FormatFloat(float64(size), 'f', 6, 64) "Gi"),
  219.  
    }
  220.  
    return
  221.  
    }
  222.  
     
  223.  
    //获取权限的
  224.  
    func (u *MiddlewareDataService) getAccessModes(accessMode string) (pvam []v13.PersistentVolumeAccessMode) {
  225.  
    var pm v13.PersistentVolumeAccessMode
  226.  
    switch accessMode {
  227.  
    case "ReadWriteOnce":
  228.  
    pm = v13.ReadWriteOnce
  229.  
    case "ReadOnlyMany":
  230.  
    pm = v13.ReadOnlyMany
  231.  
    case "ReadWriteMany":
  232.  
    pm = v13.ReadWriteMany
  233.  
    case "ReadWriteOncePod":
  234.  
    pm = v13.ReadWriteOncePod
  235.  
    default:
  236.  
    pm = v13.ReadWriteOnce
  237.  
    }
  238.  
    pvam = append(pvam, pm)
  239.  
    return pvam
  240.  
    }
  241.  
     
  242.  
    //获取容器的端口
  243.  
    func (u *MiddlewareDataService) getContainerPort(info *middleware.MiddlewareInfo) (containerPort []v13.ContainerPort) {
  244.  
    for _, v := range info.MiddlePort {
  245.  
    containerPort = append(containerPort, v13.ContainerPort{
  246.  
    Name: "middle-port-" strconv.FormatInt(int64(v.MiddlePort), 10),
  247.  
    ContainerPort: v.MiddlePort,
  248.  
    Protocol: u.getProtocol(v.MiddleProtocol),
  249.  
    })
  250.  
    }
  251.  
    return
  252.  
    }
  253.  
     
  254.  
    //获取protocol 协议
  255.  
    func (u *MiddlewareDataService) getProtocol(protocol string) v13.Protocol {
  256.  
    switch protocol {
  257.  
    case "TCP":
  258.  
    return "TCP"
  259.  
    case "UDP":
  260.  
    return "UDP"
  261.  
    case "SCTP":
  262.  
    return "SCTP"
  263.  
    default:
  264.  
    return "TCP"
  265.  
    }
  266.  
     
  267.  
    }
  268.  
     
  269.  
    //获取中间件的环境变量
  270.  
    func (u *MiddlewareDataService) getEnv(info *middleware.MiddlewareInfo) (envVar []v13.EnvVar) {
  271.  
    for _, v := range info.MiddleEnv {
  272.  
    envVar = append(envVar, v13.EnvVar{
  273.  
    Name: v.EnvKey,
  274.  
    Value: v.EnvValue,
  275.  
    ValueFrom: nil,
  276.  
    })
  277.  
    }
  278.  
    return
  279.  
    }
  280.  
     
  281.  
    //获取中间件需要的资源
  282.  
    func (u *MiddlewareDataService) getResources(info *middleware.MiddlewareInfo) (source v13.ResourceRequirements) {
  283.  
    //最大能够使用的资源
  284.  
    source.Limits = v13.ResourceList{
  285.  
    "cpu": resource.MustParse(strconv.FormatFloat(float64(info.MiddleCpu), 'f', 6, 64)),
  286.  
    "memory": resource.MustParse(strconv.FormatFloat(float64(info.MiddleMemory), 'f', 6, 64)),
  287.  
    }
  288.  
    //最小请求资源
  289.  
    source.Requests = v13.ResourceList{
  290.  
    "cpu": resource.MustParse(strconv.FormatFloat(float64(info.MiddleCpu), 'f', 6, 64)),
  291.  
    "memory": resource.MustParse(strconv.FormatFloat(float64(info.MiddleMemory), 'f', 6, 64)),
  292.  
    }
  293.  
    return
  294.  
    }
  295.  
     
  296.  
    //插入
  297.  
    func (u *MiddlewareDataService) AddMiddleware(middleware *model.Middleware) (int64, error) {
  298.  
    return u.MiddlewareRepository.CreateMiddleware(middleware)
  299.  
    }
  300.  
     
  301.  
    //删除
  302.  
    func (u *MiddlewareDataService) DeleteMiddleware(middlewareID int64) error {
  303.  
    return u.MiddlewareRepository.DeleteMiddlewareByID(middlewareID)
  304.  
    }
  305.  
     
  306.  
    //更新
  307.  
    func (u *MiddlewareDataService) UpdateMiddleware(middleware *model.Middleware) error {
  308.  
    return u.MiddlewareRepository.UpdateMiddleware(middleware)
  309.  
    }
  310.  
     
  311.  
    //查找
  312.  
    func (u *MiddlewareDataService) FindMiddlewareByID(middlewareID int64) (*model.Middleware, error) {
  313.  
    return u.MiddlewareRepository.FindMiddlewareByID(middlewareID)
  314.  
    }
  315.  
     
  316.  
    //查找
  317.  
    func (u *MiddlewareDataService) FindAllMiddleware() ([]model.Middleware, error) {
  318.  
    return u.MiddlewareRepository.FindAll()
  319.  
    }
  320.  
     
  321.  
    //根据类型查找所有的中间件
  322.  
    func (u *MiddlewareDataService) FindAllMiddlewareByTypeID(typeID int64) ([]model.Middleware, error) {
  323.  
    return u.MiddlewareRepository.FindAllByTypeID(typeID)
  324.  
    }

10-13 中间件middleware service开发(4) 

C:\Users\Administrator\Desktop\gopaas\middleware\domain\service\middleware_data_service.go

  1.  
    package service
  2.  
     
  3.  
    import (
  4.  
    "context"
  5.  
    "errors"
  6.  
    "strconv"
  7.  
     
  8.  
    "github.com/yunixiangfeng/gopaas/common"
  9.  
    "github.com/yunixiangfeng/gopaas/middleware/domain/model"
  10.  
    "github.com/yunixiangfeng/gopaas/middleware/domain/repository"
  11.  
    "github.com/yunixiangfeng/gopaas/middleware/proto/middleware"
  12.  
    v1 "k8s.io/api/apps/v1"
  13.  
    v13 "k8s.io/api/core/v1"
  14.  
    "k8s.io/apimachinery/pkg/api/resource"
  15.  
    v12 "k8s.io/apimachinery/pkg/apis/meta/v1"
  16.  
    "k8s.io/client-go/kubernetes"
  17.  
    )
  18.  
     
  19.  
    //这里是接口类型
  20.  
    type IMiddlewareDataService interface {
  21.  
    AddMiddleware(*model.Middleware) (int64, error)
  22.  
    DeleteMiddleware(int64) error
  23.  
    UpdateMiddleware(*model.Middleware) error
  24.  
    FindMiddlewareByID(int64) (*model.Middleware, error)
  25.  
    FindAllMiddleware() ([]model.Middleware, error)
  26.  
    //根据类型查找中间件
  27.  
    FindAllMiddlewareByTypeID(int64) ([]model.Middleware, error)
  28.  
    //操作中间件s
  29.  
    CreateToK8s(*middleware.MiddlewareInfo) error
  30.  
    DeleteFromK8s(*model.Middleware) error
  31.  
    UpdateToK8s(*middleware.MiddlewareInfo) error
  32.  
    }
  33.  
     
  34.  
    //创建
  35.  
    //注意:返回值 IMiddlewareDataService 接口类型
  36.  
    func NewMiddlewareDataService(middlewareRepository repository.IMiddlewareRepository, clientSet *kubernetes.Clientset) IMiddlewareDataService {
  37.  
    return &MiddlewareDataService{MiddlewareRepository: middlewareRepository, K8sClientSet: clientSet}
  38.  
    }
  39.  
     
  40.  
    type MiddlewareDataService struct {
  41.  
    //注意:这里是 IMiddlewareRepository 类型
  42.  
    MiddlewareRepository repository.IMiddlewareRepository
  43.  
    K8sClientSet *kubernetes.Clientset
  44.  
    }
  45.  
     
  46.  
    //更新中间件到k8s
  47.  
    func (u *MiddlewareDataService) UpdateToK8s(info *middleware.MiddlewareInfo) error {
  48.  
    statefulSet := u.setStatefulSet(info)
  49.  
    if _, err := u.K8sClientSet.AppsV1().StatefulSets(info.MiddleNamespace).Get(context.TODO(), info.MiddleName, v12.GetOptions{}); err != nil {
  50.  
    common.Error(err)
  51.  
    return errors.New("中间件 " info.MiddleName " 不存在请先创建")
  52.  
    } else {
  53.  
    if _, err = u.K8sClientSet.AppsV1().StatefulSets(info.MiddleNamespace).Update(context.TODO(), statefulSet, v12.UpdateOptions{}); err != nil {
  54.  
    common.Error(err)
  55.  
    return err
  56.  
    }
  57.  
    common.Info("中间件 " info.MiddleName " 更新成功!")
  58.  
    return nil
  59.  
    }
  60.  
     
  61.  
    }
  62.  
     
  63.  
    //删除中间件
  64.  
    func (u *MiddlewareDataService) DeleteFromK8s(middleware *model.Middleware) (err error) {
  65.  
    if err := u.K8sClientSet.AppsV1().StatefulSets(middleware.MiddleNamespace).Delete(context.TODO(), middleware.MiddleName, v12.DeleteOptions{}); err != nil {
  66.  
    common.Error(err)
  67.  
    return err
  68.  
    } else {
  69.  
    if err := u.DeleteMiddleware(middleware.ID); err != nil {
  70.  
    common.Error(err)
  71.  
    return err
  72.  
    }
  73.  
    common.Info("删除中间件:" middleware.MiddleName "成功!")
  74.  
    return nil
  75.  
     
  76.  
    }
  77.  
     
  78.  
    }
  79.  
     
  80.  
    //在k8s中创建中间件
  81.  
    func (u *MiddlewareDataService) CreateToK8s(info *middleware.MiddlewareInfo) error {
  82.  
    statefulSet := u.setStatefulSet(info)
  83.  
    if _, err := u.K8sClientSet.AppsV1().StatefulSets(info.MiddleNamespace).Get(context.TODO(), info.MiddleName, v12.GetOptions{}); err != nil {
  84.  
    //如果没有获取到
  85.  
    if _, err = u.K8sClientSet.AppsV1().StatefulSets(info.MiddleNamespace).Create(context.TODO(), statefulSet, v12.CreateOptions{}); err != nil {
  86.  
    common.Error(err)
  87.  
    return err
  88.  
    }
  89.  
    common.Info("中间件:" info.MiddleName "创建成功")
  90.  
    return nil
  91.  
    } else {
  92.  
    common.Error("中间件:" info.MiddleName "创建失败")
  93.  
    return errors.New("中间件:" info.MiddleName "创建失败")
  94.  
    }
  95.  
    }
  96.  
     
  97.  
    //根据info信息设置值
  98.  
    func (u *MiddlewareDataService) setStatefulSet(info *middleware.MiddlewareInfo) *v1.StatefulSet {
  99.  
    statefulSet := &v1.StatefulSet{}
  100.  
    statefulSet.TypeMeta = v12.TypeMeta{
  101.  
    Kind: "StatefulSet",
  102.  
    APIVersion: "v1",
  103.  
    }
  104.  
    //设置详情
  105.  
    statefulSet.ObjectMeta = v12.ObjectMeta{
  106.  
    Name: info.MiddleName,
  107.  
    Namespace: info.MiddleNamespace,
  108.  
    //设置label标签
  109.  
    Labels: map[string]string{
  110.  
    "app-name": info.MiddleName,
  111.  
    "author": "wu123",
  112.  
    },
  113.  
    }
  114.  
    statefulSet.Name = info.MiddleName
  115.  
    statefulSet.Spec = v1.StatefulSetSpec{
  116.  
    //副本数
  117.  
    Replicas: &info.MiddleReplicas,
  118.  
    Selector: &v12.LabelSelector{
  119.  
    MatchLabels: map[string]string{
  120.  
    "app-name": info.MiddleName,
  121.  
    },
  122.  
    },
  123.  
    //设置容器模版
  124.  
    Template: v13.PodTemplateSpec{
  125.  
    ObjectMeta: v12.ObjectMeta{
  126.  
    Labels: map[string]string{
  127.  
    "app-name": info.MiddleName,
  128.  
    },
  129.  
    },
  130.  
    //设置容器详情
  131.  
    Spec: v13.PodSpec{
  132.  
    Containers: []v13.Container{
  133.  
    {
  134.  
    Name: info.MiddleName,
  135.  
    Image: info.MiddleDockerImageVersion,
  136.  
    //获取容器的端口
  137.  
    Ports: u.getContainerPort(info),
  138.  
    //获取环境变量
  139.  
    Env: u.getEnv(info),
  140.  
    //获取容器CPU,内存
  141.  
    Resources: u.getResources(info),
  142.  
    //设置挂载目录
  143.  
    VolumeMounts: u.setMounts(info),
  144.  
    },
  145.  
    },
  146.  
    //不能设置为0,这样不安全
  147.  
    //https://kubernetes.io/docs/tasks/run-application/force-delete-stateful-set-pod/
  148.  
    TerminationGracePeriodSeconds: u.getTime("10"),
  149.  
    //私有仓库设置密钥
  150.  
    ImagePullSecrets: nil,
  151.  
    },
  152.  
    },
  153.  
    VolumeClaimTemplates: u.getPVC(info),
  154.  
    ServiceName: info.MiddleName,
  155.  
    }
  156.  
    return statefulSet
  157.  
     
  158.  
    }
  159.  
     
  160.  
    func (u *MiddlewareDataService) getTime(stringTime string) *int64 {
  161.  
    b, err := strconv.ParseInt(stringTime, 10, 64)
  162.  
    if err != nil {
  163.  
    common.Error(err)
  164.  
    return nil
  165.  
    }
  166.  
    return &b
  167.  
    }
  168.  
     
  169.  
    //设置存储路径
  170.  
    func (u *MiddlewareDataService) setMounts(info *middleware.MiddlewareInfo) (mount []v13.VolumeMount) {
  171.  
    if len(info.MiddleStorage) == 0 {
  172.  
    return
  173.  
    }
  174.  
    for _, v := range info.MiddleStorage {
  175.  
    mt := &v13.VolumeMount{
  176.  
    Name: v.MiddleStorageName,
  177.  
    MountPath: v.MiddleStoragePath,
  178.  
    }
  179.  
    mount = append(mount, *mt)
  180.  
    }
  181.  
    return
  182.  
    }
  183.  
     
  184.  
    //获取pvc
  185.  
    func (u *MiddlewareDataService) getPVC(info *middleware.MiddlewareInfo) (pvcAll []v13.PersistentVolumeClaim) {
  186.  
    if len(info.MiddleStorage) == 0 {
  187.  
    return
  188.  
    }
  189.  
    for _, v := range info.MiddleStorage {
  190.  
    pvc := &v13.PersistentVolumeClaim{
  191.  
    TypeMeta: v12.TypeMeta{
  192.  
    Kind: "PersistentVolumeClaim",
  193.  
    APIVersion: "v1",
  194.  
    },
  195.  
    ObjectMeta: v12.ObjectMeta{
  196.  
    Name: v.MiddleStorageName,
  197.  
    Namespace: info.MiddleNamespace,
  198.  
    Annotations: map[string]string{
  199.  
    "pv.kubernetes.io/bound-by-controller": "yes",
  200.  
    "volume.beta.kubernetes.io/storage-provisioner": "rbd.csi.ceph.com",
  201.  
    },
  202.  
    },
  203.  
    Spec: v13.PersistentVolumeClaimSpec{
  204.  
    AccessModes: u.getAccessModes(v.MiddleStorageAccessMode),
  205.  
    Resources: u.getPvcResource(v.MiddleStorageSize),
  206.  
    VolumeName: v.MiddleStorageName,
  207.  
    StorageClassName: &v.MiddleStorageClass,
  208.  
    },
  209.  
    }
  210.  
    pvcAll = append(pvcAll, *pvc)
  211.  
    }
  212.  
    return
  213.  
    }
  214.  
     
  215.  
    //获取大小
  216.  
    func (u *MiddlewareDataService) getPvcResource(size float32) (source v13.ResourceRequirements) {
  217.  
    source.Requests = v13.ResourceList{
  218.  
    "storage": resource.MustParse(strconv.FormatFloat(float64(size), 'f', 6, 64) "Gi"),
  219.  
    }
  220.  
    return
  221.  
    }
  222.  
     
  223.  
    //获取权限的
  224.  
    func (u *MiddlewareDataService) getAccessModes(accessMode string) (pvam []v13.PersistentVolumeAccessMode) {
  225.  
    var pm v13.PersistentVolumeAccessMode
  226.  
    switch accessMode {
  227.  
    case "ReadWriteOnce":
  228.  
    pm = v13.ReadWriteOnce
  229.  
    case "ReadOnlyMany":
  230.  
    pm = v13.ReadOnlyMany
  231.  
    case "ReadWriteMany":
  232.  
    pm = v13.ReadWriteMany
  233.  
    case "ReadWriteOncePod":
  234.  
    pm = v13.ReadWriteOncePod
  235.  
    default:
  236.  
    pm = v13.ReadWriteOnce
  237.  
    }
  238.  
    pvam = append(pvam, pm)
  239.  
    return pvam
  240.  
    }
  241.  
     
  242.  
    //获取容器的端口
  243.  
    func (u *MiddlewareDataService) getContainerPort(info *middleware.MiddlewareInfo) (containerPort []v13.ContainerPort) {
  244.  
    for _, v := range info.MiddlePort {
  245.  
    containerPort = append(containerPort, v13.ContainerPort{
  246.  
    Name: "middle-port-" strconv.FormatInt(int64(v.MiddlePort), 10),
  247.  
    ContainerPort: v.MiddlePort,
  248.  
    Protocol: u.getProtocol(v.MiddleProtocol),
  249.  
    })
  250.  
    }
  251.  
    return
  252.  
    }
  253.  
     
  254.  
    //获取protocol 协议
  255.  
    func (u *MiddlewareDataService) getProtocol(protocol string) v13.Protocol {
  256.  
    switch protocol {
  257.  
    case "TCP":
  258.  
    return "TCP"
  259.  
    case "UDP":
  260.  
    return "UDP"
  261.  
    case "SCTP":
  262.  
    return "SCTP"
  263.  
    default:
  264.  
    return "TCP"
  265.  
    }
  266.  
     
  267.  
    }
  268.  
     
  269.  
    //获取中间件的环境变量
  270.  
    func (u *MiddlewareDataService) getEnv(info *middleware.MiddlewareInfo) (envVar []v13.EnvVar) {
  271.  
    for _, v := range info.MiddleEnv {
  272.  
    envVar = append(envVar, v13.EnvVar{
  273.  
    Name: v.EnvKey,
  274.  
    Value: v.EnvValue,
  275.  
    ValueFrom: nil,
  276.  
    })
  277.  
    }
  278.  
    return
  279.  
    }
  280.  
     
  281.  
    //获取中间件需要的资源
  282.  
    func (u *MiddlewareDataService) getResources(info *middleware.MiddlewareInfo) (source v13.ResourceRequirements) {
  283.  
    //最大能够使用的资源
  284.  
    source.Limits = v13.ResourceList{
  285.  
    "cpu": resource.MustParse(strconv.FormatFloat(float64(info.MiddleCpu), 'f', 6, 64)),
  286.  
    "memory": resource.MustParse(strconv.FormatFloat(float64(info.MiddleMemory), 'f', 6, 64)),
  287.  
    }
  288.  
    //最小请求资源
  289.  
    source.Requests = v13.ResourceList{
  290.  
    "cpu": resource.MustParse(strconv.FormatFloat(float64(info.MiddleCpu), 'f', 6, 64)),
  291.  
    "memory": resource.MustParse(strconv.FormatFloat(float64(info.MiddleMemory), 'f', 6, 64)),
  292.  
    }
  293.  
    return
  294.  
    }
  295.  
     
  296.  
    //插入
  297.  
    func (u *MiddlewareDataService) AddMiddleware(middleware *model.Middleware) (int64, error) {
  298.  
    return u.MiddlewareRepository.CreateMiddleware(middleware)
  299.  
    }
  300.  
     
  301.  
    //删除
  302.  
    func (u *MiddlewareDataService) DeleteMiddleware(middlewareID int64) error {
  303.  
    return u.MiddlewareRepository.DeleteMiddlewareByID(middlewareID)
  304.  
    }
  305.  
     
  306.  
    //更新
  307.  
    func (u *MiddlewareDataService) UpdateMiddleware(middleware *model.Middleware) error {
  308.  
    return u.MiddlewareRepository.UpdateMiddleware(middleware)
  309.  
    }
  310.  
     
  311.  
    //查找
  312.  
    func (u *MiddlewareDataService) FindMiddlewareByID(middlewareID int64) (*model.Middleware, error) {
  313.  
    return u.MiddlewareRepository.FindMiddlewareByID(middlewareID)
  314.  
    }
  315.  
     
  316.  
    //查找
  317.  
    func (u *MiddlewareDataService) FindAllMiddleware() ([]model.Middleware, error) {
  318.  
    return u.MiddlewareRepository.FindAll()
  319.  
    }
  320.  
     
  321.  
    //根据类型查找所有的中间件
  322.  
    func (u *MiddlewareDataService) FindAllMiddlewareByTypeID(typeID int64) ([]model.Middleware, error) {
  323.  
    return u.MiddlewareRepository.FindAllByTypeID(typeID)
  324.  
    }

10-14 中间件service 对应版本服务代码开发 

C:\Users\Administrator\Desktop\gopaas\middleware\domain\service\middle_type_data_service.go

  1.  
    package service
  2.  
     
  3.  
    import (
  4.  
    "github.com/yunixiangfeng/gopaas/middleware/domain/model"
  5.  
    "github.com/yunixiangfeng/gopaas/middleware/domain/repository"
  6.  
    )
  7.  
     
  8.  
    //定义接口类型
  9.  
    type IMiddleTypeDataService interface {
  10.  
    AddMiddleType(*model.MiddleType) (int64, error)
  11.  
    DeleteMiddleType(int64) error
  12.  
    UpdateMiddleType(*model.MiddleType) error
  13.  
    FindMiddleTypeByID(int64) (*model.MiddleType, error)
  14.  
    FindAllMiddleType() ([]model.MiddleType, error)
  15.  
    //根据ID返回地址
  16.  
    FindImageVersionByID(int64) (string, error)
  17.  
     
  18.  
    FindVersionByID(int64) (*model.MiddleVersion, error)
  19.  
    FindAllVersionByTypeID(int64) ([]model.MiddleVersion, error)
  20.  
    }
  21.  
     
  22.  
    //注意:返回值的类型
  23.  
    func NewMiddleTypeDataService(repository repository.IMiddleTypeRepository) IMiddleTypeDataService {
  24.  
    return &MiddleTypeDataService{MiddleTypeRepository: repository}
  25.  
     
  26.  
    }
  27.  
     
  28.  
    type MiddleTypeDataService struct {
  29.  
    MiddleTypeRepository repository.IMiddleTypeRepository
  30.  
    }
  31.  
     
  32.  
    //插入
  33.  
    func (u *MiddleTypeDataService) AddMiddleType(middleType *model.MiddleType) (int64, error) {
  34.  
    return u.MiddleTypeRepository.CreateMiddleType(middleType)
  35.  
    }
  36.  
     
  37.  
    //删除
  38.  
    func (u *MiddleTypeDataService) DeleteMiddleType(middleTypeID int64) error {
  39.  
    return u.MiddleTypeRepository.DeleteMiddleTypeByID(middleTypeID)
  40.  
    }
  41.  
     
  42.  
    //更新
  43.  
    func (u *MiddleTypeDataService) UpdateMiddleType(middleType *model.MiddleType) error {
  44.  
    return u.MiddleTypeRepository.UpdateMiddleType(middleType)
  45.  
    }
  46.  
     
  47.  
    //查找
  48.  
    func (u *MiddleTypeDataService) FindMiddleTypeByID(middleTypeID int64) (*model.MiddleType, error) {
  49.  
    return u.MiddleTypeRepository.FindTypeByID(middleTypeID)
  50.  
     
  51.  
    }
  52.  
     
  53.  
    //查找所有
  54.  
    func (u *MiddleTypeDataService) FindAllMiddleType() ([]model.MiddleType, error) {
  55.  
    return u.MiddleTypeRepository.FindAll()
  56.  
    }
  57.  
     
  58.  
    //根据version ID查找镜像地址
  59.  
    func (u *MiddleTypeDataService) FindImageVersionByID(middleVersionID int64) (string, error) {
  60.  
    version, err := u.MiddleTypeRepository.FindVersionByID(middleVersionID)
  61.  
    if err != nil {
  62.  
    return "", err
  63.  
    }
  64.  
    //返回需要的镜像地址
  65.  
    return version.MiddleDockerImage ":" version.MiddleVS, nil
  66.  
     
  67.  
    }
  68.  
     
  69.  
    //根据versionID 查找单个镜像
  70.  
    func (u *MiddleTypeDataService) FindVersionByID(middleVersionID int64) (*model.MiddleVersion, error) {
  71.  
    return u.MiddleTypeRepository.FindVersionByID(middleVersionID)
  72.  
    }
  73.  
     
  74.  
    //根据中间件类型查找对应的所有版本
  75.  
    func (u *MiddleTypeDataService) FindAllVersionByTypeID(middleTypeID int64) ([]model.MiddleVersion, error) {
  76.  
    return u.MiddleTypeRepository.FindAllVersionByTypeID(middleTypeID)
  77.  
    }

10-15 中间件main调整 及 handler 开发(上)

C:\Users\Administrator\Desktop\gopaas\middleware\main.go

  1.  
    //只能执行一遍
  2.  
    //err = repository.NewMiddlewareRepository(db).InitTable()
  3.  
    //if err != nil {
  4.  
    // common.Fatal(err)
  5.  
    //}
  6.  
    //if err:= repository.NewMiddleTypeRepository(db).InitTable();err!=nil{
  7.  
    // common.Fatal(err)
  8.  
    //}
  9.  
     
  10.  
    // 注册句柄,可以快速操作已开发的服务
  11.  
    middlewareDataService := service2.NewMiddlewareDataService(repository.NewMiddlewareRepository(db), clientset)
  12.  
    middleTypeDataService := service2.NewMiddleTypeDataService(repository.NewMiddleTypeRepository(db))
  13.  
    middleware.RegisterMiddlewareHandler(service.Server(), &handler.MiddlewareHandler{MiddlewareDataService: middlewareDataService, MiddleTypeDataService: middleTypeDataService})

C:\Users\Administrator\Desktop\gopaas\middleware\handler\middlewareHandler.go

  1.  
    package handler
  2.  
     
  3.  
    import (
  4.  
    "context"
  5.  
    "strconv"
  6.  
     
  7.  
    log "github.com/asim/go-micro/v3/logger"
  8.  
    "github.com/yunixiangfeng/gopaas/common"
  9.  
    "github.com/yunixiangfeng/gopaas/middleware/domain/model"
  10.  
    "github.com/yunixiangfeng/gopaas/middleware/domain/service"
  11.  
    middleware "github.com/yunixiangfeng/gopaas/middleware/proto/middleware"
  12.  
    )
  13.  
     
  14.  
    type MiddlewareHandler struct {
  15.  
    //注意这里的类型是 IMiddlewareDataService 接口类型
  16.  
    MiddlewareDataService service.IMiddlewareDataService
  17.  
    // 添加中间件类型服务
  18.  
    MiddleTypeDataService service.IMiddleTypeDataService
  19.  
    }
  20.  
     
  21.  
    // Call is a single request handler called via client.Call or the generated client code
  22.  
    func (e *MiddlewareHandler) AddMiddleware(ctx context.Context, info *middleware.MiddlewareInfo, rsp *middleware.Response) error {
  23.  
    log.Info("Received *middleware.AddMiddleware request")
  24.  
    middleModel := &model.Middleware{}
  25.  
    if err := common.SwapTo(info, middleModel); err != nil {
  26.  
    common.Error(err)
  27.  
    rsp.Msg = err.Error()
  28.  
    return err
  29.  
    }
  30.  
    //调用其它的服务处理数据
  31.  
    //根据ID产销需要的镜像地址
  32.  
    imageAddress, err := e.MiddleTypeDataService.FindImageVersionByID(info.MiddleVersionId)
  33.  
    if err != nil {
  34.  
    common.Error(err)
  35.  
    return err
  36.  
    }
  37.  
    //赋值
  38.  
    info.MiddleDockerImageVersion = imageAddress
  39.  
    //在k8s 中创建资源
  40.  
    if err := e.MiddlewareDataService.CreateToK8s(info); err != nil {
  41.  
    common.Error(err)
  42.  
    rsp.Msg = err.Error()
  43.  
    return err
  44.  
    } else {
  45.  
    //插入数据库
  46.  
    middleID, err := e.MiddlewareDataService.AddMiddleware(middleModel)
  47.  
    if err != nil {
  48.  
    common.Error(err)
  49.  
    rsp.Msg = err.Error()
  50.  
    return err
  51.  
    }
  52.  
    rsp.Msg = "中间件添加成功 ID 号为:" strconv.FormatInt(middleID, 10)
  53.  
    common.Info(rsp.Msg)
  54.  
    }
  55.  
    return nil
  56.  
    }
  57.  
     
  58.  
    func (e *MiddlewareHandler) DeleteMiddleware(ctx context.Context, req *middleware.MiddlewareId, rsp *middleware.Response) error {
  59.  
    log.Info("Received *middleware.DeleteMiddleware request")
  60.  
    middleModel, err := e.MiddlewareDataService.FindMiddlewareByID(req.Id)
  61.  
    if err != nil {
  62.  
    common.Error(err)
  63.  
    rsp.Msg = err.Error()
  64.  
    return err
  65.  
    }
  66.  
    //删除k8s中资源
  67.  
    if err := e.MiddlewareDataService.DeleteFromK8s(middleModel); err != nil {
  68.  
    common.Error(err)
  69.  
    rsp.Msg = err.Error()
  70.  
    return err
  71.  
    }
  72.  
    return nil
  73.  
    }
  74.  
     
  75.  
    func (e *MiddlewareHandler) UpdateMiddleware(ctx context.Context, req *middleware.MiddlewareInfo, rsp *middleware.Response) error {
  76.  
    log.Info("Received *middleware.UpdateMiddleware request")
  77.  
    if err := e.MiddlewareDataService.UpdateToK8s(req); err != nil {
  78.  
    common.Error(err)
  79.  
    rsp.Msg = err.Error()
  80.  
    return err
  81.  
    }
  82.  
    //查询中间件相关的信息
  83.  
    middleModle, err := e.MiddlewareDataService.FindMiddlewareByID(req.Id)
  84.  
    if err != nil {
  85.  
    common.Error(err)
  86.  
    rsp.Msg = err.Error()
  87.  
    return err
  88.  
    }
  89.  
    //更新model数据
  90.  
    if err := common.SwapTo(req, middleModle); err != nil {
  91.  
    common.Error(err)
  92.  
    rsp.Msg = err.Error()
  93.  
    return err
  94.  
    }
  95.  
    //更新model
  96.  
    if err := e.MiddlewareDataService.UpdateMiddleware(middleModle); err != nil {
  97.  
    common.Error(err)
  98.  
    rsp.Msg = err.Error()
  99.  
    return err
  100.  
    }
  101.  
    return nil
  102.  
    }
  103.  
     
  104.  
    func (e *MiddlewareHandler) FindMiddlewareByID(ctx context.Context, req *middleware.MiddlewareId, rsp *middleware.MiddlewareInfo) error {
  105.  
    log.Info("Received *middleware.FindMiddlewareByID request")
  106.  
    //查询中间件
  107.  
    middlewareModel, err := e.MiddlewareDataService.FindMiddlewareByID(req.Id)
  108.  
    if err != nil {
  109.  
    common.Error(err)
  110.  
    return err
  111.  
    }
  112.  
    if err := common.SwapTo(middlewareModel, rsp); err != nil {
  113.  
    common.Error(err)
  114.  
    return err
  115.  
    }
  116.  
    return nil
  117.  
    }
  118.  
     
  119.  
    func (e *MiddlewareHandler) FindAllMiddleware(ctx context.Context, req *middleware.FindAll, rsp *middleware.AllMiddleware) error {
  120.  
    log.Info("Received *middleware.FindAllMiddleware request")
  121.  
    allMiddleware, err := e.MiddlewareDataService.FindAllMiddleware()
  122.  
    if err != nil {
  123.  
    common.Error(err)
  124.  
    return err
  125.  
    }
  126.  
    //整理格式
  127.  
    for _, v := range allMiddleware {
  128.  
    middleInfo := &middleware.MiddlewareInfo{}
  129.  
    if err := common.SwapTo(v, middleInfo); err != nil {
  130.  
    common.Error(err)
  131.  
    return err
  132.  
    }
  133.  
    rsp.MiddlewareInfo = append(rsp.MiddlewareInfo, middleInfo)
  134.  
    }
  135.  
    return nil
  136.  
    }

make proto 

10-16 中间件main调整 及 handler 开发(下) 

C:\Users\Administrator\Desktop\gopaas\middleware\main.go

  1.  
    package main
  2.  
     
  3.  
    import (
  4.  
    "flag"
  5.  
    "fmt"
  6.  
    "path/filepath"
  7.  
     
  8.  
    "github.com/yunixiangfeng/gopaas/common"
  9.  
    "github.com/yunixiangfeng/gopaas/middleware/domain/repository"
  10.  
     
  11.  
    //"github.com/afex/hystrix-go/hystrix"
  12.  
    "github.com/asim/go-micro/plugins/registry/consul/v3"
  13.  
    ratelimit "github.com/asim/go-micro/plugins/wrapper/ratelimiter/uber/v3"
  14.  
    opentracing2 "github.com/asim/go-micro/plugins/wrapper/trace/opentracing/v3"
  15.  
    "github.com/asim/go-micro/v3"
  16.  
    "github.com/asim/go-micro/v3/registry"
  17.  
    "github.com/asim/go-micro/v3/server"
  18.  
    "github.com/jinzhu/gorm"
  19.  
    _ "github.com/jinzhu/gorm/dialects/mysql"
  20.  
    "github.com/opentracing/opentracing-go"
  21.  
    service2 "github.com/yunixiangfeng/gopaas/middleware/domain/service"
  22.  
    "github.com/yunixiangfeng/gopaas/middleware/handler"
  23.  
     
  24.  
    //hystrix2 "github.com/yunixiangfeng/gopaas/middleware/plugin/hystrix"
  25.  
    "strconv"
  26.  
     
  27.  
    middleware "github.com/yunixiangfeng/gopaas/middleware/proto/middleware"
  28.  
    "k8s.io/client-go/kubernetes"
  29.  
    "k8s.io/client-go/tools/clientcmd"
  30.  
    "k8s.io/client-go/util/homedir"
  31.  
    )
  32.  
     
  33.  
    var (
  34.  
    //服务地址
  35.  
    hostIp = "192.168.204.130"
  36.  
    //服务地址
  37.  
    serviceHost = hostIp
  38.  
    //服务端口
  39.  
    servicePort = "8089"
  40.  
     
  41.  
    //注册中心配置
  42.  
    consulHost = hostIp
  43.  
    consulPort int64 = 8500
  44.  
    //链路追踪
  45.  
    tracerHost = hostIp
  46.  
    tracerPort = 6831
  47.  
    //熔断端口,每个服务不能重复
  48.  
    //hystrixPort = 9099
  49.  
    //监控端口,每个服务不能重复
  50.  
    prometheusPort = 9199
  51.  
    )
  52.  
     
  53.  
    func main() {
  54.  
    //需要本地启动,mysql,consul中间件服务
  55.  
    //1.注册中心
  56.  
    consul := consul.NewRegistry(func(options *registry.Options) {
  57.  
    options.Addrs = []string{
  58.  
    consulHost ":" strconv.FormatInt(consulPort, 10),
  59.  
    }
  60.  
    })
  61.  
    //2.配置中心,存放经常变动的变量
  62.  
    consulConfig, err := common.GetConsulConfig(consulHost, consulPort, "/micro/config")
  63.  
    if err != nil {
  64.  
    common.Error(err)
  65.  
    }
  66.  
    //3.使用配置中心连接 mysql
  67.  
    mysqlInfo := common.GetMysqlFromConsul(consulConfig, "mysql")
  68.  
    //初始化数据库
  69.  
    db, err := gorm.Open("mysql", mysqlInfo.User ":" mysqlInfo.Pwd "@(" mysqlInfo.Host ":3306)/" mysqlInfo.Database "?charset=utf8&parseTime=True&loc=Local")
  70.  
    if err != nil {
  71.  
    //命令行输出下,方便查看错误
  72.  
    fmt.Println(err)
  73.  
    common.Fatal(err)
  74.  
    }
  75.  
    defer db.Close()
  76.  
    //禁止复表
  77.  
    db.SingularTable(true)
  78.  
     
  79.  
    //4.添加链路追踪
  80.  
    t, io, err := common.NewTracer("go.micro.service.middleware", tracerHost ":" strconv.Itoa(tracerPort))
  81.  
    if err != nil {
  82.  
    common.Error(err)
  83.  
    }
  84.  
    defer io.Close()
  85.  
    opentracing.SetGlobalTracer(t)
  86.  
     
  87.  
    //添加熔断器,作为客户端需要启用
  88.  
    //hystrixStreamHandler := hystrix.NewStreamHandler()
  89.  
    //hystrixStreamHandler.Start()
  90.  
     
  91.  
    //添加日志中心
  92.  
    //1)需要程序日志打入到日志文件中
  93.  
    //2)在程序中添加filebeat.yml 文件
  94.  
    //3) 启动filebeat,启动命令 ./filebeat -e -c filebeat.yml
  95.  
    fmt.Println("日志统一记录在根目录 micro.log 文件中,请点击查看日志!")
  96.  
     
  97.  
    //启动监听程序
  98.  
    //go func() {
  99.  
    // //http://192.168.204.130:9092/turbine/turbine.stream
  100.  
    // //看板访问地址 http://127.0.0.1:9002/hystrix,url后面一定要带 /hystrix
  101.  
    // err = http.ListenAndServe(net.JoinHostPort("0.0.0.0",strconv.Itoa(hystrixPort)),hystrixStreamHandler)
  102.  
    // if err !=nil {
  103.  
    // common.Error(err)
  104.  
    // }
  105.  
    //}()
  106.  
     
  107.  
    //5.添加监控
  108.  
    common.PrometheusBoot(prometheusPort)
  109.  
     
  110.  
    //下载kubectl:https://kubernetes.io/docs/tasks/tools/#tabset-2
  111.  
    //macos:
  112.  
    // 1.curl -LO "https://dl.k8s.io/release/v1.21.0/bin/darwin/amd64/kubectl"
  113.  
    // 2.chmod x ./kubectl
  114.  
    // 3.sudo mv ./kubectl /usr/local/bin/kubectl
  115.  
    // sudo chown root: /usr/local/bin/kubectl
  116.  
    // 5.kubectl version --client
  117.  
    // 6.集群模式下直接拷贝服务端~/.kube/config 文件到本机 ~/.kube/confg 中
  118.  
    // 注意:- config中的域名要能解析正确
  119.  
    // - 生产环境可以创建另一个证书
  120.  
    // 7.kubectl get ns 查看是否正常
  121.  
    //
  122.  
    //6.创建k8s连接
  123.  
    //在集群外面连接
  124.  
    var kubeconfig *string
  125.  
    if home := homedir.HomeDir(); home != "" {
  126.  
    kubeconfig = flag.String("kubeconfig", filepath.Join(home, ".kube", "config"), "(optional) absolute path to the kubeconfig file")
  127.  
    } else {
  128.  
    kubeconfig = flag.String("kubeconfig", "", "absolute path to the kubeconfig file")
  129.  
    }
  130.  
    flag.Parse()
  131.  
    config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
  132.  
    if err != nil {
  133.  
    common.Fatal(err.Error())
  134.  
    }
  135.  
     
  136.  
    //在集群中外的配置
  137.  
    //config, err := rest.InClusterConfig()
  138.  
    //if err != nil {
  139.  
    // panic(err.Error())
  140.  
    //}
  141.  
     
  142.  
    // create the clientset
  143.  
    clientset, err := kubernetes.NewForConfig(config)
  144.  
    if err != nil {
  145.  
    common.Fatal(err.Error())
  146.  
    }
  147.  
     
  148.  
    //7.创建服务
  149.  
    service := micro.NewService(
  150.  
    //自定义服务地址,且必须写在其它参数前面
  151.  
    micro.Server(server.NewServer(func(options *server.Options) {
  152.  
    options.Advertise = serviceHost ":" servicePort
  153.  
    })),
  154.  
    micro.Name("go.micro.service.middleware"),
  155.  
    micro.Version("latest"),
  156.  
    //指定服务端口
  157.  
    micro.Address(":" servicePort),
  158.  
    //添加注册中心
  159.  
    micro.Registry(consul),
  160.  
    //添加链路追踪
  161.  
    micro.WrapHandler(opentracing2.NewHandlerWrapper(opentracing.GlobalTracer())),
  162.  
    micro.WrapClient(opentracing2.NewClientWrapper(opentracing.GlobalTracer())),
  163.  
    //只作为客户端的时候起作用,如果存在调用别人的情况,原则上不去主动调用
  164.  
    //micro.WrapClient(hystrix2.NewClientHystrixWrapper()),
  165.  
    //添加限流
  166.  
    micro.WrapHandler(ratelimit.NewHandlerWrapper(1000)),
  167.  
    )
  168.  
     
  169.  
    service.Init()
  170.  
     
  171.  
    //只能执行一遍
  172.  
    //err = repository.NewMiddlewareRepository(db).InitTable()
  173.  
    //if err != nil {
  174.  
    // common.Fatal(err)
  175.  
    //}
  176.  
    //if err:= repository.NewMiddleTypeRepository(db).InitTable();err!=nil{
  177.  
    // common.Fatal(err)
  178.  
    //}
  179.  
     
  180.  
    // 注册句柄,可以快速操作已开发的服务
  181.  
    middlewareDataService := service2.NewMiddlewareDataService(repository.NewMiddlewareRepository(db), clientset)
  182.  
    middleTypeDataService := service2.NewMiddleTypeDataService(repository.NewMiddleTypeRepository(db))
  183.  
    middleware.RegisterMiddlewareHandler(service.Server(), &handler.MiddlewareHandler{MiddlewareDataService: middlewareDataService, MiddleTypeDataService: middleTypeDataService})
  184.  
     
  185.  
    // 启动服务
  186.  
    if err := service.Run(); err != nil {
  187.  
    //输出启动失败信息
  188.  
    common.Fatal(err)
  189.  
    }
  190.  
    }

C:\Users\Administrator\Desktop\gopaas\middleware\handler\middlewareHandler.go

  1.  
    package handler
  2.  
     
  3.  
    import (
  4.  
    "context"
  5.  
    "strconv"
  6.  
     
  7.  
    log "github.com/asim/go-micro/v3/logger"
  8.  
    "github.com/yunixiangfeng/gopaas/common"
  9.  
    "github.com/yunixiangfeng/gopaas/middleware/domain/model"
  10.  
    "github.com/yunixiangfeng/gopaas/middleware/domain/service"
  11.  
    middleware "github.com/yunixiangfeng/gopaas/middleware/proto/middleware"
  12.  
    )
  13.  
     
  14.  
    type MiddlewareHandler struct {
  15.  
    //注意这里的类型是 IMiddlewareDataService 接口类型
  16.  
    MiddlewareDataService service.IMiddlewareDataService
  17.  
    // 添加中间件类型服务
  18.  
    MiddleTypeDataService service.IMiddleTypeDataService
  19.  
    }
  20.  
     
  21.  
    func (e *MiddlewareHandler) DeleteMiddleTypeById(context.Context, *middleware.MiddleTypeId, *middleware.Response) error {
  22.  
    panic("implement me")
  23.  
    }
  24.  
     
  25.  
    // Call is a single request handler called via client.Call or the generated client code
  26.  
    func (e *MiddlewareHandler) AddMiddleware(ctx context.Context, info *middleware.MiddlewareInfo, rsp *middleware.Response) error {
  27.  
    log.Info("Received *middleware.AddMiddleware request")
  28.  
    middleModel := &model.Middleware{}
  29.  
    if err := common.SwapTo(info, middleModel); err != nil {
  30.  
    common.Error(err)
  31.  
    rsp.Msg = err.Error()
  32.  
    return err
  33.  
    }
  34.  
    //调用其它的服务处理数据
  35.  
    //根据ID产销需要的镜像地址
  36.  
    imageAddress, err := e.MiddleTypeDataService.FindImageVersionByID(info.MiddleVersionId)
  37.  
    if err != nil {
  38.  
    common.Error(err)
  39.  
    return err
  40.  
    }
  41.  
    //赋值
  42.  
    info.MiddleDockerImageVersion = imageAddress
  43.  
    //在k8s 中创建资源
  44.  
    if err := e.MiddlewareDataService.CreateToK8s(info); err != nil {
  45.  
    common.Error(err)
  46.  
    rsp.Msg = err.Error()
  47.  
    return err
  48.  
    } else {
  49.  
    //插入数据库
  50.  
    middleID, err := e.MiddlewareDataService.AddMiddleware(middleModel)
  51.  
    if err != nil {
  52.  
    common.Error(err)
  53.  
    rsp.Msg = err.Error()
  54.  
    return err
  55.  
    }
  56.  
    rsp.Msg = "中间件添加成功 ID 号为:" strconv.FormatInt(middleID, 10)
  57.  
    common.Info(rsp.Msg)
  58.  
    }
  59.  
    return nil
  60.  
    }
  61.  
     
  62.  
    func (e *MiddlewareHandler) DeleteMiddleware(ctx context.Context, req *middleware.MiddlewareId, rsp *middleware.Response) error {
  63.  
    log.Info("Received *middleware.DeleteMiddleware request")
  64.  
    middleModel, err := e.MiddlewareDataService.FindMiddlewareByID(req.Id)
  65.  
    if err != nil {
  66.  
    common.Error(err)
  67.  
    rsp.Msg = err.Error()
  68.  
    return err
  69.  
    }
  70.  
    //删除k8s中资源
  71.  
    if err := e.MiddlewareDataService.DeleteFromK8s(middleModel); err != nil {
  72.  
    common.Error(err)
  73.  
    rsp.Msg = err.Error()
  74.  
    return err
  75.  
    }
  76.  
    return nil
  77.  
    }
  78.  
     
  79.  
    func (e *MiddlewareHandler) UpdateMiddleware(ctx context.Context, req *middleware.MiddlewareInfo, rsp *middleware.Response) error {
  80.  
    log.Info("Received *middleware.UpdateMiddleware request")
  81.  
    if err := e.MiddlewareDataService.UpdateToK8s(req); err != nil {
  82.  
    common.Error(err)
  83.  
    rsp.Msg = err.Error()
  84.  
    return err
  85.  
    }
  86.  
    //查询中间件相关的信息
  87.  
    middleModle, err := e.MiddlewareDataService.FindMiddlewareByID(req.Id)
  88.  
    if err != nil {
  89.  
    common.Error(err)
  90.  
    rsp.Msg = err.Error()
  91.  
    return err
  92.  
    }
  93.  
    //更新model数据
  94.  
    if err := common.SwapTo(req, middleModle); err != nil {
  95.  
    common.Error(err)
  96.  
    rsp.Msg = err.Error()
  97.  
    return err
  98.  
    }
  99.  
    //更新model
  100.  
    if err := e.MiddlewareDataService.UpdateMiddleware(middleModle); err != nil {
  101.  
    common.Error(err)
  102.  
    rsp.Msg = err.Error()
  103.  
    return err
  104.  
    }
  105.  
    return nil
  106.  
    }
  107.  
     
  108.  
    //查询中间件
  109.  
    func (e *MiddlewareHandler) FindMiddlewareByID(ctx context.Context, req *middleware.MiddlewareId, rsp *middleware.MiddlewareInfo) error {
  110.  
    log.Info("Received *middleware.FindMiddlewareByID request")
  111.  
    //查询中间件
  112.  
    middlewareModel, err := e.MiddlewareDataService.FindMiddlewareByID(req.Id)
  113.  
    if err != nil {
  114.  
    common.Error(err)
  115.  
    return err
  116.  
    }
  117.  
    if err := common.SwapTo(middlewareModel, rsp); err != nil {
  118.  
    common.Error(err)
  119.  
    return err
  120.  
    }
  121.  
    return nil
  122.  
    }
  123.  
     
  124.  
    //查找所有的中间件
  125.  
    func (e *MiddlewareHandler) FindAllMiddleware(ctx context.Context, req *middleware.FindAll, rsp *middleware.AllMiddleware) error {
  126.  
    log.Info("Received *middleware.FindAllMiddleware request")
  127.  
    allMiddleware, err := e.MiddlewareDataService.FindAllMiddleware()
  128.  
    if err != nil {
  129.  
    common.Error(err)
  130.  
    return err
  131.  
    }
  132.  
    //整理格式
  133.  
    for _, v := range allMiddleware {
  134.  
    middleInfo := &middleware.MiddlewareInfo{}
  135.  
    if err := common.SwapTo(v, middleInfo); err != nil {
  136.  
    common.Error(err)
  137.  
    return err
  138.  
    }
  139.  
    rsp.MiddlewareInfo = append(rsp.MiddlewareInfo, middleInfo)
  140.  
    }
  141.  
    return nil
  142.  
    }
  143.  
     
  144.  
    //查找所有的中间件
  145.  
    func (e *MiddlewareHandler) FindAllMiddlewareByTypeID(ctx context.Context, req *middleware.FindAllByTypeId, rsp *middleware.AllMiddleware) error {
  146.  
    log.Info("Received *middleware.FindAllMiddleware request")
  147.  
    allMiddleware, err := e.MiddlewareDataService.FindAllMiddlewareByTypeID(req.TypeId)
  148.  
    if err != nil {
  149.  
    common.Error(err)
  150.  
    return err
  151.  
    }
  152.  
    //整理格式
  153.  
    for _, v := range allMiddleware {
  154.  
    middleInfo := &middleware.MiddlewareInfo{}
  155.  
    if err := common.SwapTo(v, middleInfo); err != nil {
  156.  
    common.Error(err)
  157.  
    return err
  158.  
    }
  159.  
    rsp.MiddlewareInfo = append(rsp.MiddlewareInfo, middleInfo)
  160.  
    }
  161.  
    return nil
  162.  
    }
  163.  
     
  164.  
    //根据ID查找中间件类型信息
  165.  
    func (e *MiddlewareHandler) FindMiddleTypeByID(ctx context.Context, req *middleware.MiddleTypeId, rsp *middleware.MiddleTypeInfo) error {
  166.  
    typeModel, err := e.MiddleTypeDataService.FindMiddleTypeByID(req.Id)
  167.  
    if err != nil {
  168.  
    common.Error(err)
  169.  
    return err
  170.  
    }
  171.  
    if err := common.SwapTo(typeModel, rsp); err != nil {
  172.  
    common.Error(err)
  173.  
    return err
  174.  
    }
  175.  
    return nil
  176.  
    }
  177.  
     
  178.  
    //添加中间件
  179.  
    func (e *MiddlewareHandler) AddMiddleType(ctx context.Context, info *middleware.MiddleTypeInfo, rsp *middleware.Response) error {
  180.  
    typeModel := &model.MiddleType{}
  181.  
    if err := common.SwapTo(info, typeModel); err != nil {
  182.  
    common.Error(err)
  183.  
    rsp.Msg = err.Error()
  184.  
    return err
  185.  
    }
  186.  
    id, err := e.MiddleTypeDataService.AddMiddleType(typeModel)
  187.  
    if err != nil {
  188.  
    common.Error(err)
  189.  
    rsp.Msg = err.Error()
  190.  
    return err
  191.  
    }
  192.  
    rsp.Msg = "中间件类型 ID 号为: " strconv.FormatInt(id, 10)
  193.  
    common.Info(rsp.Msg)
  194.  
    return nil
  195.  
    }
  196.  
     
  197.  
    //删除中间件类型
  198.  
    func (e *MiddlewareHandler) DeleteMiddleTypeByID(ctx context.Context, req *middleware.MiddleTypeId, rsp *middleware.Response) error {
  199.  
    if err := e.MiddleTypeDataService.DeleteMiddleType(req.Id); err != nil {
  200.  
    common.Error(err)
  201.  
    rsp.Msg = err.Error()
  202.  
    return err
  203.  
    }
  204.  
    return nil
  205.  
    }
  206.  
     
  207.  
    //更新中间件类型
  208.  
    func (e *MiddlewareHandler) UpdateMiddleType(ctx context.Context, req *middleware.MiddleTypeInfo, rsp *middleware.Response) error {
  209.  
    typeModel, err := e.MiddleTypeDataService.FindMiddleTypeByID(req.Id)
  210.  
    if err != nil {
  211.  
    common.Error(err)
  212.  
    rsp.Msg = err.Error()
  213.  
    return err
  214.  
    }
  215.  
    if err := common.SwapTo(req, typeModel); err != nil {
  216.  
    common.Error(err)
  217.  
    rsp.Msg = err.Error()
  218.  
    return err
  219.  
    }
  220.  
    if err := e.MiddleTypeDataService.UpdateMiddleType(typeModel); err != nil {
  221.  
    common.Error(err)
  222.  
    rsp.Msg = err.Error()
  223.  
    return err
  224.  
    }
  225.  
    return nil
  226.  
    }
  227.  
     
  228.  
    //查找所有的类型
  229.  
    func (e *MiddlewareHandler) FindAllMiddleType(ctx context.Context, req *middleware.FindAll, rsp *middleware.AllMiddleType) error {
  230.  
    //查询所有中间件
  231.  
    allMiddleType, err := e.MiddleTypeDataService.FindAllMiddleType()
  232.  
    if err != nil {
  233.  
    common.Error(err)
  234.  
    return err
  235.  
    }
  236.  
    //整理格式
  237.  
    for _, v := range allMiddleType {
  238.  
    middleInfo := &middleware.MiddleTypeInfo{}
  239.  
    if err := common.SwapTo(v, middleInfo); err != nil {
  240.  
    common.Error(err)
  241.  
    return err
  242.  
    }
  243.  
    rsp.MiddleTypeInfo = append(rsp.MiddleTypeInfo, middleInfo)
  244.  
    }
  245.  
    return nil
  246.  
    }

make proto 

10-17 中间件前端页面以及核心API开发(上)

  1.  
    PS C:\Users\Administrator\Desktop\gopaas> .\yu-tool\yu-tool.exe newService github.com/yunixiangfeng/gopaas/middlewareApi
  2.  
     
  3.  
    make proto
  4.  
     
  5.  
    go mod tidy

C:\Users\Administrator\Desktop\gopaas\middlewareapi\proto\middlewareApi\middlewareApi.proto

  1.  
    syntax = "proto3";
  2.  
     
  3.  
    package middlewareApi;
  4.  
     
  5.  
    option go_package = "./proto/middlewareApi;middlewareApi";
  6.  
     
  7.  
    service MiddlewareApi {
  8.  
    rpc FindMiddlewareById(Request) returns (Response){}
  9.  
    rpc AddMiddleware(Request) returns (Response){}
  10.  
    rpc DeleteMiddlewareById(Request) returns (Response){}
  11.  
    rpc UpdateMiddleware(Request) returns (Response){}
  12.  
    //默认接口
  13.  
    rpc Call(Request) returns (Response){}
  14.  
    //根据类型获取所有中间件
  15.  
    rpc FindAllMiddlewareByTypeId(Request) returns (Response){}
  16.  
    //中间件类型对外开发的API
  17.  
    rpc FindMiddleTypeById(Request) returns (Response){}
  18.  
    rpc AddMiddleType(Request) returns (Response){}
  19.  
    rpc DeleteMiddleTypeById(Request) returns (Response){}
  20.  
    rpc UpdateMiddleType(Request) returns (Response){}
  21.  
    rpc FindAllMiddleType(Request) returns (Response){}
  22.  
    }
  23.  
     
  24.  
    message Pair {
  25.  
    string key = 1;
  26.  
    repeated string values = 2;
  27.  
    }
  28.  
     
  29.  
     
  30.  
    message Request {
  31.  
    string method = 1;
  32.  
    string path = 2;
  33.  
    map<string, Pair> header = 3;
  34.  
    map<string, Pair> get = 4;
  35.  
    map<string, Pair> post = 5;
  36.  
    string body = 6;
  37.  
    string url = 7;
  38.  
    }
  39.  
     
  40.  
     
  41.  
    message Response {
  42.  
    int32 statusCode = 1;
  43.  
    map<string, Pair> header = 2;
  44.  
    string body = 3;
  45.  
    }
  46.  
     

 make proto

C:\Users\Administrator\Desktop\gopaas\middlewareapi\proto\middlewareApi\middlewareApi.pb.micro.go

  1.  
    // Code generated by protoc-gen-micro. DO NOT EDIT.
  2.  
    // source: proto/middlewareApi/middlewareApi.proto
  3.  
     
  4.  
    package middlewareApi
  5.  
     
  6.  
    import (
  7.  
    fmt "fmt"
  8.  
    proto "谷歌.golang.org/protobuf/proto"
  9.  
    math "math"
  10.  
    )
  11.  
     
  12.  
    import (
  13.  
    context "context"
  14.  
    api "github.com/asim/go-micro/v3/api"
  15.  
    client "github.com/asim/go-micro/v3/client"
  16.  
    server "github.com/asim/go-micro/v3/server"
  17.  
    )
  18.  
     
  19.  
    // Reference imports to suppress errors if they are not otherwise used.
  20.  
    var _ = proto.Marshal
  21.  
    var _ = fmt.Errorf
  22.  
    var _ = math.Inf
  23.  
     
  24.  
    // Reference imports to suppress errors if they are not otherwise used.
  25.  
    var _ api.Endpoint
  26.  
    var _ context.Context
  27.  
    var _ client.Option
  28.  
    var _ server.Option
  29.  
     
  30.  
    // Api Endpoints for MiddlewareApi service
  31.  
     
  32.  
    func NewMiddlewareApiEndpoints() []*api.Endpoint {
  33.  
    return []*api.Endpoint{}
  34.  
    }
  35.  
     
  36.  
    // Client API for MiddlewareApi service
  37.  
     
  38.  
    type MiddlewareApiService interface {
  39.  
    FindMiddlewareById(ctx context.Context, in *Request, opts ...client.CallOption) (*Response, error)
  40.  
    AddMiddleware(ctx context.Context, in *Request, opts ...client.CallOption) (*Response, error)
  41.  
    DeleteMiddlewareById(ctx context.Context, in *Request, opts ...client.CallOption) (*Response, error)
  42.  
    UpdateMiddleware(ctx context.Context, in *Request, opts ...client.CallOption) (*Response, error)
  43.  
    //默认接口
  44.  
    Call(ctx context.Context, in *Request, opts ...client.CallOption) (*Response, error)
  45.  
    //根据类型获取所有中间件
  46.  
    FindAllMiddlewareByTypeId(ctx context.Context, in *Request, opts ...client.CallOption) (*Response, error)
  47.  
    //中间件类型对外开发的API
  48.  
    FindMiddleTypeById(ctx context.Context, in *Request, opts ...client.CallOption) (*Response, error)
  49.  
    AddMiddleType(ctx context.Context, in *Request, opts ...client.CallOption) (*Response, error)
  50.  
    DeleteMiddleTypeById(ctx context.Context, in *Request, opts ...client.CallOption) (*Response, error)
  51.  
    UpdateMiddleType(ctx context.Context, in *Request, opts ...client.CallOption) (*Response, error)
  52.  
    FindAllMiddleType(ctx context.Context, in *Request, opts ...client.CallOption) (*Response, error)
  53.  
    }
  54.  
     
  55.  
    type middlewareApiService struct {
  56.  
    c client.Client
  57.  
    name string
  58.  
    }
  59.  
     
  60.  
    func NewMiddlewareApiService(name string, c client.Client) MiddlewareApiService {
  61.  
    return &middlewareApiService{
  62.  
    c: c,
  63.  
    name: name,
  64.  
    }
  65.  
    }
  66.  
     
  67.  
    func (c *middlewareApiService) FindMiddlewareById(ctx context.Context, in *Request, opts ...client.CallOption) (*Response, error) {
  68.  
    req := c.c.NewRequest(c.name, "MiddlewareApi.FindMiddlewareById", in)
  69.  
    out := new(Response)
  70.  
    err := c.c.Call(ctx, req, out, opts...)
  71.  
    if err != nil {
  72.  
    return nil, err
  73.  
    }
  74.  
    return out, nil
  75.  
    }
  76.  
     
  77.  
    func (c *middlewareApiService) AddMiddleware(ctx context.Context, in *Request, opts ...client.CallOption) (*Response, error) {
  78.  
    req := c.c.NewRequest(c.name, "MiddlewareApi.AddMiddleware", in)
  79.  
    out := new(Response)
  80.  
    err := c.c.Call(ctx, req, out, opts...)
  81.  
    if err != nil {
  82.  
    return nil, err
  83.  
    }
  84.  
    return out, nil
  85.  
    }
  86.  
     
  87.  
    func (c *middlewareApiService) DeleteMiddlewareById(ctx context.Context, in *Request, opts ...client.CallOption) (*Response, error) {
  88.  
    req := c.c.NewRequest(c.name, "MiddlewareApi.DeleteMiddlewareById", in)
  89.  
    out := new(Response)
  90.  
    err := c.c.Call(ctx, req, out, opts...)
  91.  
    if err != nil {
  92.  
    return nil, err
  93.  
    }
  94.  
    return out, nil
  95.  
    }
  96.  
     
  97.  
    func (c *middlewareApiService) UpdateMiddleware(ctx context.Context, in *Request, opts ...client.CallOption) (*Response, error) {
  98.  
    req := c.c.NewRequest(c.name, "MiddlewareApi.UpdateMiddleware", in)
  99.  
    out := new(Response)
  100.  
    err := c.c.Call(ctx, req, out, opts...)
  101.  
    if err != nil {
  102.  
    return nil, err
  103.  
    }
  104.  
    return out, nil
  105.  
    }
  106.  
     
  107.  
    func (c *middlewareApiService) Call(ctx context.Context, in *Request, opts ...client.CallOption) (*Response, error) {
  108.  
    req := c.c.NewRequest(c.name, "MiddlewareApi.Call", in)
  109.  
    out := new(Response)
  110.  
    err := c.c.Call(ctx, req, out, opts...)
  111.  
    if err != nil {
  112.  
    return nil, err
  113.  
    }
  114.  
    return out, nil
  115.  
    }
  116.  
     
  117.  
    func (c *middlewareApiService) FindAllMiddlewareByTypeId(ctx context.Context, in *Request, opts ...client.CallOption) (*Response, error) {
  118.  
    req := c.c.NewRequest(c.name, "MiddlewareApi.FindAllMiddlewareByTypeId", in)
  119.  
    out := new(Response)
  120.  
    err := c.c.Call(ctx, req, out, opts...)
  121.  
    if err != nil {
  122.  
    return nil, err
  123.  
    }
  124.  
    return out, nil
  125.  
    }
  126.  
     
  127.  
    func (c *middlewareApiService) FindMiddleTypeById(ctx context.Context, in *Request, opts ...client.CallOption) (*Response, error) {
  128.  
    req := c.c.NewRequest(c.name, "MiddlewareApi.FindMiddleTypeById", in)
  129.  
    out := new(Response)
  130.  
    err := c.c.Call(ctx, req, out, opts...)
  131.  
    if err != nil {
  132.  
    return nil, err
  133.  
    }
  134.  
    return out, nil
  135.  
    }
  136.  
     
  137.  
    func (c *middlewareApiService) AddMiddleType(ctx context.Context, in *Request, opts ...client.CallOption) (*Response, error) {
  138.  
    req := c.c.NewRequest(c.name, "MiddlewareApi.AddMiddleType", in)
  139.  
    out := new(Response)
  140.  
    err := c.c.Call(ctx, req, out, opts...)
  141.  
    if err != nil {
  142.  
    return nil, err
  143.  
    }
  144.  
    return out, nil
  145.  
    }
  146.  
     
  147.  
    func (c *middlewareApiService) DeleteMiddleTypeById(ctx context.Context, in *Request, opts ...client.CallOption) (*Response, error) {
  148.  
    req := c.c.NewRequest(c.name, "MiddlewareApi.DeleteMiddleTypeById", in)
  149.  
    out := new(Response)
  150.  
    err := c.c.Call(ctx, req, out, opts...)
  151.  
    if err != nil {
  152.  
    return nil, err
  153.  
    }
  154.  
    return out, nil
  155.  
    }
  156.  
     
  157.  
    func (c *middlewareApiService) UpdateMiddleType(ctx context.Context, in *Request, opts ...client.CallOption) (*Response, error) {
  158.  
    req := c.c.NewRequest(c.name, "MiddlewareApi.UpdateMiddleType", in)
  159.  
    out := new(Response)
  160.  
    err := c.c.Call(ctx, req, out, opts...)
  161.  
    if err != nil {
  162.  
    return nil, err
  163.  
    }
  164.  
    return out, nil
  165.  
    }
  166.  
     
  167.  
    func (c *middlewareApiService) FindAllMiddleType(ctx context.Context, in *Request, opts ...client.CallOption) (*Response, error) {
  168.  
    req := c.c.NewRequest(c.name, "MiddlewareApi.FindAllMiddleType", in)
  169.  
    out := new(Response)
  170.  
    err := c.c.Call(ctx, req, out, opts...)
  171.  
    if err != nil {
  172.  
    return nil, err
  173.  
    }
  174.  
    return out, nil
  175.  
    }
  176.  
     
  177.  
    // Server API for MiddlewareApi service
  178.  
     
  179.  
    type MiddlewareApiHandler interface {
  180.  
    FindMiddlewareById(context.Context, *Request, *Response) error
  181.  
    AddMiddleware(context.Context, *Request, *Response) error
  182.  
    DeleteMiddlewareById(context.Context, *Request, *Response) error
  183.  
    UpdateMiddleware(context.Context, *Request, *Response) error
  184.  
    //默认接口
  185.  
    Call(context.Context, *Request, *Response) error
  186.  
    //根据类型获取所有中间件
  187.  
    FindAllMiddlewareByTypeId(context.Context, *Request, *Response) error
  188.  
    //中间件类型对外开发的API
  189.  
    FindMiddleTypeById(context.Context, *Request, *Response) error
  190.  
    AddMiddleType(context.Context, *Request, *Response) error
  191.  
    DeleteMiddleTypeById(context.Context, *Request, *Response) error
  192.  
    UpdateMiddleType(context.Context, *Request, *Response) error
  193.  
    FindAllMiddleType(context.Context, *Request, *Response) error
  194.  
    }
  195.  
     
  196.  
    func RegisterMiddlewareApiHandler(s server.Server, hdlr MiddlewareApiHandler, opts ...server.HandlerOption) error {
  197.  
    type middlewareApi interface {
  198.  
    FindMiddlewareById(ctx context.Context, in *Request, out *Response) error
  199.  
    AddMiddleware(ctx context.Context, in *Request, out *Response) error
  200.  
    DeleteMiddlewareById(ctx context.Context, in *Request, out *Response) error
  201.  
    UpdateMiddleware(ctx context.Context, in *Request, out *Response) error
  202.  
    Call(ctx context.Context, in *Request, out *Response) error
  203.  
    FindAllMiddlewareByTypeId(ctx context.Context, in *Request, out *Response) error
  204.  
    FindMiddleTypeById(ctx context.Context, in *Request, out *Response) error
  205.  
    AddMiddleType(ctx context.Context, in *Request, out *Response) error
  206.  
    DeleteMiddleTypeById(ctx context.Context, in *Request, out *Response) error
  207.  
    UpdateMiddleType(ctx context.Context, in *Request, out *Response) error
  208.  
    FindAllMiddleType(ctx context.Context, in *Request, out *Response) error
  209.  
    }
  210.  
    type MiddlewareApi struct {
  211.  
    middlewareApi
  212.  
    }
  213.  
    h := &middlewareApiHandler{hdlr}
  214.  
    return s.Handle(s.NewHandler(&MiddlewareApi{h}, opts...))
  215.  
    }
  216.  
     
  217.  
    type middlewareApiHandler struct {
  218.  
    MiddlewareApiHandler
  219.  
    }
  220.  
     
  221.  
    func (h *middlewareApiHandler) FindMiddlewareById(ctx context.Context, in *Request, out *Response) error {
  222.  
    return h.MiddlewareApiHandler.FindMiddlewareById(ctx, in, out)
  223.  
    }
  224.  
     
  225.  
    func (h *middlewareApiHandler) AddMiddleware(ctx context.Context, in *Request, out *Response) error {
  226.  
    return h.MiddlewareApiHandler.AddMiddleware(ctx, in, out)
  227.  
    }
  228.  
     
  229.  
    func (h *middlewareApiHandler) DeleteMiddlewareById(ctx context.Context, in *Request, out *Response) error {
  230.  
    return h.MiddlewareApiHandler.DeleteMiddlewareById(ctx, in, out)
  231.  
    }
  232.  
     
  233.  
    func (h *middlewareApiHandler) UpdateMiddleware(ctx context.Context, in *Request, out *Response) error {
  234.  
    return h.MiddlewareApiHandler.UpdateMiddleware(ctx, in, out)
  235.  
    }
  236.  
     
  237.  
    func (h *middlewareApiHandler) Call(ctx context.Context, in *Request, out *Response) error {
  238.  
    return h.MiddlewareApiHandler.Call(ctx, in, out)
  239.  
    }
  240.  
     
  241.  
    func (h *middlewareApiHandler) FindAllMiddlewareByTypeId(ctx context.Context, in *Request, out *Response) error {
  242.  
    return h.MiddlewareApiHandler.FindAllMiddlewareByTypeId(ctx, in, out)
  243.  
    }
  244.  
     
  245.  
    func (h *middlewareApiHandler) FindMiddleTypeById(ctx context.Context, in *Request, out *Response) error {
  246.  
    return h.MiddlewareApiHandler.FindMiddleTypeById(ctx, in, out)
  247.  
    }
  248.  
     
  249.  
    func (h *middlewareApiHandler) AddMiddleType(ctx context.Context, in *Request, out *Response) error {
  250.  
    return h.MiddlewareApiHandler.AddMiddleType(ctx, in, out)
  251.  
    }
  252.  
     
  253.  
    func (h *middlewareApiHandler) DeleteMiddleTypeById(ctx context.Context, in *Request, out *Response) error {
  254.  
    return h.MiddlewareApiHandler.DeleteMiddleTypeById(ctx, in, out)
  255.  
    }
  256.  
     
  257.  
    func (h *middlewareApiHandler) UpdateMiddleType(ctx context.Context, in *Request, out *Response) error {
  258.  
    return h.MiddlewareApiHandler.UpdateMiddleType(ctx, in, out)
  259.  
    }
  260.  
     
  261.  
    func (h *middlewareApiHandler) FindAllMiddleType(ctx context.Context, in *Request, out *Response) error {
  262.  
    return h.MiddlewareApiHandler.FindAllMiddleType(ctx, in, out)
  263.  
    }

C:\Users\Administrator\Desktop\gopaas\middlewareapi\proto\middlewareApi\middlewareApi.pb.go

  1.  
    // Code generated by protoc-gen-go. DO NOT EDIT.
  2.  
    // versions:
  3.  
    // protoc-gen-go v1.27.1
  4.  
    // protoc v3.15.7
  5.  
    // source: proto/middlewareApi/middlewareApi.proto
  6.  
     
  7.  
    package middlewareApi
  8.  
     
  9.  
    import (
  10.  
    protoreflect "谷歌.golang.org/protobuf/reflect/protoreflect"
  11.  
    protoimpl "谷歌.golang.org/protobuf/runtime/protoimpl"
  12.  
    reflect "reflect"
  13.  
    sync "sync"
  14.  
    )
  15.  
     
  16.  
    const (
  17.  
    // Verify that this generated code is sufficiently up-to-date.
  18.  
    _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
  19.  
    // Verify that runtime/protoimpl is sufficiently up-to-date.
  20.  
    _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
  21.  
    )
  22.  
     
  23.  
    type Pair struct {
  24.  
    state protoimpl.MessageState
  25.  
    sizeCache protoimpl.SizeCache
  26.  
    unknownFields protoimpl.UnknownFields
  27.  
     
  28.  
    Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"`
  29.  
    Values []string `protobuf:"bytes,2,rep,name=values,proto3" json:"values,omitempty"`
  30.  
    }
  31.  
     
  32.  
    func (x *Pair) Reset() {
  33.  
    *x = Pair{}
  34.  
    if protoimpl.UnsafeEnabled {
  35.  
    mi := &file_proto_middlewareApi_middlewareApi_proto_msgTypes[0]
  36.  
    ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
  37.  
    ms.StoreMessageInfo(mi)
  38.  
    }
  39.  
    }
  40.  
     
  41.  
    func (x *Pair) String() string {
  42.  
    return protoimpl.X.MessageStringOf(x)
  43.  
    }
  44.  
     
  45.  
    func (*Pair) ProtoMessage() {}
  46.  
     
  47.  
    func (x *Pair) ProtoReflect() protoreflect.Message {
  48.  
    mi := &file_proto_middlewareApi_middlewareApi_proto_msgTypes[0]
  49.  
    if protoimpl.UnsafeEnabled && x != nil {
  50.  
    ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
  51.  
    if ms.LoadMessageInfo() == nil {
  52.  
    ms.StoreMessageInfo(mi)
  53.  
    }
  54.  
    return ms
  55.  
    }
  56.  
    return mi.MessageOf(x)
  57.  
    }
  58.  
     
  59.  
    // Deprecated: Use Pair.ProtoReflect.Descriptor instead.
  60.  
    func (*Pair) Descriptor() ([]byte, []int) {
  61.  
    return file_proto_middlewareApi_middlewareApi_proto_rawDescGZIP(), []int{0}
  62.  
    }
  63.  
     
  64.  
    func (x *Pair) GetKey() string {
  65.  
    if x != nil {
  66.  
    return x.Key
  67.  
    }
  68.  
    return ""
  69.  
    }
  70.  
     
  71.  
    func (x *Pair) GetValues() []string {
  72.  
    if x != nil {
  73.  
    return x.Values
  74.  
    }
  75.  
    return nil
  76.  
    }
  77.  
     
  78.  
    type Request struct {
  79.  
    state protoimpl.MessageState
  80.  
    sizeCache protoimpl.SizeCache
  81.  
    unknownFields protoimpl.UnknownFields
  82.  
     
  83.  
    Method string `protobuf:"bytes,1,opt,name=method,proto3" json:"method,omitempty"`
  84.  
    Path string `protobuf:"bytes,2,opt,name=path,proto3" json:"path,omitempty"`
  85.  
    Header map[string]*Pair `protobuf:"bytes,3,rep,name=header,proto3" json:"header,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
  86.  
    Get map[string]*Pair `protobuf:"bytes,4,rep,name=get,proto3" json:"get,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
  87.  
    Post map[string]*Pair `protobuf:"bytes,5,rep,name=post,proto3" json:"post,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
  88.  
    Body string `protobuf:"bytes,6,opt,name=body,proto3" json:"body,omitempty"`
  89.  
    Url string `protobuf:"bytes,7,opt,name=url,proto3" json:"url,omitempty"`
  90.  
    }
  91.  
     
  92.  
    func (x *Request) Reset() {
  93.  
    *x = Request{}
  94.  
    if protoimpl.UnsafeEnabled {
  95.  
    mi := &file_proto_middlewareApi_middlewareApi_proto_msgTypes[1]
  96.  
    ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
  97.  
    ms.StoreMessageInfo(mi)
  98.  
    }
  99.  
    }
  100.  
     
  101.  
    func (x *Request) String() string {
  102.  
    return protoimpl.X.MessageStringOf(x)
  103.  
    }
  104.  
     
  105.  
    func (*Request) ProtoMessage() {}
  106.  
     
  107.  
    func (x *Request) ProtoReflect() protoreflect.Message {
  108.  
    mi := &file_proto_middlewareApi_middlewareApi_proto_msgTypes[1]
  109.  
    if protoimpl.UnsafeEnabled && x != nil {
  110.  
    ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
  111.  
    if ms.LoadMessageInfo() == nil {
  112.  
    ms.StoreMessageInfo(mi)
  113.  
    }
  114.  
    return ms
  115.  
    }
  116.  
    return mi.MessageOf(x)
  117.  
    }
  118.  
     
  119.  
    // Deprecated: Use Request.ProtoReflect.Descriptor instead.
  120.  
    func (*Request) Descriptor() ([]byte, []int) {
  121.  
    return file_proto_middlewareApi_middlewareApi_proto_rawDescGZIP(), []int{1}
  122.  
    }
  123.  
     
  124.  
    func (x *Request) GetMethod() string {
  125.  
    if x != nil {
  126.  
    return x.Method
  127.  
    }
  128.  
    return ""
  129.  
    }
  130.  
     
  131.  
    func (x *Request) GetPath() string {
  132.  
    if x != nil {
  133.  
    return x.Path
  134.  
    }
  135.  
    return ""
  136.  
    }
  137.  
     
  138.  
    func (x *Request) GetHeader() map[string]*Pair {
  139.  
    if x != nil {
  140.  
    return x.Header
  141.  
    }
  142.  
    return nil
  143.  
    }
  144.  
     
  145.  
    func (x *Request) GetGet() map[string]*Pair {
  146.  
    if x != nil {
  147.  
    return x.Get
  148.  
    }
  149.  
    return nil
  150.  
    }
  151.  
     
  152.  
    func (x *Request) GetPost() map[string]*Pair {
  153.  
    if x != nil {
  154.  
    return x.Post
  155.  
    }
  156.  
    return nil
  157.  
    }
  158.  
     
  159.  
    func (x *Request) GetBody() string {
  160.  
    if x != nil {
  161.  
    return x.Body
  162.  
    }
  163.  
    return ""
  164.  
    }
  165.  
     
  166.  
    func (x *Request) GetUrl() string {
  167.  
    if x != nil {
  168.  
    return x.Url
  169.  
    }
  170.  
    return ""
  171.  
    }
  172.  
     
  173.  
    type Response struct {
  174.  
    state protoimpl.MessageState
  175.  
    sizeCache protoimpl.SizeCache
  176.  
    unknownFields protoimpl.UnknownFields
  177.  
     
  178.  
    StatusCode int32 `protobuf:"varint,1,opt,name=statusCode,proto3" json:"statusCode,omitempty"`
  179.  
    Header map[string]*Pair `protobuf:"bytes,2,rep,name=header,proto3" json:"header,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
  180.  
    Body string `protobuf:"bytes,3,opt,name=body,proto3" json:"body,omitempty"`
  181.  
    }
  182.  
     
  183.  
    func (x *Response) Reset() {
  184.  
    *x = Response{}
  185.  
    if protoimpl.UnsafeEnabled {
  186.  
    mi := &file_proto_middlewareApi_middlewareApi_proto_msgTypes[2]
  187.  
    ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
  188.  
    ms.StoreMessageInfo(mi)
  189.  
    }
  190.  
    }
  191.  
     
  192.  
    func (x *Response) String() string {
  193.  
    return protoimpl.X.MessageStringOf(x)
  194.  
    }
  195.  
     
  196.  
    func (*Response) ProtoMessage() {}
  197.  
     
  198.  
    func (x *Response) ProtoReflect() protoreflect.Message {
  199.  
    mi := &file_proto_middlewareApi_middlewareApi_proto_msgTypes[2]
  200.  
    if protoimpl.UnsafeEnabled && x != nil {
  201.  
    ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
  202.  
    if ms.LoadMessageInfo() == nil {
  203.  
    ms.StoreMessageInfo(mi)
  204.  
    }
  205.  
    return ms
  206.  
    }
  207.  
    return mi.MessageOf(x)
  208.  
    }
  209.  
     
  210.  
    // Deprecated: Use Response.ProtoReflect.Descriptor instead.
  211.  
    func (*Response) Descriptor() ([]byte, []int) {
  212.  
    return file_proto_middlewareApi_middlewareApi_proto_rawDescGZIP(), []int{2}
  213.  
    }
  214.  
     
  215.  
    func (x *Response) GetStatusCode() int32 {
  216.  
    if x != nil {
  217.  
    return x.StatusCode
  218.  
    }
  219.  
    return 0
  220.  
    }
  221.  
     
  222.  
    func (x *Response) GetHeader() map[string]*Pair {
  223.  
    if x != nil {
  224.  
    return x.Header
  225.  
    }
  226.  
    return nil
  227.  
    }
  228.  
     
  229.  
    func (x *Response) GetBody() string {
  230.  
    if x != nil {
  231.  
    return x.Body
  232.  
    }
  233.  
    return ""
  234.  
    }
  235.  
     
  236.  
    var File_proto_middlewareApi_middlewareApi_proto protoreflect.FileDescriptor
  237.  
     
  238.  
    var file_proto_middlewareApi_middlewareApi_proto_rawDesc = []byte{
  239.  
    0x0a, 0x27, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x77, 0x61,
  240.  
    0x72, 0x65, 0x41, 0x70, 0x69, 0x2f, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x77, 0x61, 0x72, 0x65,
  241.  
    0x41, 0x70, 0x69, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0d, 0x6d, 0x69, 0x64, 0x64, 0x6c,
  242.  
    0x65, 0x77, 0x61, 0x72, 0x65, 0x41, 0x70, 0x69, 0x22, 0x30, 0x0a, 0x04, 0x50, 0x61, 0x69, 0x72,
  243.  
    0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b,
  244.  
    0x65, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03,
  245.  
    0x28, 0x09, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x22, 0xeb, 0x03, 0x0a, 0x07, 0x52,
  246.  
    0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64,
  247.  
    0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x12,
  248.  
    0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61,
  249.  
    0x74, 0x68, 0x12, 0x3a, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x03, 0x20, 0x03,
  250.  
    0x28, 0x0b, 0x32, 0x22, 0x2e, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x77, 0x61, 0x72, 0x65, 0x41,
  251.  
    0x70, 0x69, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65,
  252.  
    0x72, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x31,
  253.  
    0x0a, 0x03, 0x67, 0x65, 0x74, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x69,
  254.  
    0x64, 0x64, 0x6c, 0x65, 0x77, 0x61, 0x72, 0x65, 0x41, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x71, 0x75,
  255.  
    0x65, 0x73, 0x74, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x03, 0x67, 0x65,
  256.  
    0x74, 0x12, 0x34, 0x0a, 0x04, 0x70, 0x6f, 0x73, 0x74, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32,
  257.  
    0x20, 0x2e, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x77, 0x61, 0x72, 0x65, 0x41, 0x70, 0x69, 0x2e,
  258.  
    0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x50, 0x6f, 0x73, 0x74, 0x45, 0x6e, 0x74, 0x72,
  259.  
    0x79, 0x52, 0x04, 0x70, 0x6f, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18,
  260.  
    0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x75,
  261.  
    0x72, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x1a, 0x4e, 0x0a,
  262.  
    0x0b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03,
  263.  
    0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x29,
  264.  
    0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e,
  265.  
    0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x77, 0x61, 0x72, 0x65, 0x41, 0x70, 0x69, 0x2e, 0x50, 0x61,
  266.  
    0x69, 0x72, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x4b, 0x0a,
  267.  
    0x08, 0x47, 0x65, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79,
  268.  
    0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x29, 0x0a, 0x05, 0x76,
  269.  
    0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x6d, 0x69, 0x64,
  270.  
    0x64, 0x6c, 0x65, 0x77, 0x61, 0x72, 0x65, 0x41, 0x70, 0x69, 0x2e, 0x50, 0x61, 0x69, 0x72, 0x52,
  271.  
    0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x4c, 0x0a, 0x09, 0x50, 0x6f,
  272.  
    0x73, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01,
  273.  
    0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x29, 0x0a, 0x05, 0x76, 0x61, 0x6c,
  274.  
    0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x6d, 0x69, 0x64, 0x64, 0x6c,
  275.  
    0x65, 0x77, 0x61, 0x72, 0x65, 0x41, 0x70, 0x69, 0x2e, 0x50, 0x61, 0x69, 0x72, 0x52, 0x05, 0x76,
  276.  
    0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xcb, 0x01, 0x0a, 0x08, 0x52, 0x65, 0x73,
  277.  
    0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x43,
  278.  
    0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x75,
  279.  
    0x73, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x3b, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18,
  280.  
    0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x77, 0x61,
  281.  
    0x72, 0x65, 0x41, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x48,
  282.  
    0x65, 0x61, 0x64, 0x65, 0x72, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64,
  283.  
    0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09,
  284.  
    0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x1a, 0x4e, 0x0a, 0x0b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72,
  285.  
    0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01,
  286.  
    0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x29, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
  287.  
    0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x77,
  288.  
    0x61, 0x72, 0x65, 0x41, 0x70, 0x69, 0x2e, 0x50, 0x61, 0x69, 0x72, 0x52, 0x05, 0x76, 0x61, 0x6c,
  289.  
    0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x32, 0xa0, 0x06, 0x0a, 0x0d, 0x4d, 0x69, 0x64, 0x64, 0x6c,
  290.  
    0x65, 0x77, 0x61, 0x72, 0x65, 0x41, 0x70, 0x69, 0x12, 0x47, 0x0a, 0x12, 0x46, 0x69, 0x6e, 0x64,
  291.  
    0x4d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x77, 0x61, 0x72, 0x65, 0x42, 0x79, 0x49, 0x64, 0x12, 0x16,
  292.  
    0x2e, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x77, 0x61, 0x72, 0x65, 0x41, 0x70, 0x69, 0x2e, 0x52,
  293.  
    0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x77,
  294.  
    0x61, 0x72, 0x65, 0x41, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
  295.  
    0x00, 0x12, 0x42, 0x0a, 0x0d, 0x41, 0x64, 0x64, 0x4d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x77, 0x61,
  296.  
    0x72, 0x65, 0x12, 0x16, 0x2e, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x77, 0x61, 0x72, 0x65, 0x41,
  297.  
    0x70, 0x69, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x6d, 0x69, 0x64,
  298.  
    0x64, 0x6c, 0x65, 0x77, 0x61, 0x72, 0x65, 0x41, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f,
  299.  
    0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x49, 0x0a, 0x14, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4d,
  300.  
    0x69, 0x64, 0x64, 0x6c, 0x65, 0x77, 0x61, 0x72, 0x65, 0x42, 0x79, 0x49, 0x64, 0x12, 0x16, 0x2e,
  301.  
    0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x77, 0x61, 0x72, 0x65, 0x41, 0x70, 0x69, 0x2e, 0x52, 0x65,
  302.  
    0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x77, 0x61,
  303.  
    0x72, 0x65, 0x41, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00,
  304.  
    0x12, 0x45, 0x0a, 0x10, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x69, 0x64, 0x64, 0x6c, 0x65,
  305.  
    0x77, 0x61, 0x72, 0x65, 0x12, 0x16, 0x2e, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x77, 0x61, 0x72,
  306.  
    0x65, 0x41, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x6d,
  307.  
    0x69, 0x64, 0x64, 0x6c, 0x65, 0x77, 0x61, 0x72, 0x65, 0x41, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x73,
  308.  
    0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x39, 0x0a, 0x04, 0x43, 0x61, 0x6c, 0x6c, 0x12,
  309.  
    0x16, 0x2e, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x77, 0x61, 0x72, 0x65, 0x41, 0x70, 0x69, 0x2e,
  310.  
    0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65,
  311.  
    0x77, 0x61, 0x72, 0x65, 0x41, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
  312.  
    0x22, 0x00, 0x12, 0x4e, 0x0a, 0x19, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x4d, 0x69, 0x64,
  313.  
    0x64, 0x6c, 0x65, 0x77, 0x61, 0x72, 0x65, 0x42, 0x79, 0x54, 0x79, 0x70, 0x65, 0x49, 0x64, 0x12,
  314.  
    0x16, 0x2e, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x77, 0x61, 0x72, 0x65, 0x41, 0x70, 0x69, 0x2e,
  315.  
    0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65,
  316.  
    0x77, 0x61, 0x72, 0x65, 0x41, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
  317.  
    0x22, 0x00, 0x12, 0x47, 0x0a, 0x12, 0x46, 0x69, 0x6e, 0x64, 0x4d, 0x69, 0x64, 0x64, 0x6c, 0x65,
  318.  
    0x54, 0x79, 0x70, 0x65, 0x42, 0x79, 0x49, 0x64, 0x12, 0x16, 0x2e, 0x6d, 0x69, 0x64, 0x64, 0x6c,
  319.  
    0x65, 0x77, 0x61, 0x72, 0x65, 0x41, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
  320.  
    0x1a, 0x17, 0x2e, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x77, 0x61, 0x72, 0x65, 0x41, 0x70, 0x69,
  321.  
    0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x42, 0x0a, 0x0d, 0x41,
  322.  
    0x64, 0x64, 0x4d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x2e, 0x6d,
  323.  
    0x69, 0x64, 0x64, 0x6c, 0x65, 0x77, 0x61, 0x72, 0x65, 0x41, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x71,
  324.  
    0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x77, 0x61, 0x72,
  325.  
    0x65, 0x41, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12,
  326.  
    0x49, 0x0a, 0x14, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x54,
  327.  
    0x79, 0x70, 0x65, 0x42, 0x79, 0x49, 0x64, 0x12, 0x16, 0x2e, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65,
  328.  
    0x77, 0x61, 0x72, 0x65, 0x41, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
  329.  
    0x17, 0x2e, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x77, 0x61, 0x72, 0x65, 0x41, 0x70, 0x69, 0x2e,
  330.  
    0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x45, 0x0a, 0x10, 0x55, 0x70,
  331.  
    0x64, 0x61, 0x74, 0x65, 0x4d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16,
  332.  
    0x2e, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x77, 0x61, 0x72, 0x65, 0x41, 0x70, 0x69, 0x2e, 0x52,
  333.  
    0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x77,
  334.  
    0x61, 0x72, 0x65, 0x41, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
  335.  
    0x00, 0x12, 0x46, 0x0a, 0x11, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x4d, 0x69, 0x64, 0x64,
  336.  
    0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x2e, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x77,
  337.  
    0x61, 0x72, 0x65, 0x41, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17,
  338.  
    0x2e, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x77, 0x61, 0x72, 0x65, 0x41, 0x70, 0x69, 0x2e, 0x52,
  339.  
    0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x25, 0x5a, 0x23, 0x2e, 0x2f, 0x70,
  340.  
    0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x77, 0x61, 0x72, 0x65, 0x41,
  341.  
    0x70, 0x69, 0x3b, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x77, 0x61, 0x72, 0x65, 0x41, 0x70, 0x69,
  342.  
    0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
  343.  
    }
  344.  
     
  345.  
    var (
  346.  
    file_proto_middlewareApi_middlewareApi_proto_rawDescOnce sync.Once
  347.  
    file_proto_middlewareApi_middlewareApi_proto_rawDescData = file_proto_middlewareApi_middlewareApi_proto_rawDesc
  348.  
    )
  349.  
     
  350.  
    func file_proto_middlewareApi_middlewareApi_proto_rawDescGZIP() []byte {
  351.  
    file_proto_middlewareApi_middlewareApi_proto_rawDescOnce.Do(func() {
  352.  
    file_proto_middlewareApi_middlewareApi_proto_rawDescData = protoimpl.X.CompressGZIP(file_proto_middlewareApi_middlewareApi_proto_rawDescData)
  353.  
    })
  354.  
    return file_proto_middlewareApi_middlewareApi_proto_rawDescData
  355.  
    }
  356.  
     
  357.  
    var file_proto_middlewareApi_middlewareApi_proto_msgTypes = make([]protoimpl.MessageInfo, 7)
  358.  
    var file_proto_middlewareApi_middlewareApi_proto_goTypes = []interface{}{
  359.  
    (*Pair)(nil), // 0: middlewareApi.Pair
  360.  
    (*Request)(nil), // 1: middlewareApi.Request
  361.  
    (*Response)(nil), // 2: middlewareApi.Response
  362.  
    nil, // 3: middlewareApi.Request.HeaderEntry
  363.  
    nil, // 4: middlewareApi.Request.GetEntry
  364.  
    nil, // 5: middlewareApi.Request.PostEntry
  365.  
    nil, // 6: middlewareApi.Response.HeaderEntry
  366.  
    }
  367.  
    var file_proto_middlewareApi_middlewareApi_proto_depIdxs = []int32{
  368.  
    3, // 0: middlewareApi.Request.header:type_name -> middlewareApi.Request.HeaderEntry
  369.  
    4, // 1: middlewareApi.Request.get:type_name -> middlewareApi.Request.GetEntry
  370.  
    5, // 2: middlewareApi.Request.post:type_name -> middlewareApi.Request.PostEntry
  371.  
    6, // 3: middlewareApi.Response.header:type_name -> middlewareApi.Response.HeaderEntry
  372.  
    0, // 4: middlewareApi.Request.HeaderEntry.value:type_name -> middlewareApi.Pair
  373.  
    0, // 5: middlewareApi.Request.GetEntry.value:type_name -> middlewareApi.Pair
  374.  
    0, // 6: middlewareApi.Request.PostEntry.value:type_name -> middlewareApi.Pair
  375.  
    0, // 7: middlewareApi.Response.HeaderEntry.value:type_name -> middlewareApi.Pair
  376.  
    1, // 8: middlewareApi.MiddlewareApi.FindMiddlewareById:input_type -> middlewareApi.Request
  377.  
    1, // 9: middlewareApi.MiddlewareApi.AddMiddleware:input_type -> middlewareApi.Request
  378.  
    1, // 10: middlewareApi.MiddlewareApi.DeleteMiddlewareById:input_type -> middlewareApi.Request
  379.  
    1, // 11: middlewareApi.MiddlewareApi.UpdateMiddleware:input_type -> middlewareApi.Request
  380.  
    1, // 12: middlewareApi.MiddlewareApi.Call:input_type -> middlewareApi.Request
  381.  
    1, // 13: middlewareApi.MiddlewareApi.FindAllMiddlewareByTypeId:input_type -> middlewareApi.Request
  382.  
    1, // 14: middlewareApi.MiddlewareApi.FindMiddleTypeById:input_type -> middlewareApi.Request
  383.  
    1, // 15: middlewareApi.MiddlewareApi.AddMiddleType:input_type -> middlewareApi.Request
  384.  
    1, // 16: middlewareApi.MiddlewareApi.DeleteMiddleTypeById:input_type -> middlewareApi.Request
  385.  
    1, // 17: middlewareApi.MiddlewareApi.UpdateMiddleType:input_type -> middlewareApi.Request
  386.  
    1, // 18: middlewareApi.MiddlewareApi.FindAllMiddleType:input_type -> middlewareApi.Request
  387.  
    2, // 19: middlewareApi.MiddlewareApi.FindMiddlewareById:output_type -> middlewareApi.Response
  388.  
    2, // 20: middlewareApi.MiddlewareApi.AddMiddleware:output_type -> middlewareApi.Response
  389.  
    2, // 21: middlewareApi.MiddlewareApi.DeleteMiddlewareById:output_type -> middlewareApi.Response
  390.  
    2, // 22: middlewareApi.MiddlewareApi.UpdateMiddleware:output_type -> middlewareApi.Response
  391.  
    2, // 23: middlewareApi.MiddlewareApi.Call:output_type -> middlewareApi.Response
  392.  
    2, // 24: middlewareApi.MiddlewareApi.FindAllMiddlewareByTypeId:output_type -> middlewareApi.Response
  393.  
    2, // 25: middlewareApi.MiddlewareApi.FindMiddleTypeById:output_type -> middlewareApi.Response
  394.  
    2, // 26: middlewareApi.MiddlewareApi.AddMiddleType:output_type -> middlewareApi.Response
  395.  
    2, // 27: middlewareApi.MiddlewareApi.DeleteMiddleTypeById:output_type -> middlewareApi.Response
  396.  
    2, // 28: middlewareApi.MiddlewareApi.UpdateMiddleType:output_type -> middlewareApi.Response
  397.  
    2, // 29: middlewareApi.MiddlewareApi.FindAllMiddleType:output_type -> middlewareApi.Response
  398.  
    19, // [19:30] is the sub-list for method output_type
  399.  
    8, // [8:19] is the sub-list for method input_type
  400.  
    8, // [8:8] is the sub-list for extension type_name
  401.  
    8, // [8:8] is the sub-list for extension extendee
  402.  
    0, // [0:8] is the sub-list for field type_name
  403.  
    }
  404.  
     
  405.  
    func init() { file_proto_middlewareApi_middlewareApi_proto_init() }
  406.  
    func file_proto_middlewareApi_middlewareApi_proto_init() {
  407.  
    if File_proto_middlewareApi_middlewareApi_proto != nil {
  408.  
    return
  409.  
    }
  410.  
    if !protoimpl.UnsafeEnabled {
  411.  
    file_proto_middlewareApi_middlewareApi_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
  412.  
    switch v := v.(*Pair); i {
  413.  
    case 0:
  414.  
    return &v.state
  415.  
    case 1:
  416.  
    return &v.sizeCache
  417.  
    case 2:
  418.  
    return &v.unknownFields
  419.  
    default:
  420.  
    return nil
  421.  
    }
  422.  
    }
  423.  
    file_proto_middlewareApi_middlewareApi_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
  424.  
    switch v := v.(*Request); i {
  425.  
    case 0:
  426.  
    return &v.state
  427.  
    case 1:
  428.  
    return &v.sizeCache
  429.  
    case 2:
  430.  
    return &v.unknownFields
  431.  
    default:
  432.  
    return nil
  433.  
    }
  434.  
    }
  435.  
    file_proto_middlewareApi_middlewareApi_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
  436.  
    switch v := v.(*Response); i {
  437.  
    case 0:
  438.  
    return &v.state
  439.  
    case 1:
  440.  
    return &v.sizeCache
  441.  
    case 2:
  442.  
    return &v.unknownFields
  443.  
    default:
  444.  
    return nil
  445.  
    }
  446.  
    }
  447.  
    }
  448.  
    type x struct{}
  449.  
    out := protoimpl.TypeBuilder{
  450.  
    File: protoimpl.DescBuilder{
  451.  
    GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
  452.  
    RawDescriptor: file_proto_middlewareApi_middlewareApi_proto_rawDesc,
  453.  
    NumEnums: 0,
  454.  
    NumMessages: 7,
  455.  
    NumExtensions: 0,
  456.  
    NumServices: 1,
  457.  
    },
  458.  
    GoTypes: file_proto_middlewareApi_middlewareApi_proto_goTypes,
  459.  
    DependencyIndexes: file_proto_middlewareApi_middlewareApi_proto_depIdxs,
  460.  
    MessageInfos: file_proto_middlewareApi_middlewareApi_proto_msgTypes,
  461.  
    }.Build()
  462.  
    File_proto_middlewareApi_middlewareApi_proto = out.File
  463.  
    file_proto_middlewareApi_middlewareApi_proto_rawDesc = nil
  464.  
    file_proto_middlewareApi_middlewareApi_proto_goTypes = nil
  465.  
    file_proto_middlewareApi_middlewareApi_proto_depIdxs = nil
  466.  
    }

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgfbkig
系列文章
更多 icon
同类精品
更多 icon
继续加载