全网最详细K8S部署Nacos集群
简介
Nacos是阿里巴巴开源的一个动态服务发现、配置管理和服务管理平台,特别设计用于简化云原生应用的构建与管理。Nacos的核心特性包括:
服务发现与健康检查:Nacos支持DNS与RPC方式的服务发现机制,能够自动发现、路由及负载均衡微服务。它通过健康检查机制监控服务实例状态,确保只将请求转发给健康的实例
动态配置服务:提供了一个集中式的外部化配置存储,允许你在Nacos中集中管理应用的配置,应用可以在运行时动态获取或更新这些配置。配置变更时,Nacos能实时推送到相关应用
动态DNS服务:具备动态DNS服务功能,支持权重路由,为流量管理如蓝绿部署、灰度发布、流量镜像等场景提供灵活性
命名空间与分组管理:通过命名空间和分组,Nacos支持多环境或多租户的隔离,使得不同环境或团队的服务与配置可以独立管理,互不影响
权限控制与安全:Nacos提供了用户认证与授权机制,确保只有合法用户才能访问和修改服务及配置信息,提升了系统的安全性
服务与元数据管理:强大的服务和元数据管理能力,方便进行微服务及其相关信息的维护
Nacos旨在提升微服务平台的构建、部署与运维效率,不仅适用于云端环境,也适合传统数据中心。关于Nacos的部署,它默认开放四个端口以支持其功能,其中最重要的是客户端、控制台及OpenAPI使用的HTTP端口8848,以及客户端gRPC请求服务端端口9848。在集群部署时,通常只需对外暴露这两个端口即可
部署Nacos集群
Nacos项目环境
项目下载地址:https://github.com/alibaba/nacos/releases
参考文档:
https://nacos.io/zh-cn/docs/use-nacos-with-kubernetes.html
https://nacos.io/docs/latest/guide/user/auth/
https://nacos.io/blog/faq/nacos-user-question-history13425/
操作系统:Ubuntu 22.04
K8S版本:1.28.2
MySQL:5.7.44
Nacos:2.4.0
本文Nacos后端使用mysql存储,通过statefulset部署单实例mysql,生产环境必须部署mysql主从集群,并且根据自己的实际情况设定环境即可
创建Storage Class存储
获取NFS Subdir External Provisioner部署文件
$
wget https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner/archive/refs/tags/nfs-subdir-external-provisioner-4.0.18.zip
$
unzip -o nfs-subdir-external-provisioner-4.0.18.zip
$
cd nfs-subdir-external-provisioner-nfs-subdir-external-provisioner-4.0.18/deploy/

创建命令空间
$ kubectl create ns nacos-test
创建RBAC资源
$
sed -i
'' "s/namespace:.*/namespace: nacos-test/g" rbac.yaml deployment.yaml
$ kubectl create -f rbac.yaml

$
vim deployment.yaml
注意:/data/nfs/nacos目录一定要提前创建好

$ kubectl apply -f deployment.yaml

$ kubectl get deployment,pods -n nacos-test

部署Storage Class
$
vim class.yaml

$ kubectl apply -f class.yaml

$ kubectl get sc

配置mysql清单文件nacos-mysql.yaml
$
vim nacos-mysql.yaml
#配置mysql的secret
---
apiVersion: v1
data:
# 密码为root
mysql_root_password:
cm9vdA==
kind: Secret
metadata:
name: mysql-password
namespace: nacos-test
# 配置mysql的svc
---
apiVersion: v1
kind: Service
metadata:
name: nacos-mysql-svc
namespace: nacos-test
labels:
app: mysql
spec:
ports:
- port:
3306
name: mysql
targetPort:
3306
nodePort:
30306
selector:
app: mysql
type: NodePort
#配置mysql的statefulset
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: nacos-mysql
namespace: nacos-test
spec:
selector:
matchLabels:
app: mysql
serviceName:
"nacos-mysql-svc"
replicas:
1
template:
metadata:
labels:
app: mysql
spec:
terminationGracePeriodSeconds:
10
containers:
- args:
- --character-set-server
=utf8mb4
- --collation-server
=utf8mb4_unicode_ci
- --lower_case_table_names
=1
- --default-time_zone
=+8:00
name: mysql
image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/mysql:5.7.44
ports:
- containerPort:
3306
name: mysql
volumeMounts:
- name: mysql-data
mountPath: /var/lib/mysql
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
key: mysql_root_password
name: mysql-password
volumeClaimTemplates:
- metadata:
name: mysql-data
annotations:
volume.beta.kubernetes.io/storage-class:
"nfs-client"
spec:
accessModes:
[ "ReadWriteMany" ]
resources:
requests:
storage: 5Gi
$ kubectl apply -f nacos-mysql.yaml

