文章目录

  • docker网络4种模式介绍与实例演示
  • bridge 网络模式
  • Host 网络模式
  • container 网络模式
  • None 网络模式


docker网络4种模式介绍与实例演示

[root@zackery ~]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
8ee9b71ce0a4        bridge              bridge              local
a522d0342b3b        host                host                local
5c54111155e5        none                null                local
[root@zackery ~]#

使用docker inspect [NETWORK_NAME]命令查看网络配置详细参数

docker的资源隔离基于linux的namespace(命名空间)技术。

目前,namespace共有如下七种

名称         宏定义             隔离内容
Cgroup      CLONE_NEWCGROUP   Cgroup root directory (since Linux 4.6)
IPC         CLONE_NEWIPC      System V IPC, POSIX message queues (since Linux 2.6.19)
Network     CLONE_NEWNET      Network devices, stacks, ports, etc. (since Linux 2.6.24)
Mount       CLONE_NEWNS       Mount points (since Linux 2.4.19)
PID         CLONE_NEWPID      Process IDs (since Linux 2.6.24)
User        CLONE_NEWUSER     User and group IDs (started in Linux 2.6.23 and completed in Linux 3.8)
UTS         CLONE_NEWUTS      Hostname and NIS domain name (since Linux 2.6.19)

下面简要介绍以上不同类型的命名空间的作用:

  • IPC:用于隔离进程间通讯所需的资源( System V IPC, POSIX message queues),PID命名空间和IPC命名空间可以组合起来用,同一个IPC名字空间内的进程可以彼此看见,允许进行交互,不同空间进程无法交互
  • Network:Network Namespace为进程提供了一个完全独立的网络协议栈的视图。包括网络设备接口,IPv4和IPv6协议栈,IP路由表,防火墙规则,sockets等等。一个Network Namespace提供了一份独立的网络环境,就跟一个独立的系统一样。
  • Mount:每个进程都存在于一个mount Namespace里面,mount Namespace为进程提供了一个文件层次视图。如果不设定这个flag,子进程和父进程将共享一个mount Namespace,其后子进程调用mount或umount将会影响到所有该Namespace内的进程。如果子进程在一个独立的mount Namespace里面,就可以调用mount或umount建立一份新的文件层次视图。
  • PID::linux通过命名空间管理进程号,同一个进程,在不同的命名空间进程号不同!进程命名空间是一个父子结构,子空间对于父空间可见。
  • User:用于隔离用户
  • UTS:用于隔离主机名

docker的网络使用 UTS,Network,IPC构建,下文只讲述不同的docker网络模式所对应不同的namespace构建方法

bridge 网络模式

bridge模式是Docker默认的网络模式,若在新建容器时未指定–network参数则默认使用该网络模式,bridge模式会为容器创建一组UTS,Network,IPC命名空间,并将一个宿主机上的Docker容器连接到一个虚拟网桥上。

此时,宿主机可以与容器进行访问,示例:

创建redis容器

[root@zackery ~]# docker run --name myredis --network bridge -d redis

在宿主机使用docker inspect myredis查看IPAddress

并在宿主机使用redis客户端连接容器redis服务器

[root@zackery src]# ./redis-cli -h 172.17.0.2
172.17.0.2:6379> set docker "got it!"
OK
172.17.0.2:6379>

若有外网想要访问容器,还需要进行端口映射:

我们部署一个网络模式为bridge的nginx容器并将容器的80端口映射到主机的80端口:

[root@zackery ~]# docker container run --name mynginx --network bridge -p 80:80 --rm -d nginx:stable

解释: --network指定网络模式 -p指定端口映射格式 -d 指定在后台运行 --rm 指当容器停止运行时删除该容器。

查看端口映射:

[root@zackery ~]# docker port mynginx
80/tcp -> 0.0.0.0:80

直接访问宿主机ip的80端口即可访问容器nginx应用:

docker宿主机是自己的电脑吗 docker操作宿主机_linux

Host 网络模式

