1. 排查流程
Failed to instantiate [org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier]: Factory method 'discoveryClientServi ceInstanceListSupplier' threw exception with message: Error creating bean with name 'nacosProperties': Unsatisfied dependency expressed through field 'inetIPv6Utils': Error creating bean with name ' inetUtilsProperties': Could not bind properties to 'InetUtilsProperties' : prefix=spring.cloud.inetutils, ignoreInvalidFields=false, ignoreUnknownFields=true
最近在协助子公司进行系统升级时,我们遇到了一个看似诡异的问题,新构建的镜像在本地测试环境一切正常,但部署到对方环境后,Nacos 竟然连接不上!奇怪的是,他们的旧系统却能正常注册到同一个 Nacos 服务端。
首先确认了Nacos连接配置无误,包括注册地址、账号密码以及针对bx命名空间的读写权限都已正确配置。
spring.cloud.nacos.discovery.server-addr = http://app-nacos1.bx.tanqidi.com:8848,http://app-nacos2.bx.tanqidi.com:8848,http://app-nacos3.bx.tanqidi.com:8848
spring.cloud.nacos.username = nacosbx
spring.cloud.nacos.password = 123456
spring.cloud.nacos.discovery.username = nacosbx
spring.cloud.nacos.discovery.password = 123456
spring.cloud.nacos.discovery.group = bx
spring.cloud.nacos.discovery.namespace = bx
为了快速验证是不是环境的问题,在对方的 KubeSphere 部署环境中进行了测试,结果一次通过且配置与我方环境完全一致,排除了配置不一致的问题。
随后在对方环境中,使用 host 网络单机启动了一个 Nacos 实例,运行正常,同样一次通过。由此开始怀疑其原有的 Nacos 集群可能存在问题。查阅官网部署文档后发现,官方建议开启 8848、9848、9849 三个端口。于是继续对其集群进行 telnet 测试,仅有一个端口可连通,而单独启动的实例因使用 host 网络,三个端口均可正常连接。
目标很接近了,是端口的问题,来到他们的中间件服务器使用脚本看看部署的时候是不是使用host或者bridge模式有没有正确映射端口。
执行脚本看从提取出来的信息来看,对方所部署的nacos集群确实是使用host网络模式的,那么非bridge模式的端口映射问题就排查了,所幸是host模式但是端口不通,那么最终就是防火墙的问题了,让对方开启允许访问9848,9849端口,重启一下java程序,完全正确!问题结束。
docker inspect --format 'docker run \
--name {{printf "%q" .Name}} \
{{- with .HostConfig}}
{{- if .Privileged}}
--privileged \
{{- end}}
{{- if .AutoRemove}}
--rm \
{{- end}}
{{- if .Runtime}}
--runtime {{printf "%q" .Runtime}} \
{{- end}}
{{- range $b := .Binds}}
--volume {{printf "%q" $b}} \
{{- end}}
{{- range $v := .VolumesFrom}}
--volumes-from {{printf "%q" $v}} \
{{- end}}
{{- range $l := .Links}}
--link {{printf "%q" $l}} \
{{- end}}
{{- if index . "Mounts"}}
{{- range $m := .Mounts}}
--mount type={{.Type}}
{{- if $s := index $m "Source"}},source={{$s}}{{- end}}
{{- if $t := index $m "Target"}},destination={{$t}}{{- end}}
{{- if index $m "ReadOnly"}},readonly{{- end}}
{{- if $vo := index $m "VolumeOptions"}}
{{- range $i, $v := $vo.Labels}}
{{- printf ",volume-label=%s=%s" $i $v}}
{{- end}}
{{- if $dc := index $vo "DriverConfig" }}
{{- if $n := index $dc "Name" }}
{{- printf ",volume-driver=%s" $n}}
{{- end}}
{{- range $i, $v := $dc.Options}}
{{- printf ",volume-opt=%s=%s" $i $v}}
{{- end}}
{{- end}}
{{- end}}
{{- if $bo := index $m "BindOptions"}}
{{- if $p := index $bo "Propagation" }}
{{- printf ",bind-propagation=%s" $p}}
{{- end}}
{{- end}} \
{{- end}}
{{- end}}
{{- if .PublishAllPorts}}
--publish-all \
{{- end}}
{{- if .UTSMode}}
--uts {{printf "%q" .UTSMode}} \
{{- end}}
{{- with .LogConfig}}
--log-driver {{printf "%q" .Type}} \
{{- range $o, $v := .Config}}
--log-opt {{$o}}={{printf "%q" $v}} \
{{- end}}
{{- end}}
{{- with .RestartPolicy}}
--restart "{{.Name -}}
{{- if eq .Name "on-failure"}}:{{.MaximumRetryCount}}
{{- end}}" \
{{- end}}
{{- range $e := .ExtraHosts}}
--add-host {{printf "%q" $e}} \
{{- end}}
{{- range $v := .CapAdd}}
--cap-add {{printf "%q" $v}} \
{{- end}}
{{- range $v := .CapDrop}}
--cap-drop {{printf "%q" $v}} \
{{- end}}
{{- range $d := .Devices}}
--device {{printf "%q" (index $d).PathOnHost}}:{{printf "%q" (index $d).PathInContainer}}:{{(index $d).CgroupPermissions}} \
{{- end}}
{{- end}}
{{- with .NetworkSettings -}}
{{- range $p, $conf := .Ports}}
{{- with $conf}}
--publish "
{{- if $h := (index $conf 0).HostIp}}{{$h}}:
{{- end}}
{{- (index $conf 0).HostPort}}:{{$p}}" \
{{- end}}
{{- end}}
{{- range $n, $conf := .Networks}}
{{- with $conf}}
--network {{printf "%q" $n}} \
{{- range $a := $conf.Aliases}}
--network-alias {{printf "%q" $a}} \
{{- end}}
{{- end}}
{{- end}}
{{- end}}
{{- with .Config}}
{{- if .Hostname}}
--hostname {{printf "%q" .Hostname}} \
{{- end}}
{{- if .Domainname}}
--domainname {{printf "%q" .Domainname}} \
{{- end}}
{{- if index . "ExposedPorts"}}
{{- range $p, $conf := .ExposedPorts}}
--expose {{printf "%q" $p}} \
{{- end}}
{{- end}}
{{- if .User}}
--user {{printf "%q" .User}} \
{{- end}}
{{- range $e := .Env}}
--env {{printf "%q" $e}} \
{{- end}}
{{- range $l, $v := .Labels}}
--label {{printf "%q" $l}}={{printf "%q" $v}} \
{{- end}}
{{- if not (or .AttachStdin (or .AttachStdout .AttachStderr))}}
--detach \
{{- end}}
{{- if .AttachStdin}}
--attach stdin \
{{- end}}
{{- if .AttachStdout}}
--attach stdout \
{{- end}}
{{- if .AttachStderr}}
--attach stderr \
{{- end}}
{{- if .Tty}}
--tty \
{{- end}}
{{- if .OpenStdin}}
--interactive \
{{- end}}
{{- if .Entrypoint}}
{{- /* Since the entry point cannot be overridden from the command line with an array of size over 1,
we are fine assuming the default value in such a case. */ -}}
{{- if eq (len .Entrypoint) 1 }}
--entrypoint "
{{- range $i, $v := .Entrypoint}}
{{- if $i}} {{end}}
{{- $v}}
{{- end}}" \
{{- end}}
{{- end}}
{{printf "%q" .Image}} \
{{range .Cmd}}{{printf "%q " .}}{{- end}}
{{- end}}' \
你的容器名
docker run \
--name "/nacos1" \
--runtime "runc" \
--volume "/data/nacos1:/data" \
--volume "/log/nacos1:/log" \
--log-driver "json-file" \
--restart "always" \
--network "host" \
--hostname "HYDOKVSRA123" \
--expose "8848/tcp" \
--env "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/app/jdk/bin:/app/jdk/jre/bin" \
--env "TZ=Asia/Shanghai" \
--env "JAVA_HOME=/app/jdk" \
--env "JRE_HOME=/app/jdk/jre" \
--env "CLASSPATH=.:/app/jdk/lib/dt.jar:/app/jdk/lib/tools.jar:/app/jdk/jre/lib" \
--env "MODE=cluster" \
--label "build-date"="20200705" \
--label "license"="GPLv2" \
--label "maintainer"="tanqidi Digital Platform Project Team Maintainers <crph_dp_zy@tanqidi.com>" \
--label "name"="CentOS Base Image" \
--label "vendor"="CentOS" \
--detach \
--entrypoint "bin/docker-entrypoint.sh" \
"harbor.bx.tanqidi.com/bx/nacos:dev_latest" \
2. 操作总结
Nacos 部署挺关键的,要是出了问题,不妨先看看部署的时候有没有按官方说的那样,把 8848、9848、9849 这三个端口都开放了,有时候就是因为端口没开全导致各种莫名其妙的问题。接着也可以看看防火墙是不是把这些端口给拦了。再不行,就去 GitHub 上翻翻别人提过的问题,说不定正好有人遇到过类似的情况,还顺手把解决办法写出来了。