Loading

kubevela addon添加组件-微服务应用

addon添加组件-微服务应用

kubevela简介

背景:公司最近在研究OAM(开放应用模型),其中KubeVela 项目是 OAM 社区的官方项目,是一个端到端、面向全量场景的 OAM Kubernetes 完整实现,同时也是阿里云 EDAS 服务和内部多个核心 PaaS/Serverless 生产系统底层的核心组件。

我这边在尝试了通过vela up -f xxx.yaml方式,正常部署应用之后,对于其插件的扩展有了一点兴趣,就研究了一下,做了一个demo。

demo工程

demo工程是基于Spring-Cloud-Alibaba

因为是demo工程,所以做得比较简单,但是及时是这样简单的工程,也能体现出使用自定义组件部署应用的流程。在更加复杂的项目中也适用。

demo工程使用了:

注册中心-nacos

缓存-redis

关系型数据库-mysql 8.0

工程中有3个服务,alpha连接数据库和nacos,beta连接redis和nacos

aggregation连接nacos,通过openfeign调用服务alpha和beta做聚合逻辑

工程的内部逻辑就不多强调了,主要是其配置方面

alpha服务关于数据库和nacos的配置:

spring:
  #profiles:
  #  include: discovery-registry
  datasource:
    #数据库地址
    url: jdbc:mysql://${DB_URL}/framework_test?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC
    #数据库账号
    username: ${DB_USERNAME}
    #数据库密码
    password: ${DB_PASSWORD}
... ...
    #nacos地址
    server-addr: ${NACOS_SERVER_ADDR}
... ...

beta服务关于redis和nacos的配置:

spring:
  redis:
    redisson:
      config: |
        singleServerConfig:
          ...
          password: ${REDIS_PASSWORD}
          address: 'redis://${REDIS_IP}:${REDIS_PORT}'
          ...
... ...
    #nacos地址
    server-addr: ${NACOS_SERVER_ADDR}
... ...

aggregation关于nacos的配置

... ...
    #nacos地址
    server-addr: ${NACOS_SERVER_ADDR}
... ...

通过环境变量的方式,传入nacos,redis和mysql的相关信息

然后将这三个服务容器化,只要在部署的时候通过注入环境变量的方式就能完成nacos,redis和mysql的配置。

kubevela addon

在使用原生k8s的时候,通常在部署服务的时候,需要使用k8s资源清单,将中间件,数据库先行部署。

但是如果我们使用kubevela,能不能将部署中间件,数据库的这些步骤,和我们的服务结合起来?

将数据库,中间件这些当做项目的一个组件,做到一键部署,并且自动关联到应用中。

这就可以用到kubevela的组件了。组件定义(ComponentDefinition)可以将任何类型的可部署制品封装成待交付的“组件”。只要定义好之后,这种类型的组件就可以被用户在部署计划(Application)中引用、实例化并交付出去。

参考插件文档,我这里将redis,mysql和nacos做成组件,通过插件的方式添加进kubevela

插件目录:

其中最重要的是三个.cue文件,对应的是三个组件,其他的文件可以参考插件文档

myredis.cue:

import(
	"encoding/base64"
)
"myredis": {
	annotations: {}
	attributes: workload: definition: {
		apiVersion: "apps/v1"
		kind: "Deployment"
	}
	description: "My Redis component."
	labels: {}
	type: "component"
}

