添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

时隔二十天,喵哥又开始设置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的本机网络。

其实在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数据库了。

2.启动一个mysql镜像,并获取这个镜像的IP: 在开始的时候,从本机直接到172.17.0.2是网络不通的,但是我们本机能到 192.168.99.100,172.17.0.2到192.168.99.100也是通的,我们可以在本机配置一个到172.17.0.2通过192.168.99.100的路由: route add -p 172.17.0.0 mask 255.255.0.0 192.168.99.100 遇到的问题: windowsdocker run时使用 --network=host 希望容器共享 Docker host网络栈,容器网络配置与 host 完全一样。 服务启动后,使用localhost,vEthernetIP 均无法访问容器内服务。怀疑--network=host 没有生效。 使用docker run -p 0.0.0.0:host_port:docker_port 指定容器到主机的映射端口,重新创. 从图可看见,192.168.99.1就是docker的虚拟网卡ip,使用Docker desktop启动的docker就是如图的适配器名称,使用Docker toolbox部署的docker,网卡适配器名称是VirtualBox。作者踩的坑:我自己在度娘遨游的时候,找到了两种方法,一个是建立一个容器网络network,将容器放入这个容器网络,这种方式只能实现容器容器直接的快速交互, 若用docker虚拟网卡ip其实也可以互相访问,没必要建立容器网络mysql -u root -pvmwaremysql>use mysql; mysql>update user set host = ‘%’ where user = ‘root’; mysql>select host, user from user; 好了没了。 补充知识:Docker连接数据库容器无法本地访问,但可以远程访问的问题 以前我用id 创建网桥启动容器的同时绑定网桥同时设置固定ip​ 启动另一个服务​ 使用网桥的好处就是容器之间是共享网络的,双向的,比–link的方式要灵活,而且容器内ip可以指定号,更加可控。 目前安装,本地电脑(windows10)-vmware虚拟机(centos 7)-docker容器 网络地址 想在本地电脑上访问docker容器内服务,需要三者之间互相ping通,涉及3个IP地址 1、本地电脑IP,也即宿主机IP。通过在本地cmd采用ipconfig命令查看 2、虚拟机IP,也即宿主服务器IP。通过在虚拟机上ip addr命令查看 3、docker容器IP,通过在虚拟机上ip ... 最近,喵哥在学习数据库,遇到一个很棘手的问题,具体描述如下。 可以在黑底白字的界面熟练操作数据库的确很酷,但是实际应用数据库肯定不是为了耍酷,怎么把数据库运用到程序去才是真理。所以,喵哥就投入到怎么在Windows10上调用dockercentos系统MySQL数据库的工作。然而,事情远没有想象那么简单,安装好MySQL之后,一直连不上centos数据库。后来,去找视频学习了一... 大家玩过Docker Desktop的都知道。它设置有个2375端口是可以开放的。但是它默认绑定的是localhost。 那么有什么办法可以让别的客户端机器也能进行访问呢?这时候我们就需要用一个windows自带的命令进行端口代理(your-public-ip是你的主机当前的ipv4地址): cmd以管理员身份运行: netsh interface portproxy add v4tov4 listenport=2375 connectaddress=127.0.0.1 connectport=2375 Docker网络模式host host模型比较适合于,一台宿主机跑一个固定的容器,比较稳定,或者一个宿主机跑多个占用不同端口的应用的场景,他的网络性能是很高的。 host模型启动的容器不会有任何地址,他其实是使用了宿主机的所有信息 nginx :80 mysql:3306 redis: 6379 docker run --net=host -itd --name [容器名称] 镜像名称 do... 二、创建redis容器: ①、docker create --name redis-node1 --net host -v /data/redis-data/node1:/data redis --cluster-enabled yes --cluster-config-file nodes-node1.conf --port 6379 ②、docker docker的安装方法请看:https://blog.csdn.net/sunxiaoju/article/details/96972288 1、首先创建一个基础镜像,通过Dockerfile文件来创建,然后文件内容为: FROM ubuntu 如下图所示: 2、然后进入到该文件目录,执行:docker build -t ubuntu:wincom-node .,如下图所示: