百度360必应搜狗淘宝本站头条
当前位置:网站首页 > IT技术 > 正文

[nacos] 基于Docker安装Nacos

wptr33 2025-02-10 14:37 16 浏览

目录

  • 0 序
  • 1 安装步骤(nacos/nacos-server镜像方式)
    • Step1 拉取镜像
    • Step2 创建、并运行 Nacos Server Demo 容器
    • Step3 在宿主机中创建持久化文件目录(日志/核心配置)
    • Step4 MySQL(5.7)数据库初始化
      • 创建数据库
      • 创建用户
      • 创建表
    • Step5 修改配置文件(application.properties)
    • Step6 重建正式的 Nacos Server 容器
  • Y 扩展:nacos身份认证与鉴权
    • Y.1 Nacos启用身份认证/鉴权
      • Y.1.1 非Docker环境
      • Y.1.2 Docker环境
    • Y.2 客户端如何进行鉴权
      • Y.2.1 Java SDK鉴权
      • Y.2.2 其他语言的SDK鉴权
      • Y.2.x 身份鉴权测试类 NacosConfigTest
    • Y.3 开启服务身份识别功能
    • Y.4 旧版本升级
  • H 扩展:应用场景合集
    • 场景:指定NACOS注册中心中spring cloud微服务应用的IP
  • K 扩展:Nacos 2.x 新特性
    • K.1 新增端口
  • X 参考文献

0 序

  • Nacos(配置中心、注册中心)是分布式系统的核心子系统之一,是国内分布式系统/微服务领域的事实标准、事实上的唯一选择。
  • 环境信息

centos : 7.9docker : 25.0.4mysql : 5.7.xnacos-server : 2.1.1 (部署模式: nacos standalone / 单机mysql5.7)
注:调研了多个版本后的结论————不同nacos-server版本之间的差异较大,容器内的目录结构、脚本等变化较大。
注:v2.1.1 与 v2.0.3 的区别:1、镜像版本不同;2、mysql数据库脚本不同;(容器内的文件、目录结构,尚未发现差异点)

回到顶部(Back to Top)

1 安装步骤(nacos/nacos-server镜像方式)

Step1 拉取镜像

docker pull nacos/nacos-server:v2.1.1

docker images

Step2 创建、并运行 Nacos Server Demo 容器

  • 创建、并运行 Nacos Demo 容器
docker run --name demo-nacos-server \
-p 8848:8848 \
-p 9848:9848 \
-p 9849:9849 \
--privileged=true \
--restart=always \
-e JVM_XMS=256m \
-e JVM_XMX=256m \
-e MODE=standalone \
-e PREFER_HOST_MODE=hostname \
-d nacos/nacos-server:v2.1.1

docker ps -a
  • 访问 Nacos Server Demo 容器


http://127.0.0.1:8848/nacos/index.html

账号 / 密码 【默认】 : nacos / nacos

Step3 在宿主机中创建持久化文件目录(日志/核心配置)

  • 在宿主机中创建日志、配置目录
mkdir -p /data/nacos/logs
 
mkdir -p /data/nacos/conf
  • 从Demo容器中拷贝默认配置到宿主机中
docker exec -it demo-nacos-server sh -c "ls -la /home/nacos/conf"

docker cp demo-nacos-server:/home/nacos/conf/application.properties /data/nacos/conf/

# 拷贝 mysql 8 的 ddl sql : schema.sql (本教程中,实际不会使用)
docker cp demo-nacos-server:/home/nacos/conf/schema.sql /data/nacos/conf/
# nacos-server : 2.1.1 的docker镜像中漏掉了 mysql 5.7 的 ddl sql : nacos-mysql | 详情参加: https://github.com/alibaba/nacos/releases/tag/2.1.1 的 release 包

# 拷贝 ipv6的补丁 ddl sql : 1.4.0-ipv6_support-update.sql
docker cp demo-nacos-server:/home/nacos/conf/1.4.0-ipv6_support-update.sql /data/nacos/conf/

docker cp demo-nacos-server:/home/nacos/conf/nacos-logback.xml /data/nacos/conf/nacos-logback.xml

ls -la /data/nacos/conf/

nacos-server-2.1.1.zip 中存在 mysql 5.7 的 ddl 脚本

Step4 MySQL(5.7)数据库初始化