template: {
	output: {
		apiVersion: "v1"
		kind: "ConfigMap"
		metadata: {
			name: context.name + "-redis-config"
			labels: app: context.name
		}
		data: {
			"redis.conf": """
              dir /data
              port 6379
              bind 0.0.0.0
              appendonly yes
              protected-mode no
              pidfile /data/redis-6379.pid
              requirepass
              """ + " "  + parameter.redisPassword
		}
	}
	outputs: {
		redis: {
		apiVersion: "apps/v1"
		kind: "Deployment"
		metadata: {
			name: "redis"
			labels: app: context.name
		}
		spec: {
			replicas: 1
			selector: matchLabels: app: context.name
			template: {
				metadata: labels: app: context.name
				spec: {
					containers: [{
						name: context.name
						command: ["sh", "-c", "redis-server /usr/local/etc/redis/redis.conf"]
						image: "redis:6.2.6"
						ports: [{
							containerPort: 6379
						}]
						volumeMounts: [{
							name:      "data"
							mountPath: "/data"
						}, {
							name:      "config"
							mountPath: "/usr/local/etc/redis/redis.conf"
							subPath:   "redis.conf"
						}]
					}]
					volumes: [{
						name: "data"
						hostPath: path: parameter.hostPath
					}, {
						name: "config"
						configMap: name: context.name + "-redis-config"
					}]
				}
			}
		}
	}
	web: {
		apiVersion: "v1"
		kind:       "Service"
		metadata: {
			name: context.name
			labels: app: context.name
		}
		spec: {
			ports: [{
				name: context.name
				port: 6379
				targetPort: 6379
				if parameter.serviceType == "NodePort" {
					  nodePort:   parameter.nodePort
					}
			}]
			selector: app: context.name
			type: parameter.serviceType
	  }
	}
	secret: {
		apiVersion: "v1"
		kind:       "Secret"
		metadata: {
			name: context.name + "-myredis-secret"
		}
		type: "Opaque"
		data: {
			password: base64.Encode(null,parameter.redisPassword)
			ip: base64.Encode(null,context.name + "." + context.namespace + ".svc.cluster.local")
			port: base64.Encode(null,"6379")
		}
	}
	}
	parameter: {
              hostPath: *"/home/k8s/redis/data1" | string
              serviceType: *"ClusterIP" | "NodePort"
              redisPassword: *"123456" | string
              nodePort ?: *30003 | int
            }
}

mysql.cue

import(
	"encoding/base64"
)
mysql: {
	annotations: {}
	attributes: workload: definition: {
		apiVersion: "apps/v1"
		kind:       "StatefulSet"
	}
	description: "My mysql component."
	labels: {}
	type: "component"
}

template: {
	output: {
		apiVersion: "v1"
		data: "mysqld.cnf": """
        [mysqld]
        pid-file        = /var/run/mysqld/mysqld.pid
        socket          = /var/run/mysqld/mysqld.sock
        datadir         = /var/lib/mysql
        bind-address   = 0.0.0.0
        symbolic-links=0
        max_connections=1000
        default_storage_engine=innodb
        skip_external_locking
        lower_case_table_names=1
        skip_host_cache
        skip_name_resolve
        character_set_server=utf8
        sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
        """
		kind: "ConfigMap"
		metadata: {
			name:      context.name + "-mysql-config"
		}
	}
	outputs: {
		mysql: {
			apiVersion: "apps/v1"
			kind:       "StatefulSet"
			metadata: {
				name: context.name + "-mysql"
			}
			spec: {
				selector: matchLabels: app: context.name + "-mysql"
				replicas:    1
				serviceName: context.name + "-mysql-headless"
				template: {
					metadata: labels: app: context.name + "-mysql"
					spec: {
						containers: [{
							name: "mysql"
							env: [{
								name:  "MYSQL_ROOT_PASSWORD"
								value: parameter.rootPassword
							}, {
								if parameter.database != _|_ {
								  name:  "MYSQL_DATABASE"
								  value: parameter.database
								}
							}]
							ports: [{
								name:          "mysql"
								containerPort: 3306
							}]
							image: "mysql:8.0.28"
							volumeMounts: [{
								name: context.name + "-mysql-data"
								mountPath: "/var/lib/mysql"
							}, {
								name: context.name + "-mysql-config"
								mountPath: "/etc/mysql/conf.d/"
							},{
								if parameter.initdb != _|_{
								  name:  context.name + "-mysql-initdb"
								  mountPath: "/docker-entrypoint-initdb.d"
								}
						    }
						]
						}]
						volumes: [{
							name: context.name+ "-mysql-data"
							hostPath: path: parameter.hostPath
						}, {
							name: context.name + "-mysql-config"
							configMap: name: context.name + "-mysql-config"
						},{
					     if parameter.initdb != _|_		{
							     name: context.name + "-mysql-initdb"
							     configMap: name: parameter.initdb
						    }
					   }
				]
					}
				}
			}
		}
		"mysql-headless": {
			apiVersion: "v1"
			kind:       "Service"
			metadata: {
				name:  context.name + "-mysql-headless"
				labels: app: context.name + "-mysql"
			}
			spec: {
				ports: [{
					name:       "tcp"
					port:       3306
					protocol:   "TCP"
					targetPort: 3306
				}]
				selector: app: context.name + "-mysql"
				clusterIP: "None"
			}
		}
		"mysql-service": {
			apiVersion: "v1"
			kind:       "Service"
			metadata: {
				name: context.name + "-mysql-service"
				labels: app: context.name + "-mysql"
			}
			spec: {
				ports: [{
					name:       "tcp"
					if parameter.serviceType == "NodePort" {
					  nodePort:   parameter.nodePort
					}

					port:       3306
					protocol:   "TCP"
					targetPort: 3306
				}]
				selector: app: context.name + "-mysql"
				type: parameter.serviceType
			}
		}
	  secret: {
		  apiVersion: "v1"
		  kind:       "Secret"
		  metadata: {
			  name: context.name + "-mysql-secret"
		  }
		  type: "Opaque"
		  data: {
			  root: base64.Encode(null,"root")
			  password: base64.Encode(null,parameter.rootPassword)
			  url: base64.Encode(null,context.name + "-mysql-service." + context.namespace + ".svc.cluster.local:3306")
		  }
	  }
	}
	parameter: {
		initdb ?: string
		hostPath: *"/home/k8s/mysql" | string
    serviceType: *"ClusterIP" | "NodePort"
    nodePort ?: *30001 | int
    rootPassword: *"123456" | string
    database ?: string
	}
}

