【注意】最后更新于 February 23, 2022,文中内容可能已过时,请谨慎使用。
上一节学习了Nacos的基本概念,Nacos是一个用于构建云原生应用的动态服务发现、配置管理和服务管理平台。
在学习如何使用Nacos之前,需要先完成Nacos的部署,Nacos支持多种不同的部署模式,虽然我们这里是以学习为目的的。
但既然Nacos是用于帮助我们构建云原生应用的,那么我们今天就一步到位,在K8S集群上部署一套生产可用的Nacos集群。
Nacos的部署模式
Nacos支持三种部署模式:
- 单机模式: 用于测试和单机使用
- 集群模式: 用于生产环境,确保高可用
- 多集群模式: 用于多数据中心场景
我们本节的目标是在K8S集群上部署一套生产可用的Nacos集群,属于第二种集群部署模式。
nacos-k8s项目
https://github.com/nacos-group/nacos-k8s项目是Nacos官方项目。
该项目包含了一个可构建的Nacos Docker Image,提供并支持以k8s manifest yaml file
, Helm Chart
, Operator
三种方式在K8S上部署Nacos。
部署的Nacos集群在K8S中以StatefulSet存在。
nacos-k8s当前对于以k8s manifest yaml file方式部署提供了以下4个yaml文件(https://github.com/nacos-group/nacos-k8s/tree/master/deploy/nacos):
- nacos-no-pvc-ingress.yaml
- nacos-pvc-ceph.yaml
- nacos-pvc-nfs.yaml
- nacos-quick-start.yaml
这里选择MySQL作为Nacos的数据库,上面4个yaml文件选择使用的是nacos-no-pvc-ingress.yaml
。
在k8s集群中部署Nacos
首先进行准备工作,在MySQL数据库提前创建好nacos的数据库和用户,使用https://github.com/alibaba/nacos/blob/develop/distribution/conf/nacos-mysql.sql这个SQL文件创建好nacos数据库的表结构和初始化数据。
接下来编辑nacos-no-pvc-ingress.yaml
,针对我们的部署环境做定制化配置,主要有以下几个方面:
- 定制各个k8s资源部署的k8s namespace (nacos-no-pvc-ingress.yaml中默认的是default namespace)
- 修改nacos-cm这个ConfigMap中关于MySQL的地址、端口、数据库名、用户名、密码等信息
- 修改nacos这个StatefulSet中的Nacos镜像的版本,例如部署最新的2.0.4版本。建议将
nacos/nacos-server:v2.0.4
镜像缓存到本地的私有镜像库例如harbor.youcomany.com/library/nacos/nacos-server:v2.0.4
- 以StatefulSet部署的nacos集群的各个节点之间是使用headless service进行通信的,如果前面定制了个k8s namespace,注意调整SatefulSet Pod模板中的
NACOS_SERVERS
环境变量的值。
- nacos-no-pvc-ingress.yaml中使用了Ingress将nacos的Web控制后台暴露到K8S集群外部,但当前它的Ingress使用的
apiVersion: extensions/v1beta1
,如果你的K8S版本比较新的话,需要修改Ingress的配置,使其满足apiVersion: networking.k8s.io/v1
以下是本文对nacos-no-pvc-ingress.yaml定制配置的例子,这个例子将nacos集群部署到了k8s的nacos namespace中:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
|
###使用自建数据库;使用Ingress发布配置后台###
---
apiVersion: v1
kind: Service
metadata:
name: nacos-headless
namespace: nacos
labels:
app: nacos-headless
spec:
type: ClusterIP
clusterIP: None
ports:
- port: 8848
name: server
targetPort: 8848
- port: 9848
name: client-rpc
targetPort: 9848
- port: 9849
name: raft-rpc
targetPort: 9849
## 兼容1.4.x版本的选举端口
- port: 7848
name: old-raft-rpc
targetPort: 7848
selector:
app: nacos
---
apiVersion: v1
kind: ConfigMap
metadata:
name: nacos-cm
namespace: nacos
data:
mysql.host: "192.168.100.21"
mysql.db.name: "nacos"
mysql.port: "3306"
mysql.user: "nacos"
mysql.password: "nacospass"
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: nacos
namespace: nacos
spec:
serviceName: nacos-headless
replicas: 3
template:
metadata:
labels:
app: nacos
annotations:
pod.alpha.kubernetes.io/initialized: "true"
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: "app"
operator: In
values:
- nacos
topologyKey: "kubernetes.io/hostname"
imagePullSecrets:
- name: regsecret
containers:
- name: k8snacos
imagePullPolicy: IfNotPresent
image: harbor.youcomany.com/library/nacos/nacos-server:v2.0.4
resources:
requests:
memory: "2Gi"
cpu: "500m"
ports:
- containerPort: 8848
name: client
- containerPort: 9848
name: client-rpc
- containerPort: 9849
name: raft-rpc
- containerPort: 7848
name: old-raft-rpc
env:
- name: NACOS_REPLICAS
value: "3"
- name: MYSQL_SERVICE_HOST
valueFrom:
configMapKeyRef:
name: nacos-cm
key: mysql.host
- name: MYSQL_SERVICE_DB_NAME
valueFrom:
configMapKeyRef:
name: nacos-cm
key: mysql.db.name
- name: MYSQL_SERVICE_PORT
valueFrom:
configMapKeyRef:
name: nacos-cm
key: mysql.port
- name: MYSQL_SERVICE_USER
valueFrom:
configMapKeyRef:
name: nacos-cm
key: mysql.user
- name: MYSQL_SERVICE_PASSWORD
valueFrom:
configMapKeyRef:
name: nacos-cm
key: mysql.password
- name: MODE
value: "cluster"
- name: NACOS_SERVER_PORT
value: "8848"
- name: PREFER_HOST_MODE
value: "hostname"
- name: NACOS_SERVERS
value: "nacos-0.nacos-headless.nacos.svc.cluster.local:8848 nacos-1.nacos-headless.nacos.svc.cluster.local:8848 nacos-2.nacos-headless.nacos.svc.cluster.local:8848"
selector:
matchLabels:
app: nacos
---
# ------------------- App Ingress ------------------- #
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nacos-headless
namespace: nacos
spec:
rules:
- host: nacos.youcomany.com
http:
paths:
- path: /
pathType: ImplementationSpecific
backend:
service:
name: nacos-headless
port:
number: 8848
|
部署成功后,查看nacos在k8s中各个资源的状态:
1
2
3
4
5
6
7
8
|
kubectl get service,configmap,ingress,statefulset,pod -n nacos | grep nacos
service/nacos-headless ClusterIP None <none> 8848/TCP,9848/TCP,9849/TCP,7848/TCP 2h
configmap/nacos-cm 5 2h
ingress.networking.k8s.io/nacos-headless nginx nacos.youcomany.com 80, 443 2h
statefulset.apps/nacos 3/3 2h
pod/nacos-0 1/1 Running 0 2h
pod/nacos-1 1/1 Running 0 2h
pod/nacos-2 1/1 Running 0 2h
|
部署成功后,使用https://nacos.youcomany.com/nacos
打开nacos的Web控制台,并以默认的用户名密码(nacos/nacos)登录,

到这里,我们完成了在K8S集群中部署Nacos集群。
最后,需要注意Nacos被设计为一个在IDC内部使用的应用组件,而非面向公网环境的产品,因此需要在内部隔离网络中使用。
本文的示例中将Nacos的Web控制台和API以Ingress (nacos.youcomany.com)的形式暴露到了k8s集群外部,便于从外部测试和访问,实际部署时一定要针对这点做好网络策略控制。
参考