localhost与0.0.0.0区别

工作中启动 rpc 后台服务,当配置文件中指定 127.0.0.1作为监听的源端 ip 时,k8s 集群探活失败,导致 pod 一直重启。将 127.0.0.1替换为 0.0.0.0时,可探活成功。

问题分析

pod 状态显示一直在重启,使用 kubectl logs -f project-rpc-599cb8b6f5-m7vhg --namespace project-standard查看 pod 日志,输出如下:

{"@timestamp":"2022-02-17T21:10:45.308+08","level":"info","content":"GotsignalSIGTERM,shuttingdown..."}

可见服务可以正常启动。但启动一段时间后会接受到 signal,由此推断应该是在 k8s 的 pod 探活阶段出现了问题。

查看配置文件,发现服务的启动 ip 为 127.0.0.1,为本机回环地址。该地址不可被外部网络使用。除非 k8s 集群进入此 pod 的流量无法被 127.0.0.1地址监听。

即使再同一机器进行测试,除非客户端指定使用 127.0.0.1作为目标地址,流量才可被正确监听。若使用本地网卡的其它 ip,则无法被正常监听。效果如下:

  1. 启动 grpc server:
go run main.go -f etc/go-zero.yml
Starting rpc server at 127.0.0.1:8889...
  1. client 使用 127.0.0.1 请求:
grpcurl -plaintext 127.0.0.1:8889 list
grpc.reflection.v1alpha.ServerReflection
pb.projectRpc
  1. client 使用本机 ip 请求:

ifconfig 查看本机 ip:

en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
	options=6463<RXCSUM,TXCSUM,TSO4,TSO6,CHANNEL_IO,PARTIAL_CSUM,ZEROINVERT_CSUM>
	ether 3c:22:fb:3e:f5:43
	inet6 fe80::53:88ee:4a82:f96b%en0 prefixlen 64 secured scopeid 0x6
	inet 192.168.0.103 netmask 0xffffff00 broadcast 192.168.0.255
	nd6 options=201<PERFORMNUD,DAD>
	media: autoselect
	status: active

grpcurl 发送请求:

grpcurl -plaintext 192.168.0.103:8889 list
Failed to dial target host "192.168.0.103:8889": dial tcp 192.168.0.103:8889: connect: connection refused

0.0.0.0表示本机所有 ip,集群进入的流量可被此 ip 地址正确监听。将监听地址改为 0.0.0.0后测试如下:

  1. 使用 127.0.0.1 测试:
grpcurl -plaintext 127.0.0.1:8889 list
grpc.reflection.v1alpha.ServerReflection
pb.projectRpc
  1. 使用 192.168.0.103 测试:
grpcurl -plaintext 192.168.0.103:8889 list
grpc.reflection.v1alpha.ServerReflection
pb.projectRpc

关于 127.0.0.10.0.0.0更多解释,可点击参考链接。

参考

127.0.0.1 和 0.0.0.0 地址的区别