kubevela addon添加组件-微服务应用
addon添加组件-微服务应用
背景:公司最近在研究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文件,而是通过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-binding
拿secret
中的值,注入到pod的环境变量中
使用命令部署
# 部署
$ vela up -f deploy.yaml
# 查看应用
$ vela ls
# 查看应用状态
$ vela status web-demo
登录nacos,服务成功注册
登录aggregation 服务的knife4j页面,调用接口
访问数据库成功
访问redis成功