docker容器中无法获取宿主机hostname的解决方案

 更新时间:2021年03月22日 09:08:45   作者:任庆  
这篇文章主要介绍了docker容器中无法获取宿主机hostname的解决方案,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

在nodejs环境中测试通过,其它语言同理,只需要使用获取环境变量的方法即可。

思路:

docker容器和宿主机环境是隔离的,但是可以在启动docker容器时将宿主机的主机名以环境变量的形式传入,代码在容器中获取该值即可。

操作:

docker run -d -p 3000:3000 --name myTest -e HOST_Q=$(hostname) mytest:v1 # 使用-e 参数传入环境变量,值为主机名

如果使用yml文件启动:

version: '3'
services:
 mysql:
 image: mysql:v1
 container_name: xx-mysql
 restart: always
 networks:
  - host
 environment:
  - MYSQL_ROOT_PASSWORD=xxx0209
  - HOST_Q=$(hostname) # 在这设置
 ports:
  - 3306:3306
 volumes:
  - /opt/data/mysql:/var/lib/mysql:z

启动成功后,容器内部环境变量就多了一个HOST_Q,接下来使用程序取出即可:

nodejs:

# 从process中取出环境变量对象
let env = process.env;
console.log(JSON.stringify(env));
# env['HOST_Q']就是最终要获取的主机名
 
# output
[2019-04-17T06:54:12.951Z] [e1e7115e0a33] [info]: {"NODE_VERSION":"8.9.4","HOSTNAME":"e1e7115e0a33","YARN_VERSION":"1.3.2","HOME":"/root","HOST_Q":"emg-ubuntu-pub02","PATH":"/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin","PWD":"/"}

java:

public class Test {
 public static void main(String[] args) {
  Map<String, String> map = System.getenv();
  String hostName = map.get("HOST_Q");
  System.out.println(hostName); 
 }
}

补充:docker容器无法访问宿主机报出 No route to host

一. 问题描述

在docker部署nacos的时候遇到了这个样子的问题No route to host 导致了nacos容器无法连接宿主机的docker数据库。

然后我就进入到了nacos容器里面,ping了宿主机的地址,结果是通着的,然后使用telnet测试了3306端口,结果也会报出这个异常。

原因是什么呢?明明数据库外部可以正常连接访问,但是宿主机内部容器确实无法访问?

二. 原因分析

在进行docker部署的时候我们采用的是bridge网桥的模式。

启动docker时,docker进程会创建一个名为docker0的虚拟网桥,用于宿主机与容器之间的通信。当启动一个docker容器时,docker容器将会附加到虚拟网桥上,容器内的报文通过docker0向外转发。

如果docker容器访问宿主机,那么docker0网桥将报文直接转发到本机,报文的源地址是docker0网段的地址。而如果docker容器访问宿主机以外的机器,docker的SNAT网桥会将报文的源地址转换为宿主机的地址,通过宿主机的网卡向外发送。

因此,当docker容器访问宿主机时,如果宿主机服务端口会被防火墙拦截,从而无法连通宿主机,出现No route to host的错误。

而访问宿主机所在局域网内的其他机器,由于报文的源地址是宿主机ip,因此,不会被目的机器防火墙拦截,所以可以访问。

三. 解决方案

1> 关闭宿主机的防火墙

systemctl stop firewalld

2> 在防火墙上开发指定的端口

firewall-cmd --zone=public --add-port=3306/tcp --permanent
firewall-cmd --zone=public --add-port=3307/tcp --permanent
firewall-cmd --reload

注:在进行完防火墙的操作之后最好是要进行以下docker的重启,systemctl restart docker,否则容器到因为虚拟网桥失效而导致的iptables failed问题

四. 小结

docker的容器网络连接一直是一个问题,容器与容器之间,容器与宿主机之间,容器跨主机访问,所以在涉及到容器的网络连接的时候要注意网络的问题。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。如有错误或未考虑完全的地方,望不吝赐教。

相关文章

  • Docker镜像的制作,上传,拉取和部署操作(利用阿里云)

    Docker镜像的制作,上传,拉取和部署操作(利用阿里云)

    这篇文章主要介绍了Docker镜像的制作,上传,拉取和部署操作(利用阿里云),具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-11-11
  • 树莓派3B+安装64位ubuntu系统和docker工具的操作步骤详解

    树莓派3B+安装64位ubuntu系统和docker工具的操作步骤详解

    这篇文章主要介绍了树莓派3B+安装64位ubuntu系统和docker工具,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-09-09
  • 浅析Docker镜像分层的注意事项

    浅析Docker镜像分层的注意事项

    不知道大家在对程序进行Docker镜像打包会不会有些疑惑,比如镜像分层打包最后汇总成程序的镜像问题,所以这篇针对一些问题进行了分析,文章主要介绍了Docker镜像分层的一些注意事项,有需要的朋友们可以参考学习,下面来一起看看吧。
    2016-10-10
  • docker实践之docker-compose部署mysql方式

    docker实践之docker-compose部署mysql方式

    这篇文章主要介绍了docker实践之docker-compose部署mysql方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-08-08
  • docker mysql启动时执行初始化sql

    docker mysql启动时执行初始化sql

    这篇文章主要介绍了docker mysql启动时执行初始化sql问题,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值 ,需要的朋友可以参考下
    2019-05-05
  • 详细讲解Docker-Compose部署Kafka KRaft集群环境

    详细讲解Docker-Compose部署Kafka KRaft集群环境

    这篇文章主要为大家介绍了Docker-Compose部署Kafka KRaft集群环境的全面详细讲解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-01-01
  • Windows Server 2016 安装 Docker的过程及遇到问题

    Windows Server 2016 安装 Docker的过程及遇到问题

    若要在 Windows Server 上安装 Docker,可以使用由 Microsoft 发布的 OneGet 提供程序 PowerShell 模块,接下来通过本文给大家介绍Windows Server 2016 安装 Docker的过程及遇到问题,一起看看吧
    2021-09-09
  • docker修改容器配置文件的3种方法总结

    docker修改容器配置文件的3种方法总结

    有时候可能需要修改运行在docker容器中的nginx的配置文件,或者其他一些已经运行和启动很久的容器中的配置文件,下面这篇文章主要给大家介绍了关于docker修改容器配置文件的3种方法,需要的朋友可以参考下
    2022-04-04
  • 详解Docker数据管理(数据卷&数据卷容器)

    详解Docker数据管理(数据卷&数据卷容器)

    容器中管理数据主要有两种方式,这篇文章主要介绍了详解Docker数据管理(数据卷&数据卷容器) ,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-10-10
  • docker构建nginx alpine镜像实现步骤

    docker构建nginx alpine镜像实现步骤

    这篇文章主要介绍了docker构建nginx alpine镜像实现步骤,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-08-08

最新评论