查看mysql各资源状态
$ kubectl get pvc,svc,pod -n nacos-test

导入mysql初始化数据
nacos 2.4.0的mysql初始化sql文件:
https://github.com/alibaba/nacos/blob/2.4.0/distribution/conf/mysql-schema.sql
初始化sql文件在nacos每个版本的源码目录的conf目录下
mysql的service的3306端口已经映射为30306
$ mysql -u root -p -h
192.168.3.132 -P
30306
mysql
> create database nacos_config
;
mysql
> source /home/ubuntu2204/schma.sql
;

生成configMap清单
$ kubectl create configmap nacos-config -n nacos-test
\
--from-literal
=mode
=cluster
\
--from-literal
=nacos-servers
='nacos-0.nacos-test-svc.nacos-test.svc.cluster.local:8848 nacos-1.nacos-test-svc.nacos-test.svc.cluster.local:8848' \
--from-literal
=spring-datasource-platform
=mysql
\
--from-literal
=mysql-service-host
='nacos-mysql-0.nacos-mysql-svc.nacos-test.svc.cluster.local' \
--from-literal
=mysql-service-port
=3306 \
--from-literal
=mysql-service-db-name
=nacos_config
\
--from-literal
=mysql-service-user
=root
\
--from-literal
=mysql-database-num
=1 \
--from-literal
=mysql-service-db-param
='characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useSSL=false' \
--from-literal
=jvm-xms
=656m
\
--from-literal
=jvm-xmx
=856m
\
--from-literal
=jvm-xmn
=428m
\
--from-literal
=nacos-auth-enable
=true
\
--from-literal
=nacos-core-auth-server-identity-key
=test
\
--from-literal
=nacos-core-auth-server-identity-value
=test
\
--from-literal
=nacos-auth-token
=SecretKeyM1Z2WDc4dnVyZkQ3NmZMZjZ3RHRwZnJjNFROdkJOemEK
\
--dry-run
=client -o yaml

注意:nacos 2.2.2及其以后版本必须配置以下参数才会有登录认证界面 传统部署方式需要修改application.properties的以下几个参数
nacos.core.auth.enabled
=true
#开启认证授权
nacos.core.auth.system.type
=nacos
#认证类型
nacos.core.auth.plugin.nacos.token.secret.key
=SecretKeyM1Z2WDc4dnVyZkQ3NmZMZjZ3RHRwZnJjNFROdkJOemEK
#nacos的token
nacos.core.auth.server.identity.key
=test
#这里配置的key可以是任意值
nacos.core.auth.server.identity.value
=test
容器类部署需要传入以下环境变量
NACOS_AUTH_ENABLE=true
NACOS_CORE_AUTH_SERVER_IDENTITY_KEY=test
NACOS_CORE_AUTH_SERVER_IDENTITY_VALUE=test
NACOS_AUTH_TOKEN=SecretKeyM1Z2WDc4dnVyZkQ3NmZMZjZ3RHRwZnJjNFROdkJOemEK
参考官方文档:https://nacos.io/docs/latest/guide/user/auth/
如果以上参数未添加会出现以下错误:


