我在Docker容器中部署了dubbo的服务,在对外暴露服务时指定的host不知道怎么写。如果写宿主机的IP不行,写容器的ip,外部的应用调用不了。
Dubbo启动时执行“export url服务地址 ” 和“bind服务IP+PORT”两个动作, 这两个动作相关的IP地址是一致的,可以通过“<dubbo:protocol host="${dubbo.protocol.host}”来配置。
而在Docker容器与宿主主机所在网络是隔离(不能互通)的不同网段, 所以只能拆解dubbo的export和bind动作,分别使用不同ip,并在宿主主机上加上指向Docker容器的端口映射(docker run -p xxx:xxx)。
配置“<dubbo:protocol host="宿主网络IP”, 修改dubbo原RemotingException把0.0.0.0绑定到Docker容器, 加上端口映射即可对外暴露Dubbo服务了。
com.alibaba.dubbo.remoting.transport.AbstractServer
public AbstractServer(URL url, ChannelHandler handler) throws RemotingException {
super(url, handler);
localAddress = getUrl().toInetSocketAddress();
String host = url.getParameter(Constants.ANYHOST_KEY, false)
|| NetUtils.isInvalidLocalHost(getUrl().getHost())
? NetUtils.ANYHOST : getUrl().getHost();
bindAddress = new InetSocketAddress(host, getUrl().getPort());
this.accepts = url.getParameter(Constants.ACCEPTS_KEY, Constants.DEFAULT_ACCEPTS);
this.idleTimeout = url.getParameter(Constants.IDLE_TIMEOUT_KEY, Constants.DEFAULT_IDLE_TIMEOUT);
try {
doOpen();
if (logger.isInfoEnabled()) {
logger.info("Start " + getClass().getSimpleName() + " bind " + getBindAddress() + ", export " + getLocalAddress());
}
} catch (Throwable t) {
// throw new RemotingException(url.toInetSocketAddress(), null, "Failed to bind " + getClass().getSimpleName()
// + " on " + getLocalAddress() + ", cause: " + t.getMessage(), t);
//=======fix in docker env ================
logger.warn( "Failed to bind " + getClass().getSimpleName() + " on " + getLocalAddress() + ", cause: " + t.getMessage(), t);
bindAddress = new InetSocketAddress(NetUtils.ANYHOST, getUrl().getPort());
try {
doOpen();
if (logger.isInfoEnabled()) {
logger.info("FIX: Start " + getClass().getSimpleName() + " bind " + getBindAddress() + ", export " + getLocalAddress());
}
} catch (Throwable e) {
throw new RemotingException(url.toInetSocketAddress(), null, "Failed to bind " + getClass().getSimpleName()
+ " on " + getLocalAddress() + ", cause: " + t.getMessage(), t);
}
}
if (handler instanceof WrappedChannelHandler ){
executor = ((WrappedChannelHandler)handler).getExecutor();
}
}
( 如需要修改后的 dubbo-2.5.4-SNAPSHOT.jar 可给我留言)
扩展思路:可否使用NAT 使得Docker容器网络和宿主主机网络之间能过互通? 在混合环境下Docker的网络让人头大!
所有评论(0)