1. 网络模式
• bridge
--net=bridge 默认网络,Docker启动后创建一个docker0网桥,默认创建的容器也是添加到这个网桥中。
• host –net=host
容器不会获得一个独立的network namespace,而是与宿主机共用一个。这就意味着容器不会有自己的网卡信息,而是使用宿主
机的。容器除了网络,其他都是隔离的。
• none
--net=none
获取独立的network namespace,但不为容器进行任何网络配置,需要我们手动配置。
• container
--net=container:Name/ID
与指定的容器使用同一个network namespace,具有同样的网络配置信息,两个容器除了网络,其他都还是隔离的。
• 自定义网络
与默认的bridge原理一样,但自定义网络具备内部DNS发现,可以通过容器名或者主机名容器之间网络通信。
# ip a ### 172.17.0.1 是docker容器的网关,docker0就是所谓的网桥
.....
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN
link/ether 02:42:93:8e:5c:4a brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:93ff:fe8e:5c4a/64 scope link
valid_lft forever preferred_lft forever
.....
48: br-6607ee6831f7: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP
link/ether 02:42:d5:de:e5:07 brd ff:ff:ff:ff:ff:ff
inet 172.18.0.1/16 brd 172.18.255.255 scope global br-6607ee6831f7
valid_lft forever preferred_lft forever
inet6 fe80::42:d5ff:fede:e507/64 scope link
valid_lft forever preferred_lft forever
# docker pull busybox
# docker run -it busybox ## 容器会网络配置网段与网桥网段一致
/ # ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:AC:11:00:02
inet addr:172.17.0.2 Bcast:172.17.255.255 Mask:255.255.0.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:8 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:648 (648.0 B) TX bytes:0 (0.0 B)
# docker run -it --net=host busybox ## 容器里的网络配置与宿主机一致
# docker run -it --net=none busybox ## 容器里没有网络配置,得手动配置
容器使用同一个network namespace网络命名空间
# docker run -itd --name bs -p 99:80 busybox
4aa4f32452a2a6c027b814fa514811042f676ed36de37660f79d457a97ab3400
# docker run -d --name nginx01 --net container:bs nginx
791ec39ed9eb00c5ac602ac77c072972924de5dd8f671c0aaf900b54f0cc8961
# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
791ec39ed9eb nginx "nginx -g 'daemon of…" About a minute ago Up About a minute nginx01
4aa4f32452a2 busybox "sh" 3 minutes ago Up 3 minutes 0.0.0.0:99->80/tcp bs
# docker exec -it bs sh ## 进入bs容器
/ # netstat -ntlp ## 查看bs网络监听端口为80,这80 是我们启动的nginx容器的80端口,请求bs的80 端口将返回nginx容器的内容
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:80 0.0.0.0:* LISTEN -
自定义网络:
# docker network create bs-test ## ip a 命令会看到宿主新建了一个新的网桥brxxx,这网桥的IP将是这个虚拟网络的网关
# docker run -it --name bs1 --net bs-test busybox
# docker run -it --name bs2 --net bs-test busybox
这时候在两个容器互ping 容器名或主机名都是通的 ping bs1
2. 容器网络访问原理
image.png每创建一个容器在宿主机上都是创建一个vethxxxx 的虚拟配置对,这个是与容器的网络配对的,类似管道
# route
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
default 10.40.6.1 0.0.0.0 UG 100 0 0 eno16780032
10.40.6.0 0.0.0.0 255.255.254.0 U 100 0 0 eno16780032
172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker0
172.18.0.0 0.0.0.0 255.255.0.0 U 0 0 0 br-6607ee6831f7
172.19.0.0 0.0.0.0 255.255.0.0 U 0 0 0 br-8ea0e6186e02
image.png
docker网络主要是利用iptalbes 实现
从容器到外部是源地址转发,外部到容器里是目标地转发
# iptables-save
# Generated by iptables-save v1.4.21 on Tue May 14 22:01:47 2019
*nat
:PREROUTING ACCEPT [458:34774]
:INPUT ACCEPT [103:5876]
:OUTPUT ACCEPT [18:1152]
:POSTROUTING ACCEPT [18:1152]
:DOCKER - [0:0]
-A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
-A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER
-A POSTROUTING -s 172.19.0.0/16 ! -o br-8ea0e6186e02 -j MASQUERADE
-A POSTROUTING -s 172.18.0.0/16 ! -o br-6607ee6831f7 -j MASQUERADE
-A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE
-A POSTROUTING -s 172.17.0.2/32 -d 172.17.0.2/32 -p tcp -m tcp --dport 80 -j MASQUERADE
-A POSTROUTING -s 172.17.0.3/32 -d 172.17.0.3/32 -p tcp -m tcp --dport 80 -j MASQUERADE
-A DOCKER -i br-8ea0e6186e02 -j RETURN
-A DOCKER -i br-6607ee6831f7 -j RETURN
-A DOCKER -i docker0 -j RETURN
-A DOCKER ! -i docker0 -p tcp -m tcp --dport 98 -j DNAT --to-destination 172.17.0.2:80
-A DOCKER ! -i docker0 -p tcp -m tcp --dport 99 -j DNAT --to-destination 172.17.0.3:80
COMMIT
# Completed on Tue May 14 22:01:47 2019
# Generated by iptables-save v1.4.21 on Tue May 14 22:01:47 2019
*filter
:INPUT ACCEPT [597:374122]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [543:53853]
:DOCKER - [0:0]
:DOCKER-ISOLATION-STAGE-1 - [0:0]
:DOCKER-ISOLATION-STAGE-2 - [0:0]
:DOCKER-USER - [0:0]
-A FORWARD -j DOCKER-USER
-A FORWARD -j DOCKER-ISOLATION-STAGE-1
-A FORWARD -o br-8ea0e6186e02 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -o br-8ea0e6186e02 -j DOCKER
-A FORWARD -i br-8ea0e6186e02 ! -o br-8ea0e6186e02 -j ACCEPT
-A FORWARD -i br-8ea0e6186e02 -o br-8ea0e6186e02 -j ACCEPT
-A FORWARD -o br-6607ee6831f7 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -o br-6607ee6831f7 -j DOCKER
-A FORWARD -i br-6607ee6831f7 ! -o br-6607ee6831f7 -j ACCEPT
-A FORWARD -i br-6607ee6831f7 -o br-6607ee6831f7 -j ACCEPT
-A FORWARD -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -o docker0 -j DOCKER
-A FORWARD -i docker0 ! -o docker0 -j ACCEPT
-A FORWARD -i docker0 -o docker0 -j ACCEPT
-A DOCKER -d 172.17.0.2/32 ! -i docker0 -o docker0 -p tcp -m tcp --dport 80 -j ACCEPT
-A DOCKER -d 172.17.0.3/32 ! -i docker0 -o docker0 -p tcp -m tcp --dport 80 -j ACCEPT
-A DOCKER-ISOLATION-STAGE-1 -i br-8ea0e6186e02 ! -o br-8ea0e6186e02 -j DOCKER-ISOLATION-STAGE-2
-A DOCKER-ISOLATION-STAGE-1 -i br-6607ee6831f7 ! -o br-6607ee6831f7 -j DOCKER-ISOLATION-STAGE-2
-A DOCKER-ISOLATION-STAGE-1 -i docker0 ! -o docker0 -j DOCKER-ISOLATION-STAGE-2
-A DOCKER-ISOLATION-STAGE-1 -j RETURN
-A DOCKER-ISOLATION-STAGE-2 -o br-8ea0e6186e02 -j DROP
-A DOCKER-ISOLATION-STAGE-2 -o br-6607ee6831f7 -j DROP
-A DOCKER-ISOLATION-STAGE-2 -o docker0 -j DROP
-A DOCKER-ISOLATION-STAGE-2 -j RETURN
-A DOCKER-USER -j RETURN
COMMIT
# Completed on Tue May 14 22:01:47 2019
3、桥接宿主机网络与配置固定IP地址
将容器网络与宿主机网络同一个网络,这个不建议这么做
临时生效:
# cat set_brnetwork.sh
br_name=br0 ## 网桥名
brctl addbr $br_name ## 添加网桥
ip addr add 10.40.6.110/24 dev $br_name ## 给网桥设置IP
ip addr del 10.40.6.110/24 dev eth0 ## 删除已存在的eth0 网卡配置
ip link set $br_name up ## 激活网桥
brctl addif $br_name eth0 ##添加eth0到网桥
ip route add default via 10.40.6.1 dev $br_name ## 添加路由
## 需要在docker 启动时桥接这个网桥:
# vim /usr/lib/systemd/system/docker.service
ExecStart=/usr/bin/docker -b=br0
#systemctl restart docker
永久生效:
# vim /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
TYPE=Ethernet
ONBOOT=yes
BRIDGE=br0
# vim /etc/sysconfig/network-scripts/ifcfg-br0
DEVICE=br0
TYPE=Bridge
ONBOOT=yes
BOOTPROTO=static
IPADDR=10.40.6.110
NETMASK=255.255.255.0
GATEWAY=10.40.6.1
DNS1=8.8.8.8
创建容器配置固定IP:
创建容器,如果没指定具体IP默认会从1开始分配IP,如:10.40.6.1,这IP其实是错误的
所以创建容器的时候指定不自动分配IP,后续再进入容器手动配置网络:
# docker run -itd --name bs3 --net none busybox
使用pipework工具配置容器固定IP:
# git clone https://github.com/jpetazzo/pipework.git
# mv pipework/pipework /usr/bin/
# pipework br0 bs3 10.40.6.112/24@10.40.6.1
网友评论