Kubernetes部署Nacos2.0.1集群

Kubernetes部署Nacos2.0.1集群

鲜花的主人 845 2021-03-04

系统环境:

  • Nacos 版本:2.0.1
  • Mysql 版本:5.7
  • Kubernetes 版本:1.20.0

什么是 Nacos

Nacos 是阿里开源的服务注册中心与配置中心组件,能够帮助开发人员快速实现动态服务发现、服务配置、服务元数据及流量管理。同时能够与 SpringCloud、Kubernetes、Dubbo 等开源生态无缝集成
Nacos 支持如下核心特性:

  • 服务发现: 支持 DNS 与 RPC 服务发现,也提供原生 SDK 、OpenAPI 等多种服务注册方式和 DNS、HTTP 与 API 等多种服务发现方式
  • 服务健康监测: Nacos 提供对服务的实时的健康检查,阻止向不健康的主机或服务实例发送请求
  • 动态配置服务: Nacos 提供配置统一管理功能,能够帮助我们将配置以中心化、外部化和动态化的方式管理所有环境的应用配置和服务配置
  • 动态 DNS 服务: Nacos 支持动态 DNS 服务权重路由,能够让我们很容易地实现中间层负载均衡、更灵活的路由策略、流量控制以及数据中心内网的简单 DNS 解析服务
  • 服务及其元数据管理: Nacos 支持从微服务平台建设的视角管理数据中心的所有服务及元数据,包括管理服务的描述、生命周期、服务的静态依赖分析、服务的健康状态、服务的流量管理、路由及安全策略、服务的 SLA 以及最首要的metrics 统计数据

部署Mysql

Nacos需要提前部署Mysql,目前支持5.7及8.0版本,可参考Kubernetes部署Mysql

导入SQL相关数据

等数据库创建完成后,还需要导入 SQL 文件来创建它的表结构和一些基础数据。操作如下,我们进入Mysql客户端,执行 source命令导入SQL文件

[root@k8s01 nacos]# mysql -uroot -pxxxxx
mysql> source /xxx/nacos.sql

也可通过Navicat工具执行

[root@k8s01 nacos]# cat nacos.sql
CREATE DATABASE nacos_config_cluster;
USE nacos_config_cluster;

/******************************************/
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 '2010-05-05 00:00:00' COMMENT '创建时间',
  `gmt_modified` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '修改时间',
  `src_user` text COMMENT 'source user',
  `src_ip` varchar(20) 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';

/******************************************/
/*   数据库全名 = nacos_config   */
/*   表名称 = config_info_aggr   */
/******************************************/
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='增加租户字段';


/******************************************/
/*   数据库全名 = nacos_config   */
/*   表名称 = config_info_beta   */
/******************************************/
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 '2010-05-05 00:00:00' COMMENT '创建时间',
  `gmt_modified` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '修改时间',
  `src_user` text COMMENT 'source user',
  `src_ip` varchar(20) 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';

/******************************************/
/*   数据库全名 = nacos_config   */
/*   表名称 = config_info_tag   */
/******************************************/
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 '2010-05-05 00:00:00' COMMENT '创建时间',
  `gmt_modified` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '修改时间',
  `src_user` text COMMENT 'source user',
  `src_ip` varchar(20) 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';

/******************************************/
/*   数据库全名 = nacos_config   */
/*   表名称 = config_tags_relation   */
/******************************************/
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';

/******************************************/
/*   数据库全名 = nacos_config   */
/*   表名称 = group_capacity   */
/******************************************/
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 '2010-05-05 00:00:00' COMMENT '创建时间',
  `gmt_modified` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '修改时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_group_id` (`group_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='集群、各Group容量信息表';

/******************************************/
/*   数据库全名 = nacos_config   */
/*   表名称 = his_config_info   */
/******************************************/
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 '2010-05-05 00:00:00',
  `gmt_modified` datetime NOT NULL DEFAULT '2010-05-05 00:00:00',
  `src_user` text,
  `src_ip` varchar(20) 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='多租户改造';


/******************************************/
/*   数据库全名 = nacos_config   */
/*   表名称 = tenant_capacity   */
/******************************************/
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 '2010-05-05 00:00:00' COMMENT '创建时间',
  `gmt_modified` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' 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,
    constraint uk_username_role UNIQUE (username,role)
);