创建数据库

CREATE DATABASE nacos DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

创建用户

CREATE USER nacos@'%';
ALTER USER nacos@'%' IDENTIFIED BY 'nacosPassword';
GRANT ALL PRIVILEGES ON nacos.* TO nacos@'%';
FLUSH PRIVILEGES;

SHOW GRANTS FOR 'nacos'@'%'; -- localhost

use nacos; -- 使用 nacos 数据库

创建表

  • 执行 : nacos-mysql.sql

脚本内容来源于 :
https://github.com/alibaba/nacos/releases/tag/2.1.1 的
nacos-server-2.1.1.zip 包的conf目录的nacos-mysql.sql脚本文件
或参见:
https://github.com/alibaba/nacos/blob/2.1.1/distribution/conf/nacos-mysql.sql

/*
 * Copyright 1999-2018 Alibaba Group Holding Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/******************************************/
/*   数据库全名 = nacos_config   */
/*   表名称 = config_info   */
/******************************************/
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,
  `encrypted_data_key` text NOT NULL COMMENT '秘钥',
  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 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 '租户字段',
  `encrypted_data_key` text NOT NULL 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 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';

/******************************************/
/*   数据库全名 = 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 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容量信息表';

/******************************************/
/*   数据库全名 = nacos_config   */
/*   表名称 = his_config_info   */
/******************************************/
CREATE TABLE `his_config_info` (
  `id` bigint(20) 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 '租户字段',
  `encrypted_data_key` text NOT NULL 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 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');

  • 1.4.0-ipv6_support-update.sql
ALTER TABLE `config_info_tag`
MODIFY COLUMN `src_ip` varchar(50) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT 'source ip' AFTER `src_user`;

ALTER TABLE `his_config_info`
MODIFY COLUMN `src_ip` varchar(50) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL AFTER `src_user`;

ALTER TABLE `config_info`
MODIFY COLUMN `src_ip` varchar(50) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT 'source ip' AFTER `src_user`;

ALTER TABLE `config_info_beta`
MODIFY COLUMN `src_ip` varchar(50) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT 'source ip' AFTER `src_user`;

Step5 修改配置文件(application.properties)

  • vi /data/nacos/conf/application.properties

修改如下配置项

...

#spring.datasource.platform=${SPRING_DATASOURCE_PLATFORM:""}
spring.datasource.platform=${SPRING_DATASOURCE_PLATFORM:"mysql"}

...

db.num=${MYSQL_DATABASE_NUM:1}
# db.url.0=jdbc:mysql://127.0.0.1:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useSSL=false
db.url.0=jdbc:mysql://${MYSQL_SERVICE_HOST}:${MYSQL_SERVICE_PORT:3306}/${MYSQL_SERVICE_DB_NAME:nacos}?${MYSQL_SERVICE_DB_PARAM:characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&auto
Reconnect=true&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true}
# [注释此行] db.url.1=jdbc:mysql://${MYSQL_SERVICE_HOST}:${MYSQL_SERVICE_PORT:3306}/${MYSQL_SERVICE_DB_NAME}?${MYSQL_SERVICE_DB_PARAM:characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&aut
oReconnect=true&useSSL=false}
db.user=${MYSQL_SERVICE_USER}
db.password=${MYSQL_SERVICE_PASSWORD}

...

#server.tomcat.basedir=
server.tomcat.basedir=file:.

...

Step6 重建正式的 Nacos Server 容器

  • 删除正在运行的 Nacos Demo 容器,重新用命令创建启动
docker stop demo-nacos-server

docker rm demo-nacos-server
  • 启动 正式的 Nacos Server 容器
docker run --name nacos-server \
-p 18848:8848 \
-p 19848:9848 \
-p 19849:9849 \
--privileged=true \
--restart=always \
-e SPRING_DATASOURCE_PLATFORM=mysql \
-e NACOS_AUTH_ENABLE=true \
-e MYSQL_SERVICE_HOST="172.17.0.1" \
-e "MYSQL_SERVICE_PORT=33060" \
-e MYSQL_SERVICE_DB_NAME=nacos \
-e MYSQL_SERVICE_USER=nacos \
-e MYSQL_SERVICE_PASSWORD="123456" \
-e JVM_XMS=256m \
-e JVM_XMX=256m \
-e MODE=standalone \
-e PREFER_HOST_MODE=hostname \
-v /data/nacos/logs:/home/nacos/logs \
-v /data/nacos/conf/:/home/nacos/conf/ \
-d nacos/nacos-server:v2.1.1