nacos.cue:

import(
	"encoding/base64"
)
nacos: {
	annotations: {}
	attributes: workload: definition: {
		apiVersion: "apps/v1"
		kind:       "StatefulSet"
	}
	description: "My nacos component."
	labels: {}
	type: "component"
}

template: {
	output: {
		apiVersion: "v1"
		data: {
			"mysql.db.name":  parameter.mysql.db
			"mysql.host":     parameter.mysql.host
			"mysql.password": parameter.mysql.password
			"mysql.port":     parameter.mysql.port
			"mysql.user":     parameter.mysql.user
		}
		kind: "ConfigMap"
		metadata: {
			name: context.name + "-nacos-config"
		}
	}
	outputs: {
		nacos: {
			apiVersion: "apps/v1"
			kind:       "StatefulSet"
			metadata: {
				name: context.name + "-nacos"
			}
			spec: {
				selector: matchLabels: app: context.name + "-nacos"
				replicas:    1
				serviceName: context.name + "-nacos-headless"
				template: {
					metadata: labels: app:context.name + "-nacos"
					spec: containers: [{
						name: "nacos"
						env: [{
							name: "MYSQL_SERVICE_HOST"
							valueFrom: configMapKeyRef: {
								name: context.name + "-nacos-config"
								key:  "mysql.host"
							}
						}, {
							name: "MYSQL_SERVICE_DB_NAME"
							valueFrom: configMapKeyRef: {
								name: context.name + "-nacos-config"
								key:  "mysql.db.name"
							}
						}, {
							name: "MYSQL_SERVICE_PORT"
							valueFrom: configMapKeyRef: {
								name: context.name + "-nacos-config"
								key:  "mysql.port"
							}
						}, {
							name: "MYSQL_SERVICE_USER"
							valueFrom: configMapKeyRef: {
								name: context.name + "-nacos-config"
								key:  "mysql.user"
							}
						}, {
							name: "MYSQL_SERVICE_PASSWORD"
							valueFrom: configMapKeyRef: {
								name: context.name + "-nacos-config"
								key:  "mysql.password"
							}
						}, {
							name:  "MODE"
							value: "standalone"
						}, {
							name:  "NACOS_SERVER_PORT"
							value: "8848"
						}]
						ports: [{
							name:          "client"
							containerPort: 8848
						}]
						image:           "nacos/nacos-server:2.0.2"
					}]
				}
			}
		}
		"nacos-headless": {
			apiVersion: "v1"
			kind:       "Service"
			metadata: {
				name:      context.name + "-nacos-headless"
				labels: app: context.name + "-nacos"
			}
			spec: {
				clusterIP: "None"
				ports: [{
					name:       "server"
					port:       8848
					targetPort: 8848
				}]
				selector: app: context.name + "-nacos"
			}
		}
		"nacos-service": {
			apiVersion: "v1"
			kind:       "Service"
			metadata: {
				name:      context.name + "-nacos-service"
			}
			spec: {
				ports: [{
					name:       "http"
					port:       8848
					targetPort: 8848
					if parameter.serviceType == "NodePort" {
					  nodePort:   parameter.nodePort
					}
					protocol:   "TCP"
				}]
				selector: app: context.name + "-nacos"
				type: parameter.serviceType
			}
		}
		secret: {
		apiVersion: "v1"
		kind:       "Secret"
		metadata: {
			name: context.name + "-nacos-secret"
		}
		type: "Opaque"
		data: {
			url: base64.Encode(null,context.name + "-nacos-service." + context.namespace + ".svc.cluster.local:8848")
		}
	}
	}
	parameter: {
		mysql: {
			db: *"nacos" | string
			host: *"mysql.default.svc.cluster.local" | string
			port: *"3306" | string
			user: *"root" | string
			password: *"123456" | string
		}
		serviceType: *"ClusterIP" | "NodePort"
    nodePort ?: *30002 | int
	}
}

