Docker容器虚拟化(三)—网络管理 原

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

配置完成!

说明: 两种方法只是配置虚拟网卡的方法不同,推荐使用方法二(避免了远程连接的中断)。

(adsbygoogle = window.adsbygoogle || []).push({});

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券