什么是Nacos
-
Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service的首字母简称,一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台;
-
Nacos 致力于帮助您发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据及流量管理。
Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。 Nacos 是构建以“服务”为中心的现代应用架构 (例如微服务范式、云原生范式) 的服务基础设施。
以上内容摘自Nacos官网的简介。
Nacos支持的部署方式
- 单机模式:一般在对稳定性要求不高的场景使用,比如开发人员的PC机、开发联调环境和测试环境。
- 集群模式:常规系统的生产环境,本例就属于这种。
- 多数据中心模式:超大型系统的生产环境。
集群部署Nacos
准备数据库
- 使用MySQL作为Nacos集群的数据库;
- 可以在项目资源中直接使用已有的库,或者自行安装自行采购新的数据库;
- 收集好访问数据库的必要信息
MYSQL_SERVICE_HOST: 数据库IP或访问域名
MYSQL_SERVICE_PORT: 数据库访问端口
MYSQL_SERVICE_DB_NAME: 用于保存nacos集群信息的数据库实例名
MYSQL_SERVICE_USER: 可访问上述数据库实例的用户名
MYSQL_SERVICE_PASSWORD: 可访问上述数据库实例的密码
- 初始化支持Nacos集群运行必要的表和数据,一定要用自己部署的Nacos版本的那份SQL脚本去做初始化,这一点非常重要,使用的初始化SQL版本如果不匹配,会导致Nacos无法正常启动。
// 例如
1. https://github.com/alibaba/nacos/blob/master/distribution/conf/mysql-schema.sql
2. https://github.com/alibaba/nacos/blob/1.4.0/distribution/conf/nacos-mysql.sql
创建有状态负载
- 如果是在公有云平台部署Nacos,一般可以直接通过可视化操作界面选择镜像,一步步创建有状态负载。
- 如果没有可视化操作界面,编写yaml文件,然后通过命令行创建有状态负载。
- 不论使用哪种方式创建,特别注意spec.template.spec.containers.env中配置的环境变量,以及在spec.template.serviceName中配置的服务(Service)名。下面会详细介绍这两部分配置的用途,以及实践过程中踩过的坑。
- 启动实例后,根据自身所在的网络环境,可以直接访问nacos页面,也可能要配置一些请求转发和代理才能访问。
kind: StatefulSet
apiVersion: apps/v1
metadata:
name: nacos-cluster
namespace: mojiayi-prod
spec:
replicas: 3
selector:
matchLabels:
app: nacos-cluster
version: v1
template:
metadata:
labels:
app: nacos-cluster
version: v1
spec:
volumes:
containers:
- name: container-nacos
image: 镜像域名/组织名/nacos/nacos-server:1.4.0
env:
- name: PREFER_HOST_MODE
value: hostname
- name: SPRING_DATASOURCE_PLATFORM
value: mysql
- name: MYSQL_SERVICE_HOST
value: 173.26.10.89
- name: MYSQL_SERVICE_PORT
value: '3306'
- name: MYSQL_SERVICE_DB_NAME
value: mojiayi_nacos
- name: MYSQL_SERVICE_USER
value: mojiayi_nacos
- name: MYSQL_SERVICE_PASSWORD
value: acomplexpassword
- name: NACOS_SERVERS
value: nacos-cluster-0.headless-nacos.mojiayi-prod.svc.cluster.local:8848,nacos-cluster-1.headless-nacos.mojiayi-prod.svc.cluster.local:8848,nacos-cluster-2.headless-nacos.mojiayi-prod.svc.cluster.local:8848
resources:
limits:
cpu: '2'
memory: 3512Mi
requests:
cpu: 1500m
memory: 3000Mi
imagePullPolicy: IfNotPresent
restartPolicy: Always
terminationGracePeriodSeconds: 30
dnsPolicy: ClusterFirst
securityContext: {}
imagePullSecrets:
- name: default-secret
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: nacos
operator: In
values:
- nacos
serviceName: headless-nacos
环境变量
| 属性名称 | 用途描述 | 示例 |
|---|---|---|
| PREFER_HOST_MODE | 支持ip还是域名(hostname)模式访问,默认为 ip | hostname |
| SPRING_DATASOURCE_PLATFORM | 提供数据存储功能的关系型数据库产品 | mysql |
| MYSQL_SERVICE_HOST | 数据库IP或访问域名 | |
| MYSQL_SERVICE_PORT | 数据库访问端口 | |
| MYSQL_SERVICE_DB_NAME | 用于保存nacos集群信息的数据库实例名 | |
| MYSQL_SERVICE_USER | 可访问上述数据库实例的用户名 | |
| MYSQL_SERVICE_PASSWORD | 可访问上述数据库实例的密码 | |
| NACOS_SERVERS | 集群地址,有几个实例,就要写几个进来 |
关于NACOS_SERVERS的详细说明
nacos-cluster-0.headless-nacos.mojiayi-prod.svc.cluster.local:8848,nacos-cluster-1.headless-nacos.mojiayi-prod.svc.cluster.local:8848,nacos-cluster-2.headless-nacos.mojiayi-prod.svc.cluster.local:8848
-
只有正确配置了NACOS_SERVERS,Nacos集群才能正常启用。
-
本例中部署了3个Nacos实例,上述配置可分为3段。
-
每段由5部分内容组成,结构是 Nacos实例名称:Headless Service名称:命名空间.平台特有的固定字符:端口,其中平台特有的固定字符,在不同的公有云或直接使用开源K8S时,各不相同。
配置集群内访问服务
-
为多个Nacos实例创建集群内访问服务,使其可以被集群中的业务应用发现。
-
因为Nacos集群本身是“去中心化”的,即使配置了集群内访问服务也不具体固定的ClusterIP,还需要通过Headless Service为它做集群内负载均衡。
-
本例中配置了4个端口,因为这次实际部署的是Nacos 1.4.0,所以只配置8848和7848两个端口也可以。4个端口的用途,请看下表。
端口 用途 8848 对外暴露 API 与集群间数据同步 9848 Nacos 2.0 版本之后的grpc 的通信端口,用于客户端向服务端发起连接和请求 9849 Nacos 2.0 版本之后的grpc 的通信端口,用于服务间同步等 7848 节点选举来确定集群领袖
metadata:
name: nacos-cluster
namespace: mojiayi-prod
labels:
app: nacos-cluster
version: v1
spec:
ports:
- name: cce-service-0
protocol: TCP
port: 8848
targetPort: 8848
- name: cce-service-1
protocol: TCP
port: 9848
targetPort: 9848
- name: cce-service-2
protocol: TCP
port: 9849
targetPort: 9849
- name: cce-service-3
protocol: TCP
port: 7848
targetPort: 7848
selector:
app: nacos-cluster
version: v1
clusterIP: 10.267.198.32
clusterIPs:
- 10.267.198.32
type: ClusterIP
sessionAffinity: None
status:
loadBalancer: {}
apiVersion: v1
kind: Service
通过Headless Service实现集群内负载均衡
- 不为Service设置ClusterIP(入口IP地址),仅通过Label Selector将后端的实例列表返回给调用客户端,这就是Headless Service的功能。
- 通过spec.selector指定要为哪个服务提供负载均衡。
metadata:
name: headless-nacos
namespace: mojiayi-prod
labels:
app: nacos-cluster
version: v1
annotations:
service.alpha.kubernetes.io/tolerate-unready-endpoints: 'true'
spec:
ports:
- name: http
protocol: TCP
port: 8848
targetPort: 8848
- name: client-rpc
protocol: TCP
port: 9848
targetPort: 9848
- name: raft-rpc
protocol: TCP
port: 9849
targetPort: 9849
- name: old-raft-rpc
protocol: TCP
port: 7848
targetPort: 7848
selector:
app: nacos-cluster
version: v1
clusterIP: None
clusterIPs:
- None
type: ClusterIP
sessionAffinity: None
status:
loadBalancer: {}
apiVersion: v1
kind: Service
有些文章将它翻译成“无头服务”,我个人觉得并不形象,也没有表达出它的实际用途,既然没有好的翻译名称,就直接叫英文名吧。
在后端项目中配置Nacos地址
在基于SpringBoot搭建的工程中,直接使用上述NACOS_SERVERS对应的地址,不需要加HTTP或HTTPS这样的协议名。
spring:
profiles: prod
cloud:
nacos:
discovery:
server-addr: nacos-cluster-0.headless-nacos.chery-aps-prod.svc.cluster.local:8848,nacos-cluster-1.headless-nacos.chery-aps-prod.svc.cluster.local:8848,nacos-cluster-2.headless-nacos.chery-aps-prod.svc.cluster.local:8848
namespace: 43c817d3-2dcf-43df-881f-ccb517bdeaty
group: mojiayi-config
config:
server-addr: nacos-cluster-0.headless-nacos.chery-aps-prod.svc.cluster.local:8848,nacos-cluster-1.headless-nacos.chery-aps-prod.svc.cluster.local:8848,nacos-cluster-2.headless-nacos.chery-aps-prod.svc.cluster.local:8848
file-extension: yml
namespace: 43c817d3-2dcf-43df-881f-ccb517bdeaty
group: mojiayi-config