Go开发PaaS平台2
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开发调整
-
PS C:\Users\Administrator\Desktop\gopaas> .\yu-tool\yu-tool.exe newService github.com/yunixiangfeng/gopaas/route
-
-
cd route
-
-
go mod tidy
-
-
// versions:
-
// protoc-gen-go v1.27.1
-
// protoc v3.15.7
-
// source: proto/svc/svc.proto
-
protoc --proto_path=. --micro_out=. --go_out=:. ./proto/route/route.proto
C:\Users\Administrator\Desktop\gopaas\route\domain\model\route.go
-
package model
-
-
type Route struct {
-
ID int64 `gorm:"primary_key;not_null;auto_increment"`
-
RouteName string `json:"route_name"`
-
RouteNamespace string `json:"route_namespace"`
-
RouteHost string `json:"route_host"`
-
RoutePath []RoutePath `gorm:"ForeignKey:RouteID" json:"route_path"`
-
}
C:\Users\Administrator\Desktop\gopaas\route\domain\model\route_path.go
-
package model
-
-
type RoutePath struct {
-
ID int64 `gorm:"primary_key;not_null;auto_increment"`
-
RouteID int64 `json:"route_id"`
-
RoutePathName string `json:"route_path_name"`
-
RouteBackendService string `json:"route_backend_service"`
-
RouteBackendServicePort int32 `json:"route_backend_service_port"`
-
}
C:\Users\Administrator\Desktop\gopaas\route\domain\repository\route_repository.go
-
package repository
-
-
import (
-
"github.com/jinzhu/gorm"
-
"github.com/yunixiangfeng/gopaas/common"
-
"github.com/yunixiangfeng/gopaas/route/domain/model"
-
)
-
-
//创建需要实现的接口
-
type IRouteRepository interface {
-
//初始化表
-
InitTable() error
-
//根据ID查处找数据
-
FindRouteByID(int64) (*model.Route, error)
-
//创建一条 route 数据
-
CreateRoute(*model.Route) (int64, error)
-
//根据ID删除一条 route 数据
-
DeleteRouteByID(int64) error
-
//修改更新数据
-
UpdateRoute(*model.Route) error
-
//查找route所有数据
-
FindAll() ([]model.Route, error)
-
}
-
-
//创建routeRepository
-
func NewRouteRepository(db *gorm.DB) IRouteRepository {
-
return &RouteRepository{mysqlDb: db}
-
}
-
-
type RouteRepository struct {
-
mysqlDb *gorm.DB
-
}
-
-
//初始化表
-
func (u *RouteRepository) InitTable() error {
-
return u.mysqlDb.CreateTable(&model.Route{}, &model.RoutePath{}).Error
-
}
-
-
//根据ID查找Route信息
-
func (u *RouteRepository) FindRouteByID(routeID int64) (route *model.Route, err error) {
-
route = &model.Route{}
-
return route, u.mysqlDb.Preload("RoutePath").First(route, routeID).Error
-
}
-
-
//创建Route信息
-
func (u *RouteRepository) CreateRoute(route *model.Route) (int64, error) {
-
return route.ID, u.mysqlDb.Create(route).Error
-
}
-
-
//根据ID删除Route信息
-
func (u *RouteRepository) DeleteRouteByID(routeID int64) error {
-
tx := u.mysqlDb.Begin()
-
//遇到问题回滚
-
defer func() {
-
if r := recover(); r != nil {
-
tx.Rollback()
-
}
-
}()
-
if tx.Error != nil {
-
common.Error(tx.Error)
-
return tx.Error
-
}
-
//开始删除
-
if err := u.mysqlDb.Where("id = ?", routeID).Delete(&model.Route{}).Error; err != nil {
-
tx.Rollback()
-
common.Error(err)
-
return err
-
}
-
//删除关联表
-
if err := u.mysqlDb.Where("route_id = ?", routeID).Delete(&model.RoutePath{}).Error; err != nil {
-
tx.Rollback()
-
common.Error(err)
-
return err
-
}
-
return tx.Commit().Error
-
}
-
-
//更新Route信息
-
func (u *RouteRepository) UpdateRoute(route *model.Route) error {
-
return u.mysqlDb.Model(route).Update(route).Error
-
}
-
-
//获取结果集
-
func (u *RouteRepository) FindAll() (routeAll []model.Route, err error) {
-
return routeAll, u.mysqlDb.Preload("RoutePath").Find(&routeAll).Error
-
}
7-3 路由 service 开发
C:\Users\Administrator\Desktop\gopaas\route\domain\service\route_data_service.go
-
package service
-
-
import (
-
"context"
-
"errors"
-
"strconv"
-
-
"github.com/yunixiangfeng/gopaas/common"
-
"github.com/yunixiangfeng/gopaas/route/domain/model"
-
"github.com/yunixiangfeng/gopaas/route/domain/repository"
-
"github.com/yunixiangfeng/gopaas/route/proto/route"
-
v1 "k8s.io/api/apps/v1"
-
v12 "k8s.io/api/networking/v1"
-
v14 "k8s.io/apimachinery/pkg/apis/meta/v1"
-
"k8s.io/client-go/kubernetes"
-
)
-
-
//这里是接口类型
-
type IRouteDataService interface {
-
AddRoute(*model.Route) (int64, error)
-
DeleteRoute(int64) error
-
UpdateRoute(*model.Route) error
-
FindRouteByID(int64) (*model.Route, error)
-
FindAllRoute() ([]model.Route, error)
-
-
CreateRouteToK8s(*route.RouteInfo) error
-
DeleteRouteFromK8s(*model.Route) error
-
UpdateRouteToK8s(*route.RouteInfo) error
-
}
-
-
//创建
-
//注意:返回值 IRouteDataService 接口类型
-
func NewRouteDataService(routeRepository repository.IRouteRepository, clientSet *kubernetes.Clientset) IRouteDataService {
-
return &RouteDataService{RouteRepository: routeRepository, K8sClientSet: clientSet, deployment: &v1.Deployment{}}
-
}
-
-
type RouteDataService struct {
-
//注意:这里是 IRouteRepository 类型
-
RouteRepository repository.IRouteRepository
-
K8sClientSet *kubernetes.Clientset
-
deployment *v1.Deployment
-
}
-
-
//创建k8s(把proto 属性补全)
-
func (u *RouteDataService) CreateRouteToK8s(info *route.RouteInfo) (err error) {
-
ingress := u.setIngress(info)
-
//查找是否存在
-
if _, err = u.K8sClientSet.NetworkingV1().Ingresses(info.RouteNamespace).Get(context.TODO(), info.RouteName, v14.GetOptions{}); err != nil {
-
if _, err = u.K8sClientSet.NetworkingV1().Ingresses(info.RouteNamespace).Create(context.TODO(), ingress, v14.CreateOptions{}); err != nil {
-
//创建不成功记录错误
-
common.Error(err)
-
return err
-
}
-
return nil
-
} else {
-
common.Error("路由 " info.RouteName " 已经存在")
-
return errors.New("路由 " info.RouteName " 已经存在")
-
}
-
}
-
-
func (u *RouteDataService) setIngress(info *route.RouteInfo) *v12.Ingress {
-
route := &v12.Ingress{}
-
//设置路由
-
route.TypeMeta = v14.TypeMeta{
-
Kind: "Ingress",
-
APIVersion: "v1",
-
}
-
//设置路由基础信息
-
route.ObjectMeta = v14.ObjectMeta{
-
Name: info.RouteName,
-
Namespace: info.RouteNamespace,
-
Labels: map[string]string{
-
"app-name": info.RouteName,
-
"author": "wu123",
-
},
-
Annotations: map[string]string{
-
"k8s/generated-by-wu": "由代码创建",
-
},
-
}
-
//使用 ingress-nginx
-
className := "nginx"
-
//设置路由 spec 信息
-
route.Spec = v12.IngressSpec{
-
IngressClassName: &className,
-
//默认访问服务
-
DefaultBackend: nil,
-
//如果开启https这里要设置
-
TLS: nil,
-
Rules: u.getIngressPath(info),
-
}
-
return route
-
}
-
-
//根据info信息获取path路径
-
func (u *RouteDataService) getIngressPath(info *route.RouteInfo) (path []v12.IngressRule) {
-
//1.设置host
-
pathRule := v12.IngressRule{Host: info.RouteHost}
-
//2.设置Path
-
ingressPath := []v12.HTTPIngressPath{}
-
for _, v := range info.RoutePath {
-
pathType := v12.PathTypePrefix
-
ingressPath = append(ingressPath, v12.HTTPIngressPath{
-
Path: v.RoutePathName,
-
PathType: &pathType,
-
Backend: v12.IngressBackend{
-
Service: &v12.IngressServiceBackend{
-
Name: v.RouteBackendService,
-
Port: v12.ServiceBackendPort{
-
Number: v.RouteBackendServicePort,
-
},
-
},
-
},
-
})
-
}
-
-
//3.赋值 Path
-
pathRule.IngressRuleValue = v12.IngressRuleValue{HTTP: &v12.HTTPIngressRuleValue{Paths: ingressPath}}
-
path = append(path, pathRule)
-
return
-
}
-
-
//更新route
-
func (u *RouteDataService) UpdateRouteToK8s(info *route.RouteInfo) (err error) {
-
ingress := u.setIngress(info)
-
if _, err = u.K8sClientSet.NetworkingV1().Ingresses(info.RouteNamespace).Update(context.TODO(), ingress, v14.UpdateOptions{}); err != nil {
-
common.Error(err)
-
return err
-
}
-
return nil
-
}
-
-
//删除route
-
func (u *RouteDataService) DeleteRouteFromK8s(route2 *model.Route) (err error) {
-
//删除Ingress
-
if err = u.K8sClientSet.NetworkingV1().Ingresses(route2.RouteNamespace).Delete(context.TODO(), route2.RouteName, v14.DeleteOptions{}); err != nil {
-
//如果删除失败记录下
-
common.Error(err)
-
return err
-
} else {
-
if err := u.DeleteRoute(route2.ID); err != nil {
-
common.Error(err)
-
return err
-
}
-
common.Info("删除 ingress ID:" strconv.FormatInt(route2.ID, 10) " 成功!")
-
}
-
return
-
}
-
-
//插入
-
func (u *RouteDataService) AddRoute(route *model.Route) (int64, error) {
-
return u.RouteRepository.CreateRoute(route)
-
}
-
-
//删除
-
func (u *RouteDataService) DeleteRoute(routeID int64) error {
-
return u.RouteRepository.DeleteRouteByID(routeID)
-
}
-
-
//更新
-
func (u *RouteDataService) UpdateRoute(route *model.Route) error {
-
return u.RouteRepository.UpdateRoute(route)
-
}
-
-
//查找
-
func (u *RouteDataService) FindRouteByID(routeID int64) (*model.Route, error) {
-
return u.RouteRepository.FindRouteByID(routeID)
-
}
-
-
//查找
-
func (u *RouteDataService) FindAllRoute() ([]model.Route, error) {
-
return u.RouteRepository.FindAll()
-
}
C:\Users\Administrator\Desktop\gopaas\route\proto\route\route.proto
-
syntax = "proto3";
-
-
package route;
-
-
option go_package = "./proto/route;route";
-
-
service Route {
-
//对外提供添加服务
-
rpc AddRoute(RouteInfo) returns (Response) {}
-
rpc DeleteRoute(RouteId) returns (Response) {}
-
rpc UpdateRoute(RouteInfo) returns (Response) {}
-
rpc FindRouteByID(RouteId) returns (RouteInfo) {}
-
rpc FindAllRoute(FindAll) returns (AllRoute) {}
-
}
-
message RouteInfo {
-
int64 id = 1;
-
string route_name = 2;
-
string route_namespace =3;
-
string route_host =4;
-
repeated RoutePath route_path=5;
-
}
-
-
message RoutePath {
-
int64 id = 1;
-
int64 route_id =2;
-
string route_path_name=3;
-
string route_backend_service=4;
-
int32 route_backend_service_port=5;
-
}
-
-
message RouteId {
-
int64 id = 1;
-
}
-
-
message FindAll {
-
-
}
-
-
message Response {
-
string msg =1 ;
-
}
-
-
message AllRoute {
-
repeated RouteInfo route_info = 1;
-
}
-
-
7-4 路由 handler 逻辑开发和注意事项
创建handler对外暴露服务
C:\Users\Administrator\Desktop\gopaas\route\handler\routeHandler.go
-
package handler
-
-
import (
-
"context"
-
"strconv"
-
-
log "github.com/asim/go-micro/v3/logger"
-
"github.com/yunixiangfeng/gopaas/common"
-
"github.com/yunixiangfeng/gopaas/route/domain/model"
-
"github.com/yunixiangfeng/gopaas/route/domain/service"
-
route "github.com/yunixiangfeng/gopaas/route/proto/route"
-
)
-
-
type RouteHandler struct {
-
//注意这里的类型是 IRouteDataService 接口类型
-
RouteDataService service.IRouteDataService
-
}
-
-
// 添加路由
-
func (e *RouteHandler) AddRoute(ctx context.Context, info *route.RouteInfo, rsp *route.Response) error {
-
log.Info("Received *route.AddRoute request")
-
route := &model.Route{}
-
if err := common.SwapTo(info, route); err != nil {
-
common.Error(err)
-
rsp.Msg = err.Error()
-
return err
-
}
-
//创建route到k8s
-
if err := e.RouteDataService.CreateRouteToK8s(info); err != nil {
-
common.Error(err)
-
rsp.Msg = err.Error()
-
return err
-
} else {
-
//写入数据库
-
routeID, err := e.RouteDataService.AddRoute(route)
-
if err != nil {
-
common.Error(err)
-
rsp.Msg = err.Error()
-
return err
-
}
-
common.Info("Route 添加成功 ID 号为:" strconv.FormatInt(routeID, 10))
-
rsp.Msg = "Route 添加成功 ID 号为:" strconv.FormatInt(routeID, 10)
-
}
-
return nil
-
}
-
-
//删除route
-
func (e *RouteHandler) DeleteRoute(ctx context.Context, req *route.RouteId, rsp *route.Response) error {
-
log.Info("Received *route.DeleteRoute request")
-
routeModel, err := e.RouteDataService.FindRouteByID(req.Id)
-
if err != nil {
-
common.Error(err)
-
return err
-
}
-
//从k8s中删除,并且删除数据库中数据
-
if err := e.RouteDataService.DeleteRouteFromK8s(routeModel); err != nil {
-
common.Error(err)
-
return err
-
}
-
return nil
-
}
-
-
//更新route
-
func (e *RouteHandler) UpdateRoute(ctx context.Context, req *route.RouteInfo, rsp *route.Response) error {
-
log.Info("Received *route.UpdateRoute request")
-
if err := e.RouteDataService.UpdateRouteToK8s(req); err != nil {
-
common.Error(err)
-
return err
-
}
-
//查询数据库的信息
-
routeModel, err := e.RouteDataService.FindRouteByID(req.Id)
-
if err != nil {
-
common.Error(err)
-
return err
-
}
-
//数据更新
-
if err := common.SwapTo(req, routeModel); err != nil {
-
common.Error(err)
-
return err
-
}
-
return e.RouteDataService.UpdateRoute(routeModel)
-
}
-
-
//根据ID查询route信息
-
func (e *RouteHandler) FindRouteByID(ctx context.Context, req *route.RouteId, rsp *route.RouteInfo) error {
-
log.Info("Received *route.FindRouteByID request")
-
routeModel, err := e.RouteDataService.FindRouteByID(req.Id)
-
if err != nil {
-
common.Error(err)
-
return err
-
}
-
//数据转化
-
if err := common.SwapTo(routeModel, rsp); err != nil {
-
common.Error(err)
-
return err
-
}
-
return nil
-
}
-
-
func (e *RouteHandler) FindAllRoute(ctx context.Context, req *route.FindAll, rsp *route.AllRoute) error {
-
log.Info("Received *route.FindAllRoute request")
-
allRoute, err := e.RouteDataService.FindAllRoute()
-
if err != nil {
-
common.Error(err)
-
return err
-
}
-
//整理下格式
-
for _, v := range allRoute {
-
//创建实例
-
routeInfo := &route.RouteInfo{}
-
//把查询出来的数据进行转化
-
if err := common.SwapTo(v, routeInfo); err != nil {
-
common.Error(err)
-
return err
-
}
-
//数据合并
-
rsp.RouteInfo = append(rsp.RouteInfo, routeInfo)
-
}
-
return nil
-
}
C:\Users\Administrator\Desktop\gopaas\route\main.go
-
package main
-
-
import (
-
"flag"
-
"fmt"
-
"path/filepath"
-
-
"github.com/yunixiangfeng/gopaas/common"
-
"github.com/yunixiangfeng/gopaas/route/domain/repository"
-
-
//"github.com/afex/hystrix-go/hystrix"
-
"github.com/asim/go-micro/plugins/registry/consul/v3"
-
ratelimit "github.com/asim/go-micro/plugins/wrapper/ratelimiter/uber/v3"
-
opentracing2 "github.com/asim/go-micro/plugins/wrapper/trace/opentracing/v3"
-
"github.com/asim/go-micro/v3"
-
"github.com/asim/go-micro/v3/registry"
-
"github.com/asim/go-micro/v3/server"
-
"github.com/jinzhu/gorm"
-
_ "github.com/jinzhu/gorm/dialects/mysql"
-
"github.com/opentracing/opentracing-go"
-
service2 "github.com/yunixiangfeng/gopaas/route/domain/service"
-
"github.com/yunixiangfeng/gopaas/route/handler"
-
-
//hystrix2 "github.com/yunixiangfeng/gopaas/route/plugin/hystrix"
-
"strconv"
-
-
route "github.com/yunixiangfeng/gopaas/route/proto/route"
-
"k8s.io/client-go/kubernetes"
-
"k8s.io/client-go/tools/clientcmd"
-
"k8s.io/client-go/util/homedir"
-
)
-
-
var (
-
//服务地址
-
hostIp = "192.168.204.130"
-
//服务地址
-
serviceHost = hostIp
-
//服务端口
-
servicePort = "8085"
-
-
//注册中心配置
-
consulHost = hostIp
-
consulPort int64 = 8500
-
//链路追踪
-
tracerHost = hostIp
-
tracerPort = 6831
-
//熔断端口,每个服务不能重复
-
//hystrixPort = 9095
-
//监控端口,每个服务不能重复
-
prometheusPort = 9195
-
)
-
-
func main() {
-
//需要本地启动,mysql,consul中间件服务
-
//1.注册中心
-
consul := consul.NewRegistry(func(options *registry.Options) {
-
options.Addrs = []string{
-
consulHost ":" strconv.FormatInt(consulPort, 10),
-
}
-
})
-
//2.配置中心,存放经常变动的变量
-
consulConfig, err := common.GetConsulConfig(consulHost, consulPort, "/micro/config")
-
if err != nil {
-
common.Error(err)
-
}
-
//3.使用配置中心连接 mysql
-
mysqlInfo := common.GetMysqlFromConsul(consulConfig, "mysql")
-
//初始化数据库
-
db, err := gorm.Open("mysql", mysqlInfo.User ":" mysqlInfo.Pwd "@(" mysqlInfo.Host ":3306)/" mysqlInfo.Database "?charset=utf8&parseTime=True&loc=Local")
-
if err != nil {
-
//命令行输出下,方便查看错误
-
fmt.Println(err)
-
common.Fatal(err)
-
}
-
defer db.Close()
-
//禁止复表
-
db.SingularTable(true)
-
-
//4.添加链路追踪
-
t, io, err := common.NewTracer("go.micro.service.route", tracerHost ":" strconv.Itoa(tracerPort))
-
if err != nil {
-
common.Error(err)
-
}
-
defer io.Close()
-
opentracing.SetGlobalTracer(t)
-
-
//添加熔断器,作为客户端需要启用
-
//hystrixStreamHandler := hystrix.NewStreamHandler()
-
//hystrixStreamHandler.Start()
-
-
//添加日志中心
-
//1)需要程序日志打入到日志文件中
-
//2)在程序中添加filebeat.yml 文件
-
//3) 启动filebeat,启动命令 ./filebeat -e -c filebeat.yml
-
fmt.Println("日志统一记录在根目录 micro.log 文件中,请点击查看日志!")
-
-
//启动监听程序
-
//go func() {
-
// //http://192.168.204.130:9092/turbine/turbine.stream
-
// //看板访问地址 http://127.0.0.1:9002/hystrix,url后面一定要带 /hystrix
-
// err = http.ListenAndServe(net.JoinHostPort("0.0.0.0",strconv.Itoa(hystrixPort)),hystrixStreamHandler)
-
// if err !=nil {
-
// common.Error(err)
-
// }
-
//}()
-
-
//5.添加监控
-
common.PrometheusBoot(prometheusPort)
-
-
//下载kubectl:https://kubernetes.io/docs/tasks/tools/#tabset-2
-
//macos:
-
// 1.curl -LO "https://dl.k8s.io/release/v1.21.0/bin/darwin/amd64/kubectl"
-
// 2.chmod x ./kubectl
-
// 3.sudo mv ./kubectl /usr/local/bin/kubectl
-
// sudo chown root: /usr/local/bin/kubectl
-
// 5.kubectl version --client
-
// 6.集群模式下直接拷贝服务端~/.kube/config 文件到本机 ~/.kube/confg 中
-
// 注意:- config中的域名要能解析正确
-
// - 生产环境可以创建另一个证书
-
// 7.kubectl get ns 查看是否正常
-
//
-
//6.创建k8s连接
-
//在集群外面连接
-
var kubeconfig *string
-
if home := homedir.HomeDir(); home != "" {
-
kubeconfig = flag.String("kubeconfig", filepath.Join(home, ".kube", "config"), "(optional) absolute path to the kubeconfig file")
-
} else {
-
kubeconfig = flag.String("kubeconfig", "", "absolute path to the kubeconfig file")
-
}
-
flag.Parse()
-
config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
-
if err != nil {
-
common.Fatal(err.Error())
-
}
-
-
//在集群中外的配置
-
//config, err := rest.InClusterConfig()
-
//if err != nil {
-
// panic(err.Error())
-
//}
-
-
// create the clientset
-
clientset, err := kubernetes.NewForConfig(config)
-
if err != nil {
-
common.Fatal(err.Error())
-
}
-
-
//7.创建服务
-
service := micro.NewService(
-
//自定义服务地址,且必须写在其它参数前面
-
micro.Server(server.NewServer(func(options *server.Options) {
-
options.Advertise = serviceHost ":" servicePort
-
})),
-
micro.Name("go.micro.service.route"),
-
micro.Version("latest"),
-
//指定服务端口
-
micro.Address(":" servicePort),
-
//添加注册中心
-
micro.Registry(consul),
-
//添加链路追踪
-
micro.WrapHandler(opentracing2.NewHandlerWrapper(opentracing.GlobalTracer())),
-
micro.WrapClient(opentracing2.NewClientWrapper(opentracing.GlobalTracer())),
-
//只作为客户端的时候起作用,如果存在调用别人的情况,原则上不去主动调用
-
//micro.WrapClient(hystrix2.NewClientHystrixWrapper()),
-
//添加限流
-
micro.WrapHandler(ratelimit.NewHandlerWrapper(1000)),
-
)
-
-
service.Init()
-
-
//只能执行一遍
-
err = repository.NewRouteRepository(db).InitTable()
-
if err != nil {
-
common.Fatal(err)
-
}
-
-
// 注册句柄,可以快速操作已开发的服务
-
routeDataService := service2.NewRouteDataService(repository.NewRouteRepository(db), clientset)
-
route.RegisterRouteHandler(service.Server(), &handler.RouteHandler{RouteDataService: routeDataService})
-
-
// 启动服务
-
if err := service.Run(); err != nil {
-
//输出启动失败信息
-
common.Fatal(err)
-
}
-
}
7-5 route 对外API的开发
-
PS C:\Users\Administrator\Desktop\gopaas> .\yu-tool\yu-tool.exe createApi github.com/yunixiangfeng/gopaas/routeApi
-
-
yu-v3 --proto_path=. --micro_out=. --go_out=:. ./proto/routeApi/routeApi.proto
-
-
go mod tidy
C:\Users\Administrator\Desktop\gopaas\routeapi\main.go
-
package main
-
-
import (
-
"fmt"
-
-
"github.com/afex/hystrix-go/hystrix"
-
"github.com/asim/go-micro/plugins/registry/consul/v3"
-
ratelimit "github.com/asim/go-micro/plugins/wrapper/ratelimiter/uber/v3"
-
"github.com/asim/go-micro/plugins/wrapper/select/roundrobin/v3"
-
opentracing2 "github.com/asim/go-micro/plugins/wrapper/trace/opentracing/v3"
-
"github.com/asim/go-micro/v3"
-
"github.com/asim/go-micro/v3/registry"
-
"github.com/asim/go-micro/v3/server"
-
"github.com/yunixiangfeng/gopaas/common"
-
go_micro_service_route "github.com/yunixiangfeng/gopaas/route/proto/route"
-
-
"net"
-
"net/http"
-
"strconv"
-
-
_ "github.com/jinzhu/gorm/dialects/mysql"
-
"github.com/opentracing/opentracing-go"
-
"github.com/yunixiangfeng/gopaas/routeApi/handler"
-
hystrix2 "github.com/yunixiangfeng/gopaas/routeApi/plugin/hystrix"
-
-
routeApi "github.com/yunixiangfeng/gopaas/routeApi/proto/routeApi"
-
)
-
-
var (
-
//服务地址
-
hostIp = "192.168.204.130"
-
//服务地址
-
serviceHost = hostIp
-
//服务端口
-
servicePort = "8086"
-
//注册中心配置
-
consulHost = hostIp
-
consulPort int64 = 8500
-
//链路追踪
-
tracerHost = hostIp
-
tracerPort = 6831
-
//熔断端口,每个服务不能重复
-
hystrixPort = 9096
-
//监控端口,每个服务不能重复
-
prometheusPort = 9196
-
)
-
-
func main() {
-
//需要本地启动,mysql,consul中间件服务
-
//1.注册中心
-
consul := consul.NewRegistry(func(options *registry.Options) {
-
options.Addrs = []string{
-
consulHost ":" strconv.FormatInt(consulPort, 10),
-
}
-
})
-
-
//2.添加链路追踪
-
t, io, err := common.NewTracer("go.micro.api.routeApi", tracerHost ":" strconv.Itoa(tracerPort))
-
if err != nil {
-
common.Error(err)
-
}
-
defer io.Close()
-
opentracing.SetGlobalTracer(t)
-
-
//3.添加熔断器
-
hystrixStreamHandler := hystrix.NewStreamHandler()
-
hystrixStreamHandler.Start()
-
-
//添加日志中心
-
//1)需要程序日志打入到日志文件中
-
//2)在程序中添加filebeat.yml 文件
-
//3) 启动filebeat,启动命令 ./filebeat -e -c filebeat.yml
-
fmt.Println("日志统一记录在根目录 micro.log 文件中,请点击查看日志!")
-
-
//启动监听程序
-
go func() {
-
//http://192.168.204.130:9092/turbine/turbine.stream
-
//看板访问地址 http://127.0.0.1:9002/hystrix,url后面一定要带 /hystrix
-
err = http.ListenAndServe(net.JoinHostPort("0.0.0.0", strconv.Itoa(hystrixPort)), hystrixStreamHandler)
-
if err != nil {
-
common.Error(err)
-
}
-
}()
-
-
//4.添加监控
-
common.PrometheusBoot(prometheusPort)
-
-
//5.创建服务
-
service := micro.NewService(
-
//自定义服务地址,且必须写在其它参数前面
-
micro.Server(server.NewServer(func(opts *server.Options) {
-
opts.Advertise = serviceHost ":" servicePort
-
-
})),
-
micro.Name("go.micro.api.routeApi"),
-
micro.Version("latest"),
-
//指定服务端口
-
micro.Address(":" servicePort),
-
//添加注册中心
-
micro.Registry(consul),
-
//添加链路追踪
-
micro.WrapHandler(opentracing2.NewHandlerWrapper(opentracing.GlobalTracer())),
-
micro.WrapClient(opentracing2.NewClientWrapper(opentracing.GlobalTracer())),
-
//只作为客户端的时候起作用
-
micro.WrapClient(hystrix2.NewClientHystrixWrapper()),
-
//添加限流
-
micro.WrapHandler(ratelimit.NewHandlerWrapper(1000)),
-
//增加负载均衡
-
micro.WrapClient(roundrobin.NewClientWrapper()),
-
)
-
-
service.Init()
-
-
// 指定需要访问的服务,可以快速操作已开发的服务,
-
// 默认API服务名称带有"Api",程序会自动替换
-
// 如果不带有特定字符会使用默认"XXX" 请自行替换
-
routeService := go_micro_service_route.NewRouteService("go.micro.service.route", service.Client())
-
// 注册控制器
-
if err := routeApi.RegisterRouteApiHandler(service.Server(), &handler.RouteApi{RouteService: routeService}); err != nil {
-
common.Error(err)
-
}
-
-
// 启动服务
-
if err := service.Run(); err != nil {
-
//输出启动失败信息
-
common.Fatal(err)
-
}
-
}
C:\Users\Administrator\Desktop\gopaas\routeapi\handler\routeApiHandler.go
-
package handler
-
-
import (
-
"context"
-
"encoding/json"
-
"errors"
-
"strconv"
-
-
log "github.com/asim/go-micro/v3/logger"
-
"github.com/yunixiangfeng/gopaas/common"
-
route "github.com/yunixiangfeng/gopaas/route/proto/route"
-
routeApi "github.com/yunixiangfeng/gopaas/routeApi/proto/routeApi"
-
)
-
-
type RouteApi struct {
-
RouteService route.RouteService
-
}
-
-
// routeApi.FindRouteById 通过API向外暴露为/routeApi/findRouteById,接收http请求
-
// 即:/routeApi/FindRouteById 请求会调用go.micro.api.routeApi 服务的routeApi.FindRouteById 方法
-
func (e *RouteApi) FindRouteById(ctx context.Context, req *routeApi.Request, rsp *routeApi.Response) error {
-
log.Info("Received routeApi.FindRouteById request")
-
if _, ok := req.Get["route_id"]; !ok {
-
rsp.StatusCode = 500
-
return errors.New("参数异常")
-
}
-
//获取 route id
-
routeIdString := req.Get["route_id"].Values[0]
-
routeId, err := strconv.ParseInt(routeIdString, 10, 64)
-
if err != nil {
-
common.Error(err)
-
return err
-
}
-
//获取route信息
-
routeInfo, err := e.RouteService.FindRouteByID(ctx, &route.RouteId{
-
Id: routeId,
-
})
-
if err != nil {
-
common.Error(err)
-
return err
-
}
-
//返回route结果
-
rsp.StatusCode = 200
-
b, _ := json.Marshal(routeInfo)
-
rsp.Body = string(b)
-
return nil
-
}
-
-
// routeApi.AddRoute 通过API向外暴露为/routeApi/AddRoute,接收http请求
-
// 即:/routeApi/AddRoute 请求会调用go.micro.api.routeApi 服务的routeApi.AddRoute 方法
-
func (e *RouteApi) AddRoute(ctx context.Context, req *routeApi.Request, rsp *routeApi.Response) error {
-
log.Info("Received routeApi.AddRoute request")
-
addRouteInfo := &route.RouteInfo{}
-
routePathName, ok := req.Post["route_path_name"]
-
if ok && len(routePathName.Values) > 0 {
-
port, err := strconv.ParseInt(req.Post["route_backend_service_port"].Values[0], 10, 32)
-
if err != nil {
-
common.Error(err)
-
return err
-
}
-
//这里如果有多个Path需要处理多个
-
routePath := &route.RoutePath{
-
RoutePathName: req.Post["route_path_name"].Values[0],
-
RouteBackendService: req.Post["route_backend_service"].Values[0],
-
RouteBackendServicePort: int32(port),
-
}
-
//合并
-
addRouteInfo.RoutePath = append(addRouteInfo.RoutePath, routePath)
-
}
-
form.FormToSvcStruct(req.Post, addRouteInfo)
-
response, err := e.RouteService.AddRoute(ctx, addRouteInfo)
-
if err != nil {
-
common.Error(err)
-
return err
-
}
-
rsp.StatusCode = 200
-
b, _ := json.Marshal(response)
-
rsp.Body = string(b)
-
return nil
-
}
-
-
// routeApi.DeleteRouteById 通过API向外暴露为/routeApi/DeleteRouteById,接收http请求
-
// 即:/routeApi/DeleteRouteById 请求会调用go.micro.api.routeApi 服务的 routeApi.DeleteRouteById 方法
-
func (e *RouteApi) DeleteRouteById(ctx context.Context, req *routeApi.Request, rsp *routeApi.Response) error {
-
log.Info("Received routeApi.DeleteRouteById request")
-
if _, ok := req.Get["route_id"]; !ok {
-
rsp.StatusCode = 500
-
return errors.New("参数异常")
-
}
-
//获取 route id
-
routeIdString := req.Get["route_id"].Values[0]
-
routeId, err := strconv.ParseInt(routeIdString, 10, 64)
-
if err != nil {
-
common.Error(err)
-
return err
-
}
-
//调用route 删除服务
-
response, err := e.RouteService.DeleteRoute(ctx, &route.RouteId{
-
Id: routeId,
-
})
-
if err != nil {
-
common.Error(err)
-
return err
-
}
-
rsp.StatusCode = 200
-
b, _ := json.Marshal(response)
-
rsp.Body = string(b)
-
return nil
-
}
-
-
// routeApi.UpdateRoute 通过API向外暴露为/routeApi/UpdateRoute,接收http请求
-
// 即:/routeApi/UpdateRoute 请求会调用go.micro.api.routeApi 服务的routeApi.UpdateRoute 方法
-
func (e *RouteApi) UpdateRoute(ctx context.Context, req *routeApi.Request, rsp *routeApi.Response) error {
-
log.Info("Received routeApi.UpdateRoute request")
-
rsp.StatusCode = 200
-
b, _ := json.Marshal("{success:'成功访问/routeApi/UpdateRoute'}")
-
rsp.Body = string(b)
-
return nil
-
}
-
-
// 默认的方法routeApi.Call 通过API向外暴露为/routeApi/call,接收http请求
-
// 即:/routeApi/call或/routeApi/ 请求会调用go.micro.api.routeApi 服务的routeApi.FindRouteById 方法
-
func (e *RouteApi) Call(ctx context.Context, req *routeApi.Request, rsp *routeApi.Response) error {
-
log.Info("Received routeApi.Call request")
-
allRoute, err := e.RouteService.FindAllRoute(ctx, &route.FindAll{})
-
if err != nil {
-
common.Error(err)
-
return err
-
}
-
rsp.StatusCode = 200
-
b, _ := json.Marshal(allRoute)
-
rsp.Body = string(b)
-
return nil
-
}
C:\Users\Administrator\Desktop\gopaas\routeapi\plugin\form\form.go
-
package form
-
-
import (
-
"errors"
-
"reflect"
-
"strconv"
-
"strings"
-
"time"
-
-
"github.com/yunixiangfeng/gopaas/common"
-
"github.com/yunixiangfeng/gopaas/routeApi/proto/routeApi"
-
)
-
-
//根据结构体中name标签映射数据到结构体中并且转换类型
-
func FormToSvcStruct(data map[string]*routeApi.Pair, obj interface{}) {
-
objValue := reflect.ValueOf(obj).Elem()
-
for i := 0; i < objValue.NumField(); i {
-
//获取sql对应的值
-
dataTag := strings.Replace(objValue.Type().Field(i).Tag.Get("json"), ",omitempty", "", -1)
-
dataSlice, ok := data[dataTag]
-
if !ok {
-
continue
-
}
-
valueSlice := dataSlice.Values
-
if len(valueSlice) <= 0 {
-
continue
-
}
-
//排除port和env
-
if dataTag == "route_path" {
-
continue
-
}
-
value := valueSlice[0]
-
//端口,环境变量的单独处理
-
//获取对应字段的名称
-
name := objValue.Type().Field(i).Name
-
//获取对应字段类型
-
structFieldType := objValue.Field(i).Type()
-
//获取变量类型,也可以直接写"string类型"
-
val := reflect.ValueOf(value)
-
var err error
-
if structFieldType != val.Type() {
-
//类型转换
-
val, err = TypeConversion(value, structFieldType.Name()) //类型转换
-
if err != nil {
-
common.Error(err)
-
}
-
}
-
//设置类型值
-
objValue.FieldByName(name).Set(val)
-
}
-
}
-
-
//类型转换
-
func TypeConversion(value string, ntype string) (reflect.Value, error) {
-
if ntype == "string" {
-
return reflect.ValueOf(value), nil
-
} else if ntype == "time.Time" {
-
t, err := time.ParseInLocation("2006-01-02 15:04:05", value, time.Local)
-
return reflect.ValueOf(t), err
-
} else if ntype == "Time" {
-
t, err := time.ParseInLocation("2006-01-02 15:04:05", value, time.Local)
-
return reflect.ValueOf(t), err
-
} else if ntype == "int" {
-
i, err := strconv.Atoi(value)
-
return reflect.ValueOf(i), err
-
} else if ntype == "int32" {
-
i, err := strconv.ParseInt(value, 10, 32)
-
if err != nil {
-
return reflect.ValueOf(int32(i)), err
-
}
-
return reflect.ValueOf(int32(i)), err
-
} else if ntype == "int64" {
-
i, err := strconv.ParseInt(value, 10, 64)
-
return reflect.ValueOf(i), err
-
} else if ntype == "float32" {
-
i, err := strconv.ParseFloat(value, 64)
-
return reflect.ValueOf(float32(i)), err
-
} else if ntype == "float64" {
-
i, err := strconv.ParseFloat(value, 64)
-
return reflect.ValueOf(i), err
-
}
-
-
//else if .......增加其他一些类型的转换
-
-
return reflect.ValueOf(value), errors.New("未知的类型:" ntype)
-
}
7-6 在k8s 中创建 nginx-controller 资源对象
C:\Users\Administrator\Desktop\gopaas\ingress\deploy.yml
-
apiVersion: v1
-
kind: Namespace
-
metadata:
-
labels:
-
app.kubernetes.io/instance: ingress-nginx
-
app.kubernetes.io/name: ingress-nginx
-
name: default
-
---
-
apiVersion: v1
-
automountServiceAccountToken: true
-
kind: ServiceAccount
-
metadata:
-
labels:
-
app.kubernetes.io/component: controller
-
app.kubernetes.io/instance: ingress-nginx
-
app.kubernetes.io/name: ingress-nginx
-
app.kubernetes.io/part-of: ingress-nginx
-
app.kubernetes.io/version: 1.2.0
-
name: ingress-nginx
-
namespace: default
-
---
-
apiVersion: v1
-
kind: ServiceAccount
-
metadata:
-
labels:
-
app.kubernetes.io/component: admission-webhook
-
app.kubernetes.io/instance: ingress-nginx
-
app.kubernetes.io/name: ingress-nginx
-
app.kubernetes.io/part-of: ingress-nginx
-
app.kubernetes.io/version: 1.2.0
-
name: ingress-nginx-admission
-
namespace: default
-
---
-
apiVersion: rbac.authorization.k8s.io/v1
-
kind: Role
-
metadata:
-
labels:
-
app.kubernetes.io/component: controller
-
app.kubernetes.io/instance: ingress-nginx
-
app.kubernetes.io/name: ingress-nginx
-
app.kubernetes.io/part-of: ingress-nginx
-
app.kubernetes.io/version: 1.2.0
-
name: ingress-nginx
-
namespace: default
-
rules:
-
- apiGroups:
-
- ""
-
resources:
-
- namespaces
-
verbs:
-
- get
-
- apiGroups:
-
- ""
-
resources:
-
- configmaps
-
- pods
-
- secrets
-
- endpoints
-
verbs:
-
- get
-
- list
-
- watch
-
- apiGroups:
-
- ""
-
resources:
-
- services
-
verbs:
-
- get
-
- list
-
- watch
-
- apiGroups:
-
- networking.k8s.io
-
resources:
-
- ingresses
-
verbs:
-
- get
-
- list
-
- watch
-
- apiGroups:
-
- networking.k8s.io
-
resources:
-
- ingresses/status
-
verbs:
-
- update
-
- apiGroups:
-
- networking.k8s.io
-
resources:
-
- ingressclasses
-
verbs:
-
- get
-
- list
-
- watch
-
- apiGroups:
-
- ""
-
resourceNames:
-
- ingress-controller-leader
-
resources:
-
- configmaps
-
verbs:
-
- get
-
- update
-
- apiGroups:
-
- ""
-
resources:
-
- configmaps
-
verbs:
-
- create
-
- apiGroups:
-
- ""
-
resources:
-
- events
-
verbs:
-
- create
-
- patch
-
---
-
apiVersion: rbac.authorization.k8s.io/v1
-
kind: Role
-
metadata:
-
labels:
-
app.kubernetes.io/component: admission-webhook
-
app.kubernetes.io/instance: ingress-nginx
-
app.kubernetes.io/name: ingress-nginx
-
app.kubernetes.io/part-of: ingress-nginx
-
app.kubernetes.io/version: 1.2.0
-
name: ingress-nginx-admission
-
namespace: default
-
rules:
-
- apiGroups:
-
- ""
-
resources:
-
- secrets
-
verbs:
-
- get
-
- create
-
---
-
apiVersion: rbac.authorization.k8s.io/v1
-
kind: ClusterRole
-
metadata:
-
labels:
-
app.kubernetes.io/instance: ingress-nginx
-
app.kubernetes.io/name: ingress-nginx
-
app.kubernetes.io/part-of: ingress-nginx
-
app.kubernetes.io/version: 1.2.0
-
name: ingress-nginx
-
rules:
-
- apiGroups:
-
- ""
-
resources:
-
- configmaps
-
- endpoints
-
- nodes
-
- pods
-
- secrets
-
- namespaces
-
verbs:
-
- list
-
- watch
-
- apiGroups:
-
- ""
-
resources:
-
- nodes
-
verbs:
-
- get
-
- apiGroups:
-
- ""
-
resources:
-
- services
-
verbs:
-
- get
-
- list
-
- watch
-
- apiGroups:
-
- networking.k8s.io
-
resources:
-
- ingresses
-
verbs:
-
- get
-
- list
-
- watch
-
- apiGroups:
-
- ""
-
resources:
-
- events
-
verbs:
-
- create
-
- patch
-
- apiGroups:
-
- networking.k8s.io
-
resources:
-
- ingresses/status
-
verbs:
-
- update
-
- apiGroups:
-
- networking.k8s.io
-
resources:
-
- ingressclasses
-
verbs:
-
- get
-
- list
-
- watch
-
---
-
apiVersion: rbac.authorization.k8s.io/v1
-
kind: ClusterRole
-
metadata:
-
labels:
-
app.kubernetes.io/component: admission-webhook
-
app.kubernetes.io/instance: ingress-nginx
-
app.kubernetes.io/name: ingress-nginx
-
app.kubernetes.io/part-of: ingress-nginx
-
app.kubernetes.io/version: 1.2.0
-
name: ingress-nginx-admission
-
rules:
-
- apiGroups:
-
- admissionregistration.k8s.io
-
resources:
-
- validatingwebhookconfigurations
-
verbs:
-
- get
-
- update
-
---
-
apiVersion: rbac.authorization.k8s.io/v1
-
kind: RoleBinding
-
metadata:
-
labels:
-
app.kubernetes.io/component: controller
-
app.kubernetes.io/instance: ingress-nginx
-
app.kubernetes.io/name: ingress-nginx
-
app.kubernetes.io/part-of: ingress-nginx
-
app.kubernetes.io/version: 1.2.0
-
name: ingress-nginx
-
namespace: default
-
roleRef:
-
apiGroup: rbac.authorization.k8s.io
-
kind: Role
-
name: ingress-nginx
-
subjects:
-
- kind: ServiceAccount
-
name: ingress-nginx
-
namespace: default
-
---
-
apiVersion: rbac.authorization.k8s.io/v1
-
kind: RoleBinding
-
metadata:
-
labels:
-
app.kubernetes.io/component: admission-webhook
-
app.kubernetes.io/instance: ingress-nginx
-
app.kubernetes.io/name: ingress-nginx
-
app.kubernetes.io/part-of: ingress-nginx
-
app.kubernetes.io/version: 1.2.0
-
name: ingress-nginx-admission
-
namespace: default
-
roleRef:
-
apiGroup: rbac.authorization.k8s.io
-
kind: Role
-
name: ingress-nginx-admission
-
subjects:
-
- kind: ServiceAccount
-
name: ingress-nginx-admission
-
namespace: default
-
---
-
apiVersion: rbac.authorization.k8s.io/v1
-
kind: ClusterRoleBinding
-
metadata:
-
labels:
-
app.kubernetes.io/instance: ingress-nginx
-
app.kubernetes.io/name: ingress-nginx
-
app.kubernetes.io/part-of: ingress-nginx
-
app.kubernetes.io/version: 1.2.0
-
name: ingress-nginx
-
roleRef:
-
apiGroup: rbac.authorization.k8s.io
-
kind: ClusterRole
-
name: ingress-nginx
-
subjects:
-
- kind: ServiceAccount
-
name: ingress-nginx
-
namespace: default
-
---
-
apiVersion: rbac.authorization.k8s.io/v1
-
kind: ClusterRoleBinding
-
metadata:
-
labels:
-
app.kubernetes.io/component: admission-webhook
-
app.kubernetes.io/instance: ingress-nginx
-
app.kubernetes.io/name: ingress-nginx
-
app.kubernetes.io/part-of: ingress-nginx
-
app.kubernetes.io/version: 1.2.0
-
name: ingress-nginx-admission
-
roleRef:
-
apiGroup: rbac.authorization.k8s.io
-
kind: ClusterRole
-
name: ingress-nginx-admission
-
subjects:
-
- kind: ServiceAccount
-
name: ingress-nginx-admission
-
namespace: default
-
---
-
apiVersion: v1
-
data:
-
allow-snippet-annotations: "true"
-
kind: ConfigMap
-
metadata:
-
labels:
-
app.kubernetes.io/component: controller
-
app.kubernetes.io/instance: ingress-nginx
-
app.kubernetes.io/name: ingress-nginx
-
app.kubernetes.io/part-of: ingress-nginx
-
app.kubernetes.io/version: 1.2.0
-
name: ingress-nginx-controller
-
namespace: default
-
---
-
apiVersion: v1
-
kind: Service
-
metadata:
-
labels:
-
app.kubernetes.io/component: controller
-
app.kubernetes.io/instance: ingress-nginx
-
app.kubernetes.io/name: ingress-nginx
-
app.kubernetes.io/part-of: ingress-nginx
-
app.kubernetes.io/version: 1.2.0
-
name: ingress-nginx-controller
-
namespace: default
-
spec:
-
#externalTrafficPolicy: Local
-
ports:
-
- appProtocol: http
-
name: http
-
port: 80
-
protocol: TCP
-
targetPort: http
-
- appProtocol: https
-
name: https
-
port: 443
-
protocol: TCP
-
targetPort: https
-
selector:
-
app.kubernetes.io/component: controller
-
app.kubernetes.io/instance: ingress-nginx
-
app.kubernetes.io/name: ingress-nginx
-
# type: LoadBalancer
-
---
-
apiVersion: v1
-
kind: Service
-
metadata:
-
labels:
-
app.kubernetes.io/component: controller
-
app.kubernetes.io/instance: ingress-nginx
-
app.kubernetes.io/name: ingress-nginx
-
app.kubernetes.io/part-of: ingress-nginx
-
app.kubernetes.io/version: 1.2.0
-
name: ingress-nginx-controller-admission
-
namespace: default
-
spec:
-
ports:
-
- appProtocol: https
-
name: https-webhook
-
port: 443
-
targetPort: webhook
-
selector:
-
app.kubernetes.io/component: controller
-
app.kubernetes.io/instance: ingress-nginx
-
app.kubernetes.io/name: ingress-nginx
-
type: ClusterIP
-
---
-
apiVersion: apps/v1
-
#kind: Deployment
-
kind: DaemonSet
-
metadata:
-
labels:
-
app.kubernetes.io/component: controller
-
app.kubernetes.io/instance: ingress-nginx
-
app.kubernetes.io/name: ingress-nginx
-
app.kubernetes.io/part-of: ingress-nginx
-
app.kubernetes.io/version: 1.2.0
-
name: ingress-nginx-controller
-
namespace: default
-
spec:
-
minReadySeconds: 0
-
revisionHistoryLimit: 10
-
selector:
-
matchLabels:
-
app.kubernetes.io/component: controller
-
app.kubernetes.io/instance: ingress-nginx
-
app.kubernetes.io/name: ingress-nginx
-
template:
-
metadata:
-
labels:
-
app.kubernetes.io/component: controller
-
app.kubernetes.io/instance: ingress-nginx
-
app.kubernetes.io/name: ingress-nginx
-
spec:
-
containers:
-
- args:
-
- /nginx-ingress-controller
-
- --publish-service=$(POD_NAMESPACE)/ingress-nginx-controller
-
- --election-id=ingress-controller-leader
-
- --controller-class=k8s.io/ingress-nginx
-
- --ingress-class=nginx
-
- --configmap=$(POD_NAMESPACE)/ingress-nginx-controller
-
- --validating-webhook=:8443
-
- --validating-webhook-certificate=/usr/local/certificates/cert
-
- --validating-webhook-key=/usr/local/certificates/key
-
env:
-
- name: POD_NAME
-
valueFrom:
-
fieldRef:
-
fieldPath: metadata.name
-
- name: POD_NAMESPACE
-
valueFrom:
-
fieldRef:
-
fieldPath: metadata.namespace
-
- name: LD_PRELOAD
-
value: /usr/local/lib/libmimalloc.so
-
image: k8s.gcr.io/ingress-nginx/controller:v1.2.0@sha256:d8196e3bc1e72547c5dec66d6556c0ff92a23f6d0919b206be170bc90d5f9185
-
imagePullPolicy: IfNotPresent
-
lifecycle:
-
preStop:
-
exec:
-
command:
-
- /wait-shutdown
-
livenessProbe:
-
failureThreshold: 5
-
httpGet:
-
path: /healthz
-
port: 10254
-
scheme: HTTP
-
initialDelaySeconds: 10
-
periodSeconds: 10
-
successThreshold: 1
-
timeoutSeconds: 1
-
name: controller
-
ports:
-
- containerPort: 80
-
name: http
-
protocol: TCP
-
- containerPort: 443
-
name: https
-
protocol: TCP
-
- containerPort: 8443
-
name: webhook
-
protocol: TCP
-
readinessProbe:
-
failureThreshold: 3
-
httpGet:
-
path: /healthz
-
port: 10254
-
scheme: HTTP
-
initialDelaySeconds: 10
-
periodSeconds: 10
-
successThreshold: 1
-
timeoutSeconds: 1
-
resources:
-
requests:
-
cpu: 100m
-
memory: 90Mi
-
securityContext:
-
allowPrivilegeEscalation: true
-
capabilities:
-
add:
-
- NET_BIND_SERVICE
-
drop:
-
- ALL
-
runAsUser: 101
-
volumeMounts:
-
- mountPath: /usr/local/certificates/
-
name: webhook-cert
-
readOnly: true
-
# dnsPolicy: ClusterFirst
-
dnsPolicy: ClusterFirstWithHostNet
-
hostNetwork: true
-
nodeSelector:
-
kubernetes.io/os: linux
-
serviceAccountName: ingress-nginx
-
terminationGracePeriodSeconds: 300
-
volumes:
-
- name: webhook-cert
-
secret:
-
secretName: ingress-nginx-admission
-
---
-
apiVersion: batch/v1
-
kind: Job
-
metadata:
-
labels:
-
app.kubernetes.io/component: admission-webhook
-
app.kubernetes.io/instance: ingress-nginx
-
app.kubernetes.io/name: ingress-nginx
-
app.kubernetes.io/part-of: ingress-nginx
-
app.kubernetes.io/version: 1.2.0
-
name: ingress-nginx-admission-create
-
namespace: default
-
spec:
-
template:
-
metadata:
-
labels:
-
app.kubernetes.io/component: admission-webhook
-
app.kubernetes.io/instance: ingress-nginx
-
app.kubernetes.io/name: ingress-nginx
-
app.kubernetes.io/part-of: ingress-nginx
-
app.kubernetes.io/version: 1.2.0
-
name: ingress-nginx-admission-create
-
spec:
-
containers:
-
- args:
-
- create
-
- --host=ingress-nginx-controller-admission,ingress-nginx-controller-admission.$(POD_NAMESPACE).svc
-
- --namespace=$(POD_NAMESPACE)
-
- --secret-name=ingress-nginx-admission
-
env:
-
- name: POD_NAMESPACE
-
valueFrom:
-
fieldRef:
-
fieldPath: metadata.namespace
-
image: k8s.gcr.io/ingress-nginx/kube-webhook-certgen:v1.1.1@sha256:64d8c73dca984af206adf9d6d7e46aa550362b1d7a01f3a0a91b20cc67868660
-
imagePullPolicy: IfNotPresent
-
name: create
-
securityContext:
-
allowPrivilegeEscalation: false
-
nodeSelector:
-
kubernetes.io/os: linux
-
restartPolicy: OnFailure
-
securityContext:
-
fsGroup: 2000
-
runAsNonRoot: true
-
runAsUser: 2000
-
serviceAccountName: ingress-nginx-admission
-
---
-
apiVersion: batch/v1
-
kind: Job
-
metadata:
-
labels:
-
app.kubernetes.io/component: admission-webhook
-
app.kubernetes.io/instance: ingress-nginx
-
app.kubernetes.io/name: ingress-nginx
-
app.kubernetes.io/part-of: ingress-nginx
-
app.kubernetes.io/version: 1.2.0
-
name: ingress-nginx-admission-patch
-
namespace: default
-
spec:
-
template:
-
metadata:
-
labels:
-
app.kubernetes.io/component: admission-webhook
-
app.kubernetes.io/instance: ingress-nginx
-
app.kubernetes.io/name: ingress-nginx
-
app.kubernetes.io/part-of: ingress-nginx
-
app.kubernetes.io/version: 1.2.0
-
name: ingress-nginx-admission-patch
-
spec:
-
containers:
-
- args:
-
- patch
-
- --webhook-name=ingress-nginx-admission
-
- --namespace=$(POD_NAMESPACE)
-
- --patch-mutating=false
-
- --secret-name=ingress-nginx-admission
-
- --patch-failure-policy=Fail
-
env:
-
- name: POD_NAMESPACE
-
valueFrom:
-
fieldRef:
-
fieldPath: metadata.namespace
-
image: k8s.gcr.io/ingress-nginx/kube-webhook-certgen:v1.1.1@sha256:64d8c73dca984af206adf9d6d7e46aa550362b1d7a01f3a0a91b20cc67868660
-
imagePullPolicy: IfNotPresent
-
name: patch
-
securityContext:
-
allowPrivilegeEscalation: false
-
nodeSelector:
-
kubernetes.io/os: linux
-
restartPolicy: OnFailure
-
securityContext:
-
fsGroup: 2000
-
runAsNonRoot: true
-
runAsUser: 2000
-
serviceAccountName: ingress-nginx-admission
-
---
-
apiVersion: networking.k8s.io/v1
-
kind: IngressClass
-
metadata:
-
labels:
-
app.kubernetes.io/component: controller
-
app.kubernetes.io/instance: ingress-nginx
-
app.kubernetes.io/name: ingress-nginx
-
app.kubernetes.io/part-of: ingress-nginx
-
app.kubernetes.io/version: 1.2.0
-
name: nginx
-
spec:
-
controller: k8s.io/ingress-nginx
-
---
-
apiVersion: admissionregistration.k8s.io/v1
-
kind: ValidatingWebhookConfiguration
-
metadata:
-
labels:
-
app.kubernetes.io/component: admission-webhook
-
app.kubernetes.io/instance: ingress-nginx
-
app.kubernetes.io/name: ingress-nginx
-
app.kubernetes.io/part-of: ingress-nginx
-
app.kubernetes.io/version: 1.2.0
-
name: ingress-nginx-admission
-
webhooks:
-
- admissionReviewVersions:
-
- v1
-
clientConfig:
-
service:
-
name: ingress-nginx-controller-admission
-
namespace: default
-
path: /networking/v1/ingresses
-
failurePolicy: Fail
-
matchPolicy: Equivalent
-
name: validate.nginx.ingress.kubernetes.io
-
rules:
-
- apiGroups:
-
- networking.k8s.io
-
apiVersions:
-
- v1
-
operations:
-
- CREATE
-
- UPDATE
-
resources:
-
- ingresses
-
sideEffects: None
-
#### 在master节点执行命令
-
kubectl apply -f deploy.yml
-
-
[root@k8s-master01 k8s]# kubectl apply -f ingress-deploy.yml
-
[root@k8s-master01 k8s]# kubectl get svc
-
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
-
go-test ClusterIP 10.100.201.177 <none> 9099/TCP 13h
-
ingress-nginx-controller ClusterIP 10.106.55.124 <none> 80/TCP,443/TCP 21s
-
ingress-nginx-controller-admission ClusterIP 10.111.49.109 <none> 443/TCP 21s
-
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 94d
-
[root@k8s-master01 k8s]# kubectl get daemonset
-
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
-
ingress-nginx-controller 2 2 0 2 0 kubernetes.io/os=linux 2m51s
-
7-7 route 前端管理页面及效果演示
C:\Users\Administrator\Desktop\gopaas\go-paas-front\route-create.html
-
-
<html lang="en">
-
<head>
-
<meta charset="utf-8">
-
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
-
<meta http-equiv="X-UA-Compatible" content="IE=edge">
-
<meta name="description" content="">
-
<meta name="author" content="">
-
<link rel="shortcut icon" href="assets/img/logo-fav.png">
-
<title>CPaaS</title>
-
<link rel="stylesheet" type="text/css" href="assets/lib/perfect-scrollbar/css/perfect-scrollbar.min.css"/>
-
<link rel="stylesheet" type="text/css" href="assets/lib/material-design-icons/css/material-design-iconic-font.min.css"/><!--[if lt IE 9]>
-
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
-
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
-
<![endif]-->
-
<link rel="stylesheet" href="assets/css/style.css" type="text/css"/>
-
</head>
-
<body>
-
<div class="be-wrapper">
-
<nav class="navbar navbar-default navbar-fixed-top be-top-header">
-
<div class="container-fluid">
-
<div class="navbar-header"><a href="index.html" class="navbar-brand"></a>
-
</div>
-
<div class="be-right-navbar">
-
<ul class="nav navbar-nav navbar-right be-user-nav">
-
<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>
-
<ul role="menu" class="dropdown-menu">
-
<li>
-
<div class="user-info">
-
<div class="user-name">Túpac Amaru</div>
-
<div class="user-position online">Available</div>
-
</div>
-
</li>
-
<li><a href="#"><span class="icon mdi mdi-face"></span> Account</a></li>
-
<li><a href="#"><span class="icon mdi mdi-settings"></span> Settings</a></li>
-
<li><a href="#"><span class="icon mdi mdi-power"></span> Logout</a></li>
-
</ul>
-
</li>
-
</ul>
-
<div class="page-title"><span>Form Validation</span></div>
-
<ul class="nav navbar-nav navbar-right be-icons-nav">
-
<li class="dropdown"><a href="#" role="button" aria-expanded="false" class="be-toggle-right-sidebar"><span class="icon mdi mdi-settings"></span></a></li>
-
<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>
-
<ul class="dropdown-menu be-notifications">
-
<li>
-
<div class="title">Notifications<span class="badge">3</span></div>
-
<div class="list">
-
<div class="be-scroller">
-
<div class="content">
-
<ul>
-
<li class="notification notification-unread"><a href="#">
-
<div class="image"><img src="assets/img/avatar2.png" alt="Avatar"></div>
-
<div class="notification-info">
-
<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>
-
</div></a></li>
-
<li class="notification"><a href="#">
-
<div class="image"><img src="assets/img/avatar3.png" alt="Avatar"></div>
-
<div class="notification-info">
-
<div class="text"><span class="user-name">Joel King</span> is now following you</div><span class="date">2 days ago</span>
-
</div></a></li>
-
<li class="notification"><a href="#">
-
<div class="image"><img src="assets/img/avatar4.png" alt="Avatar"></div>
-
<div class="notification-info">
-
<div class="text"><span class="user-name">John Doe</span> is watching your main repository</div><span class="date">2 days ago</span>
-
</div></a></li>
-
<li class="notification"><a href="#">
-
<div class="image"><img src="assets/img/avatar5.png" alt="Avatar"></div>
-
<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>
-
</ul>
-
</div>
-
</div>
-
</div>
-
<div class="footer"> <a href="#">View all notifications</a></div>
-
</li>
-
</ul>
-
</li>
-
<li class="dropdown"><a href="#" data-toggle="dropdown" role="button" aria-expanded="false" class="dropdown-toggle"><span class="icon mdi mdi-apps"></span></a>
-
<ul class="dropdown-menu be-connections">
-
<li>
-
<div class="list">
-
<div class="content">
-
<div class="row">
-
<div class="col-xs-4"><a href="#" class="connection-item"><img src="assets/img/github.png" alt="Github"><span>GitHub</span></a></div>
-
<div class="col-xs-4"><a href="#" class="connection-item"><img src="assets/img/bitbucket.png" alt="Bitbucket"><span>Bitbucket</span></a></div>
-
<div class="col-xs-4"><a href="#" class="connection-item"><img src="assets/img/slack.png" alt="Slack"><span>Slack</span></a></div>
-
</div>
-
<div class="row">
-
<div class="col-xs-4"><a href="#" class="connection-item"><img src="assets/img/dribbble.png" alt="Dribbble"><span>Dribbble</span></a></div>
-
<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>
-
<div class="col-xs-4"><a href="#" class="connection-item"><img src="assets/img/dropbox.png" alt="Dropbox"><span>Dropbox</span></a></div>
-
</div>
-
</div>
-
</div>
-
<div class="footer"> <a href="#">More</a></div>
-
</li>
-
</ul>
-
</li>
-
</ul>
-
</div>
-
</div>
-
</nav>
-
<!--
-
侧边栏-开始
-
-->
-
<div class="be-left-sidebar">
-
<div class="left-sidebar-wrapper"><a href="#" class="left-sidebar-toggle">看版</a>
-
<div class="left-sidebar-spacer">
-
<div class="left-sidebar-scroll">
-
<div class="left-sidebar-content">
-
<ul class="sidebar-elements">
-
<li class="divider">菜单</li>
-
<li class="parent"><a href="#"><i class="icon mdi mdi-home"></i><span>控制台</span></a>
-
</li>
-
<li class="parent"><a href="#"><i class="icon mdi mdi-face"></i><span>应用管理</span></a>
-
<ul class="sub-menu">
-
<li ><a href="pod-index.html">添加应用</a>
-
</li>
-
</ul>
-
</li>
-
<li class="parent"><a href="charts.html"><i class="icon mdi mdi-chart-donut"></i><span>服务管理</span></a>
-
<ul class="sub-menu">
-
<li ><a href="svc-index.html">添加服务</a>
-
</li>
-
</ul>
-
</li>
-
<li class="parent"><a href="#"><i class="icon mdi mdi-dot-circle"></i><span>域名管理</span></a>
-
<ul class="sub-menu">
-
<li class="active"><a href="route-index.html">添加路由</a>
-
</li>
-
</ul>
-
</li>
-
<li class="parent"><a href="#"><i class="icon mdi mdi-border-all"></i><span>中间件</span></a>
-
<ul class="sub-menu">
-
<li><a href="tables-general.html">General</a>
-
</li>
-
<li><a href="tables-datatables.html">Data Tables</a>
-
</li>
-
<li><a href="tables-filters.html"><span class="label label-primary pull-right">New</span>Table Filters</a>
-
</li>
-
</ul>
-
</li>
-
<li class="parent"><a href="#"><i class="icon mdi mdi-layers"></i><span>应用市场</span></a>
-
<ul class="sub-menu">
-
<li><a href="pages-blank.html">Blank Page</a>
-
</li>
-
<li><a href="pages-blank-header.html">Blank Page Header</a>
-
</li>
-
<li><a href="pages-login.html">Login</a>
-
</li>
-
<li><a href="pages-login2.html">Login v2</a>
-
</li>
-
<li><a href="pages-404.html">404 Page</a>
-
</li>
-
<li><a href="pages-sign-up.html">Sign Up</a>
-
</li>
-
<li><a href="pages-forgot-password.html">Forgot Password</a>
-
</li>
-
<li><a href="pages-profile.html">Profile</a>
-
</li>
-
<li><a href="pages-pricing-tables.html">Pricing Tables</a>
-
</li>
-
<li><a href="pages-pricing-tables2.html">Pricing Tables v2</a>
-
</li>
-
<li><a href="pages-timeline.html">Timeline</a>
-
</li>
-
<li><a href="pages-timeline2.html">Timeline v2</a>
-
</li>
-
<li><a href="pages-invoice.html"><span class="label label-primary pull-right">New</span>Invoice</a>
-
</li>
-
<li><a href="pages-calendar.html">Calendar</a>
-
</li>
-
<li><a href="pages-gallery.html">Gallery</a>
-
</li>
-
<li><a href="pages-code-editor.html"><span class="label label-primary pull-right">New </span>Code Editor</a>
-
</li>
-
<li><a href="pages-booking.html"><span class="label label-primary pull-right">New</span>Booking</a>
-
</li>
-
<li><a href="pages-loaders.html"><span class="label label-primary pull-right">New</span>Loaders</a>
-
</li>
-
</ul>
-
</li>
-
-
</ul>
-
</div>
-
</div>
-
</div>
-
<div class="progress-widget">
-
<div class="progress-data"><span class="progress-value">60%</span><span class="name">Current Project</span></div>
-
<div class="progress">
-
<div style="width: 60%;" class="progress-bar progress-bar-primary"></div>
-
</div>
-
</div>
-
</div>
-
</div>
-
<!--
-
侧边栏-结束
-
-->
-
<div class="be-content">
-
<div class="main-content container-fluid">
-
<div class="row">
-
<div class="col-md-12">
-
<div class="panel panel-default panel-border-color panel-border-color-primary">
-
<div class="panel-heading panel-heading-divider">添加路由<span class="panel-subtitle"></span></div>
-
<div class="panel-body">
-
<form action="http://localhost:8080/routeApi/addRoute" class="form-horizontal group-border-dashed" method="post" >
-
<div class="form-group">
-
<label class="col-sm-3 control-label">路由名称:</label>
-
<div class="col-sm-6">
-
<input type="text" required="" class="form-control" id="route_name" name="route_name">
-
</div>
-
</div>
-
<div class="form-group">
-
<label class="col-sm-3 control-label">命名空间:</label>
-
<div class="col-sm-6">
-
<input type="text" required="" class="form-control" id="route_namespace" name="route_namespace" value="default">
-
</div>
-
</div>
-
<div class="form-group">
-
<label class="col-sm-3 control-label">设置域名:</label>
-
<div class="col-sm-6">
-
<input type="text" required="" class="form-control" id="route_host" name="route_host" >
-
</div>
-
</div>
-
<div class="form-group">
-
<label class="col-sm-3 control-label">设置路径:</label>
-
<div class="col-sm-6">
-
<input type="text" required="" class="form-control" name="route_path_name" id="route_path_name">
-
</div>
-
</div>
-
<div class="form-group">
-
<label class="col-sm-3 control-label">后端服务:</label>
-
<div class="col-sm-6">
-
<input type="text" required="" class="form-control" id="" name="route_backend_service" id="route_backend_service">
-
</div>
-
</div>
-
-
<div class="form-group">
-
<label class="col-sm-3 control-label">后端服务端口:</label>
-
<div class="col-sm-6">
-
<input type="text" required="" class="form-control" name="route_backend_service_port" id="route_backend_service_port">
-
</div>
-
</div>
-
-
<div class="form-group">
-
<div class="col-sm-2 col-sm-10">
-
<button type="submit" class="btn btn-space btn-primary">添加路由</button>
-
<button class="btn btn-space btn-default">Cancel</button>
-
</div>
-
</div>
-
</form>
-
</div>
-
</div>
-
</div>
-
</div>
-
</div>
-
</div>
-
-
</div>
-
<script src="assets/lib/jquery/jquery.min.js" type="text/javascript"></script>
-
<script src="assets/lib/perfect-scrollbar/js/perfect-scrollbar.jquery.min.js" type="text/javascript"></script>
-
<script src="assets/js/main.js" type="text/javascript"></script>
-
<script src="assets/lib/bootstrap/dist/js/bootstrap.min.js" type="text/javascript"></script>
-
<script src="assets/lib/parsley/parsley.min.js" type="text/javascript"></script>
-
-
<script type="text/javascript">
-
$(document).ready(function(){
-
App.init();
-
});
-
-
//获取url中的参数
-
function getUrlParam(name) {
-
var reg = new RegExp("(^|&)" name "=([^&]*)(&|$)"); //构造一个含有目标参数的正则表达式对象
-
var r = window.location.search.substr(1).match(reg); //匹配目标参数
-
if (r != null) return unescape(r[2]); return null; //返回参数值
-
}
-
-
</script>
-
-
</body>
-
</html>
C:\Users\Administrator\Desktop\gopaas\go-paas-front\route-detail.html
-
-
<html lang="en">
-
<head>
-
<meta charset="utf-8">
-
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
-
<meta http-equiv="X-UA-Compatible" content="IE=edge">
-
<meta name="description" content="">
-
<meta name="author" content="">
-
<link rel="shortcut icon" href="assets/img/logo-fav.png">
-
<title>CPaaS</title>
-
<link rel="stylesheet" type="text/css" href="assets/lib/perfect-scrollbar/css/perfect-scrollbar.min.css"/>
-
<link rel="stylesheet" type="text/css" href="assets/lib/material-design-icons/css/material-design-iconic-font.min.css"/><!--[if lt IE 9]>
-
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
-
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
-
<![endif]-->
-
<link rel="stylesheet" href="assets/css/style.css" type="text/css"/>
-
</head>
-
<body>
-
<div class="be-wrapper">
-
<nav class="navbar navbar-default navbar-fixed-top be-top-header">
-
<div class="container-fluid">
-
<div class="navbar-header"><a href="index.html" class="navbar-brand"></a>
-
</div>
-
<div class="be-right-navbar">
-
<ul class="nav navbar-nav navbar-right be-user-nav">
-
<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>
-
<ul role="menu" class="dropdown-menu">
-
<li>
-
<div class="user-info">
-
<div class="user-name">Túpac Amaru</div>
-
<div class="user-position online">Available</div>
-
</div>
-
</li>
-
<li><a href="#"><span class="icon mdi mdi-face"></span> Account</a></li>
-
<li><a href="#"><span class="icon mdi mdi-settings"></span> Settings</a></li>
-
<li><a href="#"><span class="icon mdi mdi-power"></span> Logout</a></li>
-
</ul>
-
</li>
-
</ul>
-
<div class="page-title"><span>Form Validation</span></div>
-
<ul class="nav navbar-nav navbar-right be-icons-nav">
-
<li class="dropdown"><a href="#" role="button" aria-expanded="false" class="be-toggle-right-sidebar"><span class="icon mdi mdi-settings"></span></a></li>
-
<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>
-
<ul class="dropdown-menu be-notifications">
-
<li>
-
<div class="title">Notifications<span class="badge">3</span></div>
-
<div class="list">
-
<div class="be-scroller">
-
<div class="content">
-
<ul>
-
<li class="notification notification-unread"><a href="#">
-
<div class="image"><img src="assets/img/avatar2.png" alt="Avatar"></div>
-
<div class="notification-info">
-
<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>
-
</div></a></li>
-
<li class="notification"><a href="#">
-
<div class="image"><img src="assets/img/avatar3.png" alt="Avatar"></div>
-
<div class="notification-info">
-
<div class="text"><span class="user-name">Joel King</span> is now following you</div><span class="date">2 days ago</span>
-
</div></a></li>
-
<li class="notification"><a href="#">
-
<div class="image"><img src="assets/img/avatar4.png" alt="Avatar"></div>
-
<div class="notification-info">
-
<div class="text"><span class="user-name">John Doe</span> is watching your main repository</div><span class="date">2 days ago</span>
-
</div></a></li>
-
<li class="notification"><a href="#">
-
<div class="image"><img src="assets/img/avatar5.png" alt="Avatar"></div>
-
<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>
-
</ul>
-
</div>
-
</div>
-
</div>
-
<div class="footer"> <a href="#">View all notifications</a></div>
-
</li>
-
</ul>
-
</li>
-
<li class="dropdown"><a href="#" data-toggle="dropdown" role="button" aria-expanded="false" class="dropdown-toggle"><span class="icon mdi mdi-apps"></span></a>
-
<ul class="dropdown-menu be-connections">
-
<li>
-
<div class="list">
-
<div class="content">
-
<div class="row">
-
<div class="col-xs-4"><a href="#" class="connection-item"><img src="assets/img/github.png" alt="Github"><span>GitHub</span></a></div>
-
<div class="col-xs-4"><a href="#" class="connection-item"><img src="assets/img/bitbucket.png" alt="Bitbucket"><span>Bitbucket</span></a></div>
-
<div class="col-xs-4"><a href="#" class="connection-item"><img src="assets/img/slack.png" alt="Slack"><span>Slack</span></a></div>
-
</div>
-
<div class="row">
-
<div class="col-xs-4"><a href="#" class="connection-item"><img src="assets/img/dribbble.png" alt="Dribbble"><span>Dribbble</span></a></div>
-
<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>
-
<div class="col-xs-4"><a href="#" class="connection-item"><img src="assets/img/dropbox.png" alt="Dropbox"><span>Dropbox</span></a></div>
-
</div>
-
</div>
-
</div>
-
<div class="footer"> <a href="#">More</a></div>
-
</li>
-
</ul>
-
</li>
-
</ul>
-
</div>
-
</div>
-
</nav>
-
<!--
-
侧边栏-开始
-
-->
-
<div class="be-left-sidebar">
-
<div class="left-sidebar-wrapper"><a href="#" class="left-sidebar-toggle">看版</a>
-
<div class="left-sidebar-spacer">
-
<div class="left-sidebar-scroll">
-
<div class="left-sidebar-content">
-
<ul class="sidebar-elements">
-
<li class="divider">菜单</li>
-
<li class="parent"><a href="#"><i class="icon mdi mdi-home"></i><span>控制台</span></a>
-
</li>
-
<li class="parent"><a href="#"><i class="icon mdi mdi-face"></i><span>应用管理</span></a>
-
<ul class="sub-menu">
-
<li ><a href="pod-index.html">添加应用</a>
-
</li>
-
</ul>
-
</li>
-
<li class="parent"><a href="charts.html"><i class="icon mdi mdi-chart-donut"></i><span>服务管理</span></a>
-
<ul class="sub-menu">
-
<li ><a href="svc-index.html">添加服务</a>
-
</li>
-
</ul>
-
</li>
-
<li class="parent"><a href="#"><i class="icon mdi mdi-dot-circle"></i><span>域名管理</span></a>
-
<ul class="sub-menu">
-
<li class="active"><a href="route-index.html">添加路由</a>
-
</li>
-
</ul>
-
</li>
-
<li class="parent"><a href="#"><i class="icon mdi mdi-border-all"></i><span>中间件</span></a>
-
<ul class="sub-menu">
-
<li><a href="tables-general.html">General</a>
-
</li>
-
<li><a href="tables-datatables.html">Data Tables</a>
-
</li>
-
<li><a href="tables-filters.html"><span class="label label-primary pull-right">New</span>Table Filters</a>
-
</li>
-
</ul>
-
</li>
-
<li class="parent"><a href="#"><i class="icon mdi mdi-layers"></i><span>应用市场</span></a>
-
<ul class="sub-menu">
-
<li><a href="pages-blank.html">Blank Page</a>
-
</li>
-
<li><a href="pages-blank-header.html">Blank Page Header</a>
-
</li>
-
<li><a href="pages-login.html">Login</a>
-
</li>
-
<li><a href="pages-login2.html">Login v2</a>
-
</li>
-
<li><a href="pages-404.html">404 Page</a>
-
</li>
-
<li><a href="pages-sign-up.html">Sign Up</a>
-
</li>
-
<li><a href="pages-forgot-password.html">Forgot Password</a>
-
</li>
-
<li><a href="pages-profile.html">Profile</a>
-
</li>
-
<li><a href="pages-pricing-tables.html">Pricing Tables</a>
-
</li>
-
<li><a href="pages-pricing-tables2.html">Pricing Tables v2</a>
-
</li>
-
<li><a href="pages-timeline.html">Timeline</a>
-
</li>
-
<li><a href="pages-timeline2.html">Timeline v2</a>
-
</li>
-
<li><a href="pages-invoice.html"><span class="label label-primary pull-right">New</span>Invoice</a>
-
</li>
-
<li><a href="pages-calendar.html">Calendar</a>
-
</li>
-
<li><a href="pages-gallery.html">Gallery</a>
-
</li>
-
<li><a href="pages-code-editor.html"><span class="label label-primary pull-right">New </span>Code Editor</a>
-
</li>
-
<li><a href="pages-booking.html"><span class="label label-primary pull-right">New</span>Booking</a>
-
</li>
-
<li><a href="pages-loaders.html"><span class="label label-primary pull-right">New</span>Loaders</a>
-
</li>
-
</ul>
-
</li>
-
-
</ul>
-
</div>
-
</div>
-
</div>
-
<div class="progress-widget">
-
<div class="progress-data"><span class="progress-value">60%</span><span class="name">Current Project</span></div>
-
<div class="progress">
-
<div style="width: 60%;" class="progress-bar progress-bar-primary"></div>
-
</div>
-
</div>
-
</div>
-
</div>
-
<!--
-
侧边栏-结束
-
-->
-
<div class="be-content">
-
<div class="main-content container-fluid">
-
<div class="row">
-
<div class="col-md-12">
-
<div class="panel panel-default panel-border-color panel-border-color-primary">
-
<div class="panel-heading panel-heading-divider">路由详情<span class="panel-subtitle">查看路由详情信息</span></div>
-
<div class="panel-body">
-
<form action="#" class="form-horizontal group-border-dashed">
-
<div class="form-group">
-
<label class="col-sm-3 control-label">路由ID:</label>
-
<div class="col-sm-6">
-
<input type="text" required="" readonly class="form-control" id="route_id" name="route_id">
-
</div>
-
</div>
-
<div class="form-group">
-
<label class="col-sm-3 control-label">路由名称:</label>
-
<div class="col-sm-6">
-
<input type="text" required="" readonly class="form-control" id="route_name" name="route_name">
-
</div>
-
</div>
-
<div class="form-group">
-
<label class="col-sm-3 control-label">命名空间:</label>
-
<div class="col-sm-6">
-
<input type="text" required="" readonly class="form-control" id="route_namespace" name="route_namespace">
-
</div>
-
</div>
-
<div class="form-group">
-
<label class="col-sm-3 control-label">设置域名:</label>
-
<div class="col-sm-6">
-
<input type="text" required="" class="form-control" id="route_host" name="route_host" >
-
</div>
-
</div>
-
<div class="form-group">
-
<label class="col-sm-3 control-label">设置路径:</label>
-
<div class="col-sm-6">
-
<input type="text" required="" class="form-control" name="route_path_name" id="route_path_name">
-
</div>
-
</div>
-
<div class="form-group">
-
<label class="col-sm-3 control-label">后端服务:</label>
-
<div class="col-sm-6">
-
<input type="text" required="" class="form-control" name="route_backend_service" id="route_backend_service">
-
</div>
-
</div>
-
-
<div class="form-group">
-
<label class="col-sm-3 control-label">后端服务端口:</label>
-
<div class="col-sm-6">
-
<input type="text" required="" class="form-control" name="route_backend_service_port" id="route_backend_service_port">
-
</div>
-
</div>
-
-
-
-
</form>
-
</div>
-
</div>
-
</div>
-
</div>
-
</div>
-
</div>
-
-
</div>
-
<script src="assets/lib/jquery/jquery.min.js" type="text/javascript"></script>
-
<script src="assets/lib/perfect-scrollbar/js/perfect-scrollbar.jquery.min.js" type="text/javascript"></script>
-
<script src="assets/js/main.js" type="text/javascript"></script>
-
<script src="assets/lib/bootstrap/dist/js/bootstrap.min.js" type="text/javascript"></script>
-
<script src="assets/lib/parsley/parsley.min.js" type="text/javascript"></script>
-
<script type="text/javascript">
-
$(document).ready(function(){
-
App.init();
-
$('form').parsley();
-
$.ajax({
-
type:"get",
-
url:"http://127.0.0.1:8080/routeApi/findRouteById?route_id=" getUrlParam('route_id'),
-
success: function(data){
-
console.log(data);
-
if(data.id != "" || data.id != null || data.id != undefined){
-
$('#route_id').val(data.id);
-
$("#route_name").val(data.route_name);
-
$('#route_namespace').val(data.route_namespace);
-
$('#route_host').val(data.route_host);
-
//这里有多个要循环
-
$('#route_path_name').val(data.route_path[0]['route_path_name']);
-
$('#route_backend_service').val(data.route_path[0]['route_backend_service']);
-
$('#route_backend_service_port').val(data.route_path[0]['route_backend_service_port']);
-
-
}else{
-
console.log(data);
-
}
-
},
-
error: function(result){
-
console.log(result);
-
}
-
});
-
});
-
-
//获取url中的参数
-
function getUrlParam(name) {
-
var reg = new RegExp("(^|&)" name "=([^&]*)(&|$)"); //构造一个含有目标参数的正则表达式对象
-
var r = window.location.search.substr(1).match(reg); //匹配目标参数
-
if (r != null) return unescape(r[2]); return null; //返回参数值
-
}
-
-
</script>
-
-
</body>
-
</html>
C:\Users\Administrator\Desktop\gopaas\go-paas-front\route-index.html
-
-
<html lang="en">
-
<head>
-
<meta charset="utf-8">
-
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
-
<meta http-equiv="X-UA-Compatible" content="IE=edge">
-
<meta name="description" content="">
-
<meta name="author" content="">
-
<link rel="shortcut icon" href="assets/img/logo-fav.png">
-
<title>CPaaS</title>
-
<link rel="stylesheet" type="text/css" href="assets/lib/perfect-scrollbar/css/perfect-scrollbar.min.css"/>
-
<link rel="stylesheet" type="text/css" href="assets/lib/material-design-icons/css/material-design-iconic-font.min.css"/><!--[if lt IE 9]>
-
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
-
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
-
<![endif]-->
-
<link rel="stylesheet" type="text/css" href="assets/lib/datatables/css/dataTables.bootstrap.min.css"/>
-
<link rel="stylesheet" href="assets/css/style.css" type="text/css"/>
-
</head>
-
<body>
-
<div class="be-wrapper">
-
<nav class="navbar navbar-default navbar-fixed-top be-top-header">
-
<div class="container-fluid">
-
<div class="navbar-header"><a href="index.html" class="navbar-brand"></a>
-
</div>
-
<div class="be-right-navbar">
-
<ul class="nav navbar-nav navbar-right be-user-nav">
-
<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>
-
<ul role="menu" class="dropdown-menu">
-
<li>
-
<div class="user-info">
-
<div class="user-name">wu123</div>
-
<div class="user-position online">在线</div>
-
</div>
-
</li>
-
<li><a href="#"><span class="icon mdi mdi-face"></span> 账户</a></li>
-
<li><a href="#"><span class="icon mdi mdi-settings"></span> 设置</a></li>
-
<li><a href="#"><span class="icon mdi mdi-power"></span> 推出登录</a></li>
-
</ul>
-
</li>
-
</ul>
-
<div class="page-title"></div>
-
<ul class="nav navbar-nav navbar-right be-icons-nav">
-
<li class="dropdown"><a href="#" role="button" aria-expanded="false" class="be-toggle-right-sidebar"><span class="icon mdi mdi-settings"></span></a></li>
-
<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>
-
<ul class="dropdown-menu be-notifications">
-
<li>
-
<div class="title">消息提醒<span class="badge">3</span></div>
-
<div class="list">
-
<div class="be-scroller">
-
<div class="content">
-
<ul>
-
<li class="notification notification-unread"><a href="#">
-
<div class="image"><img src="assets/img/avatar2.png" alt="Avatar"></div>
-
<div class="notification-info">
-
<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>
-
</div></a></li>
-
<li class="notification"><a href="#">
-
<div class="image"><img src="assets/img/avatar3.png" alt="Avatar"></div>
-
<div class="notification-info">
-
<div class="text"><span class="user-name">Joel King</span> is now following you</div><span class="date">2 days ago</span>
-
</div></a></li>
-
<li class="notification"><a href="#">
-
<div class="image"><img src="assets/img/avatar4.png" alt="Avatar"></div>
-
<div class="notification-info">
-
<div class="text"><span class="user-name">John Doe</span> is watching your main repository</div><span class="date">2 days ago</span>
-
</div></a></li>
-
<li class="notification"><a href="#">
-
<div class="image"><img src="assets/img/avatar5.png" alt="Avatar"></div>
-
<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>
-
</ul>
-
</div>
-
</div>
-
</div>
-
<div class="footer"> <a href="#">View all notifications</a></div>
-
</li>
-
</ul>
-
</li>
-
<li class="dropdown"><a href="#" data-toggle="dropdown" role="button" aria-expanded="false" class="dropdown-toggle"><span class="icon mdi mdi-apps"></span></a>
-
<ul class="dropdown-menu be-connections">
-
<li>
-
<div class="list">
-
<div class="content">
-
<div class="row">
-
<div class="col-xs-4"><a href="#" class="connection-item"><img src="assets/img/github.png" alt="Github"><span>GitHub</span></a></div>
-
<div class="col-xs-4"><a href="#" class="connection-item"><img src="assets/img/bitbucket.png" alt="Bitbucket"><span>Bitbucket</span></a></div>
-
<div class="col-xs-4"><a href="#" class="connection-item"><img src="assets/img/slack.png" alt="Slack"><span>Slack</span></a></div>
-
</div>
-
<div class="row">
-
<div class="col-xs-4"><a href="#" class="connection-item"><img src="assets/img/dribbble.png" alt="Dribbble"><span>Dribbble</span></a></div>
-
<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>
-
<div class="col-xs-4"><a href="#" class="connection-item"><img src="assets/img/dropbox.png" alt="Dropbox"><span>Dropbox</span></a></div>
-
</div>
-
</div>
-
</div>
-
<div class="footer"> <a href="#">More</a></div>
-
</li>
-
</ul>
-
</li>
-
</ul>
-
</div>
-
</div>
-
</nav>
-
<!--
-
侧边栏-开始
-
-->
-
<div class="be-left-sidebar">
-
<div class="left-sidebar-wrapper"><a href="#" class="left-sidebar-toggle">看版</a>
-
<div class="left-sidebar-spacer">
-
<div class="left-sidebar-scroll">
-
<div class="left-sidebar-content">
-
<ul class="sidebar-elements">
-
<li class="divider">菜单</li>
-
<li class="parent"><a href="#"><i class="icon mdi mdi-home"></i><span>控制台</span></a>
-
</li>
-
<li class="parent"><a href="#"><i class="icon mdi mdi-face"></i><span>应用管理</span></a>
-
<ul class="sub-menu">
-
<li ><a href="pod-index.html">添加应用</a>
-
</li>
-
</ul>
-
</li>
-
<li class="parent"><a href="charts.html"><i class="icon mdi mdi-chart-donut"></i><span>服务管理</span></a>
-
<ul class="sub-menu">
-
<li ><a href="svc-index.html">添加服务</a>
-
</li>
-
</ul>
-
</li>
-
<li class="parent"><a href="#"><i class="icon mdi mdi-dot-circle"></i><span>域名管理</span></a>
-
<ul class="sub-menu">
-
<li class="active"><a href="route-index.html">添加路由</a>
-
</li>
-
</ul>
-
</li>
-
<li class="parent"><a href="#"><i class="icon mdi mdi-border-all"></i><span>中间件</span></a>
-
<ul class="sub-menu">
-
<li><a href="tables-general.html">General</a>
-
</li>
-
<li><a href="tables-datatables.html">Data Tables</a>
-
</li>
-
<li><a href="tables-filters.html"><span class="label label-primary pull-right">New</span>Table Filters</a>
-
</li>
-
</ul>
-
</li>
-
<li class="parent"><a href="#"><i class="icon mdi mdi-layers"></i><span>应用市场</span></a>
-
<ul class="sub-menu">
-
<li><a href="pages-blank.html">Blank Page</a>
-
</li>
-
<li><a href="pages-blank-header.html">Blank Page Header</a>
-
</li>
-
<li><a href="pages-login.html">Login</a>
-
</li>
-
<li><a href="pages-login2.html">Login v2</a>
-
</li>
-
<li><a href="pages-404.html">404 Page</a>
-
</li>
-
<li><a href="pages-sign-up.html">Sign Up</a>
-
</li>
-
<li><a href="pages-forgot-password.html">Forgot Password</a>
-
</li>
-
<li><a href="pages-profile.html">Profile</a>
-
</li>
-
<li><a href="pages-pricing-tables.html">Pricing Tables</a>
-
</li>
-
<li><a href="pages-pricing-tables2.html">Pricing Tables v2</a>
-
</li>
-
<li><a href="pages-timeline.html">Timeline</a>
-
</li>
-
<li><a href="pages-timeline2.html">Timeline v2</a>
-
</li>
-
<li><a href="pages-invoice.html"><span class="label label-primary pull-right">New</span>Invoice</a>
-
</li>
-
<li><a href="pages-calendar.html">Calendar</a>
-
</li>
-
<li><a href="pages-gallery.html">Gallery</a>
-
</li>
-
<li><a href="pages-code-editor.html"><span class="label label-primary pull-right">New </span>Code Editor</a>
-
</li>
-
<li><a href="pages-booking.html"><span class="label label-primary pull-right">New</span>Booking</a>
-
</li>
-
<li><a href="pages-loaders.html"><span class="label label-primary pull-right">New</span>Loaders</a>
-
</li>
-
</ul>
-
</li>
-
-
</ul>
-
</div>
-
</div>
-
</div>
-
<div class="progress-widget">
-
<div class="progress-data"><span class="progress-value">60%</span><span class="name">Current Project</span></div>
-
<div class="progress">
-
<div style="width: 60%;" class="progress-bar progress-bar-primary"></div>
-
</div>
-
</div>
-
</div>
-
</div>
-
<!--
-
侧边栏-结束
-
-->
-
<div class="be-content">
-
<div class="page-head">
-
<h2 class="page-head-title">路由管理</h2>
-
<ol class="breadcrumb page-head-nav">
-
<li><a href="#">控制台</a></li>
-
<li><a href="#">路由管理</a></li>
-
<li class="active">路由列表</li>
-
</ol>
-
</div>
-
<div class="main-content container-fluid">
-
<div class="row">
-
<div class="col-sm-12">
-
<div class="panel panel-default panel-table">
-
<div class="panel-heading">
-
<a href="route-create.html"><button class="btn btn-space btn-primary">添加路由</button></a>
-
<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>
-
<ul role="menu" class="dropdown-menu pull-right">
-
<li><a href="#">Action</a></li>
-
<li><a href="#">Another action</a></li>
-
<li><a href="#">Something else here</a></li>
-
<li class="divider"></li>
-
<li><a href="#">Separated link</a></li>
-
</ul>
-
</div>
-
</div>
-
<div class="panel-body">
-
<table id="table1" class="table table-striped table-hover table-fw-widget">
-
<thead>
-
<tr>
-
<th>ID</th>
-
<th>域名</th>
-
<th>命名空间</th>
-
<th>路径</th>
-
<th>操作</th>
-
</tr>
-
</thead>
-
<tbody id="table-data">
-
</tbody>
-
</table>
-
</div>
-
</div>
-
</div>
-
</div>
-
-
</div>
-
</div>
-
<nav class="be-right-sidebar">
-
<div class="sb-content">
-
<div class="tab-navigation">
-
<ul role="tablist" class="nav nav-tabs nav-justified">
-
<li role="presentation" class="active"><a href="#tab1" aria-controls="tab1" role="tab" data-toggle="tab">Chat</a></li>
-
<li role="presentation"><a href="#tab2" aria-controls="tab2" role="tab" data-toggle="tab">Todo</a></li>
-
<li role="presentation"><a href="#tab3" aria-controls="tab3" role="tab" data-toggle="tab">Settings</a></li>
-
</ul>
-
</div>
-
<div class="tab-panel">
-
<div class="tab-content">
-
<div id="tab1" role="tabpanel" class="tab-pane tab-chat active">
-
<div class="chat-contacts">
-
<div class="chat-sections">
-
<div class="be-scroller">
-
<div class="content">
-
<h2>Recent</h2>
-
<div class="contact-list contact-list-recent">
-
<div class="user"><a href="#"><img src="assets/img/avatar1.png" alt="Avatar">
-
<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>
-
<div class="user"><a href="#"><img src="assets/img/avatar2.png" alt="Avatar">
-
<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>
-
<div class="user"><a href="#"><img src="assets/img/avatar3.png" alt="Avatar">
-
<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>
-
</div>
-
<h2>Contacts</h2>
-
<div class="contact-list">
-
<div class="user"><a href="#"><img src="assets/img/avatar4.png" alt="Avatar">
-
<div class="user-data2"><span class="status"></span><span class="name">Mike Bolthort</span></div></a></div>
-
<div class="user"><a href="#"><img src="assets/img/avatar5.png" alt="Avatar">
-
<div class="user-data2"><span class="status"></span><span class="name">Maggie jackson</span></div></a></div>
-
<div class="user"><a href="#"><img src="assets/img/avatar6.png" alt="Avatar">
-
<div class="user-data2"><span class="status offline"></span><span class="name">Jhon Voltemar</span></div></a></div>
-
</div>
-
</div>
-
</div>
-
</div>
-
<div class="bottom-input">
-
<input type="text" placeholder="Search..." name="q"><span class="mdi mdi-search"></span>
-
</div>
-
</div>
-
<div class="chat-window">
-
<div class="title">
-
<div class="user"><img src="assets/img/avatar2.png" alt="Avatar">
-
<h2>Maggie jackson</h2><span>Active 1h ago</span>
-
</div><span class="icon return mdi mdi-chevron-left"></span>
-
</div>
-
<div class="chat-messages">
-
<div class="be-scroller">
-
<div class="content">
-
<ul>
-
<li class="friend">
-
<div class="msg">Hello</div>
-
</li>
-
<li class="self">
-
<div class="msg">Hi, how are you?</div>
-
</li>
-
<li class="friend">
-
<div class="msg">Good, I'll need support with my pc</div>
-
</li>
-
<li class="self">
-
<div class="msg">Sure, just tell me what is going on with your computer?</div>
-
</li>
-
<li class="friend">
-
<div class="msg">I don't know it just turns off suddenly</div>
-
</li>
-
</ul>
-
</div>
-
</div>
-
</div>
-
<div class="chat-input">
-
<div class="input-wrapper"><span class="photo mdi mdi-camera"></span>
-
<input type="text" placeholder="Message..." name="q" autocomplete="off"><span class="send-msg mdi mdi-mail-send"></span>
-
</div>
-
</div>
-
</div>
-
</div>
-
<div id="tab2" role="tabpanel" class="tab-pane tab-todo">
-
<div class="todo-container">
-
<div class="todo-wrapper">
-
<div class="be-scroller">
-
<div class="todo-content"><span class="category-title">Today</span>
-
<ul class="todo-list">
-
<li>
-
<div class="be-checkbox be-checkbox-sm"><span class="delete mdi mdi-delete"></span>
-
<input id="todo1" type="checkbox" checked="">
-
<label for="todo1">Initialize the project</label>
-
</div>
-
</li>
-
<li>
-
<div class="be-checkbox be-checkbox-sm"><span class="delete mdi mdi-delete"></span>
-
<input id="todo2" type="checkbox">
-
<label for="todo2">Create the main structure</label>
-
</div>
-
</li>
-
<li>
-
<div class="be-checkbox be-checkbox-sm"><span class="delete mdi mdi-delete"></span>
-
<input id="todo3" type="checkbox">
-
<label for="todo3">Updates changes to GitHub</label>
-
</div>
-
</li>
-
</ul><span class="category-title">Tomorrow</span>
-
<ul class="todo-list">
-
<li>
-
<div class="be-checkbox be-checkbox-sm"><span class="delete mdi mdi-delete"></span>
-
<input id="todo4" type="checkbox">
-
<label for="todo4">Initialize the project</label>
-
</div>
-
</li>
-
<li>
-
<div class="be-checkbox be-checkbox-sm"><span class="delete mdi mdi-delete"></span>
-
<input id="todo5" type="checkbox">
-
<label for="todo5">Create the main structure</label>
-
</div>
-
</li>
-
<li>
-
<div class="be-checkbox be-checkbox-sm"><span class="delete mdi mdi-delete"></span>
-
<input id="todo6" type="checkbox">
-
<label for="todo6">Updates changes to GitHub</label>
-
</div>
-
</li>
-
<li>
-
<div class="be-checkbox be-checkbox-sm"><span class="delete mdi mdi-delete"></span>
-
<input id="todo7" type="checkbox">
-
<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>
-
</div>
-
</li>
-
</ul>
-
</div>
-
</div>
-
</div>
-
<div class="bottom-input">
-
<input type="text" placeholder="Create new task..." name="q"><span class="mdi mdi-plus"></span>
-
</div>
-
</div>
-
</div>
-
<div id="tab3" role="tabpanel" class="tab-pane tab-settings">
-
<div class="settings-wrapper">
-
<div class="be-scroller"><span class="category-title">General</span>
-
<ul class="settings-list">
-
<li>
-
<div class="switch-button switch-button-sm">
-
<input type="checkbox" checked="" name="st1" id="st1"><span>
-
<label for="st1"></label></span>
-
</div><span class="name">Available</span>
-
</li>
-
<li>
-
<div class="switch-button switch-button-sm">
-
<input type="checkbox" checked="" name="st2" id="st2"><span>
-
<label for="st2"></label></span>
-
</div><span class="name">Enable notifications</span>
-
</li>
-
<li>
-
<div class="switch-button switch-button-sm">
-
<input type="checkbox" checked="" name="st3" id="st3"><span>
-
<label for="st3"></label></span>
-
</div><span class="name">Login with Facebook</span>
-
</li>
-
</ul><span class="category-title">Notifications</span>
-
<ul class="settings-list">
-
<li>
-
<div class="switch-button switch-button-sm">
-
<input type="checkbox" name="st4" id="st4"><span>
-
<label for="st4"></label></span>
-
</div><span class="name">Email notifications</span>
-
</li>
-
<li>
-
<div class="switch-button switch-button-sm">
-
<input type="checkbox" checked="" name="st5" id="st5"><span>
-
<label for="st5"></label></span>
-
</div><span class="name">Project updates</span>
-
</li>
-
<li>
-
<div class="switch-button switch-button-sm">
-
<input type="checkbox" checked="" name="st6" id="st6"><span>
-
<label for="st6"></label></span>
-
</div><span class="name">New comments</span>
-
</li>
-
<li>
-
<div class="switch-button switch-button-sm">
-
<input type="checkbox" name="st7" id="st7"><span>
-
<label for="st7"></label></span>
-
</div><span class="name">Chat messages</span>
-
</li>
-
</ul><span class="category-title">Workflow</span>
-
<ul class="settings-list">
-
<li>
-
<div class="switch-button switch-button-sm">
-
<input type="checkbox" name="st8" id="st8"><span>
-
<label for="st8"></label></span>
-
</div><span class="name">Deploy on commit</span>
-
</li>
-
</ul>
-
</div>
-
</div>
-
</div>
-
</div>
-
</div>
-
</div>
-
</nav>
-
</div>
-
<script src="assets/lib/jquery/jquery.min.js" type="text/javascript"></script>
-
<script src="assets/lib/perfect-scrollbar/js/perfect-scrollbar.jquery.min.js" type="text/javascript"></script>
-
<script src="assets/js/main.js" type="text/javascript"></script>
-
<script src="assets/lib/bootstrap/dist/js/bootstrap.min.js" type="text/javascript"></script>
-
<script src="assets/lib/datatables/js/jquery.dataTables.min.js" type="text/javascript"></script>
-
<script src="assets/lib/datatables/js/dataTables.bootstrap.min.js" type="text/javascript"></script>
-
<script src="assets/lib/datatables/plugins/buttons/js/dataTables.buttons.js" type="text/javascript"></script>
-
<script src="assets/lib/datatables/plugins/buttons/js/buttons.html5.js" type="text/javascript"></script>
-
<script src="assets/lib/datatables/plugins/buttons/js/buttons.flash.js" type="text/javascript"></script>
-
<script src="assets/lib/datatables/plugins/buttons/js/buttons.print.js" type="text/javascript"></script>
-
<script src="assets/lib/datatables/plugins/buttons/js/buttons.colVis.js" type="text/javascript"></script>
-
<script src="assets/lib/datatables/plugins/buttons/js/buttons.bootstrap.js" type="text/javascript"></script>
-
<script src="assets/js/app-tables-datatables.js" type="text/javascript"></script>
-
-
<script type="text/javascript">
-
$(document).ready(function(){
-
-
//initialize the javascript
-
App.init();
-
-
App.dataTables();
-
-
$.ajax({
-
type:"get",
-
url:"http://127.0.0.1:8080/routeApi/",
-
success: function(data){
-
console.log(data);
-
$("#table-data").html("");
-
$.each(data['route_info'],function (i,item) {
-
$("#table-data").append(' <tr class="gradeA">\
-
<td>' item.id '</td>\
-
<td>' item.route_name '</td>\
-
<td>' item.route_namespace '</td>\
-
<td class="center">' item.route_host '</td>\
-
<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>\
-
</tr>'
-
);
-
})
-
},
-
error: function(result){
-
console.log(result);
-
}
-
});
-
});
-
-
-
-
</script>
-
-
</body>
-
</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
-
### Prometheus 安装说明
-
-
#### 1.解压 zip 包
-
```cassandraql
-
unzip v0.9.0.zip
-
```
-
-
#### 2.进入目录
-
```cassandraql
-
cd kube-prometheus-0.9.0
-
```
-
-
#### 3.执行安装命令
-
```cassandraql
-
//创建命名空间和CRD
-
kubectl create -f manifests/setup
-
-
//等待创建结束
-
until kubectl get servicemonitors --all-namespaces ; do date; sleep 1; echo ""; done
-
-
//创建监控组件
-
kubectl create -f manifests/
-
-
//查看 monitoring 内的 pod
-
kubectl get pods -n monitoring
-
```
-
-
#### 4.添加路由外网访问
-
通过前一章开发的 route 功能添加 monitoring 命名空间下
-
grafana.wu123.com 域名
-
第一次登录默认账号:admin 密码:admin
-
[root@k8s-worker01 kube-prometheus-0.9.0]# kubectl get pods -n monitoring
-
NAME READY STATUS RESTARTS AGE
-
alertmanager-main-0 2/2 Running 0 4m52s
-
alertmanager-main-1 2/2 Running 0 4m41s
-
blackbox-exporter-589d9b456-zs74d 3/3 Running 0 4m52s
-
grafana-6767dc8755-sl48b 1/1 Running 0 4m55s
-
kube-state-metrics-8fc46689b-hgh9w 2/3 Running 0 4m52s
-
node-exporter-5h2vw 2/2 Running 0 4m52s
-
node-exporter-6gp27 2/2 Running 0 4m52s
-
node-exporter-j6phd 2/2 Running 0 4m52s
-
prometheus-adapter-58cd975bff-9rvj8 1/1 Running 0 4m52s
-
prometheus-adapter-58cd975bff-lwjhl 1/1 Running 0 4m52s
-
prometheus-k8s-0 2/2 Running 0 4m52s
-
prometheus-k8s-1 2/2 Running 0 4m52s
-
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 安全机器初始化
-
### 基于 Centos8 系统通过 Cephadm 快速部署 Ceph16(pacific)版本
-
-
#### 前期准备
-
-
##### 1. 安装依赖
-
lvm因为系统自带的都有,所以就不用单独安装了,
-
```cassandraql
-
dnf install epel-release -y
-
dnf install python3 -y
-
dnf install podman -y
-
dnf install -y chrony
-
systemctl start chronyd && systemctl enable chronyd
-
```
-
chrony时间服务为必须安装,具体有2点原因:1为不安装在添加主机的时候会报错,2为即使安装成功ceph -s会也提示时间不同步!
-
##### 2.关闭防火墙和selinux (每台都执行)
-
```cassandraql
-
systemctl disable firewalld && systemctl stop firewalld
-
setenforce 0
-
sed -i "s/SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config
-
```
-
-
##### 3.分别在三个节点设置主机名
-
```cassandraql
-
hostnamectl set-hostname ceph01
-
hostnamectl set-hostname ceph02
-
hostnamectl set-hostname ceph03
-
```
-
重启机器 reboot
-
cephadm需要主机名为短主机名,不能为FQDN,否者在添加主机会报错!
-
-
##### 4.添加hosts文件中的主机名和IP关系,主机名需要和上面一致
-
172.31.96.70 ceph01 2Cpu 4G内存 20G系统盘,20G数据盘
-
172.31.96.71 ceph02 2Cpu 4G内存 20G系统盘,20G数据盘
-
172.31.96.72 ceph03 2Cpu 4G内存 20G系统盘,20G数据盘
-
```cassandraql
-
cat >> /etc/hosts <<EOF
-
172.31.96.70 ceph01
-
172.31.96.71 ceph02
-
172.31.96.72 ceph03
-
EOF
-
```
9-6 Go PaaS 平台cephadm 安装基础集群(上)
C:\Users\Administrator\Desktop\gopaas\ceph\1.ceph 安装.md
-
#### 安装 cephadm
-
cephadm 命令可以
-
1. 引导新集群
-
2. 使用有效的Ceph CLI启动容器化的Shell
-
3. 帮助调试容器化的Ceph守护进程。
-
以下操作只在一台节点执行就可以
-
##### 1.使用curl获取独立脚本的最新版本。网络不好的话可直接去GitHub复制
-
-
```cassandraql
-
curl --silent --remote-name --location https://github.com/ceph/ceph/raw/pacific/src/cephadm/cephadm
-
chmod x cephadm
-
./cephadm add-repo --release pacific
-
./cephadm install
-
./cephadm install ceph-common
-
```
-
官方文档中还提到了另一种安装cephadm方式,就是通过dnf install -y cephadm安装,实践证明最好不要使用这种方式,这种方式安装的cephadm可能不是最新版本的,但cephadm去拉的容器版本又是最新的,会导致两个版本不一致!
-
-
-
-
-
#### 引导新群集
-
##### 1.先创建一个目录:/etc/ceph
-
```cassandraql
-
mkdir -p /etc/ceph
-
```
-
-
##### 2.运行该命令:ceph bootstrap
-
```cassandraql
-
cephadm bootstrap --mon-ip 172.31.96.70
-
```
-
此命令将会进行以下操作:
-
- 为本地主机上的新群集创建monitor和manager守护程序。
-
- 为 Ceph 群集生成新的 SSH 密钥,并将其添加到root用户的文件/root/.ssh/authorized_keys
-
- 将与新群集通信所需的最小配置文件保存到 /etc/ceph/ceph.conf
-
- 将client.admin管理(特权!)密钥的副本写入/etc/ceph/ceph.client.admin.keyring
-
- 将公钥的副本写入/etc/ceph/ceph.pub
-
-
安装日志如下为成功
-
```cassandraql
-
[root@ceph01 ~]# cephadm bootstrap --mon-ip 172.31.96.70
-
Verifying podman|docker is present...
-
Verifying lvm2 is present...
-
Verifying time synchronization is in place...
-
Unit chronyd.service is enabled and running
-
Repeating the final host check...
-
podman (/usr/bin/podman) version 3.3.1 is present
-
systemctl is present
-
lvcreate is present
-
Unit chronyd.service is enabled and running
-
Host looks OK
-
Cluster fsid: ba25aef4-19f6-11ed-867d-00163e005933
-
Verifying IP 172.31.96.71 port 3300 ...
-
ERROR: [Errno 99] Cannot assign requested address
-
[root@ceph01 ~]# cephadm bootstrap --mon-ip 172.31.96.70
-
Verifying podman|docker is present...
-
Verifying lvm2 is present...
-
Verifying time synchronization is in place...
-
Unit chronyd.service is enabled and running
-
Repeating the final host check...
-
podman (/usr/bin/podman) version 3.3.1 is present
-
systemctl is present
-
lvcreate is present
-
Unit chronyd.service is enabled and running
-
Host looks OK
-
Cluster fsid: c32ff766-19f6-11ed-aa17-00163e005933
-
Verifying IP 172.31.96.70 port 3300 ...
-
Verifying IP 172.31.96.70 port 6789 ...
-
Mon IP `172.31.96.70` is in CIDR network `172.31.96.0/20`
-
- internal network (--cluster-network) has not been provided, OSD replication will default to the public_network
-
Pulling container image quay.io/ceph/ceph:v16...
-
Ceph version: ceph version 16.2.10 (45fa1a083152e41a408d15505f594ec5f1b4fe17) pacific (stable)
-
Extracting ceph user uid/gid from container image...
-
Creating initial keys...
-
Creating initial monmap...
-
Creating mon...
-
Waiting for mon to start...
-
Waiting for mon...
-
mon is available
-
Assimilating anything we can from ceph.conf...
-
Generating new minimal ceph.conf...
-
Restarting the monitor...
-
Setting mon public_network to 172.31.96.0/20
-
Wrote config to /etc/ceph/ceph.conf
-
Wrote keyring to /etc/ceph/ceph.client.admin.keyring
-
Creating mgr...
-
Verifying port 9283 ...
-
Waiting for mgr to start...
-
Waiting for mgr...
-
mgr not available, waiting (1/15)...
-
mgr not available, waiting (2/15)...
-
mgr not available, waiting (3/15)...
-
mgr not available, waiting (4/15)...
-
mgr is available
-
Enabling cephadm module...
-
Waiting for the mgr to restart...
-
Waiting for mgr epoch 5...
-
mgr epoch 5 is available
-
Setting orchestrator backend to cephadm...
-
Generating ssh key...
-
Wrote public SSH key to /etc/ceph/ceph.pub
-
Adding key to root@localhost authorized_keys...
-
Adding host ceph01...
-
Deploying mon service with default placement...
-
Deploying mgr service with default placement...
-
Deploying crash service with default placement...
-
Deploying prometheus service with default placement...
-
Deploying grafana service with default placement...
-
Deploying node-exporter service with default placement...
-
Deploying alertmanager service with default placement...
-
Enabling the dashboard module...
-
Waiting for the mgr to restart...
-
Waiting for mgr epoch 9...
-
mgr epoch 9 is available
-
Generating a dashboard self-signed certificate...
-
Creating initial admin user...
-
Fetching dashboard port number...
-
Ceph Dashboard is now available at:
-
-
URL: https://ceph01:8443/
-
User: admin
-
Password: 9ro6qdzyel
-
-
Enabling client.admin keyring and conf on hosts with "admin" label
-
Enabling autotune for osd_memory_target
-
You can access the Ceph CLI as following in case of multi-cluster or non-default config:
-
-
sudo /usr/sbin/cephadm shell --fsid c32ff766-19f6-11ed-aa17-00163e005933 -c /etc/ceph/ceph.conf -k /etc/ceph/ceph.client.admin.keyring
-
-
Or, if you are only running a single cluster on this host:
-
-
sudo /usr/sbin/cephcadm shell
-
-
Please consider enabling telemetry to help improve Ceph:
-
-
ceph telemetry on
-
-
For more information see:
-
-
https://docs.ceph.com/en/pacific/mgr/telemetry/
-
-
Bootstrap complete.
-
```
-
-
完成后记录以上了IP以及用户和密码,打开Ceph Dashboard并根据提示修改密码,打开后提示要激活统计模块。
-
如果错过使用命令
-
```cassandraql
-
如果Ceph Dashboard中错过了启用,也可以使用命令启用,命令是“ceph telemetry on --license sharing-1-0”。
-
```
-
-
如果忘记记录密码可以通过以下方法重置密码(将密码写入password文件中,通过命令导入密码)
-
```cassandraql
-
ceph dashboard ac-user-set-password admin -i password
-
{"username": "admin", "password": "$2b$12$6oFrEpssXCzLnKTWQy5fM.YZwlHjn8CuQRdeSSJR9hBGgVuwGCxoa", "roles": ["administrator"], "name": null, "email": null, "lastUpdate": 1620495653, "enabled": true, "pwdExpirationDate": null, "pwdUpdateRequired": false}
-
```
9-7 Go PaaS 平台cephadm 安装基础集群(下)
-
##### 3.添加主机
-
在引导成功单节点Ceph群集后会引导程序会将public key的副本写入/etc/ceph/ceph.pub,在添加主机节点前需要讲该key分发到要加入群集的主机上
-
-
拷贝到ceph02
-
```cassandraql
-
ssh-copy-id -f -i /etc/ceph/ceph.pub root@ceph02
-
```
-
-
拷贝到ceph03
-
```cassandraql
-
ssh-copy-id -f -i /etc/ceph/ceph.pub root@ceph03
-
```
-
-
添加ceph 02 节点
-
```cassandraql
-
ceph orch host add ceph02 172.31.96.71
-
```
-
添加ceph 03 节点
-
```cassandraql
-
ceph orch host add ceph03 172.31.96.72
-
```
-
-
查看节点
-
```cassandraql
-
[root@ceph01 ~]# ceph orch host ls
-
HOST ADDR LABELS STATUS
-
ceph01 172.31.96.70 _admin
-
ceph02 172.31.96.71
-
ceph03 172.31.96.72
-
3 hosts in cluster
-
```
-
-
##### 4.添加OSD
-
添加OSD需求满足以下所有条件:
-
- 设备必须没有分区。
-
- 设备不得具有任何LVM状态。
-
- 不得安装设备。
-
- 该设备不得包含文件系统。
-
- 该设备不得包含Ceph BlueStore OSD。
-
- 设备必须大于 5 GB。
-
添加OSD有2种方式,
-
1.为自动添加所有满足条件的OSD。
-
```
-
ceph orch apply osd --all-available-devices
-
```
-
2.为通过手工指定的方式添加OSD。
-
```cassandraql
-
ceph orch daemon add osd ceph1:/dev/sdb
-
```
-
本次使用第一种自动部署的方式,部署完成后查看设备列表,显示为NO就完成了。
-
```cassandraql
-
[root@ceph01 ~]# ceph orch device ls
-
HOST PATH TYPE DEVICE ID SIZE AVAILABLE REFRESHED REJECT REASONS
-
ceph01 /dev/vdb hdd j6c3xd1a6qug5beqk71y 21.4G 9s ago Insufficient space (<10 extents) on vgs, LVM detected, locked
-
ceph02 /dev/vdb hdd j6c3xd1a6qug5beqk720 21.4G 14s ago Insufficient space (<10 extents) on vgs, LVM detected, locked
-
ceph03 /dev/vdb hdd j6c3xd1a6qug5beqk71z 21.4G 14s ago Insufficient space (<10 extents) on vgs, LVM detected, locked
-
```
-
-
#### 5.查看Ceph部署服务
-
```cassandraql
-
[root@ceph01 ~]# ceph -s
-
cluster:
-
id: c32ff766-19f6-11ed-aa17-00163e005933
-
health: HEALTH_OK
-
-
services:
-
mon: 3 daemons, quorum ceph01,ceph02,ceph03 (age 4m)
-
mgr: ceph01.sdapbz(active, since 30m), standbys: ceph02.njhkgr
-
osd: 3 osds: 3 up (since 96s), 3 in (since 114s)
-
-
data:
-
pools: 1 pools, 1 pgs
-
objects: 0 objects, 0 B
-
usage: 15 MiB used, 60 GiB / 60 GiB avail
-
pgs: 1 active clean
-
-
```
-
-
打开 dashboard 看监控数据
9-8 Go PaaS 平台ceph 核心组件安装
-
#### 6.部署RGW
-
使用指定数量匹配模式部署。
-
```
-
ceph orch apply rgw rgw --placement=3
-
```
-
通过Service查看命令ceph orch ls查看该服务状态。
-
```cassandraql
-
[root@ceph01 ~]# ceph orch ls
-
NAME PORTS RUNNING REFRESHED AGE PLACEMENT
-
alertmanager ?:9093,9094 1/1 10s ago 40m count:1
-
crash 3/3 15s ago 40m *
-
grafana ?:3000 1/1 10s ago 40m count:1
-
mgr 2/2 14s ago 40m count:2
-
mon 3/5 15s ago 40m count:5
-
node-exporter ?:9100 3/3 15s ago 40m *
-
osd.all-available-devices 3 15s ago 9m *
-
prometheus ?:9095 1/1 10s ago 40m count:1
-
rgw.rgw ?:80 3/3 15s ago 30s count:3
-
```
-
通过Deamon查看命令ceph orch ps查看该进程状态。
-
```cassandraql
-
[root@ceph01 ~]# ceph orch ps
-
NAME HOST PORTS STATUS REFRESHED AGE MEM USE MEM LIM VERSION IMAGE ID CONTAINER ID
-
alertmanager.ceph01 ceph01 *:9093,9094 running (12m) 41s ago 39m 27.9M - ba2b418f427c b6fbf7382136
-
crash.ceph01 ceph01 running (39m) 41s ago 39m 7717k - 16.2.10 0d668911f040 9660dd933bd2
-
crash.ceph02 ceph02 running (14m) 44s ago 14m 9713k - 16.2.10 0d668911f040 35cac443b75c
-
crash.ceph03 ceph03 running (13m) 45s ago 13m 8632k - 16.2.10 0d668911f040 3135f2560d98
-
grafana.ceph01 ceph01 *:3000 running (38m) 41s ago 39m 67.9M - 8.3.5 dad864ee21e9 7f47d88ad676
-
mgr.ceph01.sdapbz ceph01 *:9283 running (41m) 41s ago 41m 499M - 16.2.10 0d668911f040 9e001eab3a53
-
mgr.ceph02.njhkgr ceph02 *:8443,9283 running (14m) 44s ago 14m 409M - 16.2.10 0d668911f040 146058cf2aea
-
mon.ceph01 ceph01 running (41m) 41s ago 41m 147M 2048M 16.2.10 0d668911f040 5896f4b2a014
-
mon.ceph02 ceph02 running (14m) 44s ago 14m 85.3M 2048M 16.2.10 0d668911f040 7fd0c2c36613
-
mon.ceph03 ceph03 running (13m) 45s ago 13m 82.1M 2048M 16.2.10 0d668911f040 db5a5b5039d5
-
node-exporter.ceph01 ceph01 *:9100 running (38m) 41s ago 38m 16.5M - 1dbe0e931976 2d7d68e3a0da
-
node-exporter.ceph02 ceph02 *:9100 running (14m) 44s ago 14m 18.2M - 1dbe0e931976 083f26d39f07
-
node-exporter.ceph03 ceph03 *:9100 running (12m) 45s ago 12m 14.4M - 1dbe0e931976 c3b21c79b2f4
-
osd.0 ceph03 running (9m) 45s ago 9m 40.4M 4096M 16.2.10 0d668911f040 2210df27e314
-
osd.1 ceph02 running (9m) 44s ago 9m 44.7M 4096M 16.2.10 0d668911f040 9ab8967c65b9
-
osd.2 ceph01 running (9m) 41s ago 9m 47.6M 4096M 16.2.10 0d668911f040 78a2000670f7
-
prometheus.ceph01 ceph01 *:9095 running (12m) 41s ago 38m 69.2M - 514e6a882f6e 06de63766e30
-
rgw.rgw.ceph01.bvcnos ceph01 *:80 running (58s) 41s ago 57s 43.7M - 16.2.10 0d668911f040 96c4d8963d47
-
rgw.rgw.ceph02.awygjp ceph02 *:80 running (54s) 44s ago 53s 46.2M - 16.2.10 0d668911f040 9d0bd0b0b060
-
rgw.rgw.ceph03.iiixeq ceph03 *:80 running (50s) 45s ago 49s 21.2M - 16.2.10 0d668911f040 a5d6e8a8983a
-
```
-
集成到dashboard
-
```cassandraql
-
[root@ceph01 ~]# radosgw-admin user create --uid=rgw --display-name=rgw --system
-
-
以下是输出结果
-
-
"keys": [
-
{
-
"user": "rgw",
-
"access_key": "M0XRR80H4AGGE4PP0A5B",
-
"secret_key": "Tbln48sfIceDGNill5muCrX0oMCHrQcl2oC9OURe"
-
}
-
],{
-
"user_id": "rgw",
-
"display_name": "rgw",
-
"email": "",
-
"suspended": 0,
-
"max_buckets": 1000,
-
"subusers": [],
-
"keys": [
-
{
-
"user": "rgw",
-
"access_key": "43DTMZ3EY02B10QNTJSS",
-
"secret_key": "4d3qzY1A7uqVk3LWVMsGJY0negbcxg95d8QJYuzi"
-
}
-
],
-
"swift_keys": [],
-
"caps": [],
-
"op_mask": "read, write, delete",
-
"system": "true",
-
"default_placement": "",
-
"default_storage_class": "",
-
"placement_tags": [],
-
"bucket_quota": {
-
"enabled": false,
-
"check_on_raw": false,
-
"max_size": -1,
-
"max_size_kb": 0,
-
"max_objects": -1
-
},
-
"user_quota": {
-
"enabled": false,
-
"check_on_raw": false,
-
"max_size": -1,
-
"max_size_kb": 0,
-
"max_objects": -1
-
},
-
"temp_url_keys": [],
-
"type": "rgw",
-
"mfa_ids": []
-
}
-
-
```
-
查看 Dashboard 是否集成成功
-
-
#### 7.部署Cephfs
-
部署cephfs服务并创建cepfs,创建cephfs有两种方式,一种是使用的是ceph fs命令该命令会自动创建相应的池,另一种手工创建池并创建Service,下面方法任选一种。
-
方法一:
-
```cassandraql
-
ceph fs volume create cephfs --placement=3
-
```
-
方法二:
-
```cassandraql
-
#ceph osd pool create cephfs_data 32
-
#ceph osd pool create cephfs_metadata 32
-
#ceph fs new cephfs cephfs_metadata cephfs_data
-
#ceph orch apply mds cephfs --placement=3
-
```
-
我们采用方法一
-
查看Service状态。
-
```cassandraql
-
[root@ceph01 ~]# ceph fs volume create cephfs --placement=3
-
[root@ceph01 ~]# ceph orch ls
-
NAME PORTS RUNNING REFRESHED AGE PLACEMENT
-
alertmanager ?:9093,9094 1/1 9s ago 48m count:1
-
crash 3/3 13s ago 48m *
-
grafana ?:3000 1/1 9s ago 48m count:1
-
mds.cephfs 3/3 13s ago 29s count:3
-
mgr 2/2 13s ago 48m count:2
-
mon 3/5 13s ago 48m count:5
-
node-exporter ?:9100 3/3 13s ago 48m *
-
osd.all-available-devices 3 13s ago 17m *
-
prometheus ?:9095 1/1 9s ago 48m count:1
-
rgw.rgw ?:80 3/3 13s ago 8m count:3
-
```
-
查看Deamon状态。
-
```cassandraql
-
[root@ceph01 ~]# ceph orch ps
-
NAME HOST PORTS STATUS REFRESHED AGE MEM USE MEM LIM VERSION IMAGE ID CONTAINER ID
-
alertmanager.ceph01 ceph01 *:9093,9094 running (20m) 59s ago 48m 29.5M - ba2b418f427c b6fbf7382136
-
crash.ceph01 ceph01 running (48m) 59s ago 48m 7587k - 16.2.10 0d668911f040 9660dd933bd2
-
crash.ceph02 ceph02 running (22m) 63s ago 22m 9667k - 16.2.10 0d668911f040 35cac443b75c
-
crash.ceph03 ceph03 running (21m) 63s ago 21m 8606k - 16.2.10 0d668911f040 3135f2560d98
-
grafana.ceph01 ceph01 *:3000 running (46m) 59s ago 47m 77.2M - 8.3.5 dad864ee21e9 7f47d88ad676
-
mds.cephfs.ceph01.uwclzo ceph01 running (74s) 59s ago 74s 28.2M - 16.2.10 0d668911f040 e7ead0c130a6
-
mds.cephfs.ceph02.zqmpyt ceph02 running (71s) 63s ago 70s 23.7M - 16.2.10 0d668911f040 06ed8fd3bc1a
-
mds.cephfs.ceph03.glufpl ceph03 running (67s) 63s ago 67s 22.9M - 16.2.10 0d668911f040 a3e497cb8a85
-
mgr.ceph01.sdapbz ceph01 *:9283 running (49m) 59s ago 49m 508M - 16.2.10 0d668911f040 9e001eab3a53
-
mgr.ceph02.njhkgr ceph02 *:8443,9283 running (22m) 63s ago 22m 410M - 16.2.10 0d668911f040 146058cf2aea
-
mon.ceph01 ceph01 running (50m) 59s ago 50m 177M 2048M 16.2.10 0d668911f040 5896f4b2a014
-
mon.ceph02 ceph02 running (22m) 63s ago 22m 115M 2048M 16.2.10 0d668911f040 7fd0c2c36613
-
mon.ceph03 ceph03 running (21m) 63s ago 21m 111M 2048M 16.2.10 0d668911f040 db5a5b5039d5
-
node-exporter.ceph01 ceph01 *:9100 running (47m) 59s ago 47m 17.4M - 1dbe0e931976 2d7d68e3a0da
-
node-exporter.ceph02 ceph02 *:9100 running (22m) 63s ago 22m 18.0M - 1dbe0e931976 083f26d39f07
-
node-exporter.ceph03 ceph03 *:9100 running (21m) 63s ago 21m 14.7M - 1dbe0e931976 c3b21c79b2f4
-
osd.0 ceph03 running (17m) 63s ago 17m 69.7M 4096M 16.2.10 0d668911f040 2210df27e314
-
osd.1 ceph02 running (17m) 63s ago 17m 72.6M 4096M 16.2.10 0d668911f040 9ab8967c65b9
-
osd.2 ceph01 running (17m) 59s ago 17m 72.4M 4096M 16.2.10 0d668911f040 78a2000670f7
-
prometheus.ceph01 ceph01 *:9095 running (20m) 59s ago 46m 73.6M - 514e6a882f6e 06de63766e30
-
rgw.rgw.ceph01.bvcnos ceph01 *:80 running (9m) 59s ago 9m 73.3M - 16.2.10 0d668911f040 96c4d8963d47
-
rgw.rgw.ceph02.awygjp ceph02 *:80 running (9m) 63s ago 9m 80.8M - 16.2.10 0d668911f040 9d0bd0b0b060
-
rgw.rgw.ceph03.iiixeq ceph03 *:80 running (9m) 63s ago 8m 57.4M - 16.2.10 0d668911f040 a5d6e8a8983a
-
```
-
-
查看 Dashboard
-
-
#### 8.部署NFS
-
先创建nfs所需求的池。
-
```cassandraql
-
#ceph osd pool create ganesha_data 32
-
#ceph osd pool application enable ganesha_data nfs
-
```
-
部署nfs Service。
-
```cassandraql
-
#ceph orch apply nfs nfs ganesha_data --placement=3
-
```
-
查看Service状态。
-
```cassandraql
-
[root@ceph01 ~]# ceph orch ls
-
NAME PORTS RUNNING REFRESHED AGE PLACEMENT
-
alertmanager ?:9093,9094 1/1 8s ago 52m count:1
-
crash 3/3 13s ago 52m *
-
grafana ?:3000 1/1 8s ago 52m count:1
-
mds.cephfs 3/3 13s ago 4m count:3
-
mgr 2/2 13s ago 52m count:2
-
mon 3/5 13s ago 52m count:5
-
nfs.nfs 3/3 13s ago 36s count:3
-
node-exporter ?:9100 3/3 13s ago 52m *
-
osd.all-available-devices 3 13s ago 21m *
-
prometheus ?:9095 1/1 8s ago 52m count:1
-
rgw.rgw ?:80 3/3 13s ago 12m count:3
-
```
-
-
查看Deamon状态。
-
```cassandraql
-
[root@ceph01 ~]# ceph orch ls
-
NAME PORTS RUNNING REFRESHED AGE PLACEMENT
-
alertmanager ?:9093,9094 1/1 8s ago 52m count:1
-
crash 3/3 13s ago 52m *
-
grafana ?:3000 1/1 8s ago 52m count:1
-
mds.cephfs 3/3 13s ago 4m count:3
-
mgr 2/2 13s ago 52m count:2
-
mon 3/5 13s ago 52m count:5
-
nfs.nfs 3/3 13s ago 36s count:3
-
node-exporter ?:9100 3/3 13s ago 52m *
-
osd.all-available-devices 3 13s ago 21m *
-
prometheus ?:9095 1/1 8s ago 52m count:1
-
rgw.rgw ?:80 3/3 13s ago 12m count:3
-
-
```
-
-
#### 9.部署iSCSi
-
创建iscsi所需求的池。
-
```cassandraql
-
#ceph osd pool create iscsi_pool 16 16
-
#ceph osd pool application enable iscsi_pool iscsi
-
```
-
-
部署iscsi我们换YAM方式
-
```cassandraql
-
#vi iscsi.yaml
-
service_type: iscsi
-
service_id: gw
-
placement:
-
hosts:
-
- ceph01
-
- ceph02
-
- ceph03
-
spec:
-
pool: iscsi_pool
-
trusted_ip_list: "172.31.96.70,172.31.96.71,172.31.96.72"
-
api_user: admin
-
api_password: admin
-
api_secure: false
-
-
```
-
通过apply命令部署,cephadm也是声明式的,所以如果想修改配置参数只需要直接修改YAML文件。
-
-
```cassandraql
-
[root@ceph01 ~]# ceph orch apply -i iscsi.yaml
-
Scheduled iscsi.gw update...
-
```
-
查看Service状态。
-
```cassandraql
-
[root@ceph01 ~]# ceph orch ls
-
NAME PORTS RUNNING REFRESHED AGE PLACEMENT
-
alertmanager ?:9093,9094 1/1 9s ago 67m count:1
-
crash 3/3 21s ago 67m *
-
grafana ?:3000 1/1 9s ago 67m count:1
-
iscsi.gw 3/3 21s ago 40s ceph01;ceph02;ceph03
-
mds.cephfs 3/3 21s ago 19m count:3
-
mgr 2/2 20s ago 67m count:2
-
mon 3/5 21s ago 67m count:5
-
nfs.nfs 3/3 21s ago 16m count:3
-
node-exporter ?:9100 3/3 21s ago 67m *
-
osd.all-available-devices 3 21s ago 36m *
-
prometheus ?:9095 1/1 9s ago 67m count:1
-
rgw.rgw ?:80 3/3 21s ago 27m count:3
-
```
-
查看Deamon状态。
-
```cassandraql
-
[root@ceph01 ~]# ceph orch ps
-
NAME HOST PORTS STATUS REFRESHED AGE MEM USE MEM LIM VERSION IMAGE ID CONTAINER ID
-
alertmanager.ceph01 ceph01 *:9093,9094 running (39m) 33s ago 67m 35.2M - ba2b418f427c b6fbf7382136
-
crash.ceph01 ceph01 running (67m) 33s ago 67m 7386k - 16.2.10 0d668911f040 9660dd933bd2
-
crash.ceph02 ceph02 running (41m) 44s ago 41m 10.5M - 16.2.10 0d668911f040 35cac443b75c
-
crash.ceph03 ceph03 running (40m) 45s ago 40m 10.8M - 16.2.10 0d668911f040 3135f2560d98
-
grafana.ceph01 ceph01 *:3000 running (65m) 33s ago 66m 80.2M - 8.3.5 dad864ee21e9 7f47d88ad676
-
iscsi.gw.ceph01.mqjxqu ceph01 running (60s) 33s ago 59s 76.1M - 3.5 0d668911f040 e712bdbb2d80
-
iscsi.gw.ceph02.xeggjo ceph02 running (56s) 44s ago 56s 52.9M - 3.5 0d668911f040 04c7f5263155
-
iscsi.gw.ceph03.xykglu ceph03 running (52s) 45s ago 52s 76.9M - 3.5 0d668911f040 59cb4c7bbfd5
-
mds.cephfs.ceph01.uwclzo ceph01 running (20m) 33s ago 20m 27.6M - 16.2.10 0d668911f040 e7ead0c130a6
-
mds.cephfs.ceph02.zqmpyt ceph02 running (20m) 44s ago 20m 26.8M - 16.2.10 0d668911f040 06ed8fd3bc1a
-
mds.cephfs.ceph03.glufpl ceph03 running (20m) 45s ago 20m 26.5M - 16.2.10 0d668911f040 a3e497cb8a85
-
mgr.ceph01.sdapbz ceph01 *:9283 running (68m) 33s ago 68m 495M - 16.2.10 0d668911f040 9e001eab3a53
-
mgr.ceph02.njhkgr ceph02 *:8443,9283 running (41m) 44s ago 41m 411M - 16.2.10 0d668911f040 146058cf2aea
-
mon.ceph01 ceph01 running (68m) 33s ago 69m 237M 2048M 16.2.10 0d668911f040 5896f4b2a014
-
mon.ceph02 ceph02 running (41m) 44s ago 41m 164M 2048M 16.2.10 0d668911f040 7fd0c2c36613
-
mon.ceph03 ceph03 running (40m) 45s ago 40m 146M 2048M 16.2.10 0d668911f040 db5a5b5039d5
-
nfs.nfs.0.0.ceph01.ijxnwe ceph01 *:2049 running (16m) 33s ago 16m 72.4M - 3.5 0d668911f040 f9b0609cbe7b
-
nfs.nfs.1.0.ceph02.pedadk ceph02 *:2049 running (16m) 44s ago 16m 75.8M - 3.5 0d668911f040 54d58b785ed6
-
nfs.nfs.2.0.ceph03.daqdkw ceph03 *:2049 running (16m) 45s ago 16m 73.0M - 3.5 0d668911f040 c1bebe7782d4
-
node-exporter.ceph01 ceph01 *:9100 running (66m) 33s ago 66m 17.7M - 1dbe0e931976 2d7d68e3a0da
-
node-exporter.ceph02 ceph02 *:9100 running (41m) 44s ago 41m 18.3M - 1dbe0e931976 083f26d39f07
-
node-exporter.ceph03 ceph03 *:9100 running (40m) 45s ago 40m 15.5M - 1dbe0e931976 c3b21c79b2f4
-
osd.0 ceph03 running (36m) 45s ago 36m 77.8M 4096M 16.2.10 0d668911f040 2210df27e314
-
osd.1 ceph02 running (36m) 44s ago 36m 80.1M 4096M 16.2.10 0d668911f040 9ab8967c65b9
-
osd.2 ceph01 running (36m) 33s ago 36m 79.3M 4096M 16.2.10 0d668911f040 78a2000670f7
-
prometheus.ceph01 ceph01 *:9095 running (39m) 33s ago 65m 97.3M - 514e6a882f6e 06de63766e30
-
rgw.rgw.ceph01.bvcnos ceph01 *:80 running (28m) 33s ago 28m 61.8M - 16.2.10 0d668911f040 96c4d8963d47
-
rgw.rgw.ceph02.awygjp ceph02 *:80 running (28m) 44s ago 28m 81.6M - 16.2.10 0d668911f040 9d0bd0b0b060
-
rgw.rgw.ceph03.iiixeq ceph03 *:80 running (27m) 45s ago 27m 60.0M - 16.2.10 0d668911f040 a5d6e8a8983a
-
```
9-9 Go PaaS 平台 k8s 通过CSI方式添加外部Ceph 系统(上)
C:\Users\Administrator\Desktop\gopaas\ceph\2.k8s 使用 CSI 添加 ceph 为存储.md
-
### k8s 1.21.5 CSI 模式添加 ceph 16 为为外部存储(动态存储卷)
-
-
#### 1.动态持久卷
-
不需要存储管理员干预,使k8s使用的存储image创建自动化,即根据使用需要可以动态申请存储空间并自动创建。需要先定义一个或者多个StorageClass,每个StorageClass都必须配置一个provisioner,用来决定使用哪个卷插件分配PV。然后,StorageClass资源指定持久卷声明请求StorageClass时使用哪个provisioner来在对应存储创建持久卷。
-
-
#### 2.创建一个普通用户来给k8s做rdb的映射
-
在ceph集群中创建一个k8s专用的pool和用户:
-
```cassandraql
-
ceph osd pool create kubernetes 16 16
-
ceph auth get-or-create client.kubernetes mon 'profile rbd' osd 'profile rbd pool=kubernetes' mgr 'profile rbd pool=kubernetes'
-
-
初始化
-
rbd pool init kubernetes
-
-
查看 pool
-
ceph osd pool ls
-
rados lspools
-
```
-
得到
-
```cassandraql
-
[client.kubernetes]
-
key = AQC2Q/ZiecM/MBAA2nwfDPKgfReHxz/o4kQV3A==
-
```
-
后面的配置需要用到这里的 key,如果忘了可以通过以下命令来获取:
-
```cassandraql
-
ceph auth get client.kubernetes
-
```
-
得到
-
```cassandraql
-
[client.kubernetes]
-
key = AQC2Q/ZiecM/MBAA2nwfDPKgfReHxz/o4kQV3A==
-
caps mgr = "profile rbd pool=kubernetes"
-
caps mon = "profile rbd"
-
caps osd = "profile rbd pool=kubernetes"
-
exported keyring for client.kubernetes
-
```
-
#### 3. 部署 ceph-csi 在k8s master 集群上
-
拉取 ceph-csi 的 最新 release 分支(v3.6.2)
-
```cassandraql
-
git clone --depth 1 --branch v3.6.2 https://github.com/ceph/ceph-csi
-
```
-
##### 修改 Configmap
-
获取 Ceph 集群的信息:
-
```cassandraql
-
[root@ceph01 ~]# ceph mon dump
-
epoch 3
-
fsid c32ff766-19f6-11ed-aa17-00163e005933
-
last_changed 2022-08-12T04:55:22.875422 0000
-
created 2022-08-12T04:26:27.658334 0000
-
min_mon_release 16 (pacific)
-
election_strategy: 1
-
0: [v2:172.31.96.70:3300/0,v1:172.31.96.70:6789/0] mon.ceph01
-
1: [v2:172.31.96.71:3300/0,v1:172.31.96.71:6789/0] mon.ceph02
-
2: [v2:172.31.96.72:3300/0,v1:172.31.96.72:6789/0] mon.ceph03
-
dumped monmap epoch 3
-
```
-
-
这里需要用到两个信息:
-
- fsid : 这个是 Ceph 的集群 ID。
-
- 监控节点信息。目前 ceph-csi 只支持 v1 版本的协议,所以监控节点那里我们只能用 v1 的那个 IP 和端口号(例如,172.31.96.70:6789)。
-
-
进入 ceph-csi 的 deploy/rbd/kubernetes 目录:
-
```cassandraql
-
[root@master ~]# cd ceph-csi/deploy/rbd/kubernetes
-
[root@master kubernetes]# ls -l ./
-
total 40
-
-rw-r--r-- 1 root root 309 Aug 12 20:18 csi-config-map.yaml
-
-rw-r--r-- 1 root root 435 Aug 12 20:18 csidriver.yaml
-
-rw-r--r-- 1 root root 1776 Aug 12 20:18 csi-nodeplugin-psp.yaml
-
-rw-r--r-- 1 root root 1110 Aug 12 20:18 csi-nodeplugin-rbac.yaml
-
-rw-r--r-- 1 root root 1199 Aug 12 20:18 csi-provisioner-psp.yaml
-
-rw-r--r-- 1 root root 3264 Aug 12 20:18 csi-provisioner-rbac.yaml
-
-rw-r--r-- 1 root root 8021 Aug 12 20:18 csi-rbdplugin-provisioner.yaml
-
-rw-r--r-- 1 root root 7242 Aug 12 20:18 csi-rbdplugin.yaml
-
```
-
将以上获取的信息写入 csi-config-map.yaml:
-
vi csi-config-map.yaml
-
```cassandraql
-
apiVersion: v1
-
kind: ConfigMap
-
data:
-
config.json: |-
-
[
-
{
-
"clusterID": "c32ff766-19f6-11ed-aa17-00163e005933",
-
"monitors": [
-
"172.31.96.70:6789",
-
"172.31.96.71:6789",
-
"172.31.96.72:6789"
-
]
-
}
-
]
-
metadata:
-
name: ceph-csi-config
-
```
-
将此 Configmap 存储到 Kubernetes 集群中:
-
```cassandraql
-
kubectl apply -f csi-config-map.yaml
-
```
-
-
创建ceph-config
-
```cassandraql
-
cat <<EOF > ceph-config-map.yaml
-
---
-
apiVersion: v1
-
kind: ConfigMap
-
data:
-
ceph.conf: |
-
[global]
-
auth_cluster_required = cephx
-
auth_service_required = cephx
-
auth_client_required = cephx
-
# keyring is a required key and its value should be empty
-
keyring: |
-
metadata:
-
name: ceph-config
-
EOF
-
```
-
创建
-
```cassandraql
-
kubectl apply -f ceph-config-map.yaml
-
```
-
-
创建 ceph-csi-encryption-kms-config
-
```cassandraql
-
cat <<EOF > csi-kms-config-map.yaml
-
---
-
apiVersion: v1
-
kind: ConfigMap
-
data:
-
config.json: |-
-
{}
-
metadata:
-
name: ceph-csi-encryption-kms-config
-
EOF
-
```
-
启用
-
```cassandraql
-
kubectl apply -f csi-kms-config-map.yaml
-
```
9-10 Go PaaS 平台 k8s 通过CSI方式添加外部Ceph 系统(下)
-
##### 新建 Secret
-
使用创建的 kubernetes 用户 ID 和 cephx 密钥生成 Secret:
-
```cassandraql
-
cat <<EOF > csi-rbd-secret.yaml
-
apiVersion: v1
-
kind: Secret
-
metadata:
-
name: csi-rbd-secret
-
namespace: default
-
stringData:
-
userID: kubernetes
-
userKey: AQC2Q/ZiecM/MBAA2nwfDPKgfReHxz/o4kQV3A==
-
EOF
-
```
-
部署 Secret:
-
```cassandraql
-
kubectl apply -f csi-rbd-secret.yaml
-
```
-
##### RBAC 授权
-
创建必须的 ServiceAccount 和 RBAC ClusterRole/ClusterRoleBinding 资源对象:
-
```cassandraql
-
kubectl create -f csi-provisioner-rbac.yaml
-
kubectl create -f csi-nodeplugin-rbac.yaml
-
```
-
-
创建 PodSecurityPolicy:
-
```cassandraql
-
kubectl create -f csi-provisioner-psp.yaml
-
kubectl create -f csi-nodeplugin-psp.yaml
-
```
-
-
##### 部署 CSI sidecar
-
将 csi-rbdplugin-provisioner.yaml 和 csi-rbdplugin.yaml 中的 kms 部分配置注释掉:
-
```cassandraql
-
# - name: ceph-csi-encryption-kms-config
-
# mountPath: /etc/ceph-csi-encryption-kms-config/
-
-
....
-
#- name: ceph-csi-encryption-kms-config
-
# configMap:
-
# name: ceph-csi-encryption-kms-config
-
-
```
-
注释掉pod亲和性
-
```cassandraql
-
# affinity:
-
# podAntiAffinity:
-
# requiredDuringSchedulingIgnoredDuringExecution:
-
# - labelSelector:
-
# matchExpressions:
-
# - key: app
-
# operator: In
-
# values:
-
# - csi-rbdplugin-provisioner
-
# topologyKey: "kubernetes.io/hostname"
-
```
-
-
改为一个副本
-
```cassandraql
-
spec:
-
replicas: 1
-
```
-
-
部署 csi-rbdplugin-provisioner:
-
```
-
kubectl create -f csi-rbdplugin-provisioner.yaml
-
```
-
这里面包含了 6 个 Sidecar 容器,包括 external-provisioner、external-attacher、csi-resizer 和 csi-rbdplugin。
-
-
##### 部署 RBD CSI driver
-
最后部署 RBD CSI Driver:
-
```
-
kubectl create -f csi-rbdplugin.yaml
-
```
-
Pod 中包含两个容器:CSI node-driver-registrar 和 CSI RBD driver。
-
##### 创建 Storageclass
-
```cassandraql
-
cat <<EOF > storageclass.yaml
-
---
-
apiVersion: storage.k8s.io/v1
-
kind: StorageClass
-
metadata:
-
name: csi-rbd-sc
-
provisioner: rbd.csi.ceph.com
-
parameters:
-
clusterID: c32ff766-19f6-11ed-aa17-00163e005933
-
pool: kubernetes
-
imageFeatures: layering
-
csi.storage.k8s.io/provisioner-secret-name: csi-rbd-secret
-
csi.storage.k8s.io/provisioner-secret-namespace: default
-
csi.storage.k8s.io/controller-expand-secret-name: csi-rbd-secret
-
csi.storage.k8s.io/controller-expand-secret-namespace: default
-
csi.storage.k8s.io/node-stage-secret-name: csi-rbd-secret
-
csi.storage.k8s.io/node-stage-secret-namespace: default
-
csi.storage.k8s.io/fstype: ext4
-
reclaimPolicy: Delete
-
allowVolumeExpansion: true
-
mountOptions:
-
- discard
-
EOF
-
```
-
创建 storageclass
-
```cassandraql
-
kubectl apply -f storageclass.yaml
-
```
-
-
- 这里的 clusterID 对应之前步骤中的 fsid。
-
- imageFeatures 用来确定创建的 image 特征,如果不指定,就会使用 RBD 内核中的特征列表,但 Linux 不一定支持所有特征,所以这里需要限制一下。
-
-
#### 4.试用 ceph-csi
-
Kubernetes 通过 PersistentVolume 子系统为用户和管理员提供了一组 API,将存储如何供应的细节从其如何被使用中抽象出来,其中 PV(PersistentVolume) 是实际的存储,PVC(PersistentVolumeClaim) 是用户对存储的请求。
-
-
下面通过官方仓库的示例来演示如何使用 ceph-csi。
-
-
先进入 ceph-csi 项目的 example/rbd 目录,然后直接创建 PVC:
-
```cassandraql
-
kubectl apply -f pvc.yaml
-
```
-
查看 PVC 和申请成功的 PV:
-
```cassandraql
-
$ kubectl get pvc
-
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
-
rbd-pvc Bound pvc-44b89f0e-4efd-4396-9316-10a04d289d7f 1Gi RWO csi-rbd-sc 8m21s
-
-
$ kubectl get pv
-
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
-
pvc-44b89f0e-4efd-4396-9316-10a04d289d7f 1Gi RWO Delete Bound default/rbd-pvc csi-rbd-sc 8m18s
-
```
-
再创建示例 Pod:
-
```
-
kubectl apply -f pod.yaml
-
```
-
-
进入 Pod 里面测试读写数据:
-
```cassandraql
-
kubectl apply -f pod.yaml
-
```
-
进入 Pod 里面测试读写数据:
-
```cassandraql
-
-
kubectl exec -it csi-rbd-demo-pod bash
-
root@csi-rbd-demo-pod:/# cd /var/lib/www/
-
root@csi-rbd-demo-pod:/var/lib/www# ls -l
-
total 4
-
drwxrwxrwx 3 root root 4096 Sep 14 09:09 html
-
root@csi-rbd-demo-pod:/var/lib/www# echo "你好!" > wu123.txt
-
wu123
-
```
-
列出 kubernetes pool 中的 rbd images:
-
```cassandraql
-
rbd ls -p kubernetes
-
csi-vol-fe40eb16-1a4e-11ed-bb7c-0eb2f382cefd
-
```
-
-
查看该 image 的特征:
-
-
```cassandraql
-
[root@ceph01 ceph]# rbd info csi-vol-fe40eb16-1a4e-11ed-bb7c-0eb2f382cefd -p kubernetes
-
rbd image 'csi-vol-fe40eb16-1a4e-11ed-bb7c-0eb2f382cefd':
-
size 1 GiB in 256 objects
-
order 22 (4 MiB objects)
-
snapshot_count: 0
-
id: d50f18182e6b
-
block_name_prefix: rbd_data.d50f18182e6b
-
format: 2
-
features: layering
-
op_features:
-
flags:
-
create_timestamp: Fri Aug 12 22:56:49 2022
-
access_timestamp: Fri Aug 12 22:56:49 2022
-
modify_timestamp: Fri Aug 12 22:56:49 2022
-
```
-
-
到此,k8s 使用外部 ceph 存储配置结束
9-11 Go PaaS 平台PVC 模型开发
-
yu-tool.exe newService github.com/yunixiangfeng/gopaas/volume
-
-
yu-v3 --proto_path=. --micro_out=. --go_out=:. ./proto/volume/volume.proto
-
go mod tidy
C:\Users\Administrator\Desktop\gopaas\volume\domain\model\volume.go
-
package model
-
-
type Volume struct{
-
ID int64 `gorm:"primary_key;not_null;auto_increment"`
-
//存储的名称
-
VolumeName string `json:"volume_name"`
-
//存储的所属的命名空间
-
VolumeNamespace string `json:"volume_namespace"`
-
//存储的访问模式,RWO,ROX,RWX
-
VolumeAccessMode string `json:"volume_access_mode"`
-
//sc 的 class name
-
VolumeStorageClassName string `json:"volume_storage_class_name"`
-
//请求资源的大小
-
VolumeRequest float32 `json:"volume_request"`
-
//存储类型 Block,filesystem
-
VolumePersistentVolumeMode string `json:"volume_persistent_volume_mode"`
-
}
-
C:\Users\Administrator\Desktop\gopaas\volume\proto\volume\volume.proto
-
syntax = "proto3";
-
-
package volume;
-
-
option go_package = "./proto/volume;volume";
-
-
service Volume {
-
//对外提供添加服务
-
rpc AddVolume(VolumeInfo) returns (Response) {}
-
rpc DeleteVolume(VolumeId) returns (Response) {}
-
rpc UpdateVolume(VolumeInfo) returns (Response) {}
-
rpc FindVolumeByID(VolumeId) returns (VolumeInfo) {}
-
rpc FindAllVolume(FindAll) returns (AllVolume) {}
-
}
-
message VolumeInfo {
-
int64 id = 1;
-
string volume_name=2;
-
string volume_namespace=3;
-
string volume_access_mode=4;
-
string volume_storage_class_name=5;
-
float volume_request=6;
-
string volume_persistent_volume_mode=7;
-
}
-
-
message VolumeId {
-
int64 id = 1;
-
}
-
-
message FindAll {
-
-
}
-
-
message Response {
-
string msg =1 ;
-
}
-
-
message AllVolume {
-
repeated VolumeInfo volume_info = 1;
-
}
-
-
9-12 Go PaaS 平台 Service 开发(上)
C:\Users\Administrator\Desktop\gopaas\volume\domain\service\volume_data_service.go
-
package service
-
-
import (
-
"context"
-
"errors"
-
"strconv"
-
-
"github.com/yunixiangfeng/gopaas/common"
-
"github.com/yunixiangfeng/gopaas/volume/domain/model"
-
"github.com/yunixiangfeng/gopaas/volume/domain/repository"
-
"github.com/yunixiangfeng/gopaas/volume/proto/volume"
-
"k8s.io/api/apps/v1"
-
v12 "k8s.io/api/core/v1"
-
"k8s.io/apimachinery/pkg/api/resource"
-
v13 "k8s.io/apimachinery/pkg/apis/meta/v1"
-
"k8s.io/client-go/kubernetes"
-
)
-
-
//这里是接口类型
-
type IVolumeDataService interface {
-
AddVolume(*model.Volume) (int64 , error)
-
DeleteVolume(int64) error
-
UpdateVolume(*model.Volume) error
-
FindVolumeByID(int64) (*model.Volume, error)
-
FindAllVolume() ([]model.Volume, error)
-
-
CreateVolumeToK8s(*volume.VolumeInfo) error
-
DeleteVolumeFromK8s(*model.Volume) error
-
}
-
-
-
//创建
-
//注意:返回值 IVolumeDataService 接口类型
-
func NewVolumeDataService(volumeRepository repository.IVolumeRepository,clientSet *kubernetes.Clientset) IVolumeDataService{
-
return &VolumeDataService{ VolumeRepository:volumeRepository, K8sClientSet: clientSet,deployment:&v1.Deployment{}}
-
}
-
-
type VolumeDataService struct {
-
//注意:这里是 IVolumeRepository 类型
-
VolumeRepository repository.IVolumeRepository
-
K8sClientSet *kubernetes.Clientset
-
deployment *v1.Deployment
-
}
-
//从 k8s 删除一个 pvc
-
func (u *VolumeDataService) DeleteVolumeFromK8s(volume *model.Volume) (err error) {
-
//先从K8s 中删除
-
if err = u.K8sClientSet.CoreV1().PersistentVolumeClaims(volume.VolumeNamespace).Delete(context.TODO(),volume.VolumeName, v13.DeleteOptions{});err!=nil {
-
common.Error(err)
-
return err
-
} else {
-
//从数据表中删除
-
if err := u.DeleteVolume(volume.ID);err !=nil {
-
common.Error(err)
-
return err
-
}
-
common.Info("删除存储ID" strconv.FormatInt(volume.ID,10) " 成功!")
-
}
-
return
-
}
-
-
//创建存储到 k8s 中
-
func (u *VolumeDataService) CreateVolumeToK8s(info *volume.VolumeInfo)(err error) {
-
volume := u.setVolume(info)
-
if _,err = u.K8sClientSet.CoreV1().PersistentVolumeClaims(info.VolumeNamespace).Get(context.TODO(),info.VolumeName,v13.GetOptions{});err !=nil {
-
//如果存储不存在
-
if _,err = u.K8sClientSet.CoreV1().PersistentVolumeClaims(info.VolumeNamespace).Create(context.TODO(),volume,v13.CreateOptions{});err !=nil{
-
common.Error(err)
-
return err
-
}
-
common.Info("存储创建成功")
-
return nil
-
}else {
-
common.Error("存储空间" info.VolumeName " 已经存在")
-
return errors.New("存储空间" info.VolumeName " 已经存在")
-
}
-
}
-
//设置 pvc 的详情信息
-
func (u *VolumeDataService) setVolume(info *volume.VolumeInfo) *v12.PersistentVolumeClaim {
-
pvc := &v12.PersistentVolumeClaim{}
-
//设置接口类型
-
pvc.TypeMeta = v13.TypeMeta{
-
Kind: "PersistentVolumeClaim",
-
APIVersion: "v1",
-
}
-
//设置存储基础信息
-
pvc.ObjectMeta = v13.ObjectMeta{
-
Name: info.VolumeName,
-
Namespace: info.VolumeNamespace,
-
Annotations: map[string]string{
-
"pv.kubernetes.io/bound-by-controller":"yes",
-
"volume.beta.kubernetes.io/storage-provisioner":"rbd.csi.ceph.com",
-
"wu":"wu123",
-
},
-
}
-
//设置存储动态信息
-
pvc.Spec = v12.PersistentVolumeClaimSpec{
-
AccessModes: u.getAccessModes(info),
-
Resources: u.getResource(info),
-
StorageClassName: &info.VolumeStorageClassName,
-
VolumeMode: u.getVolumeMode(info),
-
}
-
return pvc
-
-
}
-
-
//获取存储类型
-
func (u *VolumeDataService) getVolumeMode(info *volume.VolumeInfo) *v12.PersistentVolumeMode {
-
var pvm v12.PersistentVolumeMode
-
switch info.VolumePersistentVolumeMode {
-
case "Block":
-
pvm = v12.PersistentVolumeBlock
-
case "Filesystem":
-
pvm = v12.PersistentVolumeFilesystem
-
default:
-
pvm = v12.PersistentVolumeFilesystem
-
}
-
return &pvm
-
}
-
-
//插入
-
func (u *VolumeDataService) AddVolume(volume *model.Volume) (int64 ,error) {
-
return u.VolumeRepository.CreateVolume(volume)
-
}
-
-
//删除
-
func (u *VolumeDataService) DeleteVolume(volumeID int64) error {
-
return u.VolumeRepository.DeleteVolumeByID(volumeID)
-
}
-
-
//更新
-
func (u *VolumeDataService) UpdateVolume(volume *model.Volume) error {
-
return u.VolumeRepository.UpdateVolume(volume)
-
}
-
-
//查找
-
func (u *VolumeDataService) FindVolumeByID(volumeID int64) (*model.Volume, error) {
-
return u.VolumeRepository.FindVolumeByID(volumeID)
-
}
-
-
//查找
-
func (u *VolumeDataService) FindAllVolume() ([]model.Volume, error) {
-
return u.VolumeRepository.FindAll()
-
}
-
9-13 Go PaaS 平台 Service 开发(下)
C:\Users\Administrator\Desktop\gopaas\volume\domain\service\volume_data_service.go
-
//获取资源配置
-
func (u *VolumeDataService) getResource (info *volume.VolumeInfo)(source v12.ResourceRequirements) {
-
source.Requests = v12.ResourceList{
-
"storage": resource.MustParse(strconv.FormatFloat(float64(info.VolumeRequest),'f',6,64) "Gi"),
-
}
-
return
-
}
-
-
//获取访问模式
-
func (u *VolumeDataService) getAccessModes(info *volume.VolumeInfo)(pvam []v12.PersistentVolumeAccessMode) {
-
var pm v12.PersistentVolumeAccessMode
-
switch info.VolumeAccessMode {
-
case "ReadWriteOnce":
-
pm = v12.ReadWriteOnce
-
case "ReadOnlyMany":
-
pm = v12.ReadOnlyMany
-
case "ReadWriteMany":
-
pm = v12.ReadWriteMany
-
case "ReadWriteOncePod":
-
pm = v12.ReadWriteOncePod
-
default:
-
pm = v12.ReadWriteOnce
-
}
-
pvam = append(pvam,pm)
-
return pvam
-
-
}
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
-
package handler
-
-
import (
-
"context"
-
"strconv"
-
-
log "github.com/asim/go-micro/v3/logger"
-
"github.com/yunixiangfeng/gopaas/common"
-
"github.com/yunixiangfeng/gopaas/volume/domain/model"
-
"github.com/yunixiangfeng/gopaas/volume/domain/service"
-
volume "github.com/yunixiangfeng/gopaas/volume/proto/volume"
-
)
-
-
type VolumeHandler struct {
-
//注意这里的类型是 IVolumeDataService 接口类型
-
VolumeDataService service.IVolumeDataService
-
}
-
-
// Call is a single request handler called via client.Call or the generated client code
-
func (e *VolumeHandler) AddVolume(ctx context.Context, info *volume.VolumeInfo, rsp *volume.Response) error {
-
log.Info("Received *volume.AddVolume request")
-
volume := &model.Volume{}
-
if err := common.SwapTo(info, volume); err != nil {
-
common.Error(err)
-
rsp.Msg = err.Error()
-
return err
-
}
-
//创建volume
-
if err := e.VolumeDataService.CreateVolumeToK8s(info); err != nil {
-
common.Error(err)
-
rsp.Msg = err.Error()
-
return err
-
} else {
-
//写入数据库
-
volumeID, err := e.VolumeDataService.AddVolume(volume)
-
if err != nil {
-
common.Error(err)
-
rsp.Msg = err.Error()
-
return err
-
}
-
rsp.Msg = "volume 添加成功 ID 号为:" strconv.FormatInt(volumeID, 10)
-
}
-
return nil
-
}
-
-
//删除
-
func (e *VolumeHandler) DeleteVolume(ctx context.Context, req *volume.VolumeId, rsp *volume.Response) error {
-
log.Info("Received *volume.DeleteVolume request")
-
volumModel, err := e.VolumeDataService.FindVolumeByID(req.Id)
-
if err != nil {
-
common.Error(err)
-
return err
-
}
-
//从k8s中删除,并且删除数据库
-
if err := e.VolumeDataService.DeleteVolumeFromK8s(volumModel); err != nil {
-
common.Error(err)
-
return err
-
}
-
return nil
-
}
-
-
func (e *VolumeHandler) UpdateVolume(ctx context.Context, req *volume.VolumeInfo, rsp *volume.Response) error {
-
log.Info("Received *volume.UpdateVolume request")
-
return nil
-
}
-
-
//根据 ID 查找 volume
-
func (e *VolumeHandler) FindVolumeByID(ctx context.Context, req *volume.VolumeId, rsp *volume.VolumeInfo) error {
-
log.Info("Received *volume.FindVolumeByID request")
-
volumeModel, err := e.VolumeDataService.FindVolumeByID(req.Id)
-
if err != nil {
-
common.Error(err)
-
return err
-
}
-
//数据转化
-
if err := common.SwapTo(volumeModel, rsp); err != nil {
-
common.Error(err)
-
return err
-
}
-
return nil
-
}
-
-
func (e *VolumeHandler) FindAllVolume(ctx context.Context, req *volume.FindAll, rsp *volume.AllVolume) error {
-
log.Info("Received *volume.FindAllVolume request")
-
allVolume, err := e.VolumeDataService.FindAllVolume()
-
if err != nil {
-
common.Error(err)
-
return err
-
}
-
//整理格式
-
for _, v := range allVolume {
-
//创建实例
-
volumeInfo := &volume.VolumeInfo{}
-
//数据转化
-
if err := common.SwapTo(v, volumeInfo); err != nil {
-
common.Error(err)
-
return err
-
}
-
//数据合并
-
rsp.VolumeInfo = append(rsp.VolumeInfo, volumeInfo)
-
}
-
return nil
-
}
C:\Users\Administrator\Desktop\gopaas\volume\main.go
-
package main
-
-
import (
-
"flag"
-
"fmt"
-
"path/filepath"
-
-
"github.com/yunixiangfeng/gopaas/common"
-
"github.com/yunixiangfeng/gopaas/volume/domain/repository"
-
-
//"github.com/afex/hystrix-go/hystrix"
-
"github.com/asim/go-micro/plugins/registry/consul/v3"
-
ratelimit "github.com/asim/go-micro/plugins/wrapper/ratelimiter/uber/v3"
-
opentracing2 "github.com/asim/go-micro/plugins/wrapper/trace/opentracing/v3"
-
"github.com/asim/go-micro/v3"
-
"github.com/asim/go-micro/v3/registry"
-
"github.com/asim/go-micro/v3/server"
-
"github.com/jinzhu/gorm"
-
_ "github.com/jinzhu/gorm/dialects/mysql"
-
"github.com/opentracing/opentracing-go"
-
service2 "github.com/yunixiangfeng/gopaas/volume/domain/service"
-
"github.com/yunixiangfeng/gopaas/volume/handler"
-
-
//hystrix2 "github.com/yunixiangfeng/gopaas/volume/plugin/hystrix"
-
"strconv"
-
-
volume "github.com/yunixiangfeng/gopaas/volume/proto/volume"
-
"k8s.io/client-go/kubernetes"
-
"k8s.io/client-go/tools/clientcmd"
-
"k8s.io/client-go/util/homedir"
-
)
-
-
var (
-
//服务地址
-
hostIp = "192.168.204.130"
-
//服务地址
-
serviceHost = hostIp
-
//服务端口
-
servicePort = "8087"
-
-
//注册中心配置
-
consulHost = hostIp
-
consulPort int64 = 8500
-
//链路追踪
-
tracerHost = hostIp
-
tracerPort = 6831
-
//熔断端口,每个服务不能重复
-
//hystrixPort = 9097
-
//监控端口,每个服务不能重复
-
prometheusPort = 9197
-
)
-
-
func main() {
-
//需要本地启动,mysql,consul中间件服务
-
//1.注册中心
-
consul := consul.NewRegistry(func(options *registry.Options) {
-
options.Addrs = []string{
-
consulHost ":" strconv.FormatInt(consulPort, 10),
-
}
-
})
-
//2.配置中心,存放经常变动的变量
-
consulConfig, err := common.GetConsulConfig(consulHost, consulPort, "/micro/config")
-
if err != nil {
-
common.Error(err)
-
}
-
//3.使用配置中心连接 mysql
-
mysqlInfo := common.GetMysqlFromConsul(consulConfig, "mysql")
-
//初始化数据库
-
db, err := gorm.Open("mysql", mysqlInfo.User ":" mysqlInfo.Pwd "@(" mysqlInfo.Host ":3306)/" mysqlInfo.Database "?charset=utf8&parseTime=True&loc=Local")
-
if err != nil {
-
//命令行输出下,方便查看错误
-
fmt.Println(err)
-
common.Fatal(err)
-
}
-
defer db.Close()
-
//禁止复表
-
db.SingularTable(true)
-
-
//4.添加链路追踪
-
t, io, err := common.NewTracer("go.micro.service.volume", tracerHost ":" strconv.Itoa(tracerPort))
-
if err != nil {
-
common.Error(err)
-
}
-
defer io.Close()
-
opentracing.SetGlobalTracer(t)
-
-
//添加熔断器,作为客户端需要启用
-
//hystrixStreamHandler := hystrix.NewStreamHandler()
-
//hystrixStreamHandler.Start()
-
-
//添加日志中心
-
//1)需要程序日志打入到日志文件中
-
//2)在程序中添加filebeat.yml 文件
-
//3) 启动filebeat,启动命令 ./filebeat -e -c filebeat.yml
-
fmt.Println("日志统一记录在根目录 micro.log 文件中,请点击查看日志!")
-
-
//启动监听程序
-
//go func() {
-
// //http://192.168.204.130:9092/turbine/turbine.stream
-
// //看板访问地址 http://127.0.0.1:9002/hystrix,url后面一定要带 /hystrix
-
// err = http.ListenAndServe(net.JoinHostPort("0.0.0.0",strconv.Itoa(hystrixPort)),hystrixStreamHandler)
-
// if err !=nil {
-
// common.Error(err)
-
// }
-
//}()
-
-
//5.添加监控
-
common.PrometheusBoot(prometheusPort)
-
-
//下载kubectl:https://kubernetes.io/docs/tasks/tools/#tabset-2
-
//macos:
-
// 1.curl -LO "https://dl.k8s.io/release/v1.21.0/bin/darwin/amd64/kubectl"
-
// 2.chmod x ./kubectl
-
// 3.sudo mv ./kubectl /usr/local/bin/kubectl
-
// sudo chown root: /usr/local/bin/kubectl
-
// 5.kubectl version --client
-
// 6.集群模式下直接拷贝服务端~/.kube/config 文件到本机 ~/.kube/confg 中
-
// 注意:- config中的域名要能解析正确
-
// - 生产环境可以创建另一个证书
-
// 7.kubectl get ns 查看是否正常
-
//
-
//6.创建k8s连接
-
//在集群外面连接
-
var kubeconfig *string
-
if home := homedir.HomeDir(); home != "" {
-
kubeconfig = flag.String("kubeconfig", filepath.Join(home, ".kube", "config"), "(optional) absolute path to the kubeconfig file")
-
} else {
-
kubeconfig = flag.String("kubeconfig", "", "absolute path to the kubeconfig file")
-
}
-
flag.Parse()
-
config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
-
if err != nil {
-
common.Fatal(err.Error())
-
}
-
-
//在集群中外的配置
-
//config, err := rest.InClusterConfig()
-
//if err != nil {
-
// panic(err.Error())
-
//}
-
-
// create the clientset
-
clientset, err := kubernetes.NewForConfig(config)
-
if err != nil {
-
common.Fatal(err.Error())
-
}
-
-
//7.创建服务
-
service := micro.NewService(
-
//自定义服务地址,且必须写在其它参数前面
-
micro.Server(server.NewServer(func(options *server.Options) {
-
options.Advertise = serviceHost ":" servicePort
-
})),
-
micro.Name("go.micro.service.volume"),
-
micro.Version("latest"),
-
//指定服务端口
-
micro.Address(":" servicePort),
-
//添加注册中心
-
micro.Registry(consul),
-
//添加链路追踪
-
micro.WrapHandler(opentracing2.NewHandlerWrapper(opentracing.GlobalTracer())),
-
micro.WrapClient(opentracing2.NewClientWrapper(opentracing.GlobalTracer())),
-
//只作为客户端的时候起作用,如果存在调用别人的情况,原则上不去主动调用
-
//micro.WrapClient(hystrix2.NewClientHystrixWrapper()),
-
//添加限流
-
micro.WrapHandler(ratelimit.NewHandlerWrapper(1000)),
-
)
-
-
service.Init()
-
-
//只能执行一遍
-
//err = repository.NewVolumeRepository(db).InitTable()
-
//if err != nil {
-
// common.Fatal(err)
-
//}
-
-
// 注册句柄,可以快速操作已开发的服务
-
volumeDataService := service2.NewVolumeDataService(repository.NewVolumeRepository(db), clientset)
-
volume.RegisterVolumeHandler(service.Server(), &handler.VolumeHandler{VolumeDataService: volumeDataService})
-
-
// 启动服务
-
if err := service.Run(); err != nil {
-
//输出启动失败信息
-
common.Fatal(err)
-
}
-
}
9-16 Go PaaS 平台 volume api 开发
-
PS C:\Users\Administrator\Desktop\gopaas> .\yu-tool\yu-tool.exe createApi github.com/yunixiangfeng/gopaas/volumeApi
-
-
yu-v3 --proto_path=. --micro_out=. --go_out=:. ./proto/volumeApi/volumeApi.proto
-
-
go mod tidy
C:\Users\Administrator\Desktop\gopaas\volumeapi\handler\volumeApiHandler.go
-
package handler
-
-
import (
-
"context"
-
"encoding/json"
-
"errors"
-
"strconv"
-
-
log "github.com/asim/go-micro/v3/logger"
-
"github.com/yunixiangfeng/gopaas/common"
-
volume "github.com/yunixiangfeng/gopaas/volume/proto/volume"
-
"github.com/yunixiangfeng/gopaas/volumeApi/plugin/form"
-
volumeApi "github.com/yunixiangfeng/gopaas/volumeApi/proto/volumeApi"
-
)
-
-
type VolumeApi struct {
-
VolumeService volume.VolumeService
-
}
-
-
// volumeApi.FindVolumeById 通过API向外暴露为/volumeApi/findVolumeById,接收http请求
-
// 即:/volumeApi/FindVolumeById 请求会调用go.micro.api.volumeApi 服务的volumeApi.FindVolumeById 方法
-
func (e *VolumeApi) FindVolumeById(ctx context.Context, req *volumeApi.Request, rsp *volumeApi.Response) error {
-
log.Info("Received volumeApi.FindVolumeById request")
-
if _, ok := req.Get["volume_id"]; !ok {
-
rsp.StatusCode = 500
-
return errors.New("参数有异常")
-
}
-
//获取 volume_id
-
volumeIdString := req.Get["volume_id"].Values[0]
-
volumeId, err := strconv.ParseInt(volumeIdString, 10, 64)
-
if err != nil {
-
common.Error(err)
-
return err
-
}
-
//获取 volume 信息
-
volumeInfo, err := e.VolumeService.FindVolumeByID(ctx, &volume.VolumeId{
-
Id: volumeId,
-
})
-
if err != nil {
-
common.Error(err)
-
return err
-
}
-
rsp.StatusCode = 200
-
b, _ := json.Marshal(volumeInfo)
-
rsp.Body = string(b)
-
return nil
-
}
-
-
// volumeApi.AddVolume 通过API向外暴露为/volumeApi/AddVolume,接收http请求
-
// 即:/volumeApi/AddVolume 请求会调用go.micro.api.volumeApi 服务的volumeApi.AddVolume 方法
-
func (e *VolumeApi) AddVolume(ctx context.Context, req *volumeApi.Request, rsp *volumeApi.Response) error {
-
log.Info("Received volumeApi.AddVolume request")
-
addVolumeInfo := &volume.VolumeInfo{}
-
form.FormToSvcStruct(req.Post, addVolumeInfo)
-
response, err := e.VolumeService.AddVolume(ctx, addVolumeInfo)
-
if err != nil {
-
common.Error(err)
-
return err
-
}
-
rsp.StatusCode = 200
-
b, _ := json.Marshal(response)
-
rsp.Body = string(b)
-
return nil
-
}
-
-
// volumeApi.DeleteVolumeById 通过API向外暴露为/volumeApi/DeleteVolumeById,接收http请求
-
// 即:/volumeApi/DeleteVolumeById 请求会调用go.micro.api.volumeApi 服务的 volumeApi.DeleteVolumeById 方法
-
func (e *VolumeApi) DeleteVolumeById(ctx context.Context, req *volumeApi.Request, rsp *volumeApi.Response) error {
-
log.Info("Received volumeApi.DeleteVolumeById request")
-
if _, ok := req.Get["volume_id"]; !ok {
-
rsp.StatusCode = 500
-
return errors.New("参数异常")
-
}
-
//获取 volume_id
-
volumeIdString := req.Get["volume_id"].Values[0]
-
volumeId, err := strconv.ParseInt(volumeIdString, 10, 64)
-
if err != nil {
-
common.Error(err)
-
return err
-
}
-
//调用 volume 删除服务
-
response, err := e.VolumeService.DeleteVolume(ctx, &volume.VolumeId{
-
Id: volumeId,
-
})
-
if err != nil {
-
common.Error(err)
-
return err
-
}
-
rsp.StatusCode = 200
-
b, _ := json.Marshal(response)
-
rsp.Body = string(b)
-
return nil
-
}
-
-
// volumeApi.UpdateVolume 通过API向外暴露为/volumeApi/UpdateVolume,接收http请求
-
// 即:/volumeApi/UpdateVolume 请求会调用go.micro.api.volumeApi 服务的volumeApi.UpdateVolume 方法
-
func (e *VolumeApi) UpdateVolume(ctx context.Context, req *volumeApi.Request, rsp *volumeApi.Response) error {
-
log.Info("Received volumeApi.UpdateVolume request")
-
rsp.StatusCode = 200
-
b, _ := json.Marshal("{success:'成功访问/volumeApi/UpdateVolume'}")
-
rsp.Body = string(b)
-
return nil
-
}
-
-
// 默认的方法volumeApi.Call 通过API向外暴露为/volumeApi/call,接收http请求
-
// 即:/volumeApi/call或/volumeApi/ 请求会调用go.micro.api.volumeApi 服务的volumeApi.FindVolumeById 方法
-
func (e *VolumeApi) Call(ctx context.Context, req *volumeApi.Request, rsp *volumeApi.Response) error {
-
log.Info("Received volumeApi.Call request")
-
allVolume, err := e.VolumeService.FindAllVolume(ctx, &volume.FindAll{})
-
if err != nil {
-
common.Error(err)
-
return err
-
}
-
rsp.StatusCode = 200
-
b, _ := json.Marshal(allVolume)
-
rsp.Body = string(b)
-
return nil
-
}
C:\Users\Administrator\Desktop\gopaas\volumeapi\plugin\form\form.go
-
package form
-
-
import (
-
"errors"
-
"reflect"
-
"strconv"
-
"strings"
-
"time"
-
-
"github.com/yunixiangfeng/gopaas/common"
-
"github.com/yunixiangfeng/gopaas/volumeApi/proto/volumeApi"
-
)
-
-
//根据结构体中name标签映射数据到结构体中并且转换类型
-
func FormToSvcStruct(data map[string]*volumeApi.Pair, obj interface{}) {
-
objValue := reflect.ValueOf(obj).Elem()
-
for i := 0; i < objValue.NumField(); i {
-
//获取sql对应的值
-
dataTag := strings.Replace(objValue.Type().Field(i).Tag.Get("json"), ",omitempty", "", -1)
-
dataSlice, ok := data[dataTag]
-
if !ok {
-
continue
-
}
-
valueSlice := dataSlice.Values
-
if len(valueSlice) <= 0 {
-
continue
-
}
-
//排除port和env
-
if dataTag == "route_path" {
-
continue
-
}
-
value := valueSlice[0]
-
//端口,环境变量的单独处理
-
//获取对应字段的名称
-
name := objValue.Type().Field(i).Name
-
//获取对应字段类型
-
structFieldType := objValue.Field(i).Type()
-
//获取变量类型,也可以直接写"string类型"
-
val := reflect.ValueOf(value)
-
var err error
-
if structFieldType != val.Type() {
-
//类型转换
-
val, err = TypeConversion(value, structFieldType.Name()) //类型转换
-
if err != nil {
-
common.Error(err)
-
}
-
}
-
//设置类型值
-
objValue.FieldByName(name).Set(val)
-
}
-
}
-
-
//类型转换
-
func TypeConversion(value string, ntype string) (reflect.Value, error) {
-
if ntype == "string" {
-
return reflect.ValueOf(value), nil
-
} else if ntype == "time.Time" {
-
t, err := time.ParseInLocation("2006-01-02 15:04:05", value, time.Local)
-
return reflect.ValueOf(t), err
-
} else if ntype == "Time" {
-
t, err := time.ParseInLocation("2006-01-02 15:04:05", value, time.Local)
-
return reflect.ValueOf(t), err
-
} else if ntype == "int" {
-
i, err := strconv.Atoi(value)
-
return reflect.ValueOf(i), err
-
} else if ntype == "int32" {
-
i, err := strconv.ParseInt(value, 10, 32)
-
if err != nil {
-
return reflect.ValueOf(int32(i)), err
-
}
-
return reflect.ValueOf(int32(i)), err
-
} else if ntype == "int64" {
-
i, err := strconv.ParseInt(value, 10, 64)
-
return reflect.ValueOf(i), err
-
} else if ntype == "float32" {
-
i, err := strconv.ParseFloat(value, 64)
-
return reflect.ValueOf(float32(i)), err
-
} else if ntype == "float64" {
-
i, err := strconv.ParseFloat(value, 64)
-
return reflect.ValueOf(i), err
-
}
-
-
//else if .......增加其他一些类型的转换
-
-
return reflect.ValueOf(value), errors.New("未知的类型:" ntype)
-
}
C:\Users\Administrator\Desktop\gopaas\volumeapi\main.go
-
package main
-
-
import (
-
"fmt"
-
-
"github.com/afex/hystrix-go/hystrix"
-
"github.com/asim/go-micro/plugins/registry/consul/v3"
-
ratelimit "github.com/asim/go-micro/plugins/wrapper/ratelimiter/uber/v3"
-
"github.com/asim/go-micro/plugins/wrapper/select/roundrobin/v3"
-
opentracing2 "github.com/asim/go-micro/plugins/wrapper/trace/opentracing/v3"
-
"github.com/asim/go-micro/v3"
-
"github.com/asim/go-micro/v3/registry"
-
"github.com/asim/go-micro/v3/server"
-
"github.com/yunixiangfeng/gopaas/common"
-
go_micro_service_volume "github.com/yunixiangfeng/gopaas/volume/proto/volume"
-
-
"net"
-
"net/http"
-
"strconv"
-
-
_ "github.com/jinzhu/gorm/dialects/mysql"
-
"github.com/opentracing/opentracing-go"
-
"github.com/yunixiangfeng/gopaas/volumeApi/handler"
-
hystrix2 "github.com/yunixiangfeng/gopaas/volumeApi/plugin/hystrix"
-
-
volumeApi "github.com/yunixiangfeng/gopaas/volumeApi/proto/volumeApi"
-
)
-
-
var (
-
//服务地址
-
hostIp = "192.168.204.130"
-
//服务地址
-
serviceHost = hostIp
-
//服务端口
-
servicePort = "8087"
-
//注册中心配置
-
consulHost = hostIp
-
consulPort int64 = 8500
-
//链路追踪
-
tracerHost = hostIp
-
tracerPort = 6831
-
//熔断端口,每个服务不能重复
-
hystrixPort = 9097
-
//监控端口,每个服务不能重复
-
prometheusPort = 9197
-
)
-
-
func main() {
-
//需要本地启动,mysql,consul中间件服务
-
//1.注册中心
-
consul := consul.NewRegistry(func(options *registry.Options) {
-
options.Addrs = []string{
-
consulHost ":" strconv.FormatInt(consulPort, 10),
-
}
-
})
-
-
//2.添加链路追踪
-
t, io, err := common.NewTracer("go.micro.api.volumeApi", tracerHost ":" strconv.Itoa(tracerPort))
-
if err != nil {
-
common.Error(err)
-
}
-
defer io.Close()
-
opentracing.SetGlobalTracer(t)
-
-
//3.添加熔断器
-
hystrixStreamHandler := hystrix.NewStreamHandler()
-
hystrixStreamHandler.Start()
-
-
//添加日志中心
-
//1)需要程序日志打入到日志文件中
-
//2)在程序中添加filebeat.yml 文件
-
//3) 启动filebeat,启动命令 ./filebeat -e -c filebeat.yml
-
fmt.Println("日志统一记录在根目录 micro.log 文件中,请点击查看日志!")
-
-
//启动监听程序
-
go func() {
-
//http://192.168.204.130:9092/turbine/turbine.stream
-
//看板访问地址 http://127.0.0.1:9002/hystrix,url后面一定要带 /hystrix
-
err = http.ListenAndServe(net.JoinHostPort("0.0.0.0", strconv.Itoa(hystrixPort)), hystrixStreamHandler)
-
if err != nil {
-
common.Error(err)
-
}
-
}()
-
-
//4.添加监控
-
common.PrometheusBoot(prometheusPort)
-
-
//5.创建服务
-
service := micro.NewService(
-
//自定义服务地址,且必须写在其它参数前面
-
micro.Server(server.NewServer(func(opts *server.Options) {
-
opts.Advertise = serviceHost ":" servicePort
-
-
})),
-
micro.Name("go.micro.api.volumeApi"),
-
micro.Version("latest"),
-
//指定服务端口
-
micro.Address(":" servicePort),
-
//添加注册中心
-
micro.Registry(consul),
-
//添加链路追踪
-
micro.WrapHandler(opentracing2.NewHandlerWrapper(opentracing.GlobalTracer())),
-
micro.WrapClient(opentracing2.NewClientWrapper(opentracing.GlobalTracer())),
-
//只作为客户端的时候起作用
-
micro.WrapClient(hystrix2.NewClientHystrixWrapper()),
-
//添加限流
-
micro.WrapHandler(ratelimit.NewHandlerWrapper(1000)),
-
//增加负载均衡
-
micro.WrapClient(roundrobin.NewClientWrapper()),
-
)
-
-
service.Init()
-
-
// 指定需要访问的服务,可以快速操作已开发的服务,
-
// 默认API服务名称带有"Api",程序会自动替换
-
// 如果不带有特定字符会使用默认"XXX" 请自行替换
-
volumeService := go_micro_service_volume.NewVolumeService("go.micro.service.volume", service.Client())
-
// 注册控制器
-
if err := volumeApi.RegisterVolumeApiHandler(service.Server(), &handler.VolumeApi{VolumeService: volumeService}); err != nil {
-
common.Error(err)
-
}
-
-
// 启动服务
-
if err := service.Run(); err != nil {
-
//输出启动失败信息
-
common.Fatal(err)
-
}
-
}
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 平台中间件创建与管理
-
PS C:\Users\Administrator\Desktop\gopaas> .\yu-tool\yu-tool.exe newService github.com/yunixiangfeng/gopaas/middleware
-
-
yu-v3 --proto_path=. --micro_out=. --go_out=:. ./proto/middleware/middleware.proto
-
-
go mod tidy
middleware\domain\model\middleware.go
-
package model
-
-
type Middleware struct {
-
ID int64 `gorm:"primary_key;not_null;auto_increment"`
-
//中间件的名称
-
MiddleName string `json:"middle_name"`
-
//中间件创建的命名空间
-
MiddleNamespace string `json:"middle_namespace"`
-
//中间件的类型
-
MiddleTypeID int64 `json:"middle_type_id"`
-
//中间件的版本
-
MiddleVersionID int64 `json:"middle_version_id"`
-
//中间件的端口
-
MiddlePort []MiddlePort `gorm:"ForeignKey:MiddleID" json:"middle_port"`
-
//默认生成的账号密码
-
MiddleConfig MiddleConfig `gorm:"ForeignKey:MiddleID" json:"middle_config"`
-
//环境变量
-
MiddleEnv []MiddleEnv `gorm:"ForeignKey:MiddleID" json:"middle_env"`
-
//中间件的CPU
-
MiddleCpu float32 `json:"middle_cpu"`
-
//中间件内存
-
MiddleMemory float32 `json:"middle_memory"`
-
//中间件存储
-
MiddleStorage []MiddleStorage `gorm:"ForeignKey:MiddleID" json:"middle_storage"`
-
//中间件副本
-
MiddleReplicas int32 `json:"middle_replicas"`
-
}
10-2 Go PAAS平台中间件model-middle_port创建
C:\Users\Administrator\Desktop\gopaas\middleware\domain\model\middle_port.go
-
package model
-
-
type MiddlePort struct {
-
ID int64 `gorm:"primary_key;not_null;auto_increment" json:"id"`
-
//主要用来关联中间件的ID
-
MiddleID int64 `json:"middle_id"`
-
//中间件开放的端口
-
MiddlePort int32 `json:"middle_port"`
-
//中间件开放的端口协议
-
MiddleProtocol string `json:"middle_protocol"`
-
}
10-3 中间件model-middle_env创建
C:\Users\Administrator\Desktop\gopaas\middleware\domain\model\middle_env.go
-
package model
-
-
//中间件的变量
-
type MiddleEnv struct {
-
ID int64 `gorm:"primary_key;not_null;auto_increment" json:"id"`
-
//关联的环境变量ID
-
MiddleID int64 `json:"middle_id"`
-
//环境变量key
-
EnvKey string `json:"env_key"`
-
//环境变量Value
-
EnvValue string `json:"env_value"`
-
}
10-4 中间件model-MiddleConfig创建
C:\Users\Administrator\Desktop\gopaas\middleware\domain\model\middle_config.go
-
package model
-
-
//中间件配置的结构体
-
type MiddleConfig struct {
-
ID int64 `gorm:"primary_key;not_null;auto_increment" json:"id"`
-
//关联的中间件ID
-
MiddleID int64 `json:"middle_id"`
-
//可能存在的root 用户
-
MiddleConfigRootUser string `json:"middle_config_root_user"`
-
//可能存在的root 密码
-
MiddleConfigRootPwd string `json:"middle_config_root_pwd"`
-
//可能存在的普通用户
-
MiddleConfigUser string `json:"middle_config_user"`
-
//普通用户的密码
-
MiddleConfigPwd string `json:"middle_config_pwd"`
-
//预置数据库名称
-
MiddleConfigDataBase string `json:"middle_config_data_base"`
-
//其它设置
-
}
10-5 中间件model-MiddleStorage创建
C:\Users\Administrator\Desktop\gopaas\middleware\domain\model\middle_storage.go
-
package model
-
-
//中间件的存储盘
-
type MiddleStorage struct {
-
ID int64 `gorm:"primary_key;not_null;auto_increment" json:"id"`
-
//关联的中间件ID
-
MiddleID int64 `json:"middle_id"`
-
//存储名称
-
MiddleStorageName string `json:"middle_storage_name"`
-
//存储的大小
-
MiddleStorageSize float32 `json:"middle_storage_size"`
-
//存储需要挂载的目录
-
MiddleStoragePath string `json:"middle_storage_path"`
-
//存储创建的类型
-
MiddleStorageClass string `json:"middle_storage_class"`
-
//存储的权限
-
MiddleStorageAccessMode string `json:"middle_storage_access_mode"`
-
}
10-6 中间件类型type 和 version创建
C:\Users\Administrator\Desktop\gopaas\middleware\domain\model\middle_type.go
-
package model
-
-
//中间件类型
-
type MiddleType struct {
-
ID int64 `gorm:"primary_key;not_null;auto_increment" json:"id"`
-
//中间件类型名称
-
MiddleTypeName string `json:"middle_type_name"`
-
//中间件图片地址
-
MiddleTypeImageSrc string `json:"middle_type_image_src"`
-
//中间件的版本
-
MiddleVersion[] MiddleVersion `gorm:"ForeignKey:MiddleTypeID" json:"middle_version"`
-
}
C:\Users\Administrator\Desktop\gopaas\middleware\domain\model\middle_version.go
-
package model
-
-
type MiddleVersion struct {
-
ID int64 `gorm:"primary_key;not_null;auto_increment" json:"id"`
-
MiddleTypeID int64 `json:"middle_type_id"`
-
//镜像地址
-
MiddleDockerImage string `json:"middle_docker_image"`
-
//镜像版本
-
MiddleVS string `json:"middle_vs"`
-
//MiddleDockerImage:MiddleVS
-
//其它
-
}
10-7 中间件 middleware repository开发
C:\Users\Administrator\Desktop\gopaas\middleware\domain\repository\middleware_repository.go
-
package repository
-
-
import (
-
"github.com/jinzhu/gorm"
-
"github.com/yunixiangfeng/gopaas/middleware/domain/model"
-
)
-
-
//创建需要实现的接口
-
type IMiddlewareRepository interface {
-
//初始化表
-
InitTable() error
-
//根据ID查处找数据
-
FindMiddlewareByID(int64) (*model.Middleware, error)
-
//创建一条 middleware 数据
-
CreateMiddleware(*model.Middleware) (int64, error)
-
//根据ID删除一条 middleware 数据
-
DeleteMiddlewareByID(int64) error
-
//修改更新数据
-
UpdateMiddleware(*model.Middleware) error
-
//查找middleware所有数据
-
FindAll() ([]model.Middleware, error)
-
-
//根据类型查找所有中间件
-
FindAllByTypeID(int64) ([]model.Middleware, error)
-
}
-
-
//创建middlewareRepository
-
func NewMiddlewareRepository(db *gorm.DB) IMiddlewareRepository {
-
return &MiddlewareRepository{mysqlDb: db}
-
}
-
-
type MiddlewareRepository struct {
-
mysqlDb *gorm.DB
-
}
-
-
//初始化表
-
func (u *MiddlewareRepository) InitTable() error {
-
return u.mysqlDb.CreateTable(&model.Middleware{}, &model.MiddleConfig{}, &model.MiddlePort{}, &model.MiddleEnv{}, &model.MiddleStorage{}).Error
-
}
-
-
//根据ID查找Middleware信息
-
func (u *MiddlewareRepository) FindMiddlewareByID(middlewareID int64) (middleware *model.Middleware, err error) {
-
middleware = &model.Middleware{}
-
//要多个则添加 Preload
-
return middleware, u.mysqlDb.First(middleware, middlewareID).Error
-
}
-
-
//创建Middleware信息
-
func (u *MiddlewareRepository) CreateMiddleware(middleware *model.Middleware) (int64, error) {
-
return middleware.ID, u.mysqlDb.Create(middleware).Error
-
}
-
-
//根据ID删除Middleware信息
-
func (u *MiddlewareRepository) DeleteMiddlewareByID(middlewareID int64) error {
-
//开启事物
-
tx := u.mysqlDb.Begin()
-
//遇到问题回滚
-
defer func() {
-
if r := recover(); r != nil {
-
tx.Rollback()
-
}
-
}()
-
//遇到错误返回
-
if tx.Error != nil {
-
return tx.Error
-
}
-
//删除中间件
-
if err := u.mysqlDb.Where("id = ?", middlewareID).Delete(&model.Middleware{}).Error; err != nil {
-
tx.Rollback()
-
return err
-
}
-
//删除中间件的配置
-
if err := u.mysqlDb.Where("middle_id = ?", middlewareID).Delete(&model.MiddleConfig{}).Error; err != nil {
-
tx.Rollback()
-
return err
-
}
-
//删除端口
-
if err := u.mysqlDb.Where("middle_id = ?", middlewareID).Delete(&model.MiddlePort{}).Error; err != nil {
-
tx.Rollback()
-
return err
-
}
-
//删除中间件环境变量
-
if err := u.mysqlDb.Where("middle_id = ?", middlewareID).Delete(&model.MiddleEnv{}).Error; err != nil {
-
tx.Rollback()
-
return err
-
}
-
//删除中间件存储
-
if err := u.mysqlDb.Where("middle_id = ?", middlewareID).Delete(&model.MiddleStorage{}).Error; err != nil {
-
tx.Rollback()
-
return err
-
}
-
return tx.Commit().Error
-
}
-
-
//更新Middleware信息
-
func (u *MiddlewareRepository) UpdateMiddleware(middleware *model.Middleware) error {
-
return u.mysqlDb.Model(middleware).Update(middleware).Error
-
}
-
-
//获取结果集
-
func (u *MiddlewareRepository) FindAll() (middlewareAll []model.Middleware, err error) {
-
//要多个则添加 Preload
-
return middlewareAll, u.mysqlDb.Find(&middlewareAll).Error
-
}
-
-
func (u *MiddlewareRepository) FindAllByTypeID(typeID int64) (middlewareAll []model.Middleware, err error) {
-
//要多个则添加 Preload
-
return middlewareAll, u.mysqlDb.Where("middle_type_id = ?", typeID).Find(&middlewareAll).Error
-
}
10-8 中间件类型type和verison repository开发
C:\Users\Administrator\Desktop\gopaas\middleware\domain\repository\middle_type_repository.go
-
package repository
-
-
import (
-
"github.com/jinzhu/gorm"
-
"github.com/yunixiangfeng/gopaas/middleware/domain/model"
-
)
-
-
//创建需要实现的接口
-
type IMiddleTypeRepository interface {
-
//初始化表
-
InitTable() error
-
//根据ID查处找数据
-
FindTypeByID(int64) (*model.MiddleType, error)
-
//创建一条 middleware 数据
-
CreateMiddleType(*model.MiddleType) (int64, error)
-
//根据ID删除一条 middleware 数据
-
DeleteMiddleTypeByID(int64) error
-
//修改更新数据
-
UpdateMiddleType(*model.MiddleType) error
-
//查找middleware所有数据
-
FindAll() ([]model.MiddleType, error)
-
-
FindVersionByID(int64) (*model.MiddleVersion, error)
-
FindAllVersionByTypeID(int64) ([]model.MiddleVersion, error)
-
}
-
-
//创建MiddleTypeRepository
-
func NewMiddleTypeRepository(db *gorm.DB) IMiddleTypeRepository {
-
return &MiddleTypeRepository{mysqlDb: db}
-
}
-
-
type MiddleTypeRepository struct {
-
mysqlDb *gorm.DB
-
}
-
-
//初始化表
-
func (u *MiddleTypeRepository) InitTable() error {
-
return u.mysqlDb.CreateTable(&model.MiddleType{}, &model.MiddleVersion{}).Error
-
}
-
-
//按照 ID 查找中间件类型
-
func (u *MiddleTypeRepository) FindTypeByID(middleTypeID int64) (middleType *model.MiddleType, err error) {
-
middleType = &model.MiddleType{}
-
return middleType, u.mysqlDb.Preload("MiddleVersion").First(middleType, middleTypeID).Error
-
}
-
-
//创建中间件
-
func (u *MiddleTypeRepository) CreateMiddleType(middleType *model.MiddleType) (int64, error) {
-
return middleType.ID, u.mysqlDb.Create(middleType).Error
-
}
-
-
//删除中间件
-
func (u *MiddleTypeRepository) DeleteMiddleTypeByID(middleTypeID int64) error {
-
tx := u.mysqlDb.Begin()
-
//遇到问题回滚
-
defer func() {
-
if r := recover(); r != nil {
-
tx.Rollback()
-
}
-
}()
-
//遇到错误返回
-
if tx.Error != nil {
-
return tx.Error
-
}
-
//删除中间件类型
-
if err := u.mysqlDb.Where("id = ?", middleTypeID).Delete(&model.MiddleType{}).Error; err != nil {
-
tx.Rollback()
-
return err
-
}
-
//开始删除版本
-
if err := u.mysqlDb.Where("middle_type_id = ?", middleTypeID).Delete(&model.MiddleVersion{}).Error; err != nil {
-
tx.Rollback()
-
return err
-
}
-
return tx.Commit().Error
-
}
-
-
//更新middleware 信息
-
func (u *MiddleTypeRepository) UpdateMiddleType(middleType *model.MiddleType) error {
-
return u.mysqlDb.Model(middleType).Update(middleType).Error
-
}
-
-
//获取类型的结果集
-
func (u *MiddleTypeRepository) FindAll() (middleTypeAll []model.MiddleType, err error) {
-
return middleTypeAll, u.mysqlDb.Find(&middleTypeAll).Error
-
}
-
-
//根据ID查找单个版本
-
func (u *MiddleTypeRepository) FindVersionByID(middleVersionID int64) (middleVersion *model.MiddleVersion, err error) {
-
middleVersion = &model.MiddleVersion{}
-
return middleVersion, u.mysqlDb.First(middleVersion, middleVersionID).Error
-
}
-
-
//根据中间件类型查找所有版本
-
func (u *MiddleTypeRepository) FindAllVersionByTypeID(middleTypeID int64) (middleVersionAll []model.MiddleVersion, err error) {
-
return middleVersionAll, u.mysqlDb.Where("middle_type_id = ?", middleTypeID).Find(&middleVersionAll).Error
-
}
10-9 中间件 proto 文件开发
C:\Users\Administrator\Desktop\gopaas\middleware\proto\middleware\middleware.proto
-
syntax = "proto3";
-
-
package middleware;
-
-
option go_package = "./proto/middleware;middleware";
-
-
service Middleware {
-
//对外提供添加服务
-
rpc AddMiddleware(MiddlewareInfo) returns (Response) {}
-
rpc DeleteMiddleware(MiddlewareId) returns (Response) {}
-
rpc UpdateMiddleware(MiddlewareInfo) returns (Response) {}
-
rpc FindMiddlewareByID(MiddlewareId) returns (MiddlewareInfo) {}
-
rpc FindAllMiddleware(FindAll) returns (AllMiddleware) {}
-
//根据中间件的类型查找所有中间件
-
rpc FindAllMiddlewareByTypeID(FindAllByTypeId) returns (AllMiddleware){}
-
//获取中间件类型
-
rpc FindMiddleTypeByID(MiddleTypeId) returns (MiddleTypeInfo){}
-
rpc AddMiddleType(MiddleTypeInfo) returns (Response){}
-
rpc DeleteMiddleTypeByID(MiddleTypeId) returns (Response){}
-
rpc UpdateMiddleType(MiddleTypeInfo) returns(Response){}
-
rpc FindAllMiddleType(FindAll) returns (AllMiddleType){}
-
}
-
-
message MiddlewareInfo {
-
int64 id = 1;
-
string middle_name = 2;
-
string middle_namespace =3;
-
int64 middle_type_id = 4;
-
int64 middle_version_id =5;
-
repeated MiddlePort middle_port=6;
-
MiddleConfig middle_config=7;
-
repeated MiddleEnv middle_env=8;
-
float middle_cpu=9;
-
float middle_memory=10;
-
repeated MiddleStorage middle_storage =11;
-
int32 middle_replicas = 12;
-
//添加需要的镜像版本
-
string middle_docker_image_version=13;
-
}
-
//中间件的端口
-
message MiddlePort {
-
int64 middle_id=1;
-
int32 middle_port=2;
-
string middle_protocol=3;
-
}
-
//中间的配置
-
message MiddleConfig{
-
int64 middle_id =1;
-
string middle_config_root_user =2;
-
string middle_config_root_pwd =3;
-
string middle_config_user =4;
-
string middle_config_pwd =5;
-
string middle_config_data_base =6;
-
}
-
//中间件环境变量
-
message MiddleEnv {
-
int64 middle_id=1;
-
string env_key=2;
-
string env_value=3;
-
}
-
-
//中间件存储
-
message MiddleStorage{
-
int64 middle_id =1;
-
string middle_storage_name=2;
-
float middle_storage_size=3;
-
string middle_storage_path=4;
-
string middle_storage_class=5;
-
string middle_storage_access_mode=6;
-
}
-
-
message FindAllByTypeId {
-
int64 type_id =1;
-
}
-
-
message MiddleTypeId {
-
int64 id=1;
-
}
-
-
message MiddlewareId {
-
int64 id = 1;
-
}
-
-
message FindAll {
-
-
}
-
-
message Response {
-
string msg =1 ;
-
}
-
-
message AllMiddleware {
-
repeated MiddlewareInfo middleware_info = 1;
-
}
-
-
message MiddleTypeInfo {
-
int64 id =1;
-
string middle_type_name=2;
-
string middle_type_image_src=3;
-
repeated MiddleVersion middle_version=4;
-
}
-
-
message MiddleVersion{
-
int64 middle_type_id =1;
-
string middle_docker_image=2;
-
string middle_vs=3;
-
}
-
-
message AllMiddleType{
-
repeated MiddleTypeInfo middle_type_info =1;
-
}
-
-
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
-
package service
-
-
import (
-
"context"
-
"errors"
-
"strconv"
-
-
"github.com/yunixiangfeng/gopaas/common"
-
"github.com/yunixiangfeng/gopaas/middleware/domain/model"
-
"github.com/yunixiangfeng/gopaas/middleware/domain/repository"
-
"github.com/yunixiangfeng/gopaas/middleware/proto/middleware"
-
v1 "k8s.io/api/apps/v1"
-
v13 "k8s.io/api/core/v1"
-
"k8s.io/apimachinery/pkg/api/resource"
-
v12 "k8s.io/apimachinery/pkg/apis/meta/v1"
-
"k8s.io/client-go/kubernetes"
-
)
-
-
//这里是接口类型
-
type IMiddlewareDataService interface {
-
AddMiddleware(*model.Middleware) (int64, error)
-
DeleteMiddleware(int64) error
-
UpdateMiddleware(*model.Middleware) error
-
FindMiddlewareByID(int64) (*model.Middleware, error)
-
FindAllMiddleware() ([]model.Middleware, error)
-
//根据类型查找中间件
-
FindAllMiddlewareByTypeID(int64) ([]model.Middleware, error)
-
//操作中间件s
-
CreateToK8s(*middleware.MiddlewareInfo) error
-
DeleteFromK8s(*model.Middleware) error
-
UpdateToK8s(*middleware.MiddlewareInfo) error
-
}
-
-
//创建
-
//注意:返回值 IMiddlewareDataService 接口类型
-
func NewMiddlewareDataService(middlewareRepository repository.IMiddlewareRepository, clientSet *kubernetes.Clientset) IMiddlewareDataService {
-
return &MiddlewareDataService{MiddlewareRepository: middlewareRepository, K8sClientSet: clientSet}
-
}
-
-
type MiddlewareDataService struct {
-
//注意:这里是 IMiddlewareRepository 类型
-
MiddlewareRepository repository.IMiddlewareRepository
-
K8sClientSet *kubernetes.Clientset
-
}
-
-
//更新中间件到k8s
-
func (u *MiddlewareDataService) UpdateToK8s(info *middleware.MiddlewareInfo) error {
-
statefulSet := u.setStatefulSet(info)
-
if _, err := u.K8sClientSet.AppsV1().StatefulSets(info.MiddleNamespace).Get(context.TODO(), info.MiddleName, v12.GetOptions{}); err != nil {
-
common.Error(err)
-
return errors.New("中间件 " info.MiddleName " 不存在请先创建")
-
} else {
-
if _, err = u.K8sClientSet.AppsV1().StatefulSets(info.MiddleNamespace).Update(context.TODO(), statefulSet, v12.UpdateOptions{}); err != nil {
-
common.Error(err)
-
return err
-
}
-
common.Info("中间件 " info.MiddleName " 更新成功!")
-
return nil
-
}
-
-
}
-
-
//删除中间件
-
func (u *MiddlewareDataService) DeleteFromK8s(middleware *model.Middleware) (err error) {
-
if err := u.K8sClientSet.AppsV1().StatefulSets(middleware.MiddleNamespace).Delete(context.TODO(), middleware.MiddleName, v12.DeleteOptions{}); err != nil {
-
common.Error(err)
-
return err
-
} else {
-
if err := u.DeleteMiddleware(middleware.ID); err != nil {
-
common.Error(err)
-
return err
-
}
-
common.Info("删除中间件:" middleware.MiddleName "成功!")
-
return nil
-
-
}
-
-
}
-
-
//在k8s中创建中间件
-
func (u *MiddlewareDataService) CreateToK8s(info *middleware.MiddlewareInfo) error {
-
statefulSet := u.setStatefulSet(info)
-
if _, err := u.K8sClientSet.AppsV1().StatefulSets(info.MiddleNamespace).Get(context.TODO(), info.MiddleName, v12.GetOptions{}); err != nil {
-
//如果没有获取到
-
if _, err = u.K8sClientSet.AppsV1().StatefulSets(info.MiddleNamespace).Create(context.TODO(), statefulSet, v12.CreateOptions{}); err != nil {
-
common.Error(err)
-
return err
-
}
-
common.Info("中间件:" info.MiddleName "创建成功")
-
return nil
-
} else {
-
common.Error("中间件:" info.MiddleName "创建失败")
-
return errors.New("中间件:" info.MiddleName "创建失败")
-
}
-
}
-
-
//根据info信息设置值
-
func (u *MiddlewareDataService) setStatefulSet(info *middleware.MiddlewareInfo) *v1.StatefulSet {
-
statefulSet := &v1.StatefulSet{}
-
statefulSet.TypeMeta = v12.TypeMeta{
-
Kind: "StatefulSet",
-
APIVersion: "v1",
-
}
-
//设置详情
-
statefulSet.ObjectMeta = v12.ObjectMeta{
-
Name: info.MiddleName,
-
Namespace: info.MiddleNamespace,
-
//设置label标签
-
Labels: map[string]string{
-
"app-name": info.MiddleName,
-
"author": "wu123",
-
},
-
}
-
statefulSet.Name = info.MiddleName
-
statefulSet.Spec = v1.StatefulSetSpec{
-
//副本数
-
Replicas: &info.MiddleReplicas,
-
Selector: &v12.LabelSelector{
-
MatchLabels: map[string]string{
-
"app-name": info.MiddleName,
-
},
-
},
-
//设置容器模版
-
Template: v13.PodTemplateSpec{
-
ObjectMeta: v12.ObjectMeta{
-
Labels: map[string]string{
-
"app-name": info.MiddleName,
-
},
-
},
-
//设置容器详情
-
Spec: v13.PodSpec{
-
Containers: []v13.Container{
-
{
-
Name: info.MiddleName,
-
Image: info.MiddleDockerImageVersion,
-
//获取容器的端口
-
Ports: u.getContainerPort(info),
-
//获取环境变量
-
Env: u.getEnv(info),
-
//获取容器CPU,内存
-
Resources: u.getResources(info),
-
//设置挂载目录
-
VolumeMounts: u.setMounts(info),
-
},
-
},
-
//不能设置为0,这样不安全
-
//https://kubernetes.io/docs/tasks/run-application/force-delete-stateful-set-pod/
-
TerminationGracePeriodSeconds: u.getTime("10"),
-
//私有仓库设置密钥
-
ImagePullSecrets: nil,
-
},
-
},
-
VolumeClaimTemplates: u.getPVC(info),
-
ServiceName: info.MiddleName,
-
}
-
return statefulSet
-
-
}
-
-
func (u *MiddlewareDataService) getTime(stringTime string) *int64 {
-
b, err := strconv.ParseInt(stringTime, 10, 64)
-
if err != nil {
-
common.Error(err)
-
return nil
-
}
-
return &b
-
}
-
-
//设置存储路径
-
func (u *MiddlewareDataService) setMounts(info *middleware.MiddlewareInfo) (mount []v13.VolumeMount) {
-
if len(info.MiddleStorage) == 0 {
-
return
-
}
-
for _, v := range info.MiddleStorage {
-
mt := &v13.VolumeMount{
-
Name: v.MiddleStorageName,
-
MountPath: v.MiddleStoragePath,
-
}
-
mount = append(mount, *mt)
-
}
-
return
-
}
-
-
//获取pvc
-
func (u *MiddlewareDataService) getPVC(info *middleware.MiddlewareInfo) (pvcAll []v13.PersistentVolumeClaim) {
-
if len(info.MiddleStorage) == 0 {
-
return
-
}
-
for _, v := range info.MiddleStorage {
-
pvc := &v13.PersistentVolumeClaim{
-
TypeMeta: v12.TypeMeta{
-
Kind: "PersistentVolumeClaim",
-
APIVersion: "v1",
-
},
-
ObjectMeta: v12.ObjectMeta{
-
Name: v.MiddleStorageName,
-
Namespace: info.MiddleNamespace,
-
Annotations: map[string]string{
-
"pv.kubernetes.io/bound-by-controller": "yes",
-
"volume.beta.kubernetes.io/storage-provisioner": "rbd.csi.ceph.com",
-
},
-
},
-
Spec: v13.PersistentVolumeClaimSpec{
-
AccessModes: u.getAccessModes(v.MiddleStorageAccessMode),
-
Resources: u.getPvcResource(v.MiddleStorageSize),
-
VolumeName: v.MiddleStorageName,
-
StorageClassName: &v.MiddleStorageClass,
-
},
-
}
-
pvcAll = append(pvcAll, *pvc)
-
}
-
return
-
}
-
-
//获取大小
-
func (u *MiddlewareDataService) getPvcResource(size float32) (source v13.ResourceRequirements) {
-
source.Requests = v13.ResourceList{
-
"storage": resource.MustParse(strconv.FormatFloat(float64(size), 'f', 6, 64) "Gi"),
-
}
-
return
-
}
-
-
//获取权限的
-
func (u *MiddlewareDataService) getAccessModes(accessMode string) (pvam []v13.PersistentVolumeAccessMode) {
-
var pm v13.PersistentVolumeAccessMode
-
switch accessMode {
-
case "ReadWriteOnce":
-
pm = v13.ReadWriteOnce
-
case "ReadOnlyMany":
-
pm = v13.ReadOnlyMany
-
case "ReadWriteMany":
-
pm = v13.ReadWriteMany
-
case "ReadWriteOncePod":
-
pm = v13.ReadWriteOncePod
-
default:
-
pm = v13.ReadWriteOnce
-
}
-
pvam = append(pvam, pm)
-
return pvam
-
}
-
-
//获取容器的端口
-
func (u *MiddlewareDataService) getContainerPort(info *middleware.MiddlewareInfo) (containerPort []v13.ContainerPort) {
-
for _, v := range info.MiddlePort {
-
containerPort = append(containerPort, v13.ContainerPort{
-
Name: "middle-port-" strconv.FormatInt(int64(v.MiddlePort), 10),
-
ContainerPort: v.MiddlePort,
-
Protocol: u.getProtocol(v.MiddleProtocol),
-
})
-
}
-
return
-
}
-
-
//获取protocol 协议
-
func (u *MiddlewareDataService) getProtocol(protocol string) v13.Protocol {
-
switch protocol {
-
case "TCP":
-
return "TCP"
-
case "UDP":
-
return "UDP"
-
case "SCTP":
-
return "SCTP"
-
default:
-
return "TCP"
-
}
-
-
}
10-11 中间件 service 开发(2)
C:\Users\Administrator\Desktop\gopaas\middleware\domain\service\middleware_data_service.go
-
package service
-
-
import (
-
"context"
-
"errors"
-
"strconv"
-
-
"github.com/yunixiangfeng/gopaas/common"
-
"github.com/yunixiangfeng/gopaas/middleware/domain/model"
-
"github.com/yunixiangfeng/gopaas/middleware/domain/repository"
-
"github.com/yunixiangfeng/gopaas/middleware/proto/middleware"
-
v1 "k8s.io/api/apps/v1"
-
v13 "k8s.io/api/core/v1"
-
"k8s.io/apimachinery/pkg/api/resource"
-
v12 "k8s.io/apimachinery/pkg/apis/meta/v1"
-
"k8s.io/client-go/kubernetes"
-
)
-
-
//这里是接口类型
-
type IMiddlewareDataService interface {
-
AddMiddleware(*model.Middleware) (int64, error)
-
DeleteMiddleware(int64) error
-
UpdateMiddleware(*model.Middleware) error
-
FindMiddlewareByID(int64) (*model.Middleware, error)
-
FindAllMiddleware() ([]model.Middleware, error)
-
//根据类型查找中间件
-
FindAllMiddlewareByTypeID(int64) ([]model.Middleware, error)
-
//操作中间件s
-
CreateToK8s(*middleware.MiddlewareInfo) error
-
DeleteFromK8s(*model.Middleware) error
-
UpdateToK8s(*middleware.MiddlewareInfo) error
-
}
-
-
//创建
-
//注意:返回值 IMiddlewareDataService 接口类型
-
func NewMiddlewareDataService(middlewareRepository repository.IMiddlewareRepository, clientSet *kubernetes.Clientset) IMiddlewareDataService {
-
return &MiddlewareDataService{MiddlewareRepository: middlewareRepository, K8sClientSet: clientSet}
-
}
-
-
type MiddlewareDataService struct {
-
//注意:这里是 IMiddlewareRepository 类型
-
MiddlewareRepository repository.IMiddlewareRepository
-
K8sClientSet *kubernetes.Clientset
-
}
-
-
//更新中间件到k8s
-
func (u *MiddlewareDataService) UpdateToK8s(info *middleware.MiddlewareInfo) error {
-
statefulSet := u.setStatefulSet(info)
-
if _, err := u.K8sClientSet.AppsV1().StatefulSets(info.MiddleNamespace).Get(context.TODO(), info.MiddleName, v12.GetOptions{}); err != nil {
-
common.Error(err)
-
return errors.New("中间件 " info.MiddleName " 不存在请先创建")
-
} else {
-
if _, err = u.K8sClientSet.AppsV1().StatefulSets(info.MiddleNamespace).Update(context.TODO(), statefulSet, v12.UpdateOptions{}); err != nil {
-
common.Error(err)
-
return err
-
}
-
common.Info("中间件 " info.MiddleName " 更新成功!")
-
return nil
-
}
-
-
}
-
-
//删除中间件
-
func (u *MiddlewareDataService) DeleteFromK8s(middleware *model.Middleware) (err error) {
-
if err := u.K8sClientSet.AppsV1().StatefulSets(middleware.MiddleNamespace).Delete(context.TODO(), middleware.MiddleName, v12.DeleteOptions{}); err != nil {
-
common.Error(err)
-
return err
-
} else {
-
if err := u.DeleteMiddleware(middleware.ID); err != nil {
-
common.Error(err)
-
return err
-
}
-
common.Info("删除中间件:" middleware.MiddleName "成功!")
-
return nil
-
-
}
-
-
}
-
-
//在k8s中创建中间件
-
func (u *MiddlewareDataService) CreateToK8s(info *middleware.MiddlewareInfo) error {
-
statefulSet := u.setStatefulSet(info)
-
if _, err := u.K8sClientSet.AppsV1().StatefulSets(info.MiddleNamespace).Get(context.TODO(), info.MiddleName, v12.GetOptions{}); err != nil {
-
//如果没有获取到
-
if _, err = u.K8sClientSet.AppsV1().StatefulSets(info.MiddleNamespace).Create(context.TODO(), statefulSet, v12.CreateOptions{}); err != nil {
-
common.Error(err)
-
return err
-
}
-
common.Info("中间件:" info.MiddleName "创建成功")
-
return nil
-
} else {
-
common.Error("中间件:" info.MiddleName "创建失败")
-
return errors.New("中间件:" info.MiddleName "创建失败")
-
}
-
}
-
-
//根据info信息设置值
-
func (u *MiddlewareDataService) setStatefulSet(info *middleware.MiddlewareInfo) *v1.StatefulSet {
-
statefulSet := &v1.StatefulSet{}
-
statefulSet.TypeMeta = v12.TypeMeta{
-
Kind: "StatefulSet",
-
APIVersion: "v1",
-
}
-
//设置详情
-
statefulSet.ObjectMeta = v12.ObjectMeta{
-
Name: info.MiddleName,
-
Namespace: info.MiddleNamespace,
-
//设置label标签
-
Labels: map[string]string{
-
"app-name": info.MiddleName,
-
"author": "wu123",
-
},
-
}
-
statefulSet.Name = info.MiddleName
-
statefulSet.Spec = v1.StatefulSetSpec{
-
//副本数
-
Replicas: &info.MiddleReplicas,
-
Selector: &v12.LabelSelector{
-
MatchLabels: map[string]string{
-
"app-name": info.MiddleName,
-
},
-
},
-
//设置容器模版
-
Template: v13.PodTemplateSpec{
-
ObjectMeta: v12.ObjectMeta{
-
Labels: map[string]string{
-
"app-name": info.MiddleName,
-
},
-
},
-
//设置容器详情
-
Spec: v13.PodSpec{
-
Containers: []v13.Container{
-
{
-
Name: info.MiddleName,
-
Image: info.MiddleDockerImageVersion,
-
//获取容器的端口
-
Ports: u.getContainerPort(info),
-
//获取环境变量
-
Env: u.getEnv(info),
-
//获取容器CPU,内存
-
Resources: u.getResources(info),
-
//设置挂载目录
-
VolumeMounts: u.setMounts(info),
-
},
-
},
-
//不能设置为0,这样不安全
-
//https://kubernetes.io/docs/tasks/run-application/force-delete-stateful-set-pod/
-
TerminationGracePeriodSeconds: u.getTime("10"),
-
//私有仓库设置密钥
-
ImagePullSecrets: nil,
-
},
-
},
-
VolumeClaimTemplates: u.getPVC(info),
-
ServiceName: info.MiddleName,
-
}
-
return statefulSet
-
-
}
-
-
func (u *MiddlewareDataService) getTime(stringTime string) *int64 {
-
b, err := strconv.ParseInt(stringTime, 10, 64)
-
if err != nil {
-
common.Error(err)
-
return nil
-
}
-
return &b
-
}
-
-
//设置存储路径
-
func (u *MiddlewareDataService) setMounts(info *middleware.MiddlewareInfo) (mount []v13.VolumeMount) {
-
if len(info.MiddleStorage) == 0 {
-
return
-
}
-
for _, v := range info.MiddleStorage {
-
mt := &v13.VolumeMount{
-
Name: v.MiddleStorageName,
-
MountPath: v.MiddleStoragePath,
-
}
-
mount = append(mount, *mt)
-
}
-
return
-
}
-
-
//获取pvc
-
func (u *MiddlewareDataService) getPVC(info *middleware.MiddlewareInfo) (pvcAll []v13.PersistentVolumeClaim) {
-
if len(info.MiddleStorage) == 0 {
-
return
-
}
-
for _, v := range info.MiddleStorage {
-
pvc := &v13.PersistentVolumeClaim{
-
TypeMeta: v12.TypeMeta{
-
Kind: "PersistentVolumeClaim",
-
APIVersion: "v1",
-
},
-
ObjectMeta: v12.ObjectMeta{
-
Name: v.MiddleStorageName,
-
Namespace: info.MiddleNamespace,
-
Annotations: map[string]string{
-
"pv.kubernetes.io/bound-by-controller": "yes",
-
"volume.beta.kubernetes.io/storage-provisioner": "rbd.csi.ceph.com",
-
},
-
},
-
Spec: v13.PersistentVolumeClaimSpec{
-
AccessModes: u.getAccessModes(v.MiddleStorageAccessMode),
-
Resources: u.getPvcResource(v.MiddleStorageSize),
-
VolumeName: v.MiddleStorageName,
-
StorageClassName: &v.MiddleStorageClass,
-
},
-
}
-
pvcAll = append(pvcAll, *pvc)
-
}
-
return
-
}
-
-
//获取大小
-
func (u *MiddlewareDataService) getPvcResource(size float32) (source v13.ResourceRequirements) {
-
source.Requests = v13.ResourceList{
-
"storage": resource.MustParse(strconv.FormatFloat(float64(size), 'f', 6, 64) "Gi"),
-
}
-
return
-
}
-
-
//获取权限的
-
func (u *MiddlewareDataService) getAccessModes(accessMode string) (pvam []v13.PersistentVolumeAccessMode) {
-
var pm v13.PersistentVolumeAccessMode
-
switch accessMode {
-
case "ReadWriteOnce":
-
pm = v13.ReadWriteOnce
-
case "ReadOnlyMany":
-
pm = v13.ReadOnlyMany
-
case "ReadWriteMany":
-
pm = v13.ReadWriteMany
-
case "ReadWriteOncePod":
-
pm = v13.ReadWriteOncePod
-
default:
-
pm = v13.ReadWriteOnce
-
}
-
pvam = append(pvam, pm)
-
return pvam
-
}
-
-
//获取容器的端口
-
func (u *MiddlewareDataService) getContainerPort(info *middleware.MiddlewareInfo) (containerPort []v13.ContainerPort) {
-
for _, v := range info.MiddlePort {
-
containerPort = append(containerPort, v13.ContainerPort{
-
Name: "middle-port-" strconv.FormatInt(int64(v.MiddlePort), 10),
-
ContainerPort: v.MiddlePort,
-
Protocol: u.getProtocol(v.MiddleProtocol),
-
})
-
}
-
return
-
}
-
-
//获取protocol 协议
-
func (u *MiddlewareDataService) getProtocol(protocol string) v13.Protocol {
-
switch protocol {
-
case "TCP":
-
return "TCP"
-
case "UDP":
-
return "UDP"
-
case "SCTP":
-
return "SCTP"
-
default:
-
return "TCP"
-
}
-
-
}
-
-
//获取中间件的环境变量
-
func (u *MiddlewareDataService) getEnv(info *middleware.MiddlewareInfo) (envVar []v13.EnvVar) {
-
for _, v := range info.MiddleEnv {
-
envVar = append(envVar, v13.EnvVar{
-
Name: v.EnvKey,
-
Value: v.EnvValue,
-
ValueFrom: nil,
-
})
-
}
-
return
-
}
-
-
//获取中间件需要的资源
-
func (u *MiddlewareDataService) getResources(info *middleware.MiddlewareInfo) (source v13.ResourceRequirements) {
-
//最大能够使用的资源
-
source.Limits = v13.ResourceList{
-
"cpu": resource.MustParse(strconv.FormatFloat(float64(info.MiddleCpu), 'f', 6, 64)),
-
"memory": resource.MustParse(strconv.FormatFloat(float64(info.MiddleMemory), 'f', 6, 64)),
-
}
-
//最小请求资源
-
source.Requests = v13.ResourceList{
-
"cpu": resource.MustParse(strconv.FormatFloat(float64(info.MiddleCpu), 'f', 6, 64)),
-
"memory": resource.MustParse(strconv.FormatFloat(float64(info.MiddleMemory), 'f', 6, 64)),
-
}
-
return
-
}
-
-
//插入
-
func (u *MiddlewareDataService) AddMiddleware(middleware *model.Middleware) (int64, error) {
-
return u.MiddlewareRepository.CreateMiddleware(middleware)
-
}
-
-
//删除
-
func (u *MiddlewareDataService) DeleteMiddleware(middlewareID int64) error {
-
return u.MiddlewareRepository.DeleteMiddlewareByID(middlewareID)
-
}
-
-
//更新
-
func (u *MiddlewareDataService) UpdateMiddleware(middleware *model.Middleware) error {
-
return u.MiddlewareRepository.UpdateMiddleware(middleware)
-
}
-
-
//查找
-
func (u *MiddlewareDataService) FindMiddlewareByID(middlewareID int64) (*model.Middleware, error) {
-
return u.MiddlewareRepository.FindMiddlewareByID(middlewareID)
-
}
-
-
//查找
-
func (u *MiddlewareDataService) FindAllMiddleware() ([]model.Middleware, error) {
-
return u.MiddlewareRepository.FindAll()
-
}
-
-
//根据类型查找所有的中间件
-
func (u *MiddlewareDataService) FindAllMiddlewareByTypeID(typeID int64) ([]model.Middleware, error) {
-
return u.MiddlewareRepository.FindAllByTypeID(typeID)
-
}
10-12 中间件middleware service开发(3)
C:\Users\Administrator\Desktop\gopaas\middleware\domain\service\middleware_data_service.go
-
package service
-
-
import (
-
"context"
-
"errors"
-
"strconv"
-
-
"github.com/yunixiangfeng/gopaas/common"
-
"github.com/yunixiangfeng/gopaas/middleware/domain/model"
-
"github.com/yunixiangfeng/gopaas/middleware/domain/repository"
-
"github.com/yunixiangfeng/gopaas/middleware/proto/middleware"
-
v1 "k8s.io/api/apps/v1"
-
v13 "k8s.io/api/core/v1"
-
"k8s.io/apimachinery/pkg/api/resource"
-
v12 "k8s.io/apimachinery/pkg/apis/meta/v1"
-
"k8s.io/client-go/kubernetes"
-
)
-
-
//这里是接口类型
-
type IMiddlewareDataService interface {
-
AddMiddleware(*model.Middleware) (int64, error)
-
DeleteMiddleware(int64) error
-
UpdateMiddleware(*model.Middleware) error
-
FindMiddlewareByID(int64) (*model.Middleware, error)
-
FindAllMiddleware() ([]model.Middleware, error)
-
//根据类型查找中间件
-
FindAllMiddlewareByTypeID(int64) ([]model.Middleware, error)
-
//操作中间件s
-
CreateToK8s(*middleware.MiddlewareInfo) error
-
DeleteFromK8s(*model.Middleware) error
-
UpdateToK8s(*middleware.MiddlewareInfo) error
-
}
-
-
//创建
-
//注意:返回值 IMiddlewareDataService 接口类型
-
func NewMiddlewareDataService(middlewareRepository repository.IMiddlewareRepository, clientSet *kubernetes.Clientset) IMiddlewareDataService {
-
return &MiddlewareDataService{MiddlewareRepository: middlewareRepository, K8sClientSet: clientSet}
-
}
-
-
type MiddlewareDataService struct {
-
//注意:这里是 IMiddlewareRepository 类型
-
MiddlewareRepository repository.IMiddlewareRepository
-
K8sClientSet *kubernetes.Clientset
-
}
-
-
//更新中间件到k8s
-
func (u *MiddlewareDataService) UpdateToK8s(info *middleware.MiddlewareInfo) error {
-
statefulSet := u.setStatefulSet(info)
-
if _, err := u.K8sClientSet.AppsV1().StatefulSets(info.MiddleNamespace).Get(context.TODO(), info.MiddleName, v12.GetOptions{}); err != nil {
-
common.Error(err)
-
return errors.New("中间件 " info.MiddleName " 不存在请先创建")
-
} else {
-
if _, err = u.K8sClientSet.AppsV1().StatefulSets(info.MiddleNamespace).Update(context.TODO(), statefulSet, v12.UpdateOptions{}); err != nil {
-
common.Error(err)
-
return err
-
}
-
common.Info("中间件 " info.MiddleName " 更新成功!")
-
return nil
-
}
-
-
}
-
-
//删除中间件
-
func (u *MiddlewareDataService) DeleteFromK8s(middleware *model.Middleware) (err error) {
-
if err := u.K8sClientSet.AppsV1().StatefulSets(middleware.MiddleNamespace).Delete(context.TODO(), middleware.MiddleName, v12.DeleteOptions{}); err != nil {
-
common.Error(err)
-
return err
-
} else {
-
if err := u.DeleteMiddleware(middleware.ID); err != nil {
-
common.Error(err)
-
return err
-
}
-
common.Info("删除中间件:" middleware.MiddleName "成功!")
-
return nil
-
-
}
-
-
}
-
-
//在k8s中创建中间件
-
func (u *MiddlewareDataService) CreateToK8s(info *middleware.MiddlewareInfo) error {
-
statefulSet := u.setStatefulSet(info)
-
if _, err := u.K8sClientSet.AppsV1().StatefulSets(info.MiddleNamespace).Get(context.TODO(), info.MiddleName, v12.GetOptions{}); err != nil {
-
//如果没有获取到
-
if _, err = u.K8sClientSet.AppsV1().StatefulSets(info.MiddleNamespace).Create(context.TODO(), statefulSet, v12.CreateOptions{}); err != nil {
-
common.Error(err)
-
return err
-
}
-
common.Info("中间件:" info.MiddleName "创建成功")
-
return nil
-
} else {
-
common.Error("中间件:" info.MiddleName "创建失败")
-
return errors.New("中间件:" info.MiddleName "创建失败")
-
}
-
}
-
-
//根据info信息设置值
-
func (u *MiddlewareDataService) setStatefulSet(info *middleware.MiddlewareInfo) *v1.StatefulSet {
-
statefulSet := &v1.StatefulSet{}
-
statefulSet.TypeMeta = v12.TypeMeta{
-
Kind: "StatefulSet",
-
APIVersion: "v1",
-
}
-
//设置详情
-
statefulSet.ObjectMeta = v12.ObjectMeta{
-
Name: info.MiddleName,
-
Namespace: info.MiddleNamespace,
-
//设置label标签
-
Labels: map[string]string{
-
"app-name": info.MiddleName,
-
"author": "wu123",
-
},
-
}
-
statefulSet.Name = info.MiddleName
-
statefulSet.Spec = v1.StatefulSetSpec{
-
//副本数
-
Replicas: &info.MiddleReplicas,
-
Selector: &v12.LabelSelector{
-
MatchLabels: map[string]string{
-
"app-name": info.MiddleName,
-
},
-
},
-
//设置容器模版
-
Template: v13.PodTemplateSpec{
-
ObjectMeta: v12.ObjectMeta{
-
Labels: map[string]string{
-
"app-name": info.MiddleName,
-
},
-
},
-
//设置容器详情
-
Spec: v13.PodSpec{
-
Containers: []v13.Container{
-
{
-
Name: info.MiddleName,
-
Image: info.MiddleDockerImageVersion,
-
//获取容器的端口
-
Ports: u.getContainerPort(info),
-
//获取环境变量
-
Env: u.getEnv(info),
-
//获取容器CPU,内存
-
Resources: u.getResources(info),
-
//设置挂载目录
-
VolumeMounts: u.setMounts(info),
-
},
-
},
-
//不能设置为0,这样不安全
-
//https://kubernetes.io/docs/tasks/run-application/force-delete-stateful-set-pod/
-
TerminationGracePeriodSeconds: u.getTime("10"),
-
//私有仓库设置密钥
-
ImagePullSecrets: nil,
-
},
-
},
-
VolumeClaimTemplates: u.getPVC(info),
-
ServiceName: info.MiddleName,
-
}
-
return statefulSet
-
-
}
-
-
func (u *MiddlewareDataService) getTime(stringTime string) *int64 {
-
b, err := strconv.ParseInt(stringTime, 10, 64)
-
if err != nil {
-
common.Error(err)
-
return nil
-
}
-
return &b
-
}
-
-
//设置存储路径
-
func (u *MiddlewareDataService) setMounts(info *middleware.MiddlewareInfo) (mount []v13.VolumeMount) {
-
if len(info.MiddleStorage) == 0 {
-
return
-
}
-
for _, v := range info.MiddleStorage {
-
mt := &v13.VolumeMount{
-
Name: v.MiddleStorageName,
-
MountPath: v.MiddleStoragePath,
-
}
-
mount = append(mount, *mt)
-
}
-
return
-
}
-
-
//获取pvc
-
func (u *MiddlewareDataService) getPVC(info *middleware.MiddlewareInfo) (pvcAll []v13.PersistentVolumeClaim) {
-
if len(info.MiddleStorage) == 0 {
-
return
-
}
-
for _, v := range info.MiddleStorage {
-
pvc := &v13.PersistentVolumeClaim{
-
TypeMeta: v12.TypeMeta{
-
Kind: "PersistentVolumeClaim",
-
APIVersion: "v1",
-
},
-
ObjectMeta: v12.ObjectMeta{
-
Name: v.MiddleStorageName,
-
Namespace: info.MiddleNamespace,
-
Annotations: map[string]string{
-
"pv.kubernetes.io/bound-by-controller": "yes",
-
"volume.beta.kubernetes.io/storage-provisioner": "rbd.csi.ceph.com",
-
},
-
},
-
Spec: v13.PersistentVolumeClaimSpec{
-
AccessModes: u.getAccessModes(v.MiddleStorageAccessMode),
-
Resources: u.getPvcResource(v.MiddleStorageSize),
-
VolumeName: v.MiddleStorageName,
-
StorageClassName: &v.MiddleStorageClass,
-
},
-
}
-
pvcAll = append(pvcAll, *pvc)
-
}
-
return
-
}
-
-
//获取大小
-
func (u *MiddlewareDataService) getPvcResource(size float32) (source v13.ResourceRequirements) {
-
source.Requests = v13.ResourceList{
-
"storage": resource.MustParse(strconv.FormatFloat(float64(size), 'f', 6, 64) "Gi"),
-
}
-
return
-
}
-
-
//获取权限的
-
func (u *MiddlewareDataService) getAccessModes(accessMode string) (pvam []v13.PersistentVolumeAccessMode) {
-
var pm v13.PersistentVolumeAccessMode
-
switch accessMode {
-
case "ReadWriteOnce":
-
pm = v13.ReadWriteOnce
-
case "ReadOnlyMany":
-
pm = v13.ReadOnlyMany
-
case "ReadWriteMany":
-
pm = v13.ReadWriteMany
-
case "ReadWriteOncePod":
-
pm = v13.ReadWriteOncePod
-
default:
-
pm = v13.ReadWriteOnce
-
}
-
pvam = append(pvam, pm)
-
return pvam
-
}
-
-
//获取容器的端口
-
func (u *MiddlewareDataService) getContainerPort(info *middleware.MiddlewareInfo) (containerPort []v13.ContainerPort) {
-
for _, v := range info.MiddlePort {
-
containerPort = append(containerPort, v13.ContainerPort{
-
Name: "middle-port-" strconv.FormatInt(int64(v.MiddlePort), 10),
-
ContainerPort: v.MiddlePort,
-
Protocol: u.getProtocol(v.MiddleProtocol),
-
})
-
}
-
return
-
}
-
-
//获取protocol 协议
-
func (u *MiddlewareDataService) getProtocol(protocol string) v13.Protocol {
-
switch protocol {
-
case "TCP":
-
return "TCP"
-
case "UDP":
-
return "UDP"
-
case "SCTP":
-
return "SCTP"
-
default:
-
return "TCP"
-
}
-
-
}
-
-
//获取中间件的环境变量
-
func (u *MiddlewareDataService) getEnv(info *middleware.MiddlewareInfo) (envVar []v13.EnvVar) {
-
for _, v := range info.MiddleEnv {
-
envVar = append(envVar, v13.EnvVar{
-
Name: v.EnvKey,
-
Value: v.EnvValue,
-
ValueFrom: nil,
-
})
-
}
-
return
-
}
-
-
//获取中间件需要的资源
-
func (u *MiddlewareDataService) getResources(info *middleware.MiddlewareInfo) (source v13.ResourceRequirements) {
-
//最大能够使用的资源
-
source.Limits = v13.ResourceList{
-
"cpu": resource.MustParse(strconv.FormatFloat(float64(info.MiddleCpu), 'f', 6, 64)),
-
"memory": resource.MustParse(strconv.FormatFloat(float64(info.MiddleMemory), 'f', 6, 64)),
-
}
-
//最小请求资源
-
source.Requests = v13.ResourceList{
-
"cpu": resource.MustParse(strconv.FormatFloat(float64(info.MiddleCpu), 'f', 6, 64)),
-
"memory": resource.MustParse(strconv.FormatFloat(float64(info.MiddleMemory), 'f', 6, 64)),
-
}
-
return
-
}
-
-
//插入
-
func (u *MiddlewareDataService) AddMiddleware(middleware *model.Middleware) (int64, error) {
-
return u.MiddlewareRepository.CreateMiddleware(middleware)
-
}
-
-
//删除
-
func (u *MiddlewareDataService) DeleteMiddleware(middlewareID int64) error {
-
return u.MiddlewareRepository.DeleteMiddlewareByID(middlewareID)
-
}
-
-
//更新
-
func (u *MiddlewareDataService) UpdateMiddleware(middleware *model.Middleware) error {
-
return u.MiddlewareRepository.UpdateMiddleware(middleware)
-
}
-
-
//查找
-
func (u *MiddlewareDataService) FindMiddlewareByID(middlewareID int64) (*model.Middleware, error) {
-
return u.MiddlewareRepository.FindMiddlewareByID(middlewareID)
-
}
-
-
//查找
-
func (u *MiddlewareDataService) FindAllMiddleware() ([]model.Middleware, error) {
-
return u.MiddlewareRepository.FindAll()
-
}
-
-
//根据类型查找所有的中间件
-
func (u *MiddlewareDataService) FindAllMiddlewareByTypeID(typeID int64) ([]model.Middleware, error) {
-
return u.MiddlewareRepository.FindAllByTypeID(typeID)
-
}
10-13 中间件middleware service开发(4)
C:\Users\Administrator\Desktop\gopaas\middleware\domain\service\middleware_data_service.go
-
package service
-
-
import (
-
"context"
-
"errors"
-
"strconv"
-
-
"github.com/yunixiangfeng/gopaas/common"
-
"github.com/yunixiangfeng/gopaas/middleware/domain/model"
-
"github.com/yunixiangfeng/gopaas/middleware/domain/repository"
-
"github.com/yunixiangfeng/gopaas/middleware/proto/middleware"
-
v1 "k8s.io/api/apps/v1"
-
v13 "k8s.io/api/core/v1"
-
"k8s.io/apimachinery/pkg/api/resource"
-
v12 "k8s.io/apimachinery/pkg/apis/meta/v1"
-
"k8s.io/client-go/kubernetes"
-
)
-
-
//这里是接口类型
-
type IMiddlewareDataService interface {
-
AddMiddleware(*model.Middleware) (int64, error)
-
DeleteMiddleware(int64) error
-
UpdateMiddleware(*model.Middleware) error
-
FindMiddlewareByID(int64) (*model.Middleware, error)
-
FindAllMiddleware() ([]model.Middleware, error)
-
//根据类型查找中间件
-
FindAllMiddlewareByTypeID(int64) ([]model.Middleware, error)
-
//操作中间件s
-
CreateToK8s(*middleware.MiddlewareInfo) error
-
DeleteFromK8s(*model.Middleware) error
-
UpdateToK8s(*middleware.MiddlewareInfo) error
-
}
-
-
//创建
-
//注意:返回值 IMiddlewareDataService 接口类型
-
func NewMiddlewareDataService(middlewareRepository repository.IMiddlewareRepository, clientSet *kubernetes.Clientset) IMiddlewareDataService {
-
return &MiddlewareDataService{MiddlewareRepository: middlewareRepository, K8sClientSet: clientSet}
-
}
-
-
type MiddlewareDataService struct {
-
//注意:这里是 IMiddlewareRepository 类型
-
MiddlewareRepository repository.IMiddlewareRepository
-
K8sClientSet *kubernetes.Clientset
-
}
-
-
//更新中间件到k8s
-
func (u *MiddlewareDataService) UpdateToK8s(info *middleware.MiddlewareInfo) error {
-
statefulSet := u.setStatefulSet(info)
-
if _, err := u.K8sClientSet.AppsV1().StatefulSets(info.MiddleNamespace).Get(context.TODO(), info.MiddleName, v12.GetOptions{}); err != nil {
-
common.Error(err)
-
return errors.New("中间件 " info.MiddleName " 不存在请先创建")
-
} else {
-
if _, err = u.K8sClientSet.AppsV1().StatefulSets(info.MiddleNamespace).Update(context.TODO(), statefulSet, v12.UpdateOptions{}); err != nil {
-
common.Error(err)
-
return err
-
}
-
common.Info("中间件 " info.MiddleName " 更新成功!")
-
return nil
-
}
-
-
}
-
-
//删除中间件
-
func (u *MiddlewareDataService) DeleteFromK8s(middleware *model.Middleware) (err error) {
-
if err := u.K8sClientSet.AppsV1().StatefulSets(middleware.MiddleNamespace).Delete(context.TODO(), middleware.MiddleName, v12.DeleteOptions{}); err != nil {
-
common.Error(err)
-
return err
-
} else {
-
if err := u.DeleteMiddleware(middleware.ID); err != nil {
-
common.Error(err)
-
return err
-
}
-
common.Info("删除中间件:" middleware.MiddleName "成功!")
-
return nil
-
-
}
-
-
}
-
-
//在k8s中创建中间件
-
func (u *MiddlewareDataService) CreateToK8s(info *middleware.MiddlewareInfo) error {
-
statefulSet := u.setStatefulSet(info)
-
if _, err := u.K8sClientSet.AppsV1().StatefulSets(info.MiddleNamespace).Get(context.TODO(), info.MiddleName, v12.GetOptions{}); err != nil {
-
//如果没有获取到
-
if _, err = u.K8sClientSet.AppsV1().StatefulSets(info.MiddleNamespace).Create(context.TODO(), statefulSet, v12.CreateOptions{}); err != nil {
-
common.Error(err)
-
return err
-
}
-
common.Info("中间件:" info.MiddleName "创建成功")
-
return nil
-
} else {
-
common.Error("中间件:" info.MiddleName "创建失败")
-
return errors.New("中间件:" info.MiddleName "创建失败")
-
}
-
}
-
-
//根据info信息设置值
-
func (u *MiddlewareDataService) setStatefulSet(info *middleware.MiddlewareInfo) *v1.StatefulSet {
-
statefulSet := &v1.StatefulSet{}
-
statefulSet.TypeMeta = v12.TypeMeta{
-
Kind: "StatefulSet",
-
APIVersion: "v1",
-
}
-
//设置详情
-
statefulSet.ObjectMeta = v12.ObjectMeta{
-
Name: info.MiddleName,
-
Namespace: info.MiddleNamespace,
-
//设置label标签
-
Labels: map[string]string{
-
"app-name": info.MiddleName,
-
"author": "wu123",
-
},
-
}
-
statefulSet.Name = info.MiddleName
-
statefulSet.Spec = v1.StatefulSetSpec{
-
//副本数
-
Replicas: &info.MiddleReplicas,
-
Selector: &v12.LabelSelector{
-
MatchLabels: map[string]string{
-
"app-name": info.MiddleName,
-
},
-
},
-
//设置容器模版
-
Template: v13.PodTemplateSpec{
-
ObjectMeta: v12.ObjectMeta{
-
Labels: map[string]string{
-
"app-name": info.MiddleName,
-
},
-
},
-
//设置容器详情
-
Spec: v13.PodSpec{
-
Containers: []v13.Container{
-
{
-
Name: info.MiddleName,
-
Image: info.MiddleDockerImageVersion,
-
//获取容器的端口
-
Ports: u.getContainerPort(info),
-
//获取环境变量
-
Env: u.getEnv(info),
-
//获取容器CPU,内存
-
Resources: u.getResources(info),
-
//设置挂载目录
-
VolumeMounts: u.setMounts(info),
-
},
-
},
-
//不能设置为0,这样不安全
-
//https://kubernetes.io/docs/tasks/run-application/force-delete-stateful-set-pod/
-
TerminationGracePeriodSeconds: u.getTime("10"),
-
//私有仓库设置密钥
-
ImagePullSecrets: nil,
-
},
-
},
-
VolumeClaimTemplates: u.getPVC(info),
-
ServiceName: info.MiddleName,
-
}
-
return statefulSet
-
-
}
-
-
func (u *MiddlewareDataService) getTime(stringTime string) *int64 {
-
b, err := strconv.ParseInt(stringTime, 10, 64)
-
if err != nil {
-
common.Error(err)
-
return nil
-
}
-
return &b
-
}
-
-
//设置存储路径
-
func (u *MiddlewareDataService) setMounts(info *middleware.MiddlewareInfo) (mount []v13.VolumeMount) {
-
if len(info.MiddleStorage) == 0 {
-
return
-
}
-
for _, v := range info.MiddleStorage {
-
mt := &v13.VolumeMount{
-
Name: v.MiddleStorageName,
-
MountPath: v.MiddleStoragePath,
-
}
-
mount = append(mount, *mt)
-
}
-
return
-
}
-
-
//获取pvc
-
func (u *MiddlewareDataService) getPVC(info *middleware.MiddlewareInfo) (pvcAll []v13.PersistentVolumeClaim) {
-
if len(info.MiddleStorage) == 0 {
-
return
-
}
-
for _, v := range info.MiddleStorage {
-
pvc := &v13.PersistentVolumeClaim{
-
TypeMeta: v12.TypeMeta{
-
Kind: "PersistentVolumeClaim",
-
APIVersion: "v1",
-
},
-
ObjectMeta: v12.ObjectMeta{
-
Name: v.MiddleStorageName,
-
Namespace: info.MiddleNamespace,
-
Annotations: map[string]string{
-
"pv.kubernetes.io/bound-by-controller": "yes",
-
"volume.beta.kubernetes.io/storage-provisioner": "rbd.csi.ceph.com",
-
},
-
},
-
Spec: v13.PersistentVolumeClaimSpec{
-
AccessModes: u.getAccessModes(v.MiddleStorageAccessMode),
-
Resources: u.getPvcResource(v.MiddleStorageSize),
-
VolumeName: v.MiddleStorageName,
-
StorageClassName: &v.MiddleStorageClass,
-
},
-
}
-
pvcAll = append(pvcAll, *pvc)
-
}
-
return
-
}
-
-
//获取大小
-
func (u *MiddlewareDataService) getPvcResource(size float32) (source v13.ResourceRequirements) {
-
source.Requests = v13.ResourceList{
-
"storage": resource.MustParse(strconv.FormatFloat(float64(size), 'f', 6, 64) "Gi"),
-
}
-
return
-
}
-
-
//获取权限的
-
func (u *MiddlewareDataService) getAccessModes(accessMode string) (pvam []v13.PersistentVolumeAccessMode) {
-
var pm v13.PersistentVolumeAccessMode
-
switch accessMode {
-
case "ReadWriteOnce":
-
pm = v13.ReadWriteOnce
-
case "ReadOnlyMany":
-
pm = v13.ReadOnlyMany
-
case "ReadWriteMany":
-
pm = v13.ReadWriteMany
-
case "ReadWriteOncePod":
-
pm = v13.ReadWriteOncePod
-
default:
-
pm = v13.ReadWriteOnce
-
}
-
pvam = append(pvam, pm)
-
return pvam
-
}
-
-
//获取容器的端口
-
func (u *MiddlewareDataService) getContainerPort(info *middleware.MiddlewareInfo) (containerPort []v13.ContainerPort) {
-
for _, v := range info.MiddlePort {
-
containerPort = append(containerPort, v13.ContainerPort{
-
Name: "middle-port-" strconv.FormatInt(int64(v.MiddlePort), 10),
-
ContainerPort: v.MiddlePort,
-
Protocol: u.getProtocol(v.MiddleProtocol),
-
})
-
}
-
return
-
}
-
-
//获取protocol 协议
-
func (u *MiddlewareDataService) getProtocol(protocol string) v13.Protocol {
-
switch protocol {
-
case "TCP":
-
return "TCP"
-
case "UDP":
-
return "UDP"
-
case "SCTP":
-
return "SCTP"
-
default:
-
return "TCP"
-
}
-
-
}
-
-
//获取中间件的环境变量
-
func (u *MiddlewareDataService) getEnv(info *middleware.MiddlewareInfo) (envVar []v13.EnvVar) {
-
for _, v := range info.MiddleEnv {
-
envVar = append(envVar, v13.EnvVar{
-
Name: v.EnvKey,
-
Value: v.EnvValue,
-
ValueFrom: nil,
-
})
-
}
-
return
-
}
-
-
//获取中间件需要的资源
-
func (u *MiddlewareDataService) getResources(info *middleware.MiddlewareInfo) (source v13.ResourceRequirements) {
-
//最大能够使用的资源
-
source.Limits = v13.ResourceList{
-
"cpu": resource.MustParse(strconv.FormatFloat(float64(info.MiddleCpu), 'f', 6, 64)),
-
"memory": resource.MustParse(strconv.FormatFloat(float64(info.MiddleMemory), 'f', 6, 64)),
-
}
-
//最小请求资源
-
source.Requests = v13.ResourceList{
-
"cpu": resource.MustParse(strconv.FormatFloat(float64(info.MiddleCpu), 'f', 6, 64)),
-
"memory": resource.MustParse(strconv.FormatFloat(float64(info.MiddleMemory), 'f', 6, 64)),
-
}
-
return
-
}
-
-
//插入
-
func (u *MiddlewareDataService) AddMiddleware(middleware *model.Middleware) (int64, error) {
-
return u.MiddlewareRepository.CreateMiddleware(middleware)
-
}
-
-
//删除
-
func (u *MiddlewareDataService) DeleteMiddleware(middlewareID int64) error {
-
return u.MiddlewareRepository.DeleteMiddlewareByID(middlewareID)
-
}
-
-
//更新
-
func (u *MiddlewareDataService) UpdateMiddleware(middleware *model.Middleware) error {
-
return u.MiddlewareRepository.UpdateMiddleware(middleware)
-
}
-
-
//查找
-
func (u *MiddlewareDataService) FindMiddlewareByID(middlewareID int64) (*model.Middleware, error) {
-
return u.MiddlewareRepository.FindMiddlewareByID(middlewareID)
-
}
-
-
//查找
-
func (u *MiddlewareDataService) FindAllMiddleware() ([]model.Middleware, error) {
-
return u.MiddlewareRepository.FindAll()
-
}
-
-
//根据类型查找所有的中间件
-
func (u *MiddlewareDataService) FindAllMiddlewareByTypeID(typeID int64) ([]model.Middleware, error) {
-
return u.MiddlewareRepository.FindAllByTypeID(typeID)
-
}
10-14 中间件service 对应版本服务代码开发
C:\Users\Administrator\Desktop\gopaas\middleware\domain\service\middle_type_data_service.go
-
package service
-
-
import (
-
"github.com/yunixiangfeng/gopaas/middleware/domain/model"
-
"github.com/yunixiangfeng/gopaas/middleware/domain/repository"
-
)
-
-
//定义接口类型
-
type IMiddleTypeDataService interface {
-
AddMiddleType(*model.MiddleType) (int64, error)
-
DeleteMiddleType(int64) error
-
UpdateMiddleType(*model.MiddleType) error
-
FindMiddleTypeByID(int64) (*model.MiddleType, error)
-
FindAllMiddleType() ([]model.MiddleType, error)
-
//根据ID返回地址
-
FindImageVersionByID(int64) (string, error)
-
-
FindVersionByID(int64) (*model.MiddleVersion, error)
-
FindAllVersionByTypeID(int64) ([]model.MiddleVersion, error)
-
}
-
-
//注意:返回值的类型
-
func NewMiddleTypeDataService(repository repository.IMiddleTypeRepository) IMiddleTypeDataService {
-
return &MiddleTypeDataService{MiddleTypeRepository: repository}
-
-
}
-
-
type MiddleTypeDataService struct {
-
MiddleTypeRepository repository.IMiddleTypeRepository
-
}
-
-
//插入
-
func (u *MiddleTypeDataService) AddMiddleType(middleType *model.MiddleType) (int64, error) {
-
return u.MiddleTypeRepository.CreateMiddleType(middleType)
-
}
-
-
//删除
-
func (u *MiddleTypeDataService) DeleteMiddleType(middleTypeID int64) error {
-
return u.MiddleTypeRepository.DeleteMiddleTypeByID(middleTypeID)
-
}
-
-
//更新
-
func (u *MiddleTypeDataService) UpdateMiddleType(middleType *model.MiddleType) error {
-
return u.MiddleTypeRepository.UpdateMiddleType(middleType)
-
}
-
-
//查找
-
func (u *MiddleTypeDataService) FindMiddleTypeByID(middleTypeID int64) (*model.MiddleType, error) {
-
return u.MiddleTypeRepository.FindTypeByID(middleTypeID)
-
-
}
-
-
//查找所有
-
func (u *MiddleTypeDataService) FindAllMiddleType() ([]model.MiddleType, error) {
-
return u.MiddleTypeRepository.FindAll()
-
}
-
-
//根据version ID查找镜像地址
-
func (u *MiddleTypeDataService) FindImageVersionByID(middleVersionID int64) (string, error) {
-
version, err := u.MiddleTypeRepository.FindVersionByID(middleVersionID)
-
if err != nil {
-
return "", err
-
}
-
//返回需要的镜像地址
-
return version.MiddleDockerImage ":" version.MiddleVS, nil
-
-
}
-
-
//根据versionID 查找单个镜像
-
func (u *MiddleTypeDataService) FindVersionByID(middleVersionID int64) (*model.MiddleVersion, error) {
-
return u.MiddleTypeRepository.FindVersionByID(middleVersionID)
-
}
-
-
//根据中间件类型查找对应的所有版本
-
func (u *MiddleTypeDataService) FindAllVersionByTypeID(middleTypeID int64) ([]model.MiddleVersion, error) {
-
return u.MiddleTypeRepository.FindAllVersionByTypeID(middleTypeID)
-
}
10-15 中间件main调整 及 handler 开发(上)
C:\Users\Administrator\Desktop\gopaas\middleware\main.go
-
//只能执行一遍
-
//err = repository.NewMiddlewareRepository(db).InitTable()
-
//if err != nil {
-
// common.Fatal(err)
-
//}
-
//if err:= repository.NewMiddleTypeRepository(db).InitTable();err!=nil{
-
// common.Fatal(err)
-
//}
-
-
// 注册句柄,可以快速操作已开发的服务
-
middlewareDataService := service2.NewMiddlewareDataService(repository.NewMiddlewareRepository(db), clientset)
-
middleTypeDataService := service2.NewMiddleTypeDataService(repository.NewMiddleTypeRepository(db))
-
middleware.RegisterMiddlewareHandler(service.Server(), &handler.MiddlewareHandler{MiddlewareDataService: middlewareDataService, MiddleTypeDataService: middleTypeDataService})
C:\Users\Administrator\Desktop\gopaas\middleware\handler\middlewareHandler.go
-
package handler
-
-
import (
-
"context"
-
"strconv"
-
-
log "github.com/asim/go-micro/v3/logger"
-
"github.com/yunixiangfeng/gopaas/common"
-
"github.com/yunixiangfeng/gopaas/middleware/domain/model"
-
"github.com/yunixiangfeng/gopaas/middleware/domain/service"
-
middleware "github.com/yunixiangfeng/gopaas/middleware/proto/middleware"
-
)
-
-
type MiddlewareHandler struct {
-
//注意这里的类型是 IMiddlewareDataService 接口类型
-
MiddlewareDataService service.IMiddlewareDataService
-
// 添加中间件类型服务
-
MiddleTypeDataService service.IMiddleTypeDataService
-
}
-
-
// Call is a single request handler called via client.Call or the generated client code
-
func (e *MiddlewareHandler) AddMiddleware(ctx context.Context, info *middleware.MiddlewareInfo, rsp *middleware.Response) error {
-
log.Info("Received *middleware.AddMiddleware request")
-
middleModel := &model.Middleware{}
-
if err := common.SwapTo(info, middleModel); err != nil {
-
common.Error(err)
-
rsp.Msg = err.Error()
-
return err
-
}
-
//调用其它的服务处理数据
-
//根据ID产销需要的镜像地址
-
imageAddress, err := e.MiddleTypeDataService.FindImageVersionByID(info.MiddleVersionId)
-
if err != nil {
-
common.Error(err)
-
return err
-
}
-
//赋值
-
info.MiddleDockerImageVersion = imageAddress
-
//在k8s 中创建资源
-
if err := e.MiddlewareDataService.CreateToK8s(info); err != nil {
-
common.Error(err)
-
rsp.Msg = err.Error()
-
return err
-
} else {
-
//插入数据库
-
middleID, err := e.MiddlewareDataService.AddMiddleware(middleModel)
-
if err != nil {
-
common.Error(err)
-
rsp.Msg = err.Error()
-
return err
-
}
-
rsp.Msg = "中间件添加成功 ID 号为:" strconv.FormatInt(middleID, 10)
-
common.Info(rsp.Msg)
-
}
-
return nil
-
}
-
-
func (e *MiddlewareHandler) DeleteMiddleware(ctx context.Context, req *middleware.MiddlewareId, rsp *middleware.Response) error {
-
log.Info("Received *middleware.DeleteMiddleware request")
-
middleModel, err := e.MiddlewareDataService.FindMiddlewareByID(req.Id)
-
if err != nil {
-
common.Error(err)
-
rsp.Msg = err.Error()
-
return err
-
}
-
//删除k8s中资源
-
if err := e.MiddlewareDataService.DeleteFromK8s(middleModel); err != nil {
-
common.Error(err)
-
rsp.Msg = err.Error()
-
return err
-
}
-
return nil
-
}
-
-
func (e *MiddlewareHandler) UpdateMiddleware(ctx context.Context, req *middleware.MiddlewareInfo, rsp *middleware.Response) error {
-
log.Info("Received *middleware.UpdateMiddleware request")
-
if err := e.MiddlewareDataService.UpdateToK8s(req); err != nil {
-
common.Error(err)
-
rsp.Msg = err.Error()
-
return err
-
}
-
//查询中间件相关的信息
-
middleModle, err := e.MiddlewareDataService.FindMiddlewareByID(req.Id)
-
if err != nil {
-
common.Error(err)
-
rsp.Msg = err.Error()
-
return err
-
}
-
//更新model数据
-
if err := common.SwapTo(req, middleModle); err != nil {
-
common.Error(err)
-
rsp.Msg = err.Error()
-
return err
-
}
-
//更新model
-
if err := e.MiddlewareDataService.UpdateMiddleware(middleModle); err != nil {
-
common.Error(err)
-
rsp.Msg = err.Error()
-
return err
-
}
-
return nil
-
}
-
-
func (e *MiddlewareHandler) FindMiddlewareByID(ctx context.Context, req *middleware.MiddlewareId, rsp *middleware.MiddlewareInfo) error {
-
log.Info("Received *middleware.FindMiddlewareByID request")
-
//查询中间件
-
middlewareModel, err := e.MiddlewareDataService.FindMiddlewareByID(req.Id)
-
if err != nil {
-
common.Error(err)
-
return err
-
}
-
if err := common.SwapTo(middlewareModel, rsp); err != nil {
-
common.Error(err)
-
return err
-
}
-
return nil
-
}
-
-
func (e *MiddlewareHandler) FindAllMiddleware(ctx context.Context, req *middleware.FindAll, rsp *middleware.AllMiddleware) error {
-
log.Info("Received *middleware.FindAllMiddleware request")
-
allMiddleware, err := e.MiddlewareDataService.FindAllMiddleware()
-
if err != nil {
-
common.Error(err)
-
return err
-
}
-
//整理格式
-
for _, v := range allMiddleware {
-
middleInfo := &middleware.MiddlewareInfo{}
-
if err := common.SwapTo(v, middleInfo); err != nil {
-
common.Error(err)
-
return err
-
}
-
rsp.MiddlewareInfo = append(rsp.MiddlewareInfo, middleInfo)
-
}
-
return nil
-
}
make proto
10-16 中间件main调整 及 handler 开发(下)
C:\Users\Administrator\Desktop\gopaas\middleware\main.go
-
package main
-
-
import (
-
"flag"
-
"fmt"
-
"path/filepath"
-
-
"github.com/yunixiangfeng/gopaas/common"
-
"github.com/yunixiangfeng/gopaas/middleware/domain/repository"
-
-
//"github.com/afex/hystrix-go/hystrix"
-
"github.com/asim/go-micro/plugins/registry/consul/v3"
-
ratelimit "github.com/asim/go-micro/plugins/wrapper/ratelimiter/uber/v3"
-
opentracing2 "github.com/asim/go-micro/plugins/wrapper/trace/opentracing/v3"
-
"github.com/asim/go-micro/v3"
-
"github.com/asim/go-micro/v3/registry"
-
"github.com/asim/go-micro/v3/server"
-
"github.com/jinzhu/gorm"
-
_ "github.com/jinzhu/gorm/dialects/mysql"
-
"github.com/opentracing/opentracing-go"
-
service2 "github.com/yunixiangfeng/gopaas/middleware/domain/service"
-
"github.com/yunixiangfeng/gopaas/middleware/handler"
-
-
//hystrix2 "github.com/yunixiangfeng/gopaas/middleware/plugin/hystrix"
-
"strconv"
-
-
middleware "github.com/yunixiangfeng/gopaas/middleware/proto/middleware"
-
"k8s.io/client-go/kubernetes"
-
"k8s.io/client-go/tools/clientcmd"
-
"k8s.io/client-go/util/homedir"
-
)
-
-
var (
-
//服务地址
-
hostIp = "192.168.204.130"
-
//服务地址
-
serviceHost = hostIp
-
//服务端口
-
servicePort = "8089"
-
-
//注册中心配置
-
consulHost = hostIp
-
consulPort int64 = 8500
-
//链路追踪
-
tracerHost = hostIp
-
tracerPort = 6831
-
//熔断端口,每个服务不能重复
-
//hystrixPort = 9099
-
//监控端口,每个服务不能重复
-
prometheusPort = 9199
-
)
-
-
func main() {
-
//需要本地启动,mysql,consul中间件服务
-
//1.注册中心
-
consul := consul.NewRegistry(func(options *registry.Options) {
-
options.Addrs = []string{
-
consulHost ":" strconv.FormatInt(consulPort, 10),
-
}
-
})
-
//2.配置中心,存放经常变动的变量
-
consulConfig, err := common.GetConsulConfig(consulHost, consulPort, "/micro/config")
-
if err != nil {
-
common.Error(err)
-
}
-
//3.使用配置中心连接 mysql
-
mysqlInfo := common.GetMysqlFromConsul(consulConfig, "mysql")
-
//初始化数据库
-
db, err := gorm.Open("mysql", mysqlInfo.User ":" mysqlInfo.Pwd "@(" mysqlInfo.Host ":3306)/" mysqlInfo.Database "?charset=utf8&parseTime=True&loc=Local")
-
if err != nil {
-
//命令行输出下,方便查看错误
-
fmt.Println(err)
-
common.Fatal(err)
-
}
-
defer db.Close()
-
//禁止复表
-
db.SingularTable(true)
-
-
//4.添加链路追踪
-
t, io, err := common.NewTracer("go.micro.service.middleware", tracerHost ":" strconv.Itoa(tracerPort))
-
if err != nil {
-
common.Error(err)
-
}
-
defer io.Close()
-
opentracing.SetGlobalTracer(t)
-
-
//添加熔断器,作为客户端需要启用
-
//hystrixStreamHandler := hystrix.NewStreamHandler()
-
//hystrixStreamHandler.Start()
-
-
//添加日志中心
-
//1)需要程序日志打入到日志文件中
-
//2)在程序中添加filebeat.yml 文件
-
//3) 启动filebeat,启动命令 ./filebeat -e -c filebeat.yml
-
fmt.Println("日志统一记录在根目录 micro.log 文件中,请点击查看日志!")
-
-
//启动监听程序
-
//go func() {
-
// //http://192.168.204.130:9092/turbine/turbine.stream
-
// //看板访问地址 http://127.0.0.1:9002/hystrix,url后面一定要带 /hystrix
-
// err = http.ListenAndServe(net.JoinHostPort("0.0.0.0",strconv.Itoa(hystrixPort)),hystrixStreamHandler)
-
// if err !=nil {
-
// common.Error(err)
-
// }
-
//}()
-
-
//5.添加监控
-
common.PrometheusBoot(prometheusPort)
-
-
//下载kubectl:https://kubernetes.io/docs/tasks/tools/#tabset-2
-
//macos:
-
// 1.curl -LO "https://dl.k8s.io/release/v1.21.0/bin/darwin/amd64/kubectl"
-
// 2.chmod x ./kubectl
-
// 3.sudo mv ./kubectl /usr/local/bin/kubectl
-
// sudo chown root: /usr/local/bin/kubectl
-
// 5.kubectl version --client
-
// 6.集群模式下直接拷贝服务端~/.kube/config 文件到本机 ~/.kube/confg 中
-
// 注意:- config中的域名要能解析正确
-
// - 生产环境可以创建另一个证书
-
// 7.kubectl get ns 查看是否正常
-
//
-
//6.创建k8s连接
-
//在集群外面连接
-
var kubeconfig *string
-
if home := homedir.HomeDir(); home != "" {
-
kubeconfig = flag.String("kubeconfig", filepath.Join(home, ".kube", "config"), "(optional) absolute path to the kubeconfig file")
-
} else {
-
kubeconfig = flag.String("kubeconfig", "", "absolute path to the kubeconfig file")
-
}
-
flag.Parse()
-
config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
-
if err != nil {
-
common.Fatal(err.Error())
-
}
-
-
//在集群中外的配置
-
//config, err := rest.InClusterConfig()
-
//if err != nil {
-
// panic(err.Error())
-
//}
-
-
// create the clientset
-
clientset, err := kubernetes.NewForConfig(config)
-
if err != nil {
-
common.Fatal(err.Error())
-
}
-
-
//7.创建服务
-
service := micro.NewService(
-
//自定义服务地址,且必须写在其它参数前面
-
micro.Server(server.NewServer(func(options *server.Options) {
-
options.Advertise = serviceHost ":" servicePort
-
})),
-
micro.Name("go.micro.service.middleware"),
-
micro.Version("latest"),
-
//指定服务端口
-
micro.Address(":" servicePort),
-
//添加注册中心
-
micro.Registry(consul),
-
//添加链路追踪
-
micro.WrapHandler(opentracing2.NewHandlerWrapper(opentracing.GlobalTracer())),
-
micro.WrapClient(opentracing2.NewClientWrapper(opentracing.GlobalTracer())),
-
//只作为客户端的时候起作用,如果存在调用别人的情况,原则上不去主动调用
-
//micro.WrapClient(hystrix2.NewClientHystrixWrapper()),
-
//添加限流
-
micro.WrapHandler(ratelimit.NewHandlerWrapper(1000)),
-
)
-
-
service.Init()
-
-
//只能执行一遍
-
//err = repository.NewMiddlewareRepository(db).InitTable()
-
//if err != nil {
-
// common.Fatal(err)
-
//}
-
//if err:= repository.NewMiddleTypeRepository(db).InitTable();err!=nil{
-
// common.Fatal(err)
-
//}
-
-
// 注册句柄,可以快速操作已开发的服务
-
middlewareDataService := service2.NewMiddlewareDataService(repository.NewMiddlewareRepository(db), clientset)
-
middleTypeDataService := service2.NewMiddleTypeDataService(repository.NewMiddleTypeRepository(db))
-
middleware.RegisterMiddlewareHandler(service.Server(), &handler.MiddlewareHandler{MiddlewareDataService: middlewareDataService, MiddleTypeDataService: middleTypeDataService})
-
-
// 启动服务
-
if err := service.Run(); err != nil {
-
//输出启动失败信息
-
common.Fatal(err)
-
}
-
}
C:\Users\Administrator\Desktop\gopaas\middleware\handler\middlewareHandler.go
-
package handler
-
-
import (
-
"context"
-
"strconv"
-
-
log "github.com/asim/go-micro/v3/logger"
-
"github.com/yunixiangfeng/gopaas/common"
-
"github.com/yunixiangfeng/gopaas/middleware/domain/model"
-
"github.com/yunixiangfeng/gopaas/middleware/domain/service"
-
middleware "github.com/yunixiangfeng/gopaas/middleware/proto/middleware"
-
)
-
-
type MiddlewareHandler struct {
-
//注意这里的类型是 IMiddlewareDataService 接口类型
-
MiddlewareDataService service.IMiddlewareDataService
-
// 添加中间件类型服务
-
MiddleTypeDataService service.IMiddleTypeDataService
-
}
-
-
func (e *MiddlewareHandler) DeleteMiddleTypeById(context.Context, *middleware.MiddleTypeId, *middleware.Response) error {
-
panic("implement me")
-
}
-
-
// Call is a single request handler called via client.Call or the generated client code
-
func (e *MiddlewareHandler) AddMiddleware(ctx context.Context, info *middleware.MiddlewareInfo, rsp *middleware.Response) error {
-
log.Info("Received *middleware.AddMiddleware request")
-
middleModel := &model.Middleware{}
-
if err := common.SwapTo(info, middleModel); err != nil {
-
common.Error(err)
-
rsp.Msg = err.Error()
-
return err
-
}
-
//调用其它的服务处理数据
-
//根据ID产销需要的镜像地址
-
imageAddress, err := e.MiddleTypeDataService.FindImageVersionByID(info.MiddleVersionId)
-
if err != nil {
-
common.Error(err)
-
return err
-
}
-
//赋值
-
info.MiddleDockerImageVersion = imageAddress
-
//在k8s 中创建资源
-
if err := e.MiddlewareDataService.CreateToK8s(info); err != nil {
-
common.Error(err)
-
rsp.Msg = err.Error()
-
return err
-
} else {
-
//插入数据库
-
middleID, err := e.MiddlewareDataService.AddMiddleware(middleModel)
-
if err != nil {
-
common.Error(err)
-
rsp.Msg = err.Error()
-
return err
-
}
-
rsp.Msg = "中间件添加成功 ID 号为:" strconv.FormatInt(middleID, 10)
-
common.Info(rsp.Msg)
-
}
-
return nil
-
}
-
-
func (e *MiddlewareHandler) DeleteMiddleware(ctx context.Context, req *middleware.MiddlewareId, rsp *middleware.Response) error {
-
log.Info("Received *middleware.DeleteMiddleware request")
-
middleModel, err := e.MiddlewareDataService.FindMiddlewareByID(req.Id)
-
if err != nil {
-
common.Error(err)
-
rsp.Msg = err.Error()
-
return err
-
}
-
//删除k8s中资源
-
if err := e.MiddlewareDataService.DeleteFromK8s(middleModel); err != nil {
-
common.Error(err)
-
rsp.Msg = err.Error()
-
return err
-
}
-
return nil
-
}
-
-
func (e *MiddlewareHandler) UpdateMiddleware(ctx context.Context, req *middleware.MiddlewareInfo, rsp *middleware.Response) error {
-
log.Info("Received *middleware.UpdateMiddleware request")
-
if err := e.MiddlewareDataService.UpdateToK8s(req); err != nil {
-
common.Error(err)
-
rsp.Msg = err.Error()
-
return err
-
}
-
//查询中间件相关的信息
-
middleModle, err := e.MiddlewareDataService.FindMiddlewareByID(req.Id)
-
if err != nil {
-
common.Error(err)
-
rsp.Msg = err.Error()
-
return err
-
}
-
//更新model数据
-
if err := common.SwapTo(req, middleModle); err != nil {
-
common.Error(err)
-
rsp.Msg = err.Error()
-
return err
-
}
-
//更新model
-
if err := e.MiddlewareDataService.UpdateMiddleware(middleModle); err != nil {
-
common.Error(err)
-
rsp.Msg = err.Error()
-
return err
-
}
-
return nil
-
}
-
-
//查询中间件
-
func (e *MiddlewareHandler) FindMiddlewareByID(ctx context.Context, req *middleware.MiddlewareId, rsp *middleware.MiddlewareInfo) error {
-
log.Info("Received *middleware.FindMiddlewareByID request")
-
//查询中间件
-
middlewareModel, err := e.MiddlewareDataService.FindMiddlewareByID(req.Id)
-
if err != nil {
-
common.Error(err)
-
return err
-
}
-
if err := common.SwapTo(middlewareModel, rsp); err != nil {
-
common.Error(err)
-
return err
-
}
-
return nil
-
}
-
-
//查找所有的中间件
-
func (e *MiddlewareHandler) FindAllMiddleware(ctx context.Context, req *middleware.FindAll, rsp *middleware.AllMiddleware) error {
-
log.Info("Received *middleware.FindAllMiddleware request")
-
allMiddleware, err := e.MiddlewareDataService.FindAllMiddleware()
-
if err != nil {
-
common.Error(err)
-
return err
-
}
-
//整理格式
-
for _, v := range allMiddleware {
-
middleInfo := &middleware.MiddlewareInfo{}
-
if err := common.SwapTo(v, middleInfo); err != nil {
-
common.Error(err)
-
return err
-
}
-
rsp.MiddlewareInfo = append(rsp.MiddlewareInfo, middleInfo)
-
}
-
return nil
-
}
-
-
//查找所有的中间件
-
func (e *MiddlewareHandler) FindAllMiddlewareByTypeID(ctx context.Context, req *middleware.FindAllByTypeId, rsp *middleware.AllMiddleware) error {
-
log.Info("Received *middleware.FindAllMiddleware request")
-
allMiddleware, err := e.MiddlewareDataService.FindAllMiddlewareByTypeID(req.TypeId)
-
if err != nil {
-
common.Error(err)
-
return err
-
}
-
//整理格式
-
for _, v := range allMiddleware {
-
middleInfo := &middleware.MiddlewareInfo{}
-
if err := common.SwapTo(v, middleInfo); err != nil {
-
common.Error(err)
-
return err
-
}
-
rsp.MiddlewareInfo = append(rsp.MiddlewareInfo, middleInfo)
-
}
-
return nil
-
}
-
-
//根据ID查找中间件类型信息
-
func (e *MiddlewareHandler) FindMiddleTypeByID(ctx context.Context, req *middleware.MiddleTypeId, rsp *middleware.MiddleTypeInfo) error {
-
typeModel, err := e.MiddleTypeDataService.FindMiddleTypeByID(req.Id)
-
if err != nil {
-
common.Error(err)
-
return err
-
}
-
if err := common.SwapTo(typeModel, rsp); err != nil {
-
common.Error(err)
-
return err
-
}
-
return nil
-
}
-
-
//添加中间件
-
func (e *MiddlewareHandler) AddMiddleType(ctx context.Context, info *middleware.MiddleTypeInfo, rsp *middleware.Response) error {
-
typeModel := &model.MiddleType{}
-
if err := common.SwapTo(info, typeModel); err != nil {
-
common.Error(err)
-
rsp.Msg = err.Error()
-
return err
-
}
-
id, err := e.MiddleTypeDataService.AddMiddleType(typeModel)
-
if err != nil {
-
common.Error(err)
-
rsp.Msg = err.Error()
-
return err
-
}
-
rsp.Msg = "中间件类型 ID 号为: " strconv.FormatInt(id, 10)
-
common.Info(rsp.Msg)
-
return nil
-
}
-
-
//删除中间件类型
-
func (e *MiddlewareHandler) DeleteMiddleTypeByID(ctx context.Context, req *middleware.MiddleTypeId, rsp *middleware.Response) error {
-
if err := e.MiddleTypeDataService.DeleteMiddleType(req.Id); err != nil {
-
common.Error(err)
-
rsp.Msg = err.Error()
-
return err
-
}
-
return nil
-
}
-
-
//更新中间件类型
-
func (e *MiddlewareHandler) UpdateMiddleType(ctx context.Context, req *middleware.MiddleTypeInfo, rsp *middleware.Response) error {
-
typeModel, err := e.MiddleTypeDataService.FindMiddleTypeByID(req.Id)
-
if err != nil {
-
common.Error(err)
-
rsp.Msg = err.Error()
-
return err
-
}
-
if err := common.SwapTo(req, typeModel); err != nil {
-
common.Error(err)
-
rsp.Msg = err.Error()
-
return err
-
}
-
if err := e.MiddleTypeDataService.UpdateMiddleType(typeModel); err != nil {
-
common.Error(err)
-
rsp.Msg = err.Error()
-
return err
-
}
-
return nil
-
}
-
-
//查找所有的类型
-
func (e *MiddlewareHandler) FindAllMiddleType(ctx context.Context, req *middleware.FindAll, rsp *middleware.AllMiddleType) error {
-
//查询所有中间件
-
allMiddleType, err := e.MiddleTypeDataService.FindAllMiddleType()
-
if err != nil {
-
common.Error(err)
-
return err
-
}
-
//整理格式
-
for _, v := range allMiddleType {
-
middleInfo := &middleware.MiddleTypeInfo{}
-
if err := common.SwapTo(v, middleInfo); err != nil {
-
common.Error(err)
-
return err
-
}
-
rsp.MiddleTypeInfo = append(rsp.MiddleTypeInfo, middleInfo)
-
}
-
return nil
-
}
make proto
10-17 中间件前端页面以及核心API开发(上)
-
PS C:\Users\Administrator\Desktop\gopaas> .\yu-tool\yu-tool.exe newService github.com/yunixiangfeng/gopaas/middlewareApi
-
-
make proto
-
-
go mod tidy
C:\Users\Administrator\Desktop\gopaas\middlewareapi\proto\middlewareApi\middlewareApi.proto
-
syntax = "proto3";
-
-
package middlewareApi;
-
-
option go_package = "./proto/middlewareApi;middlewareApi";
-
-
service MiddlewareApi {
-
rpc FindMiddlewareById(Request) returns (Response){}
-
rpc AddMiddleware(Request) returns (Response){}
-
rpc DeleteMiddlewareById(Request) returns (Response){}
-
rpc UpdateMiddleware(Request) returns (Response){}
-
//默认接口
-
rpc Call(Request) returns (Response){}
-
//根据类型获取所有中间件
-
rpc FindAllMiddlewareByTypeId(Request) returns (Response){}
-
//中间件类型对外开发的API
-
rpc FindMiddleTypeById(Request) returns (Response){}
-
rpc AddMiddleType(Request) returns (Response){}
-
rpc DeleteMiddleTypeById(Request) returns (Response){}
-
rpc UpdateMiddleType(Request) returns (Response){}
-
rpc FindAllMiddleType(Request) returns (Response){}
-
}
-
-
message Pair {
-
string key = 1;
-
repeated string values = 2;
-
}
-
-
-
message Request {
-
string method = 1;
-
string path = 2;
-
map<string, Pair> header = 3;
-
map<string, Pair> get = 4;
-
map<string, Pair> post = 5;
-
string body = 6;
-
string url = 7;
-
}
-
-
-
message Response {
-
int32 statusCode = 1;
-
map<string, Pair> header = 2;
-
string body = 3;
-
}
-
make proto
C:\Users\Administrator\Desktop\gopaas\middlewareapi\proto\middlewareApi\middlewareApi.pb.micro.go
-
// Code generated by protoc-gen-micro. DO NOT EDIT.
-
// source: proto/middlewareApi/middlewareApi.proto
-
-
package middlewareApi
-
-
import (
-
fmt "fmt"
-
proto "谷歌.golang.org/protobuf/proto"
-
math "math"
-
)
-
-
import (
-
context "context"
-
api "github.com/asim/go-micro/v3/api"
-
client "github.com/asim/go-micro/v3/client"
-
server "github.com/asim/go-micro/v3/server"
-
)
-
-
// Reference imports to suppress errors if they are not otherwise used.
-
var _ = proto.Marshal
-
var _ = fmt.Errorf
-
var _ = math.Inf
-
-
// Reference imports to suppress errors if they are not otherwise used.
-
var _ api.Endpoint
-
var _ context.Context
-
var _ client.Option
-
var _ server.Option
-
-
// Api Endpoints for MiddlewareApi service
-
-
func NewMiddlewareApiEndpoints() []*api.Endpoint {
-
return []*api.Endpoint{}
-
}
-
-
// Client API for MiddlewareApi service
-
-
type MiddlewareApiService interface {
-
FindMiddlewareById(ctx context.Context, in *Request, opts ...client.CallOption) (*Response, error)
-
AddMiddleware(ctx context.Context, in *Request, opts ...client.CallOption) (*Response, error)
-
DeleteMiddlewareById(ctx context.Context, in *Request, opts ...client.CallOption) (*Response, error)
-
UpdateMiddleware(ctx context.Context, in *Request, opts ...client.CallOption) (*Response, error)
-
//默认接口
-
Call(ctx context.Context, in *Request, opts ...client.CallOption) (*Response, error)
-
//根据类型获取所有中间件
-
FindAllMiddlewareByTypeId(ctx context.Context, in *Request, opts ...client.CallOption) (*Response, error)
-
//中间件类型对外开发的API
-
FindMiddleTypeById(ctx context.Context, in *Request, opts ...client.CallOption) (*Response, error)
-
AddMiddleType(ctx context.Context, in *Request, opts ...client.CallOption) (*Response, error)
-
DeleteMiddleTypeById(ctx context.Context, in *Request, opts ...client.CallOption) (*Response, error)
-
UpdateMiddleType(ctx context.Context, in *Request, opts ...client.CallOption) (*Response, error)
-
FindAllMiddleType(ctx context.Context, in *Request, opts ...client.CallOption) (*Response, error)
-
}
-
-
type middlewareApiService struct {
-
c client.Client
-
name string
-
}
-
-
func NewMiddlewareApiService(name string, c client.Client) MiddlewareApiService {
-
return &middlewareApiService{
-
c: c,
-
name: name,
-
}
-
}
-
-
func (c *middlewareApiService) FindMiddlewareById(ctx context.Context, in *Request, opts ...client.CallOption) (*Response, error) {
-
req := c.c.NewRequest(c.name, "MiddlewareApi.FindMiddlewareById", in)
-
out := new(Response)
-
err := c.c.Call(ctx, req, out, opts...)
-
if err != nil {
-
return nil, err
-
}
-
return out, nil
-
}
-
-
func (c *middlewareApiService) AddMiddleware(ctx context.Context, in *Request, opts ...client.CallOption) (*Response, error) {
-
req := c.c.NewRequest(c.name, "MiddlewareApi.AddMiddleware", in)
-
out := new(Response)
-
err := c.c.Call(ctx, req, out, opts...)
-
if err != nil {
-
return nil, err
-
}
-
return out, nil
-
}
-
-
func (c *middlewareApiService) DeleteMiddlewareById(ctx context.Context, in *Request, opts ...client.CallOption) (*Response, error) {
-
req := c.c.NewRequest(c.name, "MiddlewareApi.DeleteMiddlewareById", in)
-
out := new(Response)
-
err := c.c.Call(ctx, req, out, opts...)
-
if err != nil {
-
return nil, err
-
}
-
return out, nil
-
}
-
-
func (c *middlewareApiService) UpdateMiddleware(ctx context.Context, in *Request, opts ...client.CallOption) (*Response, error) {
-
req := c.c.NewRequest(c.name, "MiddlewareApi.UpdateMiddleware", in)
-
out := new(Response)
-
err := c.c.Call(ctx, req, out, opts...)
-
if err != nil {
-
return nil, err
-
}
-
return out, nil
-
}
-
-
func (c *middlewareApiService) Call(ctx context.Context, in *Request, opts ...client.CallOption) (*Response, error) {
-
req := c.c.NewRequest(c.name, "MiddlewareApi.Call", in)
-
out := new(Response)
-
err := c.c.Call(ctx, req, out, opts...)
-
if err != nil {
-
return nil, err
-
}
-
return out, nil
-
}
-
-
func (c *middlewareApiService) FindAllMiddlewareByTypeId(ctx context.Context, in *Request, opts ...client.CallOption) (*Response, error) {
-
req := c.c.NewRequest(c.name, "MiddlewareApi.FindAllMiddlewareByTypeId", in)
-
out := new(Response)
-
err := c.c.Call(ctx, req, out, opts...)
-
if err != nil {
-
return nil, err
-
}
-
return out, nil
-
}
-
-
func (c *middlewareApiService) FindMiddleTypeById(ctx context.Context, in *Request, opts ...client.CallOption) (*Response, error) {
-
req := c.c.NewRequest(c.name, "MiddlewareApi.FindMiddleTypeById", in)
-
out := new(Response)
-
err := c.c.Call(ctx, req, out, opts...)
-
if err != nil {
-
return nil, err
-
}
-
return out, nil
-
}
-
-
func (c *middlewareApiService) AddMiddleType(ctx context.Context, in *Request, opts ...client.CallOption) (*Response, error) {
-
req := c.c.NewRequest(c.name, "MiddlewareApi.AddMiddleType", in)
-
out := new(Response)
-
err := c.c.Call(ctx, req, out, opts...)
-
if err != nil {
-
return nil, err
-
}
-
return out, nil
-
}
-
-
func (c *middlewareApiService) DeleteMiddleTypeById(ctx context.Context, in *Request, opts ...client.CallOption) (*Response, error) {
-
req := c.c.NewRequest(c.name, "MiddlewareApi.DeleteMiddleTypeById", in)
-
out := new(Response)
-
err := c.c.Call(ctx, req, out, opts...)
-
if err != nil {
-
return nil, err
-
}
-
return out, nil
-
}
-
-
func (c *middlewareApiService) UpdateMiddleType(ctx context.Context, in *Request, opts ...client.CallOption) (*Response, error) {
-
req := c.c.NewRequest(c.name, "MiddlewareApi.UpdateMiddleType", in)
-
out := new(Response)
-
err := c.c.Call(ctx, req, out, opts...)
-
if err != nil {
-
return nil, err
-
}
-
return out, nil
-
}
-
-
func (c *middlewareApiService) FindAllMiddleType(ctx context.Context, in *Request, opts ...client.CallOption) (*Response, error) {
-
req := c.c.NewRequest(c.name, "MiddlewareApi.FindAllMiddleType", in)
-
out := new(Response)
-
err := c.c.Call(ctx, req, out, opts...)
-
if err != nil {
-
return nil, err
-
}
-
return out, nil
-
}
-
-
// Server API for MiddlewareApi service
-
-
type MiddlewareApiHandler interface {
-
FindMiddlewareById(context.Context, *Request, *Response) error
-
AddMiddleware(context.Context, *Request, *Response) error
-
DeleteMiddlewareById(context.Context, *Request, *Response) error
-
UpdateMiddleware(context.Context, *Request, *Response) error
-
//默认接口
-
Call(context.Context, *Request, *Response) error
-
//根据类型获取所有中间件
-
FindAllMiddlewareByTypeId(context.Context, *Request, *Response) error
-
//中间件类型对外开发的API
-
FindMiddleTypeById(context.Context, *Request, *Response) error
-
AddMiddleType(context.Context, *Request, *Response) error
-
DeleteMiddleTypeById(context.Context, *Request, *Response) error
-
UpdateMiddleType(context.Context, *Request, *Response) error
-
FindAllMiddleType(context.Context, *Request, *Response) error
-
}
-
-
func RegisterMiddlewareApiHandler(s server.Server, hdlr MiddlewareApiHandler, opts ...server.HandlerOption) error {
-
type middlewareApi interface {
-
FindMiddlewareById(ctx context.Context, in *Request, out *Response) error
-
AddMiddleware(ctx context.Context, in *Request, out *Response) error
-
DeleteMiddlewareById(ctx context.Context, in *Request, out *Response) error
-
UpdateMiddleware(ctx context.Context, in *Request, out *Response) error
-
Call(ctx context.Context, in *Request, out *Response) error
-
FindAllMiddlewareByTypeId(ctx context.Context, in *Request, out *Response) error
-
FindMiddleTypeById(ctx context.Context, in *Request, out *Response) error
-
AddMiddleType(ctx context.Context, in *Request, out *Response) error
-
DeleteMiddleTypeById(ctx context.Context, in *Request, out *Response) error
-
UpdateMiddleType(ctx context.Context, in *Request, out *Response) error
-
FindAllMiddleType(ctx context.Context, in *Request, out *Response) error
-
}
-
type MiddlewareApi struct {
-
middlewareApi
-
}
-
h := &middlewareApiHandler{hdlr}
-
return s.Handle(s.NewHandler(&MiddlewareApi{h}, opts...))
-
}
-
-
type middlewareApiHandler struct {
-
MiddlewareApiHandler
-
}
-
-
func (h *middlewareApiHandler) FindMiddlewareById(ctx context.Context, in *Request, out *Response) error {
-
return h.MiddlewareApiHandler.FindMiddlewareById(ctx, in, out)
-
}
-
-
func (h *middlewareApiHandler) AddMiddleware(ctx context.Context, in *Request, out *Response) error {
-
return h.MiddlewareApiHandler.AddMiddleware(ctx, in, out)
-
}
-
-
func (h *middlewareApiHandler) DeleteMiddlewareById(ctx context.Context, in *Request, out *Response) error {
-
return h.MiddlewareApiHandler.DeleteMiddlewareById(ctx, in, out)
-
}
-
-
func (h *middlewareApiHandler) UpdateMiddleware(ctx context.Context, in *Request, out *Response) error {
-
return h.MiddlewareApiHandler.UpdateMiddleware(ctx, in, out)
-
}
-
-
func (h *middlewareApiHandler) Call(ctx context.Context, in *Request, out *Response) error {
-
return h.MiddlewareApiHandler.Call(ctx, in, out)
-
}
-
-
func (h *middlewareApiHandler) FindAllMiddlewareByTypeId(ctx context.Context, in *Request, out *Response) error {
-
return h.MiddlewareApiHandler.FindAllMiddlewareByTypeId(ctx, in, out)
-
}
-
-
func (h *middlewareApiHandler) FindMiddleTypeById(ctx context.Context, in *Request, out *Response) error {
-
return h.MiddlewareApiHandler.FindMiddleTypeById(ctx, in, out)
-
}
-
-
func (h *middlewareApiHandler) AddMiddleType(ctx context.Context, in *Request, out *Response) error {
-
return h.MiddlewareApiHandler.AddMiddleType(ctx, in, out)
-
}
-
-
func (h *middlewareApiHandler) DeleteMiddleTypeById(ctx context.Context, in *Request, out *Response) error {
-
return h.MiddlewareApiHandler.DeleteMiddleTypeById(ctx, in, out)
-
}
-
-
func (h *middlewareApiHandler) UpdateMiddleType(ctx context.Context, in *Request, out *Response) error {
-
return h.MiddlewareApiHandler.UpdateMiddleType(ctx, in, out)
-
}
-
-
func (h *middlewareApiHandler) FindAllMiddleType(ctx context.Context, in *Request, out *Response) error {
-
return h.MiddlewareApiHandler.FindAllMiddleType(ctx, in, out)
-
}
C:\Users\Administrator\Desktop\gopaas\middlewareapi\proto\middlewareApi\middlewareApi.pb.go
-
// Code generated by protoc-gen-go. DO NOT EDIT.
-
// versions:
-
// protoc-gen-go v1.27.1
-
// protoc v3.15.7
-
// source: proto/middlewareApi/middlewareApi.proto
-
-
package middlewareApi
-
-
import (
-
protoreflect "谷歌.golang.org/protobuf/reflect/protoreflect"
-
protoimpl "谷歌.golang.org/protobuf/runtime/protoimpl"
-
reflect "reflect"
-
sync "sync"
-
)
-
-
const (
-
// Verify that this generated code is sufficiently up-to-date.
-
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
-
// Verify that runtime/protoimpl is sufficiently up-to-date.
-
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
-
)
-
-
type Pair struct {
-
state protoimpl.MessageState
-
sizeCache protoimpl.SizeCache
-
unknownFields protoimpl.UnknownFields
-
-
Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"`
-
Values []string `protobuf:"bytes,2,rep,name=values,proto3" json:"values,omitempty"`
-
}
-
-
func (x *Pair) Reset() {
-
*x = Pair{}
-
if protoimpl.UnsafeEnabled {
-
mi := &file_proto_middlewareApi_middlewareApi_proto_msgTypes[0]
-
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-
ms.StoreMessageInfo(mi)
-
}
-
}
-
-
func (x *Pair) String() string {
-
return protoimpl.X.MessageStringOf(x)
-
}
-
-
func (*Pair) ProtoMessage() {}
-
-
func (x *Pair) ProtoReflect() protoreflect.Message {
-
mi := &file_proto_middlewareApi_middlewareApi_proto_msgTypes[0]
-
if protoimpl.UnsafeEnabled && x != nil {
-
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-
if ms.LoadMessageInfo() == nil {
-
ms.StoreMessageInfo(mi)
-
}
-
return ms
-
}
-
return mi.MessageOf(x)
-
}
-
-
// Deprecated: Use Pair.ProtoReflect.Descriptor instead.
-
func (*Pair) Descriptor() ([]byte, []int) {
-
return file_proto_middlewareApi_middlewareApi_proto_rawDescGZIP(), []int{0}
-
}
-
-
func (x *Pair) GetKey() string {
-
if x != nil {
-
return x.Key
-
}
-
return ""
-
}
-
-
func (x *Pair) GetValues() []string {
-
if x != nil {
-
return x.Values
-
}
-
return nil
-
}
-
-
type Request struct {
-
state protoimpl.MessageState
-
sizeCache protoimpl.SizeCache
-
unknownFields protoimpl.UnknownFields
-
-
Method string `protobuf:"bytes,1,opt,name=method,proto3" json:"method,omitempty"`
-
Path string `protobuf:"bytes,2,opt,name=path,proto3" json:"path,omitempty"`
-
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"`
-
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"`
-
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"`
-
Body string `protobuf:"bytes,6,opt,name=body,proto3" json:"body,omitempty"`
-
Url string `protobuf:"bytes,7,opt,name=url,proto3" json:"url,omitempty"`
-
}
-
-
func (x *Request) Reset() {
-
*x = Request{}
-
if protoimpl.UnsafeEnabled {
-
mi := &file_proto_middlewareApi_middlewareApi_proto_msgTypes[1]
-
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-
ms.StoreMessageInfo(mi)
-
}
-
}
-
-
func (x *Request) String() string {
-
return protoimpl.X.MessageStringOf(x)
-
}
-
-
func (*Request) ProtoMessage() {}
-
-
func (x *Request) ProtoReflect() protoreflect.Message {
-
mi := &file_proto_middlewareApi_middlewareApi_proto_msgTypes[1]
-
if protoimpl.UnsafeEnabled && x != nil {
-
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-
if ms.LoadMessageInfo() == nil {
-
ms.StoreMessageInfo(mi)
-
}
-
return ms
-
}
-
return mi.MessageOf(x)
-
}
-
-
// Deprecated: Use Request.ProtoReflect.Descriptor instead.
-
func (*Request) Descriptor() ([]byte, []int) {
-
return file_proto_middlewareApi_middlewareApi_proto_rawDescGZIP(), []int{1}
-
}
-
-
func (x *Request) GetMethod() string {
-
if x != nil {
-
return x.Method
-
}
-
return ""
-
}
-
-
func (x *Request) GetPath() string {
-
if x != nil {
-
return x.Path
-
}
-
return ""
-
}
-
-
func (x *Request) GetHeader() map[string]*Pair {
-
if x != nil {
-
return x.Header
-
}
-
return nil
-
}
-
-
func (x *Request) GetGet() map[string]*Pair {
-
if x != nil {
-
return x.Get
-
}
-
return nil
-
}
-
-
func (x *Request) GetPost() map[string]*Pair {
-
if x != nil {
-
return x.Post
-
}
-
return nil
-
}
-
-
func (x *Request) GetBody() string {
-
if x != nil {
-
return x.Body
-
}
-
return ""
-
}
-
-
func (x *Request) GetUrl() string {
-
if x != nil {
-
return x.Url
-
}
-
return ""
-
}
-
-
type Response struct {
-
state protoimpl.MessageState
-
sizeCache protoimpl.SizeCache
-
unknownFields protoimpl.UnknownFields
-
-
StatusCode int32 `protobuf:"varint,1,opt,name=statusCode,proto3" json:"statusCode,omitempty"`
-
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"`
-
Body string `protobuf:"bytes,3,opt,name=body,proto3" json:"body,omitempty"`
-
}
-
-
func (x *Response) Reset() {
-
*x = Response{}
-
if protoimpl.UnsafeEnabled {
-
mi := &file_proto_middlewareApi_middlewareApi_proto_msgTypes[2]
-
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-
ms.StoreMessageInfo(mi)
-
}
-
}
-
-
func (x *Response) String() string {
-
return protoimpl.X.MessageStringOf(x)
-
}
-
-
func (*Response) ProtoMessage() {}
-
-
func (x *Response) ProtoReflect() protoreflect.Message {
-
mi := &file_proto_middlewareApi_middlewareApi_proto_msgTypes[2]
-
if protoimpl.UnsafeEnabled && x != nil {
-
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-
if ms.LoadMessageInfo() == nil {
-
ms.StoreMessageInfo(mi)
-
}
-
return ms
-
}
-
return mi.MessageOf(x)
-
}
-
-
// Deprecated: Use Response.ProtoReflect.Descriptor instead.
-
func (*Response) Descriptor() ([]byte, []int) {
-
return file_proto_middlewareApi_middlewareApi_proto_rawDescGZIP(), []int{2}
-
}
-
-
func (x *Response) GetStatusCode() int32 {
-
if x != nil {
-
return x.StatusCode
-
}
-
return 0
-
}
-
-
func (x *Response) GetHeader() map[string]*Pair {
-
if x != nil {
-
return x.Header
-
}
-
return nil
-
}
-
-
func (x *Response) GetBody() string {
-
if x != nil {
-
return x.Body
-
}
-
return ""
-
}
-
-
var File_proto_middlewareApi_middlewareApi_proto protoreflect.FileDescriptor
-
-
var file_proto_middlewareApi_middlewareApi_proto_rawDesc = []byte{
-
0x0a, 0x27, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x77, 0x61,
-
0x72, 0x65, 0x41, 0x70, 0x69, 0x2f, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x77, 0x61, 0x72, 0x65,
-
0x41, 0x70, 0x69, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0d, 0x6d, 0x69, 0x64, 0x64, 0x6c,
-
0x65, 0x77, 0x61, 0x72, 0x65, 0x41, 0x70, 0x69, 0x22, 0x30, 0x0a, 0x04, 0x50, 0x61, 0x69, 0x72,
-
0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b,
-
0x65, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03,
-
0x28, 0x09, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x22, 0xeb, 0x03, 0x0a, 0x07, 0x52,
-
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64,
-
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x12,
-
0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61,
-
0x74, 0x68, 0x12, 0x3a, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x03, 0x20, 0x03,
-
0x28, 0x0b, 0x32, 0x22, 0x2e, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x77, 0x61, 0x72, 0x65, 0x41,
-
0x70, 0x69, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65,
-
0x72, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x31,
-
0x0a, 0x03, 0x67, 0x65, 0x74, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6d, 0x69,
-
0x64, 0x64, 0x6c, 0x65, 0x77, 0x61, 0x72, 0x65, 0x41, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x71, 0x75,
-
0x65, 0x73, 0x74, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x03, 0x67, 0x65,
-
0x74, 0x12, 0x34, 0x0a, 0x04, 0x70, 0x6f, 0x73, 0x74, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32,
-
0x20, 0x2e, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x77, 0x61, 0x72, 0x65, 0x41, 0x70, 0x69, 0x2e,
-
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x50, 0x6f, 0x73, 0x74, 0x45, 0x6e, 0x74, 0x72,
-
0x79, 0x52, 0x04, 0x70, 0x6f, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18,
-
0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x75,
-
0x72, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x1a, 0x4e, 0x0a,
-
0x0b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03,
-
0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x29,
-
0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e,
-
0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x77, 0x61, 0x72, 0x65, 0x41, 0x70, 0x69, 0x2e, 0x50, 0x61,
-
0x69, 0x72, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x4b, 0x0a,
-
0x08, 0x47, 0x65, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79,
-
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x29, 0x0a, 0x05, 0x76,
-
0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x6d, 0x69, 0x64,
-
0x64, 0x6c, 0x65, 0x77, 0x61, 0x72, 0x65, 0x41, 0x70, 0x69, 0x2e, 0x50, 0x61, 0x69, 0x72, 0x52,
-
0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x4c, 0x0a, 0x09, 0x50, 0x6f,
-
0x73, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01,
-
0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x29, 0x0a, 0x05, 0x76, 0x61, 0x6c,
-
0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x6d, 0x69, 0x64, 0x64, 0x6c,
-
0x65, 0x77, 0x61, 0x72, 0x65, 0x41, 0x70, 0x69, 0x2e, 0x50, 0x61, 0x69, 0x72, 0x52, 0x05, 0x76,
-
0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xcb, 0x01, 0x0a, 0x08, 0x52, 0x65, 0x73,
-
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x43,
-
0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x75,
-
0x73, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x3b, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18,
-
0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x77, 0x61,
-
0x72, 0x65, 0x41, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x48,
-
0x65, 0x61, 0x64, 0x65, 0x72, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64,
-
0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09,
-
0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x1a, 0x4e, 0x0a, 0x0b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72,
-
0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01,
-
0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x29, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
-
0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x77,
-
0x61, 0x72, 0x65, 0x41, 0x70, 0x69, 0x2e, 0x50, 0x61, 0x69, 0x72, 0x52, 0x05, 0x76, 0x61, 0x6c,
-
0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x32, 0xa0, 0x06, 0x0a, 0x0d, 0x4d, 0x69, 0x64, 0x64, 0x6c,
-
0x65, 0x77, 0x61, 0x72, 0x65, 0x41, 0x70, 0x69, 0x12, 0x47, 0x0a, 0x12, 0x46, 0x69, 0x6e, 0x64,
-
0x4d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x77, 0x61, 0x72, 0x65, 0x42, 0x79, 0x49, 0x64, 0x12, 0x16,
-
0x2e, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x77, 0x61, 0x72, 0x65, 0x41, 0x70, 0x69, 0x2e, 0x52,
-
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x77,
-
0x61, 0x72, 0x65, 0x41, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
-
0x00, 0x12, 0x42, 0x0a, 0x0d, 0x41, 0x64, 0x64, 0x4d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x77, 0x61,
-
0x72, 0x65, 0x12, 0x16, 0x2e, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x77, 0x61, 0x72, 0x65, 0x41,
-
0x70, 0x69, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x6d, 0x69, 0x64,
-
0x64, 0x6c, 0x65, 0x77, 0x61, 0x72, 0x65, 0x41, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f,
-
0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x49, 0x0a, 0x14, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4d,
-
0x69, 0x64, 0x64, 0x6c, 0x65, 0x77, 0x61, 0x72, 0x65, 0x42, 0x79, 0x49, 0x64, 0x12, 0x16, 0x2e,
-
0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x77, 0x61, 0x72, 0x65, 0x41, 0x70, 0x69, 0x2e, 0x52, 0x65,
-
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x77, 0x61,
-
0x72, 0x65, 0x41, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00,
-
0x12, 0x45, 0x0a, 0x10, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x69, 0x64, 0x64, 0x6c, 0x65,
-
0x77, 0x61, 0x72, 0x65, 0x12, 0x16, 0x2e, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x77, 0x61, 0x72,
-
0x65, 0x41, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x6d,
-
0x69, 0x64, 0x64, 0x6c, 0x65, 0x77, 0x61, 0x72, 0x65, 0x41, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x73,
-
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x39, 0x0a, 0x04, 0x43, 0x61, 0x6c, 0x6c, 0x12,
-
0x16, 0x2e, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x77, 0x61, 0x72, 0x65, 0x41, 0x70, 0x69, 0x2e,
-
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65,
-
0x77, 0x61, 0x72, 0x65, 0x41, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
-
0x22, 0x00, 0x12, 0x4e, 0x0a, 0x19, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x4d, 0x69, 0x64,
-
0x64, 0x6c, 0x65, 0x77, 0x61, 0x72, 0x65, 0x42, 0x79, 0x54, 0x79, 0x70, 0x65, 0x49, 0x64, 0x12,
-
0x16, 0x2e, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x77, 0x61, 0x72, 0x65, 0x41, 0x70, 0x69, 0x2e,
-
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65,
-
0x77, 0x61, 0x72, 0x65, 0x41, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
-
0x22, 0x00, 0x12, 0x47, 0x0a, 0x12, 0x46, 0x69, 0x6e, 0x64, 0x4d, 0x69, 0x64, 0x64, 0x6c, 0x65,
-
0x54, 0x79, 0x70, 0x65, 0x42, 0x79, 0x49, 0x64, 0x12, 0x16, 0x2e, 0x6d, 0x69, 0x64, 0x64, 0x6c,
-
0x65, 0x77, 0x61, 0x72, 0x65, 0x41, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
-
0x1a, 0x17, 0x2e, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x77, 0x61, 0x72, 0x65, 0x41, 0x70, 0x69,
-
0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x42, 0x0a, 0x0d, 0x41,
-
0x64, 0x64, 0x4d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x2e, 0x6d,
-
0x69, 0x64, 0x64, 0x6c, 0x65, 0x77, 0x61, 0x72, 0x65, 0x41, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x71,
-
0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x77, 0x61, 0x72,
-
0x65, 0x41, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12,
-
0x49, 0x0a, 0x14, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x54,
-
0x79, 0x70, 0x65, 0x42, 0x79, 0x49, 0x64, 0x12, 0x16, 0x2e, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65,
-
0x77, 0x61, 0x72, 0x65, 0x41, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
-
0x17, 0x2e, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x77, 0x61, 0x72, 0x65, 0x41, 0x70, 0x69, 0x2e,
-
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x45, 0x0a, 0x10, 0x55, 0x70,
-
0x64, 0x61, 0x74, 0x65, 0x4d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16,
-
0x2e, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x77, 0x61, 0x72, 0x65, 0x41, 0x70, 0x69, 0x2e, 0x52,
-
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x77,
-
0x61, 0x72, 0x65, 0x41, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
-
0x00, 0x12, 0x46, 0x0a, 0x11, 0x46, 0x69, 0x6e, 0x64, 0x41, 0x6c, 0x6c, 0x4d, 0x69, 0x64, 0x64,
-
0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x2e, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x77,
-
0x61, 0x72, 0x65, 0x41, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17,
-
0x2e, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x77, 0x61, 0x72, 0x65, 0x41, 0x70, 0x69, 0x2e, 0x52,
-
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x25, 0x5a, 0x23, 0x2e, 0x2f, 0x70,
-
0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x77, 0x61, 0x72, 0x65, 0x41,
-
0x70, 0x69, 0x3b, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x77, 0x61, 0x72, 0x65, 0x41, 0x70, 0x69,
-
0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
-
}
-
-
var (
-
file_proto_middlewareApi_middlewareApi_proto_rawDescOnce sync.Once
-
file_proto_middlewareApi_middlewareApi_proto_rawDescData = file_proto_middlewareApi_middlewareApi_proto_rawDesc
-
)
-
-
func file_proto_middlewareApi_middlewareApi_proto_rawDescGZIP() []byte {
-
file_proto_middlewareApi_middlewareApi_proto_rawDescOnce.Do(func() {
-
file_proto_middlewareApi_middlewareApi_proto_rawDescData = protoimpl.X.CompressGZIP(file_proto_middlewareApi_middlewareApi_proto_rawDescData)
-
})
-
return file_proto_middlewareApi_middlewareApi_proto_rawDescData
-
}
-
-
var file_proto_middlewareApi_middlewareApi_proto_msgTypes = make([]protoimpl.MessageInfo, 7)
-
var file_proto_middlewareApi_middlewareApi_proto_goTypes = []interface{}{
-
(*Pair)(nil), // 0: middlewareApi.Pair
-
(*Request)(nil), // 1: middlewareApi.Request
-
(*Response)(nil), // 2: middlewareApi.Response
-
nil, // 3: middlewareApi.Request.HeaderEntry
-
nil, // 4: middlewareApi.Request.GetEntry
-
nil, // 5: middlewareApi.Request.PostEntry
-
nil, // 6: middlewareApi.Response.HeaderEntry
-
}
-
var file_proto_middlewareApi_middlewareApi_proto_depIdxs = []int32{
-
3, // 0: middlewareApi.Request.header:type_name -> middlewareApi.Request.HeaderEntry
-
4, // 1: middlewareApi.Request.get:type_name -> middlewareApi.Request.GetEntry
-
5, // 2: middlewareApi.Request.post:type_name -> middlewareApi.Request.PostEntry
-
6, // 3: middlewareApi.Response.header:type_name -> middlewareApi.Response.HeaderEntry
-
0, // 4: middlewareApi.Request.HeaderEntry.value:type_name -> middlewareApi.Pair
-
0, // 5: middlewareApi.Request.GetEntry.value:type_name -> middlewareApi.Pair
-
0, // 6: middlewareApi.Request.PostEntry.value:type_name -> middlewareApi.Pair
-
0, // 7: middlewareApi.Response.HeaderEntry.value:type_name -> middlewareApi.Pair
-
1, // 8: middlewareApi.MiddlewareApi.FindMiddlewareById:input_type -> middlewareApi.Request
-
1, // 9: middlewareApi.MiddlewareApi.AddMiddleware:input_type -> middlewareApi.Request
-
1, // 10: middlewareApi.MiddlewareApi.DeleteMiddlewareById:input_type -> middlewareApi.Request
-
1, // 11: middlewareApi.MiddlewareApi.UpdateMiddleware:input_type -> middlewareApi.Request
-
1, // 12: middlewareApi.MiddlewareApi.Call:input_type -> middlewareApi.Request
-
1, // 13: middlewareApi.MiddlewareApi.FindAllMiddlewareByTypeId:input_type -> middlewareApi.Request
-
1, // 14: middlewareApi.MiddlewareApi.FindMiddleTypeById:input_type -> middlewareApi.Request
-
1, // 15: middlewareApi.MiddlewareApi.AddMiddleType:input_type -> middlewareApi.Request
-
1, // 16: middlewareApi.MiddlewareApi.DeleteMiddleTypeById:input_type -> middlewareApi.Request
-
1, // 17: middlewareApi.MiddlewareApi.UpdateMiddleType:input_type -> middlewareApi.Request
-
1, // 18: middlewareApi.MiddlewareApi.FindAllMiddleType:input_type -> middlewareApi.Request
-
2, // 19: middlewareApi.MiddlewareApi.FindMiddlewareById:output_type -> middlewareApi.Response
-
2, // 20: middlewareApi.MiddlewareApi.AddMiddleware:output_type -> middlewareApi.Response
-
2, // 21: middlewareApi.MiddlewareApi.DeleteMiddlewareById:output_type -> middlewareApi.Response
-
2, // 22: middlewareApi.MiddlewareApi.UpdateMiddleware:output_type -> middlewareApi.Response
-
2, // 23: middlewareApi.MiddlewareApi.Call:output_type -> middlewareApi.Response
-
2, // 24: middlewareApi.MiddlewareApi.FindAllMiddlewareByTypeId:output_type -> middlewareApi.Response
-
2, // 25: middlewareApi.MiddlewareApi.FindMiddleTypeById:output_type -> middlewareApi.Response
-
2, // 26: middlewareApi.MiddlewareApi.AddMiddleType:output_type -> middlewareApi.Response
-
2, // 27: middlewareApi.MiddlewareApi.DeleteMiddleTypeById:output_type -> middlewareApi.Response
-
2, // 28: middlewareApi.MiddlewareApi.UpdateMiddleType:output_type -> middlewareApi.Response
-
2, // 29: middlewareApi.MiddlewareApi.FindAllMiddleType:output_type -> middlewareApi.Response
-
19, // [19:30] is the sub-list for method output_type
-
8, // [8:19] is the sub-list for method input_type
-
8, // [8:8] is the sub-list for extension type_name
-
8, // [8:8] is the sub-list for extension extendee
-
0, // [0:8] is the sub-list for field type_name
-
}
-
-
func init() { file_proto_middlewareApi_middlewareApi_proto_init() }
-
func file_proto_middlewareApi_middlewareApi_proto_init() {
-
if File_proto_middlewareApi_middlewareApi_proto != nil {
-
return
-
}
-
if !protoimpl.UnsafeEnabled {
-
file_proto_middlewareApi_middlewareApi_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
-
switch v := v.(*Pair); i {
-
case 0:
-
return &v.state
-
case 1:
-
return &v.sizeCache
-
case 2:
-
return &v.unknownFields
-
default:
-
return nil
-
}
-
}
-
file_proto_middlewareApi_middlewareApi_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
-
switch v := v.(*Request); i {
-
case 0:
-
return &v.state
-
case 1:
-
return &v.sizeCache
-
case 2:
-
return &v.unknownFields
-
default:
-
return nil
-
}
-
}
-
file_proto_middlewareApi_middlewareApi_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
-
switch v := v.(*Response); i {
-
case 0:
-
return &v.state
-
case 1:
-
return &v.sizeCache
-
case 2:
-
return &v.unknownFields
-
default:
-
return nil
-
}
-
}
-
}
-
type x struct{}
-
out := protoimpl.TypeBuilder{
-
File: protoimpl.DescBuilder{
-
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
-
RawDescriptor: file_proto_middlewareApi_middlewareApi_proto_rawDesc,
-
NumEnums: 0,
-
NumMessages: 7,
-
NumExtensions: 0,
-
NumServices: 1,
-
},
-
GoTypes: file_proto_middlewareApi_middlewareApi_proto_goTypes,
-
DependencyIndexes: file_proto_middlewareApi_middlewareApi_proto_depIdxs,
-
MessageInfos: file_proto_middlewareApi_middlewareApi_proto_msgTypes,
-
}.Build()
-
File_proto_middlewareApi_middlewareApi_proto = out.File
-
file_proto_middlewareApi_middlewareApi_proto_rawDesc = nil
-
file_proto_middlewareApi_middlewareApi_proto_goTypes = nil
-
file_proto_middlewareApi_middlewareApi_proto_depIdxs = nil
-
}
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgfbkig
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
怎样阻止微信小程序自动打开
PHP中文网 06-13 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01