Kubernetes(k8s)搭建部署nacos集群

✍️Auth:运维笔记       Date:2025/06/18       Cat:Linux服务器       👁️:100 次浏览

一,下载官方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"

打赏作者

发表评论