Windows宿主与docker容器网络连接——Windows10环境下“远程”访问docker中centos系统里的MySQL数据库之续集

 

时隔二十天,喵哥又开始设置docker里centos容器的网络。目标是实现在宿主——Windows10下面可以访问docker中centos容器里的MySQL数据库。

之前一篇博客记录的是喵哥妥协解决这个问题的方案——在172.17.0.0这个网段里面设置两个centos容器,这样就可以保证两者互相访问数据库,但这没有达到喵哥对数据库服务器的要求——在宿主(Windows10)下编程使用数据库。

这一次,喵哥从docker的网络模式开始学习、理解、然后去解决问题。

1.docker的网络模式

Docker常见的网络模式有:

  1. Bridge模式 --net=bridge(默认)
  2. Host模式 --net=host
  3. Container模式 --net=container:指定容器名
  4. None模式 --net=none
  5. 用户自定义模式

1.1bridge模式

Docker网络的默认模式,在docker run启动容器的时候,如果不加--net参数,就默认采用这种网络模式。其特点如下:

  • 使用一个 linux bridge,默认为 docker0

  • 使用 veth 对,一头在容器的网络 namespace 中,一头在 docker0 上

  • 该模式下Docker Container不具有一个公有IP,因为宿主机的IP地址与veth pair的 IP地址不在同一个网段内

  • Docker采用 NAT 方式,将容器内部的服务监听的端口与宿主机的某一个端口port 进行“绑定”,使得宿主机以外的世界可以主动将网络报文发送至容器内部

  • 外界访问容器内的服务时,需要访问宿主机的 IP 以及宿主机的端口 port

  • NAT 模式由于是在三层网络上的实现手段,故肯定会影响网络的传输效率。

  • 容器拥有独立、隔离的网络栈;让容器和宿主机以外的世界通过NAT建立通信

 

Docker完成以上网络配置的过程大致是这样的:

1. 在主机上创建一对虚拟网卡veth pair设备。veth设备总是成对出现的,它们组成了一个数据的通道,数据从一个设备进入,就会从另一个设备出来。因此,veth设备常用来连接两个网络设备。 

2. Docker将veth pair设备的一端放在新创建的容器中,并命名为eth0。另一端放在主机中,以veth65f9这样类似的名字命名,并将这个网络设备加入到docker0网桥中。

 

容器要跟外埠网络通信,还需要一个NAT路由器,在Windows下它的名称为dockerNAT。

外界的机器要访问docker容器,可以用端口映射的办法把docker容器的端口跟宿主的端口做一个映射即可。

iptables -t nat -A  DOCKER -p tcp --dport 8001 -j DNAT --to-destination 172.17.0.19:8000

在Windows下是:

netsh interface portproxy add v4tov4 listenaddress=主机的IP listenport=50001 connectaddress=172.17.0.2 connectport=3306

然而,对于我来说,这些还是不够。虽然,仿佛打通了外界机器与容器的通信,但是消息往往就到宿主就找不到路了。因为没有路由表。在宿主添加10.0.75.1到172.17.0.0网段的路由表,这样就可以了。

 

1.2host模式

定义:

Host 模式并没有为容器创建一个隔离的网络环境。而之所以称之为host模式,是因为该模式下的 Docker 容器会和 host 宿主机共享同一个网络 namespace,故 Docker Container可以和宿主机一样,使用宿主机的eth0,实现和外界的通信。换言之,Docker Container的 IP 地址即为宿主机 eth0 的 IP 地址。其特点包括:

  • 这种模式下的容器没有隔离的 network namespace

  • 容器的 IP 地址同 Docker host 的 IP 地址

  • 需要注意容器中服务的端口号不能与 Docker host 上已经使用的端口号相冲突

  • host 模式能够和其它模式共存

 

1.3container模式

 Container 网络模式是 Docker 中一种较为特别的网络的模式。处于这个模式下的 Docker 容器会共享其他容器的网络环境,因此,至少这两个容器之间不存在网络隔离,而这两个容器又与宿主机以及除此之外其他的容器存在网络隔离。  

 

1.4none模式

 

 网络模式为 none,即不为 Docker 容器构造任何网络环境。一旦Docker 容器采用了none 网络模式,那么容器内部就只能使用loopback网络设备,不会再有其他的网络资源。Docker Container的none网络模式意味着不给该容器创建任何网络环境,容器只能使用127.0.0.1的本机网络。

 

2.解决

其实在1.1中已经把解决的方案大致说明了。

只要添加一个10.0.75.1网关到172.17.0.0网段的路由表即可。由于是在宿主访问,不需要添加端口映射表。

 

route add -p 172.17.0.0 mask 255.255.255.0 10.0.75.2

然后只要在容器中的MySQL设置好访问权限即可:

mysql> grant all PRIVILEGES on db_name.* to 'username'@'xxx.xxx.xx.x' identified by 'password' WITH GRANT OPTION;
 
#说明#
 
/*
  数据库的授权用grant:
              grant 权限 on 数据库.表 to 用户 【identified by '密码'】 with grant option;
  其中,
              权限有:select、insert、update、delete和all privileges。
              数据库为本地存在的数据库名,表为数据库中的表,如果要全选某个项目,可用*代替,如
                    *.*表示所有数据库的表,exp_country.*表示exp_country中的所有表,max_sal.k1表示max_sal中的k1表。
              用户,可以在本地自建。也可以是远程的,用'username'@'IP地址'表示。
              密码为可选项。
              附带的with grant option可以使得被授权用户也有赋予其他用户权限的权力
  数据库收回权限用revoke:
              revoke 权限 【on 数据库.表】 option from 用户; 
*/

例如,喵哥的centos容器需要通过10.0.75.1来转发数据包,所以在MySQL中赋予权限的对象是10.0.75.1.

grant all PRIVILEGES on db_name.* to 'username'@'10.0.75.1' identified by 'password' WITH GRANT OPTION;

然后就可以在Windows端的MySQL登录centos的MySQL数据库了。

 

 

 

 

 

相关推荐
©️2020 CSDN 皮肤主题: 精致技术 设计师:CSDN官方博客 返回首页