NACOS_AUTH_ENABLE=true : 开启身份鉴权(默认:不开启)。若不开启,有安全风险(可直接调用Nacos Web API,这是高危漏洞)172.17.0.1 : 在Linux系统中,可以使用特殊的IP地址172.17.0.1来代表宿主机,这个IP地址通常用于Docker默认的网络桥接模式中。

注:docker 容器内的 127.0.0.1 ≠ 宿主机中的 127.0.0.1

  • 查看 Nacos Server 容器
docker ps -a
docker logs nacos-server

ls -la /data/nacos/logs

docker exec -it nacos-server sh -c "ls -la /home/nacos/conf/application.properties"
docker exec -it nacos-server sh -c "cat /home/nacos/conf/application.properties"

# ↓ 此命令无效,需进入容器内部才能查看到真实情况
# docker exec -it nacos-server sh -c "echo $MYSQL_SERVICE_HOST"

docker exec -it nacos-server bash
> echo $MYSQL_SERVICE_HOST
> exit

# 宿主机中测验:
curl http://127.0.0.1:18848/nacos
  • 测验:调用Nacos Web API
# 通过Nacos Web API 获取登录accessToken (nacos server开启身份鉴权后,web api request中需依赖此accessToken)
curl -X POST 'http://xx.yy.zz.ff:18848/nacos/v1/auth/login' -d 'username=nacos&password=nacos'
# 注:demo response : {"accessToken":"eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJuYWNvcyIsImV4cCI6MTcxMTYzNzE3NX0.ul940V4eB3aQwsQLeGQqgbnkrL0n45bkeSYBfGvYM2w","tokenTtl":18000,"globalAdmin":true,"username":"nacos"}
# 注:demo 关键内容翻译 : accessToken : '{"alg":"HS256"}.{"sub":"nacos","exp":1711637175}.ul940V4eB3aQwsQLeGQqgbnkrL0n45bkeSYBfGvYM2w'

# 服务注册
# curl -X POST 'http://xx.yy.zz.ff:18848/nacos/v1/ns/instance?serviceName=nacos.naming.serviceName&ip=20.18.7.10&port=8080'
curl -X POST 'http://xx.yy.zz.ff:18848/nacos/v1/ns/instance?serviceName=nacos.naming.serviceName&ip=20.18.7.10&port=8080&accessToken=eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJuYWNvcyIsImV4cCI6MTcxMTYzNzE3NX0.ul940V4eB3aQwsQLeGQqgbnkrL0n45bkeSYBfGvYM2w'

# 服务发现
# curl -X GET 'http://xx.yy.zz.ff:18848/nacos/v1/ns/instance/list?serviceName=nacos.naming.serviceName'
curl -X GET 'http://xx.yy.zz.ff:18848/nacos/v1/ns/instance/list?serviceName=nacos.naming.serviceName&accessToken=eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJuYWNvcyIsImV4cCI6MTcxMTYzNzE3NX0.ul940V4eB3aQwsQLeGQqgbnkrL0n45bkeSYBfGvYM2w'

# 发布配置
# curl -X POST "http://xx.yy.zz.ff:18848/nacos/v1/cs/configs?dataId=nacos.cfg.dataId&group=test&content=HelloWorld"
curl -X POST "http://xx.yy.zz.ff:18848/nacos/v1/cs/configs?dataId=nacos.cfg.dataId&group=test&content=HelloWorld&accessToken=eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJuYWNvcyIsImV4cCI6MTcxMTYzNzE3NX0.ul940V4eB3aQwsQLeGQqgbnkrL0n45bkeSYBfGvYM2w"

# 获取配置
# curl -X GET "http://xx.yy.zz.ff:18848/nacos/v1/cs/configs?dataId=nacos.cfg.dataId&group=test"
curl -X GET "http://xx.yy.zz.ff:18848/nacos/v1/cs/configs?dataId=nacos.cfg.dataId&group=test&accessToken=eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJuYWNvcyIsImV4cCI6MTcxMTYzNzE3NX0.ul940V4eB3aQwsQLeGQqgbnkrL0n45bkeSYBfGvYM2w"