Nacos的hub官方镜像提供了很多可以传给容器的环境变量:https://hub.docker.com/r/nacos/nacos-server
Nacos官方文档系统参数:https://nacos.io/docs/latest/manual/admin/system-configurations/
变量名描述
MODE nacos启动模式,cluster为集群模式,standalone为单节点模式 NACOS_SERVERS nacos集群的服务器地址,格式为ip1:port ip2:port多个用空格隔开 SPRING_DATASOURCE_PLATFORM nacos使用的数据库,单节点支持mysql,默认为空 PREFER_HOST_MODE 是否支持主机名,默认是IP,k8s部署必须开启此变量 NACOS_SERVER_IP 多网络环境中配置nacos服务IP NACOS_APPLICATION_PORT nacos服务端口,默认是8848 MYSQL_SERVICE_HOST mysql数据库地址 MYSQL_SERVICE_PORT mysql端口 MYSQL_SERVICE_DB_NAME nacos的mysql数据库名 MYSQL_SERVICE_USER nacos访问数据库的用户名 MYSQL_SERVICE_PASSWORD nacos访问数据库的用户名密码 MYSQL_DATABASE_NUM mysql数据库的数量,默认为1 MYSQL_SERVICE_DB_PARAM mysql连接字符串后面的参数,默认:characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useSSL=false JVM_XMS jvm永久区最小大小,默认1G JVM_XMX jvm永久区最大大小,默认1G JVM_XMN jvm新生区大小,默认512M JVM_MS -XX:MetaspaceSize元空间大小,默认128M JVM_MMS -XX:MaxMetaspaceSize最大元空间大小,默认320M NACOS_DEBUG 是否开启远程DEBUG,默认开启 TOMCAT_ACCESSLOG_ENABLED 是否开启nacos中的tomcat访问日志,默认关闭 NACOS_AUTH_SYSTEM_TYPE nacos的认证方式,默认以及仅仅支持nacos NACOS_AUTH_ENABLE 是否开启认证授权,默认关闭 NACOS_AUTH_TOKEN_EXPIRE_SECONDS token过期时间,默认18000s NACOS_AUTH_TOKEN nacos的token,开启授权后需要指定 NACOS_AUTH_CACHE_ENABLE 开启或关闭认证信息缓存,默认关闭,开启后信息更新会有15s延迟 MEMBER_LIST 通过环境变量或配置文件的方式设置集群地址列表 EMBEDDED_STORAGE 是否开启集群嵌入式存储模式,默认为空 NACOS_AUTH_USER_AGENT_AUTH_WHITE_ENABLE 是否开启nacos认证用户白名单 NACOS_AUTH_IDENTITY_KEY nacos认证授权指定key NACOS_AUTH_IDENTITY_VALUE nacos认证授权指定key的值 NACOS_SECURITY_IGNORE_URLS nacos忽略安全校验的地址 DB_POOL_CONNECTION_TIMEOUT 数据库连接池超时时间,单位为毫秒 NACOS_CONSOLE_UI_ENABLED 开启或关闭nacos控制台,默认开启 NACOS_CORE_PARAM_CHECK_ENABLED 是否开启nacos服务端参数校验,默认false
配置nacos集群清单文件nacos-test.yaml
$
vim nacos-test.yaml
#配置nacos的configMap
apiVersion: v1
kind: ConfigMap
metadata:
name: nacos-config
namespace: nacos-test
data:
jvm-xmn: 428m
jvm-xms: 656m
jvm-xmx: 856m
mode: cluster
mysql-database-num:
"1"
mysql-service-db-name: nacos_config
mysql-service-db-param:
characterEncoding=utf8
&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
&useSSL=false
mysql-service-host: nacos-mysql-0.nacos-mysql-svc.nacos-test.svc.cluster.local
mysql-service-port:
"3306"
mysql-service-user: root
mysql-service-pd: root
nacos-servers: nacos-0.nacos-headless.nacos-test.svc.cluster.local:8848 nacos-1.nacos-headless.nacos-test.svc.cluster.local:8848
spring-datasource-platform: mysql
nacos-auth-enable:
"true"
nacos-auth-token:
"SecretKeyM1Z2WDc4dnVyZkQ3NmZMZjZ3RHRwZnJjNFROdkJOemEK"
nacos-core-auth-server-identity-key:
"test"
nacos-core-auth-server-identity-value:
"test"
#配置nacos集群对外访问的service
---
apiVersion: v1
kind: Service
metadata:
name: nacos-external
namespace: nacos-test
labels:
app: nacos-external
spec:
ports:
- name:
8848-8848
protocol: TCP
port:
8848
targetPort:
8848
nodePort:
31848
type: NodePort
selector:
app: nacos
#配置nacos集群的无头服务
---
apiVersion: v1
kind: Service
metadata:
name: nacos-headless
namespace: nacos-test
labels:
app: nacos
spec:
ports:
- port:
8848
name: server
targetPort:
8848
- name: clien-rpc
port:
9848
targetPort:
9848
- name: old-ratf-rpc
port:
7848
targetPort:
7848
- name: ratf-rpc
port:
9849
targetPort:
9849
clusterIP: None
type: ClusterIP
selector:
app: nacos
#配置nacos的statefulset
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: nacos
namespace: nacos-test
spec:
selector:
matchLabels:
app: nacos
serviceName:
"nacos-headless"
replicas:
2
template:
metadata:
labels:
app: nacos
spec:
containers:
- name: nacos
image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/nacos/nacos-server:v2.4.0
ports:
- name: server
containerPort:
8848
- name: clien-rpc
containerPort:
9848
- name: old-ratf-rpc
containerPort:
7848
- name: ratf-rpc
containerPort:
9849
env:
- name: PREFER_HOST_MODE
value:
hostname
- name: JVM_XMN
valueFrom:
configMapKeyRef:
key: jvm-xmn
name: nacos-config
- name: JVM_XMS
valueFrom:
configMapKeyRef:
key: jvm-xms
name: nacos-config
- name: JVM_XMX
valueFrom:
configMapKeyRef:
key: jvm-xmx
name: nacos-config
- name: MODE
valueFrom:
configMapKeyRef:
key: mode
name: nacos-config
- name: MYSQL_DATABASE_NUM
valueFrom:
configMapKeyRef:
key: mysql-database-num
name: nacos-config
- name: MYSQL_SERVICE_DB_NAME
valueFrom:
configMapKeyRef:
key: mysql-service-db-name
name: nacos-config
- name: MYSQL_SERVICE_DB_PARAM
valueFrom:
configMapKeyRef:
key: mysql-service-db-param
name: nacos-config
- name: MYSQL_SERVICE_HOST
valueFrom:
configMapKeyRef:
key: mysql-service-host
name: nacos-config
- name: MYSQL_SERVICE_PASSWORD
valueFrom:
configMapKeyRef:
key: mysql-service-pd
name: nacos-config
- name: MYSQL_SERVICE_PORT
valueFrom:
configMapKeyRef:
key: mysql-service-port
name: nacos-config
- name: MYSQL_SERVICE_USER
valueFrom:
configMapKeyRef:
key: mysql-service-user
name: nacos-config
- name: NACOS_SERVERS
valueFrom:
configMapKeyRef:
key: nacos-servers
name: nacos-config
- name: MEMBER_LIST
valueFrom:
configMapKeyRef:
key: nacos-servers
name: nacos-config
- name: SPRING_DATASOURCE_PLATFORM
valueFrom:
configMapKeyRef:
key: spring-datasource-platform
name: nacos-config
- name: NACOS_AUTH_ENABLE
valueFrom:
configMapKeyRef:
key: nacos-auth-enable
name: nacos-config
- name: NACOS_CORE_AUTH_SERVER_IDENTITY_KEY
valueFrom:
configMapKeyRef:
key: nacos-core-auth-server-identity-key
name: nacos-config
- name: NACOS_CORE_AUTH_SERVER_IDENTITY_VALUE
valueFrom:
configMapKeyRef:
key: nacos-core-auth-server-identity-value
name: nacos-config
- name: NACOS_AUTH_TOKEN
valueFrom:
configMapKeyRef:
key: nacos-auth-token
name: nacos-config
volumeMounts:
- name: datadir
mountPath: /home/nacos/data
- name: logdir
mountPath: /home/nacos/logs
volumeClaimTemplates:
- metadata:
name: datadir
annotations:
volume.beta.kubernetes.io/storage-class:
"nfs-client"
spec:
accessModes:
[ "ReadWriteMany" ]
resources:
requests:
storage: 5Gi
- metadata:
name: logdir
annotations:
volume.beta.kubernetes.io/storage-class:
"nfs-client"
spec:
accessModes:
[ "ReadWriteMany" ]
resources:
requests:
storage: 5Gi
$ kubectl apply -f nacos-test.yaml

