目录
一,下载官方k8s项目
这里使用官方提供的k8s文件修改。
git clone https://github.com/nacos-group/nacos-k8s.git
cd nacos-k8s
二,创建对应的 NFS StorageClass 和 PV
使用NFS作为PVC持久化。
官方提供了k8s的nfs部署,/nacos-k8s/deploy/nfs/ ,可以直接使用的官方的。
但是生产环境中通常会部署独立的 NFS 服务(比如用 NAS、GlusterFS、CephFS),而不是依赖容器内运行的 NFS Server。所以我这里使用了物理机的提前安装好的NFS服务。
1,StorageClass 定义
#创建新文件来定义
vim nfs-sc.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: managed-nfs-storage
provisioner: nfs.csi.k8s.io
parameters:
server: 172.16.81.129
share: /opt/k8s-data/nacos # ⬅️ 修改为你在 NFS 上为 nacos 准备的路径
reclaimPolicy: Retain
mountOptions:
- vers=4.1
使用 kubectl apply -f nfs-sc.yaml
来创建它。
2,创建NFS路径
在 NFS 服务器上(172.16.81.129):
mkdir -p /opt/k8s-data/nacos
chmod 777 /opt/k8s-data/nacos
确保这个路径已经在 /etc/exports
中:
/opt/k8s-data *(rw,sync,no_subtree_check,no_root_squash)
然后重新加载 NFS 配置:
exportfs -ra
3,确认 csi-driver 已正确安装
NFS CSI 驱动是实现自动创建 PV(动态供给),不用手动创建。
手动创建可自行参考:Kubernetes(k8s)搭建部署redis cluster集群
查看是否安装命令:
kubectl get csidriver
没有安装的话可以用以下方式安装:
#在线安装(目前最新版本v4.11.0):
curl -skSL https://raw.githubusercontent.com/kubernetes-csi/csi-driver-nfs/v4.11.0/deploy/install-driver.sh | bash -s v4.11.0 --
#下载本地安装
git clone https://github.com/kubernetes-csi/csi-driver-nfs.git
cd csi-driver-nfs
./deploy/install-driver.sh v4.11.0 local
三,启动yaml 文件修改
修改默认的nacos-pvc-nfs.yaml
配置文件,有些配置不需要,或者需要更改配置。
1,增加namespace
方便以后管理,这里单独创建一个namaspace和其他隔离,不创建也行,会在默认namespace中。
vim namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: backend-cluster
使用 kubectl apply -f namespace.yaml
来创建backend-cluster
命名空间。
默认配置文件,也需增加
namespace: backend-cluster
2,修改 YAML的 serviceAccountName
由于使用的自定义的NFS,需要删除原来的账号配置,否则报错
# 原来
spec:
serviceAccountName: nfs-client-provisioner
改为 删除该行,或者改为默认的:
# 可选:使用默认服务账号
spec:
serviceAccountName: default
3,peer-finder-plugin-install 镜像修改
默认的官方镜像,只有amd版本,没有arm版本,按需修改。
initContainers:
- name: peer-finder-plugin-install
image: nacos/nacos-peer-finder-plugin:1.1
修改为下面的镜像,支持amd和arm系统。
initContainers:
- name: peer-finder-plugin-install
image: minstonehub/nacos-peer-finder-plugin:1.1
4,降低配置和改成软约束(可选)
已经有3个节点以上,配置足够,无需修改。这里测试只有2个node,所以需要修改配置,跑3个nacos。
修改方式一:
降低副本数到2,默认是3个副本
spec:
replicas: 2
修改方式二:
不想降低副本,需要3个副本测试集群。
当前 StatefulSet
配置中使用了 pod 反亲和性(PodAntiAffinity):
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: "app"
operator: In
values:
- nacos
topologyKey: "kubernetes.io/hostname"
意思是:Nacos 的 Pod 必须调度到不同的节点(即 nacos-0、nacos-1、nacos-2 各在不同节点)
可以改成软约束(preferred):
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
podAffinityTerm:
labelSelector:
matchExpressions:
- key: "app"
operator: In
values:
- nacos
topologyKey: "kubernetes.io/hostname"
这样如果能调度到不同节点就尽量不同,如果不能也能调度到相同节点。
如果服务器配置不够,也会无法启动,这里测试降低内存配置,2G改为1G。
resources:
requests:
memory: "1Gi"
cpu: "500m"
5,开启鉴权和使用外部数据库
数据库这里也是使用外部,不使用k8s内部的数据库,因为实际生产部署,数据库一般使用数据库官方集群部署。
data:
mysql.host: "198.19.249.12"
mysql.db.name: "nacos"
mysql.port: "3306"
mysql.user: "root"
mysql.password: "qwe123"
添加鉴权相关配置:
#这段配置,3.0以下需要加,3.0+以上不需要,默认开启
- name: NACOS_AUTH_ENABLE
value: "true"
3.0+配置4个足矣,3.0以下5个配置
---
apiVersion: v1
kind: Service
metadata:
name: nacos-headless
....
- name: NACOS_AUTH_ENABLE
value: "true"
- name: NACOS_SERVERS
value: "nacos-0.nacos-headless.default.svc.cluster.local:8848,nacos-1.nacos-headless.default.svc.cluster.local:8848,nacos-2.nacos-headless.default.svc.cluster.local:8848"
- name: NACOS_AUTH_TOKEN
value: ${your_nacos_auth_secret_token}
- name: NACOS_AUTH_IDENTITY_KEY
value: ${your_nacos_server_identity_key}
- name: NACOS_AUTH_IDENTITY_VALUE
value: ${your_nacos_server_identity_value}
selector:
matchLabels:
app: nacos
6,完整配置
修改nacos-pvc-nfs.yaml
配置如下
nacos-k8s/deploy/nacos# cat nacos-pvc-nfs.yaml
# 请阅读Wiki文章
# https://github.com/nacos-group/nacos-k8s/wiki/%E4%BD%BF%E7%94%A8peerfinder%E6%89%A9%E5%AE%B9%E6%8F%92%E4%BB%B6
---
apiVersion: v1
kind: Service
metadata:
name: nacos-headless
namespace: backend-cluster
labels:
app: nacos
spec:
publishNotReadyAddresses: true
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
clusterIP: None
selector:
app: nacos
---
apiVersion: v1
kind: ConfigMap
metadata:
name: nacos-cm
namespace: backend-cluster
data:
mysql.host: "198.19.249.12"
mysql.db.name: "nacos"
mysql.port: "3306"
mysql.user: "root"
mysql.password: "qwe123"
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: nacos
namespace: backend-cluster
spec:
podManagementPolicy: Parallel
serviceName: nacos-headless
replicas: 3
template:
metadata:
labels:
app: nacos
annotations:
pod.alpha.kubernetes.io/initialized: "true"
spec:
affinity:
podAntiAffinity:
#requiredDuringSchedulingIgnoredDuringExecution:
#- labelSelector:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
podAffinityTerm:
labelSelector:
matchExpressions:
- key: "app"
operator: In
values:
- nacos
topologyKey: "kubernetes.io/hostname"
initContainers:
- name: peer-finder-plugin-install
#image: nacos/nacos-peer-finder-plugin:1.1
image: minstonehub/nacos-peer-finder-plugin:1.1
imagePullPolicy: Always
volumeMounts:
- mountPath: /home/nacos/plugins/peer-finder
name: data
subPath: peer-finder
containers:
- name: nacos
imagePullPolicy: Always
image: nacos/nacos-server:latest
resources:
requests:
memory: "1Gi"
cpu: "500m"
ports:
- containerPort: 8848
name: client-port
- containerPort: 9848
name: client-rpc
- containerPort: 9849
name: raft-rpc
- containerPort: 7848
name: old-raft-rpc
env:
- name: NACOS_REPLICAS
value: "3"
- name: SERVICE_NAME
value: "nacos-headless"
- name: DOMAIN_NAME
value: "cluster.local"
- name: POD_NAMESPACE
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.namespace
- 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: SPRING_DATASOURCE_PLATFORM
value: "mysql"
- name: NACOS_SERVER_PORT
value: "8848"
- name: NACOS_APPLICATION_PORT
value: "8848"
- name: PREFER_HOST_MODE
value: "hostname"
- name: NACOS_SERVERS
#更改过命名空间,default改成backend-cluster
value: "nacos-0.nacos-headless.backend-cluster.svc.cluster.local:8848,nacos-1.nacos-headless.backend-cluster.svc.cluster.local:8848,nacos-2.nacos-headless.backend-cluster.svc.cluster.local:8848"
- name: NACOS_AUTH_TOKEN
value: "fkd5b2JB1MDfDCZm7aiKIynemyAF6k8tUkzKL/QVjN8="
- name: NACOS_AUTH_IDENTITY_KEY
value: "nacos"
- name: NACOS_AUTH_IDENTITY_VALUE
value: "nacos"
volumeMounts:
- name: data
mountPath: /home/nacos/plugins/peer-finder
subPath: peer-finder
- name: data
mountPath: /home/nacos/data
subPath: data
- name: data
mountPath: /home/nacos/logs
subPath: logs
volumeClaimTemplates:
- metadata:
name: data
annotations:
volume.beta.kubernetes.io/storage-class: "managed-nfs-storage"
spec:
accessModes: [ "ReadWriteMany" ]
resources:
requests:
storage: 20Gi
selector:
matchLabels:
app: nacos
最后启动kubectl apply -f nacos-pvc-nfs.yaml
服务。
查看服务正常启动。
root@master:/opt/nacos-k8s/deploy/nacos# kubectl get pods -n backend-cluster -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nacos-0 1/1 Running 0 52m 10.244.196.191 node01 <none> <none>
nacos-1 1/1 Running 0 52m 10.244.196.129 node01 <none> <none>
nacos-2 1/1 Running 0 52m 10.244.219.78 master <none> <none>
四,访问 Nacos Web 管理界面
此nacos版本为3.0+,管理界面不在是 ip:8848/nacos,而是直接访问8080端口,所以服务都是暴露8080端口。
版本3.0以下改成8848端口即可。
方式一:本地端口转发(最简单)
执行命令后,你就可以在本地浏览器访问 http://localhost:8080
kubectl port-forward -n backend-cluster svc/nacos-headless 8080:8080
适合测试、临时访问,不需要暴露服务到公网。
方式二:添加一个 NodePort 服务(暴露到集群外部)
修改你的服务配置 nacos-service.yaml
(你需要手动创建一个非 Headless 的 Service):
apiVersion: v1
kind: Service
metadata:
name: nacos
namespace: backend-cluster
labels:
app: nacos
spec:
type: NodePort
selector:
app: nacos
ports:
- name: client
port: 8080
targetPort: 8080
nodePort: 30848 # 任意30000-32767之间未占用端口
然后部署:
kubectl apply -f nacos-service.yaml
现在可以通过 任意 Node 的 IP + nodePort 访问 Nacos:
http://<NodeIP>:30848/nacos
例如:
http://192.168.88.11:30848
(你可以通过 kubectl get nodes -o wide
查看节点实际 IP)
方式三:Ingress 方式(生产推荐)
创建一个普通 Service(暴露给 Ingress 使用)
# nacos-service.yaml
apiVersion: v1
kind: Service
metadata:
name: nacos
namespace: backend-cluster
labels:
app: nacos
spec:
selector:
app: nacos
ports:
- port: 8080
targetPort: 8080
protocol: TCP
name: http
type: ClusterIP
注意:不要用 nacos-headless
,Ingress 要用普通 Service 才能转发。
创建 Ingress 资源(以 nginx-ingress 为例)
# nacos-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nacos-ingress
namespace: backend-cluster
annotations:
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
spec:
rules:
- host: nacos.local
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nacos
port:
number: 8080
应用配置:
kubectl apply -f nacos-service.yaml
kubectl apply -f nacos-ingress.yaml
浏览器访问测试,局域网本地配置hosts,如服务器IP为172.16.81.128
172.16.81.128 nacos.local
最后浏览器访问,Ingress两种模式访问
#1:使用 NodePort 暴露 Ingress(最常见)
#kubectl get svc -n ingress-nginx 查看暴露的端口,如:80:30201/TCP,然后访问
http://nacos.local:30201
#2: 使用 hostNetwork 模式(无需端口映射)
#如果安装 Ingress Controller 时用了 hostNetwork: true,那么它会直接监听节点的 80、443 端口,直接访问
http://nacos.local
任意node节点都可以访问,测试命令
#master
curl http://172.16.81.128:30201 -H "Host: nacos.local"
#node
curl http://172.16.81.129:30201 -H "Host: nacos.local"