Docker 网络知识
1:创建两个busybox容器:
-
执行下面命令:创建一个命名为test1容器:
[root@localhost ~]# docker run -d --name test1 busybox /bin/sh -c "while true;do sleep 3600;done"
-
创建一个命名为test2的容器:
[root@localhost ~]# docker run -d --name test2 busybox /bin/sh -c "while true;do sleep 3600;done"
-
查看启动的容器:
[root@localhost ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS NAMES dab318a2d42a busybox "/bin/sh -c 'while t…" 2 minutes ago Up 2 minutes test2 607729cf3cfc busybox "/bin/sh -c 'while t…" 2 minutes ago Up 2 minutes test1
-
查看test1容器的IP:
[root@localhost ~]# docker exec 607729cf3cfc ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 18: eth0@if19: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0 valid_lft forever preferred_lft forever
-
查看test2容器的IP:
[root@localhost ~]# docker exec dab318a2d42a ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 20: eth0@if21: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff inet 172.17.0.3/16 brd 172.17.255.255 scope global eth0 valid_lft forever preferred_lft forever
-
进入test1容器去ping 一下test2容器:
[root@localhost ~]# docker exec -it 607729cf3cfc /bin/sh
-
再test1容器里去ping test2容器的IP:
/ # ping 172.17.0.2 PING 172.17.0.2 (172.17.0.2): 56 data bytes 64 bytes from 172.17.0.2: seq=0 ttl=64 time=0.304 ms 64 bytes from 172.17.0.2: seq=1 ttl=64 time=0.419 ms 64 bytes from 172.17.0.2: seq=2 ttl=64 time=0.146 ms 64 bytes from 172.17.0.2: seq=3 ttl=64 time=0.113 ms 64 bytes from 172.17.0.2: seq=4 ttl=64 time=0.165 ms 64 bytes from 172.17.0.2: seq=5 ttl=64 time=0.126 ms 64 bytes from 172.17.0.2: seq=6 ttl=64 time=0.150 ms 64 bytes from 172.17.0.2: seq=7 ttl=64 time=0.108 ms
2:Linux命名空间进行创建、删除、查看 :
-
查看本地网络命名空间:
-
ip netns list
[root@localhost ~]# ip netns list test1
-
-
删除:
ip netns delete test1
-
添加:
ip netns add test1
3:再命名空间里进行查看容器的IP地址:
-
再Linux命名空间进行容器IP地址查看:
-
ip netns exec test1 ip a
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
-
ip netns exec test1 ip link
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
-
可以看到 我们的LOOPBACK 都是
DOWN
的状态
-
4:图解Linux网络命名空间原理:
如果test1 跟 test2 之间想连接相同,就必须有Veth pair作为中间介质
。
5:Linux创建Veth:
-
执行命令:
ip link add veth-test1 type veth peer name veth-test2
-
查看本地网络命名:
-
ip link
22: veth-test2@veth-test1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/ether 22:8d:39:bd:73:59 brd ff:ff:ff:ff:ff:ff 23: veth-test1@veth-test2: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/ether 0a:9a:25:54:ec:14 brd ff:ff:ff:ff:ff:ff
-
状态还是DOWN
-
-
将本地的veth-test1 添加 test1中:
ip link set veth-test1 netns test1
-
查看容器test1中的ip:
-
ip netns exec test1 ip a
[root@localhost ~]# ip netns exec test1 ip a 1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 23: veth-test1@if22: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000 link/ether 0a:9a:25:54:ec:14 brd ff:ff:ff:ff:ff:ff link-netnsid 0
-
都是没有IP地址,并且状态都是DOWN
-
-
查看本地的IP:
-
ip link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000 link/ether 00:0c:29:37:a8:09 brd ff:ff:ff:ff:ff:ff 3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default link/ether 02:42:8e:70:36:0d brd ff:ff:ff:ff:ff:ff 19: vethffde676@if18: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP mode DEFAULT group default link/ether 22:eb:3a:c2:1f:bd brd ff:ff:ff:ff:ff:ff link-netnsid 0 21: vethad6ba20@if20: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP mode DEFAULT group default link/ether b2:bb:bc:af:18:55 brd ff:ff:ff:ff:ff:ff link-netnsid 1 22: veth-test2@if23: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/ether 22:8d:39:bd:73:59 brd ff:ff:ff:ff:ff:ff link-netnsid 2
-
-
发现veth-test1的没有了,添加到了test1中。
-
同理再把 veth-test2 添加到test2中。
-
启动
test1中的veth-test1端口:ip netns exec test1 ip link set dev veth-test1 up
-
启动
test2中的veth-test2端口:ip netns exec test2 ip link set dev veth-test2 up
-
查看test1:
-
ip netns exec test1 ip link
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 23: veth-test1@if22: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000 link/ether 0a:9a:25:54:ec:14 brd ff:ff:ff:ff:ff:ff link-netnsid 1 # 已经看到UP起来
-
-
设置test1中的
veth-test1
IP地址:ip netns exec test1 ip addr add 192.168.1.1/24 dev veth-test1
-
设置test2中的
veth-test2
IP地址:ip netns exec test2 ip addr add 192.168.1.2/24 dev veth-test2
-
查看test1中的IP:
-
ip netns exec test1 ip a
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 23: veth-test1@if22: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000 link/ether 0a:9a:25:54:ec:14 brd ff:ff:ff:ff:ff:ff link-netnsid 1 inet 192.168.1.1/24 scope global veth-test1 valid_lft forever preferred_lft forever inet6 fe80::89a:25ff:fe54:ec14/64 scope link valid_lft forever preferred_lft forever
-
可以看到设置的IP地址
-
-
再test1中ping test2的IP地址,看是否接通
-
ip netns exec test1 ping 192.168.1.2
[root@localhost ~]# ip netns exec test1 ping 192.168.1.2 PING 192.168.1.2 (192.168.1.2) 56(84) bytes of data. 64 bytes from 192.168.1.2: icmp_seq=1 ttl=64 time=0.906 ms 64 bytes from 192.168.1.2: icmp_seq=2 ttl=64 time=0.056 ms 64 bytes from 192.168.1.2: icmp_seq=3 ttl=64 time=0.044 ms 64 bytes from 192.168.1.2: icmp_seq=4 ttl=64 time=0.055 ms 64 bytes from 192.168.1.2: icmp_seq=5 ttl=64 time=0.084 ms
-
可以看到ping通了
-
6:Dokcer网络Bridge:
-
创建docker 自定义的网络:
docker network create -d bridge my-bridge
-
查看docker都有哪些网络:
-
docker network ls
[root@localhost ~]# docker network ls NETWORK ID NAME DRIVER SCOPE 8007b3552e07 bridge bridge local 4c32045b0224 host host local 53cc6a947569 my-bridge bridge local # 上面自定义创建的 e11e02817643 none null local
-
-
检查
bridge
网络上都有哪些容器:-
docker network inspect NETWORK[ID]
# 名字test1使用的是bridge网络 Containers": { "607729cf3cfc43c4fdfc94ead3e4909f6689cf6d18139855c2c5644dfa4d5f73": { "Name": "test1", "EndpointID": "6d45b6c07a60670b3bac72d2ee7ac8db56ed7b8ad6c4ecae82f51c1fdbb6bd6a", "MacAddress": "02:42:ac:11:00:02", # MAC地址 "IPv4Address": "172.17.0.2/16", # IP地址 "IPv6Address": "" } },
-
-
CentOS安装brctl:
sudo yum install bridge-utils
-
查看已有的网桥:
-
brctl show
[root@localhost ~]# brctl show bridge name bridge id STP enabled interfaces br-53cc6a947569 8000.0242cb2b1706 no # 自定义创建的my-dridge docker0 8000.02428e70360d no veth3b37054 vethffde676
-
-
两个容器如何通信?
- 图解:
-
两个容器通过docker0就可以进行通信了
-
单个容器如何访问Internet的呢?
- 图解:
7:Docker之间的Link:
-
通过test1创建一个test2的容器,并且让两个容器间相关联:
docker run -d --name test2 --link test1 busybox /bin/sh -c "while true;do sleep 3600; done"
-
进入test2容器中:
docker exec -it test2 /bin/sh
-
ping test1地址:
-
ping test1
/ # ping test1 PING test1 (172.17.0.2): 56 data bytes 64 bytes from 172.17.0.2: seq=0 ttl=64 time=0.144 ms 64 bytes from 172.17.0.2: seq=1 ttl=64 time=0.168 ms
-
发现通过名字也可以ping通,
但是进入test1容器 ping test2是不可以,根上面的执行命令相关
-
上面命令:
test2 --link test1:说明test2用的也是test1的DNS
-
-
新创建test3并,
指定到新创建的网络my-bridge
上:-
docker run -d --name test3 --network my-bridge busybox /bin/sh -c "while true; do sleep 3600;done"
-
检查
my-bridge网络有哪些容器连接
[root@localhost ~]# docker network ls # 检查都有哪些网络 NETWORK ID NAME DRIVER SCOPE 8007b3552e07 bridge bridge local 4c32045b0224 host host local 53cc6a947569 my-bridge bridge local e11e02817643 none null local [root@localhost ~]# docker network inspect 53cc6a947569 "Containers": { "6a28b3fae552b33d514512d4c0ea6731db523e0bdf807d9954fa2a2e24fad966": { "Name": "test3", # 可以看到只有test3连接的my-bridge网络 "EndpointID": "36befe805eb1431a4274860fd5982736c273ad6ee9c8ab4b5f75cb63de831b7c", "MacAddress": "02:42:ac:12:00:02", "IPv4Address": "172.18.0.2/16", "IPv6Address": "" }
-
查看已有的网络:
bridge name bridge id STP enabled interfaces br-53cc6a947569 8000.0242cb2b1706 no vethc14ba31 # 这回后面新增了网络接口 docker0 8000.02428e70360d no veth3b37054 vethffde676
-
-
将test2(bridge网络)移动到test3(my-bridge)网络上。
docker network connect my-bridge test2
my-bridge网络中有test2容器,也有test3容器,但是再原来的bridge网络中也有test2容器。
8:容器的端口映射:
- 如何将docker容器中的Nginx的80端口映射到本地?
-
1.创建nginx的容器
docker run --name web -d nginx
-
2.启动运行容器,并将Nginx的端口映射到本地:
docker run --name web -d -p 80:80 nginx
- 1.参数 -p:就是端口的映射 前者80端口指容器中nginx的端口, 后者80端口指的映射到本地的80端口
-
3.反问本地的80端口,查看是否能访问到容器中的Nginx:
-
curl 127.0.0.1
:说明出现以下信息,端口映射成功<!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to nginx!</h1> <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p> <p>For online documentation and support please refer to <a href="http://nginx.org/">nginx.org</a>.<br/> Commercial support is available at <a href="http://nginx.com/">nginx.com</a>.</p> <p><em>Thank you for using nginx.</em></p> </body> </html>
-
-
4.查看运行的容器:
-
docker ps
CONTAIN IMAGE COMMAND STATUS PORTS(新增信息) NAMES cf2a5d3 nginx "nginx -g 'daemon of…" Up 8 minutes 0.0.0.0:80->80/tcp web
-
-
5.图解以上原理:
访问本地192.168.205.10:80 的时候就会通过docker0网络转发到 docker容器中Nginx的服务172.17.0.2:80
。
-
9:Docker网络之host和none:
[root@localhost ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
8007b3552e07 bridge bridge local
4c32045b0224 host host local
53cc6a947569 my-bridge bridge local
e11e02817643 none null local
一、简介none:
-
1.none的使用场景,个人理解只能
本地通过
交互才可以访问,其余都不可以访问,作用就是处理安全性比较高的一些私密东西,使用none网络。 -
2.启动一个容器,名字是test1网络连接的none的容器。
docker run -d --name test1 --network none busybox /bin/sh -c "while true; do sleep 3600; done"
-
3.查看该none网络上的详情信息:
-
docker network inspect e11e02817643
"Containers": { "aa6afa3faf12bdd2d81a687c56b60767e1111a589bd8d5ddae2db15960b10d83": { "Name": "test1", "EndpointID": "daae452aae2982ff4bbc00337849e6b941dd22eb361e00ded88857aa509167e9", "MacAddress": "", "IPv4Address": "", "IPv6Address": "" } }, "Options": {}, "Labels": {}
-
-
4.可以看到Containers里面的 Mac,IPv4,IPv6都是空,
只有再本地进入交互模式才可以访问
。 -
5.进入交互模式
-
docker exec -it test1 /bin/sh
-
查看ip
-
ip a
/ # ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever
-
-
可以看到只有本地才能访问
-
二、简介host:
-
1.创建一个test1容器,网络host:
docker run -d --name test1 --network host busybox /bin/sh -c "while true; do sleep 3600; done"
-
2…查看该host网络上的详情信息:
-
docker network inspect host
"Containers": { "25ec50e6b22749f0c5e9d8f3509d917fb635cd615b6928c4beb58306a79c0d90": { "Name": "test1", "EndpointID": "f48f76d341e3beea4c23dfb41ade95371f3e3ba66b3ae7ad18d6eee8c9e026d1", "MacAddress": "", "IPv4Address": "", "IPv6Address": "" } },
-
可以看到MAC,IPV4,IPV6也都是空的。
-
-
3.进入交互式:
-
docker exec -it test1/bin/sh
-
ip a
查看所有IP地址/ # ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast qlen 1000 link/ether 00:0c:29:37:a8:09 brd ff:ff:ff:ff:ff:ff inet 192.168.1.10/24 brd 192.168.1.255 scope global dynamic ens33 valid_lft 70966sec preferred_lft 70966sec inet6 2409:8a00:7839:8910:3859:567c:5f6c:d03e/64 scope global dynamic valid_lft 259141sec preferred_lft 172741sec inet6 fe80::98e6:e7e9:dc3a:a3a/64 scope link valid_lft forever preferred_lft forever 3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue link/ether 02:42:8e:70:36:0d 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:8eff:fe70:360d/64 scope link valid_lft forever preferred_lft forever 26: br-53cc6a947569: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue link/ether 02:42:cb:2b:17:06 brd ff:ff:ff:ff:ff:ff inet 172.18.0.1/16 brd 172.18.255.255 scope global br-53cc6a947569 valid_lft forever preferred_lft forever inet6 fe80::42:cbff:fe2b:1706/64 scope link valid_lft forever preferred_lft forever
-
会发现test1使用的host网络跟我本地网络的ip使用的是一样的。
-
-
总结:
创建host容器test1时他没有独立的网络,它是跟我们主机共享一套网络的,不建议使用,因为可能会出现端口有冲突的问题。