cue语法可以参考:

cue

其实我这里也不是从零开始写的cue文件,而是通过vela def init nacos -t component --desc "My nacos component." --template-yaml ./nacos.yaml -o nacos.cue这个命令将yaml文件生成cue文件,然后在此基础上更改的。

也就是说编写组件的流程是:

1.先写好一个yaml文件,即普通的k8s资源清单,比如:

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis
  namespace: redis
  labels:
    app: redis
spec:
  replicas: 1
  selector:
    matchLabels:
      app: redis
  template:
    metadata:
      labels:
        app: redis
    spec:
      containers:
        - name: redis
          image: redis:6.2.6
          command:
            - "sh"
            - "-c"
            - "redis-server /usr/local/etc/redis/redis.conf"
          ports:
            - containerPort: 6379
          volumeMounts:
            - name: data
              mountPath: /data
            - name: config
              mountPath: /usr/local/etc/redis/redis.conf
              subPath: redis.conf
      volumes:
        - name: data
          hostPath:
            path: /home/k8s/redis/data
        - name: config
          configMap:
            name: redis-config

2.通过vela def init {component-name} -t component --desc "xxx" --template-yaml ./xxx.yaml -o xxx.cue命令,生成cue文件

3.修改cue文件,完成组件编写

在cue文件中,我这里使用了encoding/base64,将ip,password,port存入了一个secret中,这是因为kubevela在部署应用的时候,可以通过一个叫service-binding的一个trait,将secret映射到pod的环境变量中

CUE 有很多 internal packages 可以被 KubeVela 使用,这样可以满足更多的开发需求。

安装插件

当前kubevela(1.2版本)通过UX在页面上只能添加github或者aliyunOSS的插件,本地插件,gitlab中的插件不支持,所以这里使用CLI命令安装

# 进入插件代码目录
$ cd /home/kubevela-addon
$ vela addon enable /home/kubevela-addon

# 查看插件是否安装成功
$ vela addon ls
# 查看插件中定义的component
$ vela component

部署应用

还记得我们的工程中是如何配置中间件和数据库的吗?

是使用环境变量的方式

为什么要这样去配置呢?

因为kubevela在部署应用的时候,可以通过一个叫service-binding的一个trait,将secret映射到pod的环境变量中

这样就能达到在不同环境中,自定义组件配置的目的

在部署之前,我们需要对数据库进行初始化,在编写mysql.cue的时候,有这样一段:

             {
								if parameter.initdb != _|_{
								  name:  context.name + "-mysql-initdb"
								  mountPath: "/docker-entrypoint-initdb.d"
								}
						    }
						]
						}]
						volumes: [
              ...
              ,{
					     if parameter.initdb != _|_		{
							     name: context.name + "-mysql-initdb"
							     configMap: name: parameter.initdb

这里的意思是将configmap与容器中docker-entrypoint-initdb.d这个目录关联起来。

根据MySQL Docker镜像README,与容器启动时的数据初始化相关的部分是确保你所有的初始化文件都挂载到容器的//docker-entrypoint-initdb.d文件夹

所以我们要先创建一个configmap,初始化nacos的库

apiVersion: v1
data:
  initdb.sql: |
    CREATE TABLE `config_info` (
      `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
      `data_id` varchar(255) NOT NULL COMMENT 'data_id',
      `group_id` varchar(255) DEFAULT NULL,
      `content` longtext NOT NULL COMMENT 'content',
      `md5` varchar(32) DEFAULT NULL COMMENT 'md5',
      `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
      `gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',
      `src_user` text COMMENT 'source user',
      `src_ip` varchar(50) DEFAULT NULL COMMENT 'source ip',
      `app_name` varchar(128) DEFAULT NULL,
      `tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段',
      `c_desc` varchar(256) DEFAULT NULL,
      `c_use` varchar(64) DEFAULT NULL,
      `effect` varchar(64) DEFAULT NULL,
      `type` varchar(64) DEFAULT NULL,
      `c_schema` text,
      PRIMARY KEY (`id`),
      UNIQUE KEY `uk_configinfo_datagrouptenant` (`data_id`,`group_id`,`tenant_id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_info';

    CREATE TABLE `config_info_aggr` (
      `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
      `data_id` varchar(255) NOT NULL COMMENT 'data_id',
      `group_id` varchar(255) NOT NULL COMMENT 'group_id',
      `datum_id` varchar(255) NOT NULL COMMENT 'datum_id',
      `content` longtext NOT NULL COMMENT '内容',
      `gmt_modified` datetime NOT NULL COMMENT '修改时间',
      `app_name` varchar(128) DEFAULT NULL,
      `tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段',
      PRIMARY KEY (`id`),
      UNIQUE KEY `uk_configinfoaggr_datagrouptenantdatum` (`data_id`,`group_id`,`tenant_id`,`datum_id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='增加租户字段';

    CREATE TABLE `config_info_beta` (
      `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
      `data_id` varchar(255) NOT NULL COMMENT 'data_id',
      `group_id` varchar(128) NOT NULL COMMENT 'group_id',
      `app_name` varchar(128) DEFAULT NULL COMMENT 'app_name',
      `content` longtext NOT NULL COMMENT 'content',
      `beta_ips` varchar(1024) DEFAULT NULL COMMENT 'betaIps',
      `md5` varchar(32) DEFAULT NULL COMMENT 'md5',
      `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
      `gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',
      `src_user` text COMMENT 'source user',
      `src_ip` varchar(50) DEFAULT NULL COMMENT 'source ip',
      `tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段',
      PRIMARY KEY (`id`),
      UNIQUE KEY `uk_configinfobeta_datagrouptenant` (`data_id`,`group_id`,`tenant_id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_info_beta';

    CREATE TABLE `config_info_tag` (
      `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
      `data_id` varchar(255) NOT NULL COMMENT 'data_id',
      `group_id` varchar(128) NOT NULL COMMENT 'group_id',
      `tenant_id` varchar(128) DEFAULT '' COMMENT 'tenant_id',
      `tag_id` varchar(128) NOT NULL COMMENT 'tag_id',
      `app_name` varchar(128) DEFAULT NULL COMMENT 'app_name',
      `content` longtext NOT NULL COMMENT 'content',
      `md5` varchar(32) DEFAULT NULL COMMENT 'md5',
      `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
      `gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',
      `src_user` text COMMENT 'source user',
      `src_ip` varchar(50) DEFAULT NULL COMMENT 'source ip',
      PRIMARY KEY (`id`),
      UNIQUE KEY `uk_configinfotag_datagrouptenanttag` (`data_id`,`group_id`,`tenant_id`,`tag_id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_info_tag';

    CREATE TABLE `config_tags_relation` (
      `id` bigint(20) NOT NULL COMMENT 'id',
      `tag_name` varchar(128) NOT NULL COMMENT 'tag_name',
      `tag_type` varchar(64) DEFAULT NULL COMMENT 'tag_type',
      `data_id` varchar(255) NOT NULL COMMENT 'data_id',
      `group_id` varchar(128) NOT NULL COMMENT 'group_id',
      `tenant_id` varchar(128) DEFAULT '' COMMENT 'tenant_id',
      `nid` bigint(20) NOT NULL AUTO_INCREMENT,
      PRIMARY KEY (`nid`),
      UNIQUE KEY `uk_configtagrelation_configidtag` (`id`,`tag_name`,`tag_type`),
      KEY `idx_tenant_id` (`tenant_id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_tag_relation';

    CREATE TABLE `group_capacity` (
      `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
      `group_id` varchar(128) NOT NULL DEFAULT '' COMMENT 'Group ID,空字符表示整个集群',
      `quota` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '配额,0表示使用默认值',
      `usage` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '使用量',
      `max_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个配置大小上限,单位为字节,0表示使用默认值',
      `max_aggr_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '聚合子配置最大个数,,0表示使用默认值',
      `max_aggr_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个聚合数据的子配置大小上限,单位为字节,0表示使用默认值',
      `max_history_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '最大变更历史数量',
      `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
      `gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',
      PRIMARY KEY (`id`),
      UNIQUE KEY `uk_group_id` (`group_id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='集群、各Group容量信息表';

    CREATE TABLE `his_config_info` (
      `id` bigint(64) unsigned NOT NULL,
      `nid` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
      `data_id` varchar(255) NOT NULL,
      `group_id` varchar(128) NOT NULL,
      `app_name` varchar(128) DEFAULT NULL COMMENT 'app_name',
      `content` longtext NOT NULL,
      `md5` varchar(32) DEFAULT NULL,
      `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
      `gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
      `src_user` text,
      `src_ip` varchar(50) DEFAULT NULL,
      `op_type` char(10) DEFAULT NULL,
      `tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段',
      PRIMARY KEY (`nid`),
      KEY `idx_gmt_create` (`gmt_create`),
      KEY `idx_gmt_modified` (`gmt_modified`),
      KEY `idx_did` (`data_id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='多租户改造';

    CREATE TABLE `tenant_capacity` (
      `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
      `tenant_id` varchar(128) NOT NULL DEFAULT '' COMMENT 'Tenant ID',
      `quota` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '配额,0表示使用默认值',
      `usage` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '使用量',
      `max_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个配置大小上限,单位为字节,0表示使用默认值',
      `max_aggr_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '聚合子配置最大个数',
      `max_aggr_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个聚合数据的子配置大小上限,单位为字节,0表示使用默认值',
      `max_history_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '最大变更历史数量',
      `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
      `gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',
      PRIMARY KEY (`id`),
      UNIQUE KEY `uk_tenant_id` (`tenant_id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='租户容量信息表';

    CREATE TABLE `tenant_info` (
      `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
      `kp` varchar(128) NOT NULL COMMENT 'kp',
      `tenant_id` varchar(128) default '' COMMENT 'tenant_id',
      `tenant_name` varchar(128) default '' COMMENT 'tenant_name',
      `tenant_desc` varchar(256) DEFAULT NULL COMMENT 'tenant_desc',
      `create_source` varchar(32) DEFAULT NULL COMMENT 'create_source',
      `gmt_create` bigint(20) NOT NULL COMMENT '创建时间',
      `gmt_modified` bigint(20) NOT NULL COMMENT '修改时间',
      PRIMARY KEY (`id`),
      UNIQUE KEY `uk_tenant_info_kptenantid` (`kp`,`tenant_id`),
      KEY `idx_tenant_id` (`tenant_id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='tenant_info';

    CREATE TABLE `users` (
        `username` varchar(50) NOT NULL PRIMARY KEY,
        `password` varchar(500) NOT NULL,
        `enabled` boolean NOT NULL
    );

    CREATE TABLE `roles` (
        `username` varchar(50) NOT NULL,
        `role` varchar(50) NOT NULL,
        UNIQUE INDEX `idx_user_role` (`username` ASC, `role` ASC) USING BTREE
    );

    CREATE TABLE `permissions` (
        `role` varchar(50) NOT NULL,
        `resource` varchar(255) NOT NULL,
        `action` varchar(8) NOT NULL,
        UNIQUE INDEX `uk_role_permission` (`role`,`resource`,`action`) USING BTREE
    );

    INSERT INTO users (username, password, enabled) VALUES ('nacos', '$2a$10$EuWPZHzz32dJN7jexM34MOeYirDdFAZm2kuWj7VEOJhhZkDrxfvUu', TRUE);

    INSERT INTO roles (username, role) VALUES ('nacos', 'ROLE_ADMIN');
kind: ConfigMap
metadata:
  name: web-demo-initdb
  namespace: default

Kubevela 部署文件deploy.yaml

apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
  name: web-demo
  namespace: default
spec:
  components:
    - name: redis
      type: myredis
      properties:
        serviceType: NodePort
    - name: mysql
      type: mysql
      properties:
        serviceType: NodePort
        database: nacos
        initdb: web-demo-initdb
    - name: nacos
      type: nacos
      properties:
        serviceType: NodePort
        mysql:
          host: web-demo-mysql-service.default.svc.cluster.local
    - name: alpha
      type: webservice
      properties:
        image: harbor.dev.wh.digitalchina.com/kubevela/labrador-service-alpha:latest
        port: 8090
      traits:
        - type: service-binding
          properties:
            envMappings:
              NACOS_SERVER_ADDR:
                secret: nacos-nacos-secret
                key: url
              DB_URL:
                secret: mysql-mysql-secret
                key: url
              DB_PASSWORD:
                secret: mysql-mysql-secret
                key: password
    - name: beta
      type: webservice
      properties:
        image: harbor.dev.wh.digitalchina.com/kubevela/labrador-service-beta:latest
        port: 9090
      traits:
        - type: service-binding
          properties:
            envMappings:
              NACOS_SERVER_ADDR:
                secret: nacos-nacos-secret
                key: url
              REDIS_IP:
                secret: redis-myredis-secret
                key: ip
              REDIS_PASSWORD:
                secret: redis-myredis-secret
                key: password
              REDIS_PORT:
                secret: redis-myredis-secret
                key: port
    - name: aggregation
      type: webservice
      properties:
        image: harbor.dev.wh.digitalchina.com/kubevela/labrador-service-aggregation:latest
        port: 8080
      traits:
        - type: service-binding
          properties:
            envMappings:
              NACOS_SERVER_ADDR:
                secret: nacos-nacos-secret
                key: url
    - name: service
      type: k8s-objects
      properties:
        objects:
        - apiVersion: v1
          kind: Service
          metadata:
            name: web
          labels:
            app: web
          spec:
            type: NodePort
            ports:
              - name: web
                port: 8080
                targetPort: 8080
                nodePort: 30080
            selector:
              app.oam.dev/component: aggregation

使用service-bindingsecret中的值,注入到pod的环境变量中

使用命令部署

# 部署
$ vela up -f deploy.yaml

# 查看应用
$ vela ls

# 查看应用状态
$ vela status web-demo

登录nacos,服务成功注册

登录aggregation 服务的knife4j页面,调用接口

访问数据库成功

访问redis成功

posted @ 2022-03-17 16:20  硝酸铜  阅读(331)  评论(0编辑  收藏  举报