文章目录
- 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应用:
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)
/ #