CREATE TABLE permissions (
    role varchar(50) NOT NULL,
    resource varchar(512) NOT NULL,
    action varchar(8) NOT NULL,
    constraint uk_role_permission UNIQUE (role,resource,action)
);

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

INSERT INTO roles (username, role) VALUES ('nacos', 'ROLE_ADMIN');

部署Nacos

部署Nacos集群模式,整体如下示意图,Kubernetes 中创建一个 Service,Service 关联Nacos中的多个Pod,一个Pod就是Nacos节点,Pod之间通过该Service进行交互,最后我们会配置一个NodePort方式对外访问,当然,你如果你的 Kubernetes 集群已经部署了 Ingress Controller 则可以创建 Ingress 规则对外提供访问
nacos1.png

创建RBAC资源

nacos-rbac.yaml

[root@k8s01 nacos]# vim nacos-rbac.yaml 
apiVersion: v1
kind: ServiceAccount
metadata:
  name: nacos-admin
  namespace: tools-env
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: nacos-admin-clusterrole
rules:
- apiGroups: [""]
  resources: ["persistentvolumes"]
  verbs: ["get", "list", "watch", "create", "delete"]
- apiGroups: [""]
  resources: ["persistentvolumeclaims"]
  verbs: ["get", "list", "watch", "update"]
- apiGroups: [""]
  resources: ["endpoints"]
  verbs: ["get", "list", "watch", "create", "update", "patch"]
- apiGroups: ["storage.k8s.io"]
  resources: ["storageclasses"]
  verbs: ["get", "list", "watch"]
