如何将VM上的Consul客户端接入Kubernetes中的Consul集群?
问题:外部VM的Consul客户端无法加入K8s内的Consul集群
环境说明
- 物理服务器上运行4台VM:
- k8s master
- k8s worker 1(IP:192.168.1.207)
- k8s worker 2(IP:192.168.1.208)
- vm1(外部VM,IP:192.168.1.230)
- 通过Helm Chart在K8s集群部署Consul,每个worker节点运行1个server和1个client,集群内部服务发现正常。
当前Consul Helm配置
global: name: consul enabled: true datacenter: dc1 gossipEncryption: autoGenerate: true tls: enabled: true enableAutoEncrypt: true verify: true acls: manageSystemACLs: true # client: # exposeGossipPorts: true server: replicas: 2 # exposeGossipAndRPCPorts: true # ports: # serflan: # port: 9301 extraConfig: | { "log_level": "debug" } exposeService: enabled: true type: NodePort nodePort: http: 31500 # 8500 + 23k https: 31501 # 8501 + 23k grpc: 31503 # 8503 + 23k serf: 32301 # 9301 + 23k rpc: 31300 # 8300 + 23k securityContext: runAsNonRoot: false runAsUser: 0 storageClass: nfs-synology-test connectInject: enabled: true controller: enabled: true syncCatalog: enabled: true dns: enabled: true
外部VM(vm1)的Consul客户端配置
{ "server": false, "domain": "consul", "datacenter": "dc1", "data_dir": "/etc/consul/data", "tls": { "defaults": { "ca_file": "/etc/consul/tls/ca/tls.crt", "verify_incoming": false, "verify_outgoing": true }, "internal_rpc": { "verify_server_hostname": true } }, "auto_encrypt": { "tls": true }, "encrypt": "redacted", "log_level": "DEBUG", "enable_syslog": true, "leave_on_terminate": true, "retry_join": [ "192.168.1.207:32301", "192.168.1.208:32301", "10.233.94.138:8300", "10.233.119.94:8300" ], "advertise_addr": "192.168.1.230", "bind_addr": "0.0.0.0", "ports": { "server": 31300 }, "acl": { "tokens": { "agent": "redacted", "default": "redacted" } } }
ACL策略(用于客户端token)
node_prefix "" { policy = "write" } service_prefix "" { policy = "read" }
遇到的错误
- UDP连接失败
- 客户端自动尝试连接K8s内部集群IP(未加入
retry_join列表) - 超时错误,以及
rpc error: lead thread didn't get connection
解决方案
1. 补全Gossip的UDP端口暴露
Consul的Serf Gossip同时依赖UDP和TCP,你当前只暴露了TCP端口,需要在Helm配置中新增UDP端口映射:
server: exposeService: enabled: true type: NodePort nodePort: # ... 保留原有端口配置 serfUdp: 32302 # 新增:UDP 9301映射到NodePort 32302
更新后重新部署:helm upgrade consul hashicorp/consul -f your-values.yaml
2. 清理无效的retry_join地址
删掉K8s内部Cluster IP(10.233.x.x),这些地址对外部VM不可访问,修改客户端的retry_join为:
"retry_join": [ "192.168.1.207:32301", "192.168.1.208:32301" ]
3. 删除客户端无用的端口配置
客户端节点不需要ports.server配置,直接删掉这一行,避免混淆:
// 移除该行 "ports": { "server": 31300 },
4. 补充ACL权限
当前策略缺少客户端注册自身agent的权限,更新ACL策略:
node_prefix "" { policy = "write" } service_prefix "" { policy = "read" } agent_prefix "" { policy = "write" }
重新生成token并替换客户端配置中的acl.tokens值。
5. 验证网络连通性
在vm1上执行以下命令确认端口可达:
# 验证UDP Gossip端口 nc -uvz 192.168.1.207 32302 nc -uvz 192.168.1.208 32302 # 验证TCP RPC端口 nc -vz 192.168.1.207 31300
6. 修正Consul Server的宣告地址
确保K8s内的Consul Server对外宣告Worker节点的外部IP,在Helm配置中添加:
server: extraConfig: | { "log_level": "debug", "advertise_addr": "{{ GetInterfaceIP \"eth0\" }}" }
如果Worker节点IP是静态的,也可以直接写死IP,比如"advertise_addr": "192.168.1.207"(每个server对应自身Worker节点IP)。
内容的提问来源于stack exchange,提问作者Lukáš Stuchlík
相关产品推荐
相关产品推荐