nacos ui

回到顶部(Back to Top)

Y 扩展:nacos身份认证与鉴权

Y.1 Nacos启用身份认证/鉴权

  • 注意

Nacos是一个内部微服务组件,需要在可信的内部网络中运行,不可暴露在公网环境,防止带来安全风险。Nacos提供简单的鉴权实现,为防止业务错用的弱鉴权体系,不是防止恶意攻击的强鉴权体系。如果运行在不可信的网络环境或者有强鉴权诉求,请参考官方简单实现做替换增强。

Y.1.1 非Docker环境

  • 按照官方文档配置启动,默认是不需要登录的,这样会导致配置中心对外直接暴露。而启用鉴权之后,需要在使用用户名和密码登录之后,才能正常使用nacos。
  • 开启鉴权之前,application.properties中的配置信息为:
### If turn on auth system:
nacos.core.auth.enabled=false
  • 开启鉴权之后,application.properties中的配置信息为:
### If turn on auth system:
nacos.core.auth.system.type=nacos
nacos.core.auth.enabled=true
  • 【自定义密钥】
    开启鉴权之后,你可以自定义用于生成JWT令牌的密钥,application.properties中的配置信息为:

注意:
文档中提供的密钥为公开密钥,在实际部署时请更换为其他密钥内容,防止密钥泄漏导致安全风险。
在2.2.1版本后,社区发布版本将移除以文档如下值作为默认值,需要自行填充,否则无法启动节点。
密钥需要保持节点间一致,长时间不一致可能导致403 invalid token错误。

### The default token(Base64 String):
nacos.core.auth.default.token.secret.key=SecretKey012345678901234567890123456789012345678901234567890123456789

自定义密钥时,推荐将配置项设置为Base64编码的字符串,且原始密钥长度不得低于32字符。例如下面的的例子:

### The default token(Base64 String):
nacos.core.auth.default.token.secret.key=VGhpc0lzTXlDdXN0b21TZWNyZXRLZXkwMTIzNDU2Nzg=

注意:鉴权开关是修改之后立马生效的,不需要重启服务端。

Y.1.2 Docker环境

  • 官方镜像

如果使用官方镜像,请在启动docker容器时,添加如下环境变量

NACOS_AUTH_ENABLE=true

例如,可以通过如下命令运行开启了鉴权的容器:

docker run --env PREFER_HOST_MODE=hostname --env MODE=standalone --env NACOS_AUTH_ENABLE=true -p 8848:8848 nacos/nacos-server

除此之外,还可以添加其他鉴权相关的环境变量信息:

name

description

option

NACOS_AUTH_ENABLE

是否开启权限系统

默认:false

NACOS_AUTH_TOKEN_EXPIRE_SECONDS

token 失效时间

默认:18000

NACOS_AUTH_TOKEN

token

默认
:SecretKey012345678901234567890123456789012345678901234567890123456789

NACOS_AUTH_CACHE_ENABLE

权限缓存开关 ,开启后权限缓存的更新默认有15秒的延迟

默认 : false

然后运行docker-compose构建命令,例如

docker-compose -f example/standalone-derby.yaml up
  • 自定义镜像

如果选择自定义镜像,请在构建镜像之前,修改nacos工程中的application.properties文件,
将下面这一行配置信息

nacos.core.auth.enabled=false

修改为

nacos.core.auth.system.type=nacos
nacos.core.auth.enabled=true

然后再配置nacos启动命令。

Y.2 客户端如何进行鉴权

Y.2.1 Java SDK鉴权

在构建“Properties”类时,需传入用户名和密码。

properties.put("username","${username}");
properties.put("password","${password}");
  • 示例代码
