Spring Cloud笔记02: 在k8s集群中部署Nacos集群
2022-02-23
上一节学习了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###使用自建数据库;使用Ingress发布配置后台###
2---
3apiVersion: v1
4kind: Service
5metadata:
6 name: nacos-headless
7 namespace: nacos
8 labels:
9 app: nacos-headless
10spec:
11 type: ClusterIP
12 clusterIP: None
13 ports:
14 - port: 8848
15 name: server
16 targetPort: 8848
17 - port: 9848
18 name: client-rpc
19 targetPort: 9848
20 - port: 9849
21 name: raft-rpc
22 targetPort: 9849
23 ## 兼容1.4.x版本的选举端口
24 - port: 7848
25 name: old-raft-rpc
26 targetPort: 7848
27 selector:
28 app: nacos
29---
30apiVersion: v1
31kind: ConfigMap
32metadata:
33 name: nacos-cm
34 namespace: nacos
35data:
36 mysql.host: "192.168.100.21"
37 mysql.db.name: "nacos"
38 mysql.port: "3306"
39 mysql.user: "nacos"
40 mysql.password: "nacospass"
41---
42apiVersion: apps/v1
43kind: StatefulSet
44metadata:
45 name: nacos
46 namespace: nacos
47spec:
48 serviceName: nacos-headless
49 replicas: 3
50 template:
51 metadata:
52 labels:
53 app: nacos
54 annotations:
55 pod.alpha.kubernetes.io/initialized: "true"
56 spec:
57 affinity:
58 podAntiAffinity:
59 requiredDuringSchedulingIgnoredDuringExecution:
60 - labelSelector:
61 matchExpressions:
62 - key: "app"
63 operator: In
64 values:
65 - nacos
66 topologyKey: "kubernetes.io/hostname"
67 imagePullSecrets:
68 - name: regsecret
69 containers:
70 - name: k8snacos
71 imagePullPolicy: IfNotPresent
72 image: harbor.youcomany.com/library/nacos/nacos-server:v2.0.4
73 resources:
74 requests:
75 memory: "2Gi"
76 cpu: "500m"
77 ports:
78 - containerPort: 8848
79 name: client
80 - containerPort: 9848
81 name: client-rpc
82 - containerPort: 9849
83 name: raft-rpc
84 - containerPort: 7848
85 name: old-raft-rpc
86 env:
87 - name: NACOS_REPLICAS
88 value: "3"
89 - name: MYSQL_SERVICE_HOST
90 valueFrom:
91 configMapKeyRef:
92 name: nacos-cm
93 key: mysql.host
94 - name: MYSQL_SERVICE_DB_NAME
95 valueFrom:
96 configMapKeyRef:
97 name: nacos-cm
98 key: mysql.db.name
99 - name: MYSQL_SERVICE_PORT
100 valueFrom:
101 configMapKeyRef:
102 name: nacos-cm
103 key: mysql.port
104 - name: MYSQL_SERVICE_USER
105 valueFrom:
106 configMapKeyRef:
107 name: nacos-cm
108 key: mysql.user
109 - name: MYSQL_SERVICE_PASSWORD
110 valueFrom:
111 configMapKeyRef:
112 name: nacos-cm
113 key: mysql.password
114 - name: MODE
115 value: "cluster"
116 - name: NACOS_SERVER_PORT
117 value: "8848"
118 - name: PREFER_HOST_MODE
119 value: "hostname"
120 - name: NACOS_SERVERS
121 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"
122 selector:
123 matchLabels:
124 app: nacos
125
126
127
128
129---
130# ------------------- App Ingress ------------------- #
131apiVersion: networking.k8s.io/v1
132kind: Ingress
133metadata:
134 name: nacos-headless
135 namespace: nacos
136spec:
137 rules:
138 - host: nacos.youcomany.com
139 http:
140 paths:
141 - path: /
142 pathType: ImplementationSpecific
143 backend:
144 service:
145 name: nacos-headless
146 port:
147 number: 8848
部署成功后,查看nacos在k8s中各个资源的状态:
1kubectl get service,configmap,ingress,statefulset,pod -n nacos | grep nacos
2service/nacos-headless ClusterIP None <none> 8848/TCP,9848/TCP,9849/TCP,7848/TCP 2h
3configmap/nacos-cm 5 2h
4ingress.networking.k8s.io/nacos-headless nginx nacos.youcomany.com 80, 443 2h
5statefulset.apps/nacos 3/3 2h
6pod/nacos-0 1/1 Running 0 2h
7pod/nacos-1 1/1 Running 0 2h
8pod/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集群外部,便于从外部测试和访问,实际部署时一定要针对这点做好网络策略控制。