起因:原先部署的 nacos 在服务器上,一直都是用 ip:port 的方式,维护下可谓是很差了,故想要直接部署到 k8s 后续方便管理。

k8s deploy 文件的编写

这里可以参考 nacos-k8s 项目的配置文件

nacos-no-pvc-ingress.yaml  
nacos-pvc-ceph.yaml  
nacos-pvc-nfs.yaml  
nacos-quick-start.yaml  

这里我们一般自己部署 mysql 所以不需要 pvc 对配置进行持久化,所以选择 nacos-no-pvc-ingress.yaml 即可

###使用自建数据库;使用Ingress发布配置后台###
---
apiVersion: v1
kind: Service
metadata:
  name: nacos-headless
  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
data:
  # 修改为自己的数据库配置
  mysql.host: "mysql"
  mysql.db.name: "nacos_devtest"
  mysql.port: "3306"
  mysql.user: "nacos"
  mysql.password: "nacos"
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: 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"
      containers:
        - name: nacos
          imagePullPolicy: Always
          image: nacos/nacos-server:latest
          resources:
            requests:
              # 我觉得 1Gi 就够了
              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: SPRING_DATASOURCE_PLATFORM
              value: "mysql"
            - name: MODE
              value: "cluster"
            - name: NACOS_SERVER_PORT
              value: "8848"
            - name: PREFER_HOST_MODE
              value: "hostname"
            - 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"
              # 为 true 则可以开启权限
            - name: NACOS_AUTH_ENABLE
              value: "true"
  selector:
    matchLabels:
      app: nacos




---
# ------------------- App Ingress ------------------- #
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nacos-headless
spec:
  rules:
    # 填写自己 k8s 集群中 ingress 对外暴露的域名
  - host: nacos-web.nacos-demo.com
    http:
      paths:
      - path: /nacos
        pathType: Prefix
        backend:
          service: 
            name: nacos-headless
            port:
              name: server

上面配置要注意以下几点

  • 如果你部署到非 default 命名空间,需要修改 NACOS_SERVERS 配置。辟如我需要将 nacos 部署到 test 命名空间,NACOS_SERVERS 的值则为 nacos-0.nacos-headless.test.svc.cluster.local:8848 nacos-1.nacos-headless.test.svc.cluster.local:8848 nacos-2.nacos-headless.test.svc.cluster.local:8848
  • 部署到公网后切记需要开启权限
    # 为 true 则可以开启权限
    name: NACOS_AUTH_ENABLE
    value: "true"
    
    开启权限后你需要在原来项目拉取配置和注册的配置中补充以下内容给
    spring.cloud.nacos.config.username={username}
    spring.cloud.nacos.config.password={password}
    spring.cloud.nacos.discovery.username={username}
    spring.cloud.nacos.discovery.password={password}
    
    {username} {password} 替换为 nacos ui 登录的账号密码即可

程序获取配置和注册

在上述内容已经部署完成后,我们访问 https://nacos-web.nacos-demo.com/nacos 应该就能正常访问了。但我们原来是用 ip:port 的方式访问的,如果你现在将 spring.cloud.nacos.config.server-addr 配置单纯的改为 https://nacos-web.nacos-demo.com/nacos 你会发现根本拉不到配置和注册。
我们追溯到代码中 ServerHttpAgent#getUrl 这个方法

private String getUrl(String serverAddr, String relativePath) {
    // this.serverListMgr 的结果为 nacos
    String contextPath = this.serverListMgr.getContentPath().startsWith("/") ? this.serverListMgr.getContentPath() : "/" + this.serverListMgr.getContentPath();
    // 那么这里会自动拼接为 https://nacos-web.nacos-demo.com/nacos + /nacos + xxxxx
    return serverAddr + contextPath + relativePath;
}

getUrl 中多拼接了一个 /nacos,所以我们 spring.cloud.nacos.config.server-addr 的值直接填写 https://nacos-web.nacos-demo.com 即可。

nacos-web.nacos-demo.com 是演示用的,自己部署的话 yaml 别填这个,填写自己 k8s 集群中 ingress 对外暴露的域名。