在 k8s 中部署公网可访问的 Nacos 集群
起因:原先部署的 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 对外暴露的域名。