try {
    // Initialize the configuration service, and the console automatically obtains the following parameters through the sample code.
	String serverAddr = "{serverAddr}";
	Properties properties = new Properties();
	properties.put("serverAddr", serverAddr);

    // if need username and password to login
        properties.put("username","nacos");
        properties.put("password","nacos");

	ConfigService configService = NacosFactory.createConfigService(properties);
} catch (NacosException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

Y.2.2 其他语言的SDK鉴权

  • Open-API鉴权

首先需要使用用户名和密码登陆nacos。

curl -X POST '127.0.0.1:8848/nacos/v1/auth/login' -d 'username=nacos&password=nacos'

若用户名和密码正确,返回信息如下:

{"accessToken":"eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJuYWNvcyIsImV4cCI6MTYwNTYyOTE2Nn0.2TogGhhr11_vLEjqKko1HJHUJEmsPuCxkur-CfNojDo","tokenTtl":18000,"globalAdmin":true}

接下来进行配置信息或服务信息时,应当使用该accessToken鉴权,在url后添加参数accessToken={accessToken},其中{accessToken}为登录时返回的token信息,例如

curl -X GET '127.0.0.1:8848/nacos/v1/cs/configs?accessToken=eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJuYWNvcyIsImV4cCI6MTYwNTYyMzkyM30.O-s2yWfDSUZ7Svd3Vs7jy9tsfDNHs1SuebJB4KlNY8Q&dataId=nacos.example.1&group=nacos_group'
curl -X POST 'http://127.0.0.1:8848/nacos/v1/ns/instance?accessToken=eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJuYWNvcyIsImV4cCI6MTYwNTYyMzkyM30.O-s2yWfDSUZ7Svd3Vs7jy9tsfDNHs1SuebJB4KlNY8Q&port=8848&healthy=true&ip=11.11.11.11&weight=1.0&serviceName=nacos.test.3&encoding=GBK&namespaceId=n1'

Y.2.x 身份鉴权测试类 NacosConfigTest

  • 引入Maven依赖
  
    UTF-8
    1.8
    1.8

    
    
    4.13.1
    

    
    1.4.4

    1.7.25
    2.13.3
    28.0-jre
    2.13.4

    4.5.13
    0.9.0
  

  
    
      junit
      junit
      ${junit.version}
      test
    

    
    
    
      com.alibaba.nacos
      nacos-api
      ${nacos-client.version}
    
    
      com.alibaba.nacos
      nacos-common
      ${nacos-client.version}
    

    
    
      com.alibaba.nacos
      nacos-client
      ${nacos-client.version}
    
    

    
    
      org.slf4j
      slf4j-api
      ${slf4j.version}
    
    
      org.apache.logging.log4j
      log4j-api
      ${log4j.version}
    
    
      org.apache.logging.log4j
      log4j-core
      ${log4j.version}
    
    
      org.apache.logging.log4j
      log4j-slf4j-impl
      ${log4j.version}
    
    
      org.apache.logging.log4j
      log4j-jul
      
      ${log4j.version}
      compile
    
    

    
    
      com.google.guava
      guava
      ${guava.version}
    
    

    
    
      com.fasterxml.jackson.core
      jackson-core
      ${jackson.version}
    
    
      com.fasterxml.jackson.core
      jackson-annotations
      ${jackson.version}
    
    
      com.fasterxml.jackson.core
      jackson-databind
      ${jackson.version}
    
    
      com.fasterxml.jackson.datatype
      jackson-datatype-jsr310
      ${jackson.version}
    
    


    
      org.apache.httpcomponents
      httpclient
      ${httpclient.version} 
    

    
    
    
    
      io.prometheus
      simpleclient
      ${prometheus.client.version}
    

    
      io.prometheus
      simpleclient_httpserver
      ${prometheus.client.version}
    

    
      io.prometheus
      simpleclient_pushgateway
      ${prometheus.client.version}
    
    

  
  • NacosConfigTest
package org.example;

import com.alibaba.nacos.api.NacosFactory;
import com.alibaba.nacos.api.PropertyKeyConst;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.exception.NacosException;
import org.junit.Test;

import java.util.Properties;

/**
 * nacos 配置中心测试
 * @description NACOS Server 端 : 2.0.3 / NACOS 客户端 : 1.4.3
 * @reference-doc
 *  [1] NACOS 用户指南(JAVA SDK) - nacos - https://nacos.io/zh-cn/docs/sdk.html
 *  [2] https://mvnrepository.com/artifact/com.alibaba.nacos/nacos-client
 */
public class NacosConfigTest {
    /** NACOS 服务器地址 **/
    private final static String SERVER_ADDR = "https://config-uat.xxxx.com.cn"; // 形如 : 127.0.0.1:8848 或 http://127.0.0.1:8848

    private final static String USERNAME = "nacos";//nacos
    private final static String PASSWORD = "nacos";//nacos
    private final static String NAMESPACE = "xxx_team";//public
    private final static String GROUP = "DEFAULT_GROUP";//DEFAULT_GROUP
    private final static String DATA_ID = "cn.com.xxxx.business.parse";

    /**
     * NACOS 服务器端启用强制客户端输入密码,但客户端不提供密码
     * @sample [shell] curl -X GET 'http://127.0.0.1:8848/nacos/v1/cs/configs?dataId=nacos.example&group=com.alibaba.nacos'
     * @descrption
     * [1] nacos server 2.0.3 : 执行成功
     * [2] nacos server 2.3.1 : 执行失败,ErrCode:403, ErrMsg:

Whitelabel Error Page

This application has no explicit mapping for /error, so you are seeing this as a fallback */ @Test public void nacosServerEnablePasswordButClientNotUsePasswordTest(){ try { Properties properties = new Properties(); properties.put(PropertyKeyConst.SERVER_ADDR, SERVER_ADDR); properties.put(PropertyKeyConst.NAMESPACE, NAMESPACE); //properties.put(PropertyKeyConst.USERNAME, USERNAME); //properties.put(PropertyKeyConst.PASSWORD, PASSWORD); ConfigService configService = NacosFactory.createConfigService(properties); String content = configService.getConfig(DATA_ID, GROUP, 5000); System.out.println(content); } catch (NacosException e) {//读取配置超时或网络异常,抛出 NacosException 异常 // TODO Auto-generated catch block e.printStackTrace(); throw new RuntimeException(e); } } /** * NACOS 服务器端不启用强制客户端输入密码,且客户端也提供密码 * @description * [1] nacos server 2.0.3 : 密码正确时,执行成功 ; 密码错误时, 报 403 * [1] nacos server 2.3.1 : 密码正确时,执行成功 ; 密码错误时, 报 403 */ @Test public void nacosServerDisablePasswordAndClientUsePasswordTest(){ try { Properties properties = new Properties(); properties.put(PropertyKeyConst.SERVER_ADDR, SERVER_ADDR); properties.put(PropertyKeyConst.NAMESPACE, NAMESPACE); properties.put(PropertyKeyConst.USERNAME, USERNAME); properties.put(PropertyKeyConst.PASSWORD, PASSWORD); ConfigService configService = NacosFactory.createConfigService(properties); String content = configService.getConfig(DATA_ID, GROUP, 5000); System.out.println(content); } catch (NacosException e) {//读取配置超时或网络异常,抛出 NacosException 异常 // TODO Auto-generated catch block e.printStackTrace(); throw new RuntimeException(e); } } /** * NACOS 服务器端不启用强制客户端输入密码,但客户端不提供密码 * @sample [shell] curl -X GET 'http://127.0.0.1:8848/nacos/v1/cs/configs?dataId=nacos.example&group=com.alibaba.nacos' * @description * [1] nacos server 2.0.3 : 请求成功 * [2] nacos server 2.3.1 : 请求成功 */ @Test public void nacosServerDisablePasswordButClientNotUsePasswordTest(){ try { Properties properties = new Properties(); properties.put(PropertyKeyConst.SERVER_ADDR, SERVER_ADDR); properties.put(PropertyKeyConst.NAMESPACE, NAMESPACE); //properties.put(PropertyKeyConst.USERNAME, USERNAME); //properties.put(PropertyKeyConst.PASSWORD, PASSWORD); ConfigService configService = NacosFactory.createConfigService(properties); String content = configService.getConfig(DATA_ID, GROUP, 5000); System.out.println(content); } catch (NacosException e) {//读取配置超时或网络异常,抛出 NacosException 异常 // TODO Auto-generated catch block e.printStackTrace(); throw new RuntimeException(e); } } /** * NACOS 服务器端启用强制客户端输入密码,且客户端也提供密码 * @description 执行成功 */ @Test public void nacosServerEnablePasswordAndClientUsePasswordTest(){ try { Properties properties = new Properties(); properties.put(PropertyKeyConst.SERVER_ADDR, SERVER_ADDR); properties.put(PropertyKeyConst.NAMESPACE, NAMESPACE); properties.put(PropertyKeyConst.USERNAME, USERNAME); properties.put(PropertyKeyConst.PASSWORD, PASSWORD); ConfigService configService = NacosFactory.createConfigService(properties); String content = configService.getConfig(DATA_ID, GROUP, 5000); System.out.println(content); } catch (NacosException e) {//读取配置超时或网络异常,抛出 NacosException 异常 // TODO Auto-generated catch block e.printStackTrace(); throw new RuntimeException(e); } } }

Y.3 开启服务身份识别功能

  • 开启鉴权功能后,服务端之间的请求也会通过鉴权系统的影响。考虑到服务端之间的通信应该是可信的,因此在1.2~1.4.0版本期间,通过User-Agent中是否包含Nacos-Server来进行判断请求是否来自其他服务端。
  • 但这种实现由于过于简单且固定,导致可能存在安全问题。因此从1.4.1版本开始,Nacos添加服务身份识别功能,用户可以自行配置服务端的Identity,不再使用User-Agent作为服务端请求的判断标准。

开启方式:

### 开启鉴权
nacos.core.auth.enabled=true

### 关闭使用user-agent判断服务端请求并放行鉴权的功能
nacos.core.auth.enable.userAgentAuthWhite=false

### 配置自定义身份识别的key(不可为空)和value(不可为空)
nacos.core.auth.server.identity.key=example
nacos.core.auth.server.identity.value=example

注意 : 所有集群均需要配置相同的server.identity信息,否则可能导致服务端之间数据不一致或无法删除实例等问题。

Y.4 旧版本升级

  • 考虑到旧版本用户需要升级,可以在升级期间,开启nacos.core.auth.enable.userAgentAuthWhite=true功能,待集群整体升级到1.4.1并稳定运行后,再关闭此功能。

回到顶部(Back to Top)

H 扩展:应用场景合集

场景:指定NACOS注册中心中spring cloud微服务应用的IP

spring:
  cloud:
    nacos:
      discovery:
        ip: 127.0.0.1

修改完成、并重启服务之后在nacos查看的地址如下:

回到顶部(Back to Top)

K 扩展:Nacos 2.x 新特性

K.1 新增端口

  • 2.x最大的变化就是端口。

在默认主端口: 8848 之外又新增了三个端口,新增端口是在配置的主端口(server.port)基础上,进行一定偏移量自动生成:

9848 (主端口+1000)客户端gRPC请求服务端端口,用于客户端向服务端发起连接和请求

9849 (主端口+1001)服务端gRPC请求服务端端口,用于服务间同步等

7848 (主端口-1000)Jraft请求服务端端口,用于处理服务端间的Raft相关请求

  • 注意事项

所以,需要注意的是,若需要对主端口做修改, 8848 在修改后一定要大于 1000
如果需要使用Nginx做转发或映射端口,还需要额外转发 主端口 +1000 端口。
使用Nginx请求时,需要配置成TCP转发,不能配置http2转发,否则连接会被Nginx断开。 98497848 端口为服务端之间的通信端口,请勿暴露到外部网络环境和客户端测。

  • nginx

检查你的Nginx是否支持TCP转发:

sudo nginx -V | grep with-stream

配置:

http{
    upstream nacos {
        server xxx.xxx.xxx.xxx:8848;
    }
    server{
        listen 8000;
        location / {
            proxy_pass http://nacos;
        }
    }
}

TCP转发:

stream{
    upstream nacosss {
        server xxx.xxx.xxx.xxx:9848;
    }
    server{
        listen 9000;
        proxy_pass nacosss;
    }
}

回到顶部(Back to Top)

X 参考文献

  • nacos


https://nacos.io/en-us/docs/quick-start-docker.html权限认证 - Nacos 【参考/推荐】
https://github.com/nacos-group/nacos-docker/blob/v2.1.1https://github.com/nacos-group/nacos-docker/tree/v2.1.1https://github.com/nacos-group/nacos-docker/blob/v2.1.1/example/standalone-mysql-5.7.yamlhttps://github.com/nacos-group/nacos-docker/blob/v2.1.1/env/mysql.envhttps://github.com/alibaba/nacos/blob/2.1.1https://github.com/alibaba/nacos/blob/2.1.1/distribution/conf/nacos-mysql.sql 【推荐】
https://github.com/alibaba/nacos/blob/master/config/src/main/resources/META-INF/nacos-db.sql

  • docker

https://hub-stage.docker.com/


原文作者千千寰宇
原文链接
https://www.cnblogs.com/johnnyzen/p/18097914

相关推荐

C++企业级开发规范指南(c++开发gui)

打造高质量、可维护的C++代码标准一、前言C++作为一门功能强大的系统级编程语言,被广泛应用于操作系统、游戏引擎、高性能服务器、数据库系统等领域。知名互联网公司(如Google、Microsoft、腾...

C++|整型的最值、上溢、下溢、截断、类型提升和转换

整数在计算机内以有限字长表示,当超出最值(有限字长)时,需要截断(溢出,求模)操作。不同字长的整型具有不同的值域,混合运算时,需要类型提升和转换。1整形最值在<limit.h>中有整型的...

C++|漫谈STL细节及内部原理(c++ std stl)

1988年,AlexanderStepanov开始进入惠普的PaloAlto实验室工作,在随后的4年中,他从事的是有关磁盘驱动器方面的工作。直到1992年,由于参加并主持了实验室主任BillWo...

C++11新特性总结 (二)(c++11新特性 pdf)

1.范围for语句C++11引入了一种更为简单的for语句,这种for语句可以很方便的遍历容器或其他序列的所有元素vector<int>vec={1,2,3,4,5,6};f...

C++ STL 漫谈(c++中的stl到底指的什么)

标准模板库(StandardTemplateLibrary,STL)是惠普实验室开发的一个函数库和类库。它是由AlexanderStepanov、MengLee和DavidRMusser在...

C++学习教程_C++语言随到随学_不耽误上班_0基础

C++学习教程0基础学C++也可以,空闲时间学习,不耽误上班.2019年C语言新课程已经上线,随到随学,互动性强,效果好!带你征服C++语言,让所有学过和没有学过C++语言的人,或是正准备学习C++语...

C++遍历vector元素的四种方式(c++ 遍历vector)

vector是相同类型对象的集合,集合中的每个对象有个对应的索引。vector常被称为容器(container)。C++中遍历vector的所有元素是相当常用的操作,这里介绍四种方式。1、通过下标访问...

一起学习c++11——c++11中的新增的容器

c++11新增的容器1:array当时的初衷是希望提供一个在栈上分配的,定长数组,而且可以使用stl中的模板算法。array的用法如下:#include<string>#includ...

C++编程实战基础篇:一维数组应用之投票统计

题目描述班上有N个同学,有五位候选人“A,B,C,D,E”,请所有的同学投票并选举出班长,现在请你编写程序来他们计算候选人的得票总数,每位同学投票将以数字的形式投票“12345”分别代表五位候选人,...

C++20 新特性(6):new表达式也支持数组大小推导

new表达式也支持数组大小推导在C++17标准中,在定义并初始化静态数组时,是可以忽略数组大小,然后通过初始化数据来推导数组的大小。但使用new来定义并初始化动态数组时,并不支持这种自动推导数组大...

C++ 结构体(struct)最全详解(c++结构体用法)

一、定义与声明1.先定义结构体类型再单独进行变量定义structStudent{intCode;charName[20];charSex;intA...

自学 C++ 第 6 课 二维数组找最值

键盘输入一个m×n的二维数组,通过C++编程找出元素中的最大值,并输出其所在的位置坐标。例如,输入一个4×5的二维数组,数组元素分别为{{556623749},{578964563},...

从缺陷中学习C/C++:聊聊 C++ 中常见的内存问题

在写C/C++程序时,一提到内存,大多数人会想到内存泄露。内存泄露是一个令人头疼的问题,尤其在开发大的软件系统时。一个经典的现象是,系统运行了10天、1个月都好好的,忽然有一天宕机了:OOM(Out...

C++开发者都应该使用的十个C++11特性(上)

在C++11新标准中,语言本身和标准库都增加了很多新内容,本文只涉及了一些皮毛。不过我相信这些新特性当中有一些,应该成为所有C++开发者的常规装备。你也许看到过许多类似介绍各种C++11特性的文章。下...

深度解读C/C++指针与数组(c++指针和数组的区别)

指针和数组是密切相关的。事实上,指针和数组在很多情况下是可以互换的。例如,一个指向数组开头的指针,可以通过使用指针的算术运算或数组索引来访问数组。今天我们就来聊一聊数组和指针千丝万缕的关系;一维数组与...