- apiGroups: [""]
  resources: ["events"]
  verbs: ["create", "update", "patch"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: nacos-admin-binding
subjects:
- kind: ServiceAccount
  name: nacos-admin
  namespace: tools-env
roleRef:
  kind: ClusterRole
  name: nacos-admin-clusterrole
  apiGroup: rbac.authorization.k8s.io
  
[root@k8s01 nacos]# kubectl apply -f nacos-rbac.yaml
serviceaccount/nacos-admin created
clusterrole.rbac.authorization.k8s.io/nacos-admin-clusterrole created
clusterrolebinding.rbac.authorization.k8s.io/nacos-admin-binding created

创建数据库配置ConfigMap资源

nacos-config.yaml

[root@k8s01 nacos]# vim nacos-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: nacos-config
  namespace: tools-env
data:
  SERVICE_NAME: "nacos-headless"
  DOMAIN_NAME: "cluster.local"
  NACOS_REPLICAS: "3"
  PREFER_HOST_MODE: "hostname"
  NACOS_SERVER_PORT: "8848"
  NACOS_APPLICATION_PORT: "8848"
  JVM_XMX: "2g"
  JVM_XMS: "2g"
  JVM_XMN: "1g"
  MYSQL_SERVICE_HOST: "10.66.xxx.xxx"
  MYSQL_SERVICE_DB_NAME: "nacos_config_cluster"
  MYSQL_SERVICE_PORT: "3306"
  MYSQL_SERVICE_USER: "root"
  MYSQL_SERVICE_PASSWORD: "xxxxxx"
  
[root@k8s01 nacos]# kubectl apply -f nacos-config.yaml
configmap/nacos-config created

参数说明:

  • MYSQL_SERVICE_HOST:数据库地址(这里使用上面部署的 Mysql,由于部署在 K8S 里面,所以使用 Mysql Service 提供的 K8S 内部地址)
  • MYSQL_SERVICE_PORT: 数据库端口
  • MYSQL_SERVICE_DB_NAME: 指定使用的库名称
  • MYSQL_SERVICE_USER: 数据库用户名
  • MYSQL_SERVICE_PASSWORD: 数据库密码
  • NACOS_APPLICATION_PORT:指定 Nacos 端口号
  • PREFER_HOST_MODE:配置 Nacos 集群节点间服务发现使用的模式,支持 hostname、ip 两种模式
  • JVM_XMS: 设置 JVM 最大堆内存大小
  • JVM_XMX: 设置 JVM 最初是堆内存大小
  • JVM_XMN: 设置 JVM 堆内新生代的内存大小
  • SERVICE_NAME:指定 Nacos 部署在 K8S 中的 Service 名称
  • DOMAIN_NAME:指定 k8s domain 配置,一般默认即可

创建Nacos应用

nacos-deploy.yaml

[root@k8s01 nacos]# vim nacos-deploy.yaml
apiVersion: v1
kind: Service
metadata:
  name: nacos-headless
  namespace: tools-env
  labels:
    app: nacos
spec:
  ports:
    - name: server
      port: 8848
      targetPort: 8848
    - name: rpc
      port: 7848
      targetPort: 7848
  clusterIP: None
  selector:
    app: nacos
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: nacos
  namespace: tools-env
spec:
  serviceName: nacos-headless
  replicas: 3
  template:
    metadata:
      labels:
        app: nacos
    spec:
      terminationGracePeriodSeconds: 10  #配置优雅停机时间
      serviceAccountName: nacos-admin    #分配服务账户给应用,方便应用能够获取一定的权限
      initContainers:                    #初始化镜像执行初始化操作
        - name: peer-finder-plugin-install
          image: nacos/nacos-peer-finder-plugin:1.0
          imagePullPolicy: IfNotPresent
          volumeMounts:
            - mountPath: "/home/nacos/plugins/peer-finder"
              name: plugindir
      affinity:    #配置Pod反亲和性,放置Pod都起在同一节点上(如果都在一个节点,节点宕机将会使全部实例不可用)       
          podAntiAffinity:    
            requiredDuringSchedulingIgnoredDuringExecution: #硬策略,pod一定不能启在同一个节点上
              - topologyKey: "kubernetes.io/hostname"
                labelSelector:
                  matchExpressions:
                    - key: "app"
                      operator: In
                      values:
                        - nacos
      containers:
        - name: nacos
          image: nacos/nacos-server:2.0.1
          imagePullPolicy: IfNotPresent
          resources:
            limits:
              cpu: 2
              memory: "2Gi"
            requests:
              cpu: 100m
              memory: "1Gi"
          ports:
            - name: client-port
              containerPort: 8848
            - name: rpc
              containerPort: 7848
          envFrom:
            - configMapRef:
                name: nacos-config
          env:
            - name: POD_NAMESPACE
              valueFrom:
                fieldRef:
                  apiVersion: v1
                  fieldPath: metadata.namespace
          volumeMounts:
            - name: plugindir
              mountPath: /home/nacos/plugins/peer-finder
            - name: datadir
              mountPath: /home/nacos/data
            - name: logdir
              mountPath: /home/nacos/logs
  volumeClaimTemplates:
    - metadata:
        name: plugindir
      spec:
        storageClassName: managed-nfs-storage #指定storageclass名称,这里需要根据你的K8S集群进行修改
        accessModes: ["ReadWriteMany"]
        resources:
          requests:
            storage: 5Gi
    - metadata:
        name: datadir
      spec:
        storageClassName: managed-nfs-storage
        accessModes: ["ReadWriteMany"]
        resources:
          requests:
            storage: 5Gi
    - metadata:
        name: logdir
      spec:
        storageClassName: managed-nfs-storage
        accessModes: ["ReadWriteMany"]
        resources:
          requests:
            storage: 5Gi
  selector:
    matchLabels:
      app: nacos

配置中使用的是 StatefulSet 资源创建的 Nacos,所以需要存储驱动支持 StorageClass 来动态创建 PVC,这里使用的 NFS,并且使用 nfs-client-provisioner 插件来动态创建 PVC

暴露Nacos对外访问

我们再创建一个Service资源,设置其类型为NodePort 方式,NodePort端口为30848,可以通过IP:30848来访问,也可通过配置Ingress来实现域名访问,本文通过Ingress配置访问

[root@k8s01 nacos]# vim nacos-ing.yaml 
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: nacos-ing
  namespace: tools-env
  annotations:
    kubernetes.io/ingress.class: "nginx"
spec:
  rules:
  - host: nacos.xxx.com (根据实际域名填写)
    http:
      paths:
      - path: /
        backend:
          serviceName: nacos-headless
          servicePort: 8848

[root@k8s01 nacos]# kubectl apply -f nacos-ing.yaml 
ingress.extensions/nacos-ing configured

访问Nacos进行测试

如若本地部署的话,建议使用暴露nodeport端口访问,通过域名的话需要解析或者写入本地host,由于 Nacos 默认会带上前缀 /nacos,所以我们可以输入nacos.xxxx.com/nacos访问 Nacos 页面
nacos2.png
用户名/密码: nacos/nacos ,登录 Nacos 后会看到如下页面
nacos3.png