时隔二十天,喵哥又开始设置docker里centos容器的网络。目标是实现在宿主——Windows10下面可以访问docker中centos容器里的MySQL数据库。
之前一篇博客记录的是喵哥妥协解决这个问题的方案——在172.17.0.0这个网段里面设置两个centos容器,这样就可以保证两者互相访问数据库,但这没有达到喵哥对数据库服务器的要求——在宿主(Windows10)下编程使用数据库。
这一次,喵哥从docker的网络模式开始学习、理解、然后去解决问题。
1.docker的网络模式
Docker常见的网络模式有:
-
Bridge模式 --net=bridge(默认)
-
Host模式 --net=host
-
Container模式 --net=container:指定容器名
-
None模式 --net=none
-
用户自定义模式
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
遇到的问题:
windows 上docker run时使用 --network=host 希望容器共享 Docker host 的网络栈,容器的网络配置与 host 完全一样。
服务启动后,使用localhost,vEthernet中IP 均无法访问容器内服务。怀疑--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上调用docker中centos系统里面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 .,如下图所示: