Docker网络管理-网络模式
docker有四种网络模式:
- host模式,使用docker run时使用--net=host指定docker使用的网络实际上和宿主机一样,在容器内看到的网卡ip是宿主机上的ip
- container模式,使用--net=container:container_id/container_name多个容器使用共同的网络,看到的ip是一样的
- none模式,使用--net=none指定这种模式下,不会配置任何网络
- bridge模式,使用--net=bridge指定默认模式,不用指定默认就是这种网络模式。这种模式会为每个容器分配一个独立的Network Namespace。类似于vmware的nat网络模式。同一个宿主机上的所有容器会在同一个网段下,相互之间是可以通信的。
host模式
[root@study ~]# docker run -it --rm --net=host centos-7-x86_64-minimal bash
[root@study /]# ifconfig
docker0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
inet 172.17.0.1 netmask 255.255.0.0 broadcast 0.0.0.0
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.8.139 netmask 255.255.255.0 broadcast 192.168.8.255
docker0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
inet 172.17.0.1 netmask 255.255.0.0 broadcast 0.0.0.0
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.8.139 netmask 255.255.255.0 broadcast 192.168.8.255
即,容器IP和母机IP一样。
container模式
[root@study ~]# docker run -itd --name test centos bash
cf20bbfce47ed505874ec741b3f8bd76b080e20eba4a2773c58f25ce2787d67d
[root@study ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
cf20bbfce47e centos "bash" 11 seconds ago Up 8 seconds test
[root@study ~]# docker exec -it test bash
[root@cf20bbfce47e /]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.2 netmask 255.255.0.0 broadcast 0.0.0.0
[root@study ~]# docker run -it --net=container:test --name test2 centos_with_net bash
[root@cf20bbfce47e /]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.2 netmask 255.255.0.0 broadcast 0.0.0.0
即,容器test2和test的IP一样,且id也一样。
none模式
[root@study ~]# docker run -it --rm --net=none --name test3 centos_with_net bash
[root@043d5e570507 /]# ifconfig
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
无网络连接。
bridge模式
平时使用的模式。。
Docker网络管理-如何让外部网络访问docker资源
首先使用centos镜像新建一个容器,然后在该容器中安装httpd服务,并启动 ,再把该容器导成一个新的镜像(centos-httpd),然后再使用新镜像创建容器,并指定端口映射:
docker run -itd -p 5123:80 centos-httpd bash //-p
可以指定端口映射,本例中将容器的80端口映射为本地的5123端口
[root@study ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
cf20bbfce47e centos "bash" 27 hours ago Up 2 minutes test
[root@study ~]# docker exec -it test bash
安装httpd服务:
[root@cf20bbfce47e /]# yum install -y httpd
启动httpd服务:
[root@cf20bbfce47e /]# httpd -k start
将test容器保存为新的镜像:
[root@study ~]# docker commit -m "centos_installd_httpd" -a "adailinux" test centos_with_httpd:adai
[root@study ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos_with_httpd adai ccd04a9b21a1 9 seconds ago
做端口映射:
[root@study ~]# docker run -itd --name test2 -p 5123:80 centos_with_httpd:adai bash
##-p:指定映射端口
##将宿主机的某端口映射到容器的80端口
[root@study ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
641e7f27617e centos_with_httpd:adai "bash" 18 seconds ago Up 16 seconds 0.0.0.0:5123->80/tcp test2
进入test2容器:
[root@study ~]# docker exec -it test2 bash
启动httpd服务:
[root@641e7f27617e /]# httpd -k start
创建测试文件:
[root@641e7f27617e /]# vi /var/www/html/test.html
adai is here!
测试:
[root@641e7f27617e /]# curl localhost/test.html
adai is here!
在宿主机测试:
[root@study ~]# curl 192.168.8.139:5123/test.html
adai is here!
##访问成功!
Docker网络管理-容器互联
在同一台母机上的容器可以通过IP连接,配置容器互联后,容器之间可以通过name进行连接。
查看test2的IP:
[root@study ~]# docker exec -it test2 bash
[root@641e7f27617e /]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.3 netmask 255.255.0.0 broadcast 0.0.0.0
在test容器中测试test2 的连通性:
[root@study ~]# docker exec -it test bash
[root@cf20bbfce47e /]# curl 172.17.0.3/test.html
adai is here!
##通畅!!!
准备工作
创建一个数据库容器data:
创建容器db:
[root@study ~]# docker run -itd --name db centos_with_net /usr/sbin/init
[root@study ~]# docker exec -it db bash
安装centos7自带mariadb数据库:
[root@a3254ef9500d /]# yum install -y mariadb mariadb-server
启动mariadb:
[root@d9699f1a028b /]# systemctl start mariadb
[root@d9699f1a028b /]# netstat -lntp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:3306 0.0.0.0:* LISTEN -
##启动成功!
保存该容器为新镜像:
[root@study ~]# docker commit -m "centos_with_mariadb" -a "adai" db centos_with_mariadb
创建数据库容器data:
[root@study ~]# docker run -itd --name data -p 13306:3306 centos_with_mariadb /usr/sbin/init
数据库容器创建完成!
排错:
如果你是使用bash创建centos7的docker容器(docker run -itd centos bash),那么在运行systemctl命令时可能会要到如下报错:
[root@study ~]# docker run -itd --name db centos_with_net bash
[root@a3254ef9500d /]# systemctl start mariadb
Failed to get D-Bus connection: Operation not permitted
原因:dbus-daemon没能启动。其实systemctl并不是不可以使用,需要在启动容器的时候将CMD或者entrypoint设置为/usr/sbin/init,这样才能自动将dbus等服务启动起来,方法如下:
[root@study ~]# docker run -itd --name db centos_with_net /usr/sbin/init
然后再使用systemctl命令就可以了。
有的人说在CentOS7.2中解决了通过systemctl运行报错的问题,但是我在实际操作中还是遇到这样的问题。 还有一种解决办法,就是在通过Dockerfile生成镜像文件的时候通过CMD来执行/usr/sbin/init这条命令,即: CMD [ "/usr/sbin/init"]。
参考:https://github.com/docker/docker/issues/7459 https://github.com/docker/docker/issues/2296
连接数据库容器
新建一个web容器并和data容器互联:
[root@study ~]# docker run -itd -p 18080:80 --name web --link data:webdb centos_with_httpd:adai /usr/sbin/init
## --link:参数中data为数据库容器的名称,webdata为web容器中数据库显示的名称
在web上运行env命令可以查看到关于db的环境变量:
[root@study ~]# docker exec -it web bash
[root@ce08c9da9129 /]# env
WEBDB_PORT_3306_TCP=tcp://172.17.0.4:3306
HOSTNAME=ce08c9da9129
WEBDB_NAME=/web/webdb
TERM=xterm
WEBDB_PORT=tcp://172.17.0.4:3306
WEBDB_PORT_3306_TCP_PROTO=tcp
PWD=/
SHLVL=1
HOME=/root
WEBDB_PORT_3306_TCP_ADDR=172.17.0.4
WEBDB_PORT_3306_TCP_PORT=3306
查看data容器IP:
[root@study ~]# docker exec -it data bash
[root@0e945222f8c0 /]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.4 netmask 255.255.0.0 broadcast 0.0.0.0
即,两容器完成互连。
Docker网络管理-配置桥接网络(方法一)
建议:在进行该操作前先做快照!!!
为了使本地网络中的机器和Docker容器更方便的通信,我们经常会有将Docker容器配置到和主机同一网段的需求。这个需求其实很容易实现,我们只要将Docker容器和宿主机的网卡桥接起来,再给Docker容器配上IP就可以了。
系统:centos7
宿主机网卡信息:
name:ens33
IP:192.168.8.139
gateway:192.168.8.2
dns:119.29.29.29
停止docker服务
[root@study ~]# systemctl stop docker
删除docker0网卡
安装网桥配置命令:
[root@study ~]# yum install -y bridge-utils
[root@study ~]# ip link set dev docker0 down
[root@study ~]# brctl delbr docker0
新建桥接物理网络虚拟网卡br0
添加网卡br0:
[root@study ~]# brctl addbr br0
[root@study ~]# ip link set dev br0 up
为br0分配物理网络中的ip地址:
[root@study ~]# ip addr add 192.168.8.201/24 dev br0
##此处虚拟机网络可能会中断
将宿主机网卡的IP清空:
[root@study ~]# ip addr del 192.168。8.139/24 dev ens0
将宿主机网卡挂到br0上:
[root@study ~]# brctl addif br0 ens33
删除原路由:
[root@study ~]# ip route del default
为br0设置路由:
[root@study ~]# ip route add default via 192.168.8.2 dev br0
设置docker启动参数
这里要注意,不同的linux操作系统docker的配置文件所在不同,centos7 在/etc/sysconfig/docker,其他操作系统请参考:https://docs.docker.com/installation/#installation 。
[root@study ~]# vim /etc/sysconfig/docker
OPTIONS='--selinux-enabled -b=br0'
##添加参数-b=br0,即让docker服务启动时使用br0网卡进行桥接
启动docker:
安装pipework工具
[root@study ~]# git clone https://github.com/jpetazzo/pipework
[root@study ~]# cp pipework/pipework /usr/local/bin/
启动一个手动设置网络的容器
创建容器bridge:
[root@study ~]# docker run -itd --net=none --name bridge centos /bin/bash
bride容器配置IP
[root@study ~]# pipework br0 bridge 192.168.8.110/24@192.168.8.2
##为bridge容器设置一个与桥接物理网络同地址段的ip@网关
注意:执行此操作的时候要保证对应的容器为开启状态。
查看容器IP
[root@study ~]# docker exec -it bridge bash
[root@dba96eac22e7 /]# ifconfig
eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.8.110 netmask 255.255.255.0 broadcast 192.168.8..255
[root@dba96eac22e7 /]# ping www.baidu.com
PING www.a.shifen.com (61.135.169.125) 56(84) bytes of data.
64 bytes from 61.135.169.125 (61.135.169.125): icmp_seq=1 ttl=128 time=7.86 ms
64 bytes from 61.135.169.125 (61.135.169.125): icmp_seq=2 ttl=128 time=8.51 ms
配置完成!
Docker网络管理-配置桥接网络(方法二)
该过程中因为br0和ens33配置了同样的IP,所以避免了xshell远程连接的中断。
配置虚拟网卡
添加虚拟网卡:
[root@study ~]# cp /etc/sysconfig/network-scripts/ifcfg-ens33 /etc/sysconfig/network-scripts/ifcfg-br0
配置网卡信息:
[root@study ~]# vim /etc/sysconfig/network-scripts/ifcfg-ens33
增加参数:
BRIDGE=br0
删除:IPADDR、NETMASK、GATEWAY、DNS1
[root@study ~]# vim /etc/sysconfig/network-scripts/ifcfg-br0
TYPE=Bridge
NAME=br0
DEVICE=br0
删除UUID
重启网络:
[root@study ~]# systemctl restart network
[root@study ~]# ifconfig
br0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.8.139 netmask 255.255.255.0 broadcast 192.168.8.255
虚拟网卡准备完毕!
配置docker
同样要安装pipework工具。
启动一个手动设置网络的容器:
[root@study ~]# docker run -itd --net=none --name bridge centos /bin/bash
bride容器配置IP:
[root@study ~]# pipework br0 bridge 172.17.0.110/24@192.168.8.2
##为bridge容器设置一个与桥接物理网络同地址段的ip@网关
注意:执行此操作的时候要保证对应的容器为开启状态。
配置结果:
[root@study ~]# pipework br0 bridge 192.168.8.110/24@192.168.8.2
[root@study ~]# docker exec -it bridge bash
[root@dba96eac22e7 /]# ifconfig
eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.8.110 netmask 255.255.255.0 broadcast 192.168.8.255
[root@dba96eac22e7 /]# ping 192.168.8.2
PING 192.168.8.2 (192.168.8.2) 56(84) bytes of data.
64 bytes from 192.168.8.2: icmp_seq=1 ttl=128 time=2.31 ms
[root@dba96eac22e7 /]# ping www.baidu.com
PING www.a.shifen.com (61.135.169.121) 56(84) bytes of data.
64 bytes from 61.135.169.121 (61.135.169.121): icmp_seq=1 ttl=128 time=9.26 ms
配置完成!
说明: 两种方法只是配置虚拟网卡的方法不同,推荐使用方法二(避免了远程连接的中断)。