查看各个资源状态
$ kubectl get pod,svc,pvc -n nacos-test

查看初始化日志
$ kubectl logs -f nacos-1 -n nacos-test
在nacos某一节点的初始化日志中可以看到nacos的自动发现脚本自动将找到的集群节点的DNS加入到cluster.conf文件中

访问登录Nacos
自2.4.0版本开始,Nacos构建时不再提供管理员用户nacos的默认密码,需要在首次开启鉴权后,通过API或 Nacos控制台进行管理员用户nacos的密码初始化 。当Nacos集群开启鉴权后,访问Nacos控制台时,会校验管理员用户nacos的密码是否已经初始化,若发现未初始化密码时,则会跳转至初始化密码的页面进行初始化
资源清单中已经将nacos的访问端口映射为30848,使用浏览器访问k8s集群的任何一个节点IP都可以访问nacos登录界面,这里使用:30848/nacos,默认用户名是nacos,密码也是nacos



出现“权限认证失败”后点击确定,然后输入上面初始化的用户名和密码登录,查看“集群管理”->“节点管理”,可以看到两个nacos节点都为up状态

测试配置
找到“配置管理”->“配置列表”,点击“创建配置”,填写完基本信息后点击“发布”


登录数据库查看信息
mysql
> use nacos_config
;
mysql
> select * from
`nacos_config`.`config_info`;

通过Nacos API接口测试
使用用户名和密码登陆nacos集群,若用户名和密码正确会返回Token信息
$
curl -X POST
':31848/nacos/v1/auth/login' -d
'username=nacos&password=nacos'
{"accessToken":"eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJuYWNvcyIsImV4cCI6MTcyOTA3Njc3MH0.jBDTcSYb6q9mg2IBLwJieu53jQthmRqwTB35f6lmRjY",
"tokenTtl":18000,
"globalAdmin":true,
"username":"nacos"}
服务注册
$
curl -X POST
':31848/nacos/v1/ns/instance?accessToken=eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJuYWNvcyIsImV4cCI6MTcyOTA3Njc3MH0.jBDTcSYb6q9mg2IBLwJieu53jQthmRqwTB35f6lmRjY&serviceName=nacos.naming.serviceName&ip=192.168.8.181&port=30306'
返回ok
服务发现
$
curl -X GET
':31848/nacos/v1/ns/instance/list?accessToken=eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJuYWNvcyIsImV4cCI6MTcyOTA3Njc3MH0.jBDTcSYb6q9mg2IBLwJieu53jQthmRqwTB35f6lmRjY&serviceName=nacos.naming.serviceName'
返回
{"name":"DEFAULT_GROUP@@nacos.naming.serviceName",
"groupName":"DEFAULT_GROUP",
"clusters":"",
"cacheMillis":10000,
"hosts":
[],
"lastRefTime":1729060467432,
"checksum":"",
"allIPs":false,
"reachProtectionThreshold":false,
"valid":true
}
发布配置
$
curl -X POST ':31848/nacos/v1/cs/configs?accessToken
=eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJuYWNvcyIsImV4cCI6MTcyOTA3Njc3MH0.jBDTcSYb6q9mg2IBLwJieu53jQthmRqwTB35f6lmRjY
&dataId=nacos.cfg.dataId
&group=test
&content=helloWorld"
返回true
获取配置
$
curl -X GET
':31848/nacos/v1/cs/configs?accessToken=eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJuYWNvcyIsImV4cCI6MTcyOTA3Njc3MH0.jBDTcSYb6q9mg2IBLwJieu53jQthmRqwTB35f6lmRjY&dataId=nacos.cfg.dataId&group=test'
返回helloWorld