若在新建容器时指定–network host,docker将不会为容器创建一组命名空间,而是使用宿主机的UTS,Network,IPC命名空间。

这种模式下容器没有任何自己的网络相关资源,而是和宿主机共享网络资源。网络的配置、ip、端口与宿主机一致。

假设我们部署一个网络模式为host的busybox容器,并进入命令行执行ifconfig进行查看:

[root@kane ~]# docker container run --name mybusybox --network host -it busybox

–network 指定网络模式为host -it进入交互页面

在容器内使用ifconfig查看网络详情

/ # ifconfig
docker0   Link encap:Ethernet  HWaddr 02:42:D7:12:49:6B  
          inet addr:172.17.0.1  Bcast:172.17.255.255  Mask:255.255.0.0
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:17326 errors:0 dropped:0 overruns:0 frame:0
          TX packets:18409 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:1026682 (1002.6 KiB)  TX bytes:49821679 (47.5 MiB)

eth0      Link encap:Ethernet  HWaddr 00:16:3E:06:60:F1  
          inet addr:172.19.178.3  Bcast:172.19.191.255  Mask:255.255.240.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:3887439 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1962814 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:2465423420 (2.2 GiB)  TX bytes:487096497 (464.5 MiB)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:306493 errors:0 dropped:0 overruns:0 frame:0
          TX packets:306493 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:103439303 (98.6 MiB)  TX bytes:103439303 (98.6 MiB)

可以看到容器内存在docker默认网卡 docker0 ,以太网接口 eth0 ,回环接口 lo,与宿主机一致,且没有生成其它虚拟网卡。

container 网络模式

若在新建容器时指定–network container:NAME_or_ID,docker将不会为新创建的容器创建一组命名空间,而是使用指定容器的的UTS,Network,IPC命名空间。

与host模式相似,container模式将和指定容器共享网络资源。

这里需要注意,端口号不能冲突,假设部署两个nginx应用,要注意nginx默认80端口的冲突问题。

使用之前创建的myredis容器网络命名空间创建Ubuntu容器:

docker run --name myubuntu --network container:myredis --rm  -it ubuntu:18.04

查看Ubuntu容器网络,可以看到inet 172.17.0.2,与之前创建的myredis容器一致:

root@54520666735e:/# apt install net-tools
root@54520666735e:/# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.2  netmask 255.255.0.0  broadcast 172.17.255.255
        ether 02:42:ac:11:00:02  txqueuelen 0  (Ethernet)
        RX packets 5631  bytes 18263813 (18.2 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 5458  bytes 443251 (443.2 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 77  bytes 27044 (27.0 KB)

在Ubuntu容器种安装redis,并启动redis服务,因为和myredis容器共享网络,此时会提示端口号被占用

root@54520666735e:/# apt-get update
root@54520666735e:/# apt-get install redis
root@54520666735e:/# redis-server &
[1] 381
root@54520666735e:/# 381:C 09 Sep 08:56:20.227 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
381:C 09 Sep 08:56:20.227 # Redis version=4.0.9, bits=64, commit=00000000, modified=0, pid=381, just started
381:C 09 Sep 08:56:20.227 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
381:M 09 Sep 08:56:20.228 # Creating Server TCP listening socket *:6379: bind: Address already in use

在Ubuntu容器中直接使用redis客户端连接本地redis服务器(也就是redis容器上启动的redis服务),并获取到myredis种设置的key值。

root@54520666735e:/# redis-cli -h 127.0.0.1
127.0.0.1:6379> get docker
"got it!"
127.0.0.1:6379>

None 网络模式

若在新建容器时指定–network none,docker会为新创建的容器创建一组命名空间,但是,并不会为该容器进行任何网络配置。该容器可以字行配置网卡,ip,路由等信息。

一般的,使用无网络应用镜像(例如:数据处理)或需要高度定制网络的情况下会使用none网络模式。

创建无网络docker容器并使用ifconfig查看

[root@kane ~]# docker run --name mybox2 --network none -it --rm busybox
/ # ifconfig
lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

/ #