docker容器网络配置

2022/4/29 6:13:03

本文主要是介绍docker容器网络配置,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

Linux内核实现名称空间的创建

ip netns命令

可以借助ip netns命令来完成对 Network Namespace 的各种操作。ip netns命令来自于iproute安装包,一般系统会默认安装,如果没有的话,请自行安装。

注意:ip netns命令修改网络配置时需要 sudo 权限。

可以通过ip netns命令完成对Network Namespace 的相关操作,可以通过ip netns help查看命令帮助信息:

 1 [root@localhost ~]# ip netns help   
 2 Usage:    ip netns list      #    查看名称空间
 3     ip netns add NAME    #  添加名称空间
 4     ip netns attach NAME PID   #   进到空间里去
 5     ip netns set NAME NETNSID   #   设置名称空间的名字
 6     ip [-all] netns delete [NAME]   # 删除  
 7     ip netns identify [PID]
 8     ip netns pids NAME     #    pid
 9     ip [-all] netns exec [NAME] cmd ...   #   进到空间去并执行命令
10     ip netns monitor       #   监控
11     ip netns list-id [target-nsid POSITIVE-INT] [nsid POSITIVE-INT]
12 NETNSID := auto | POSITIVE-INT    #   列出id

默认情况下,Linux系统中是没有任何 Network Namespace的,所以ip netns list命令不会返回任何信息。

创建Network Namespace

通过命令创建一个名为ns0的命名空间:

1 [root@localhost ~]# ip netns add ns0    #   创建一个叫ns0的名称空间
2 [root@localhost ~]# ip netns list        #    查看
3 ns0

新创建的 Network Namespace 会出现在/var/run/netns/目录下。如果相同名字的 namespace 已经存在,命令会报Cannot create namespace file "/var/run/netns/ns0": File exists的错误。

 1 [root@localhost ~]# cd /var/run/netns/    #  进到存放名称空间的目录
 2 [root@localhost netns]# ls
 3 ns0
 4 [root@localhost ~]# file /var/run/netns/    
 5 /var/run/netns/: directory
 6 [root@localhost ~]# file /var/run/netns/ns0 
 7 /var/run/netns/ns0: empty
 8 [root@localhost ~]# touch /var/run/netns/ns1  
 9 [root@localhost ~]# file /var/run/netns/ns1
10 /var/run/netns/ns1: empty        #  touch出来的,看着都一样
11 [root@localhost ~]# ip netns list    #  但是你查看就会报错
12 Error: Peer netns reference is invalid.
13 Error: Peer netns reference is invalid.      #  必须要用命令创建,
14 ns1
15 ns0
16 [root@localhost ~]# ip netns add ns0     #  不能创建相同名字,会报错
17 Cannot create namespace file "/var/run/netns/ns0": File exists

对于每个 Network Namespace 来说,它会有自己独立的网卡、路由表、ARP 表、iptables 等和网络相关的资源。

操作Network Namespace

ip命令提供了ip netns exec子命令可以在对应的 Network Namespace 中执行命令。

查看新创建 Network Namespace 的网卡信息

1 [root@localhost ~]# ip netns exec ns0 ip a   #  进到ns0查看网络信息
2 1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000    #   就一块lo网卡,而且没有激活
3     link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

可以看到,新创建的Network Namespace中会默认创建一个lo回环网卡,此时网卡处于关闭状态。此时,尝试去 ping 该lo回环网卡,会提示Network is unreachable

通过下面的命令启用lo回环网卡:

 1 [root@localhost ~]# ip netns exec ns0 ping 127.0.0.1    #  进到ns0,ping自己 
 2 connect: 网络不可达  
 3 [root@localhost ~]# ip netns exec ns0 ip link set lo up   #  进到ns0设置lo网卡启动
 4 [root@localhost ~]# ip netns exec ns0 ip a
 5 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
 6     link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
 7     inet 127.0.0.1/8 scope host lo    #  有id了激活了
 8        valid_lft forever preferred_lft forever
 9     inet6 ::1/128 scope host 
10        valid_lft forever preferred_lft forever
11 [root@localhost ~]# ip netns exec ns0 ping 127.0.0.1   #  此时就ping的通
12 PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
13 64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=40.5 ms
14 64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.062 ms
15 64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.095 ms
16

    [root@localhost ~]# ip netns exec ns1 ip link set lo up   # 激活ns1的网卡
    [root@localhost ~]# ip netns exec ns1 ip a
    1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default 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              #  两个空间的本地网络通了,他们两个之间是不能通信的真机也不能和他们通信,内部是可以通信的,

转移设备

我们可以在不同的 Network Namespace 之间转移设备(如veth)。由于一个设备只能属于一个 Network Namespace ,所以转移后在这个 Network Namespace 内就看不到这个设备了。

其中,veth设备属于可转移设备,而很多其它设备(如lo、vxlan、ppp、bridge等)是不可以转移的。

veth pair

veth pair 全称是 Virtual Ethernet Pair(一对虚拟的以太网),是一个成对的端口,所有从这对端口一 端进入的数据包都将从另一端出来,反之也是一样。
引入veth pair是为了在不同的 Network Namespace 直接进行通信,利用它可以直接将两个 Network Namespace 连接起来。

 

 

 

创建veth pair

 1 [root@localhost ~]#  ip link show     #  此时只有3个网卡
 2 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
 3     link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
 4 2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
 5     link/ether 00:0c:29:bc:11:bf brd ff:ff:ff:ff:ff:ff
 6 3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN mode DEFAULT group default 
 7     link/ether 02:42:e7:69:ef:af brd ff:ff:ff:ff:ff:ff
 8 [root@localhost ~]# ip link add type veth   #  生产了一对设备38: veth0   39: veth1而且是没有激活的状态
 9 [root@localhost ~]# ip link show
10 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
11     link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
12 2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
13     link/ether 00:0c:29:bc:11:bf brd ff:ff:ff:ff:ff:ff
14 3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN mode DEFAULT group default 
15     link/ether 02:42:e7:69:ef:af brd ff:ff:ff:ff:ff:ff
16 38: veth0@veth1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
17     link/ether d2:62:7c:c0:44:7f brd ff:ff:ff:ff:ff:ff
18 39: veth1@veth0: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
19     link/ether 7e:b1:dd:27:56:87 brd ff:ff:ff:ff:ff:ff

可以看到,此时系统中新增了一对veth pair,将veth0和veth1两个虚拟网卡连接了起来,此时这对 veth pair 处于”未启用“状态。

实现Network Namespace间通信

下面我们利用veth pair实现两个不同的 Network Namespace 之间的通信。刚才我们已经创建了一个名为ns0的 Network Namespace,下面再创建一个信息Network Namespace,命名为ns1

然后我们将veth0加入到ns0,将veth1加入到ns1

然后我们分别为这对veth pair配置上ip地址,并启用它们

查看这对veth pair的状态

可以看到,veth pair成功实现了两个不同Network Namespace之间的网络交互

 1 [root@localhost ~]# ip link set veth0 netns ns0   # 把veth0给ns0用
 2 [root@localhost ~]# ip netns exec ns0 ip a  
 3 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
 4     link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
 5     inet 127.0.0.1/8 scope host lo
 6        valid_lft forever preferred_lft forever
 7     inet6 ::1/128 scope host 
 8        valid_lft forever preferred_lft forever
 9 38: veth0@if39: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
10     link/ether d2:62:7c:c0:44:7f brd ff:ff:ff:ff:ff:ff link-netnsid 0
11 [root@localhost ~]# ip netns exec ns0 ip link set veth0 up  #  激活veth0
12 [root@localhost ~]# ip netns exec ns0 ip a    #  此时已激活但是没有ip
13 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
14     link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
15     inet 127.0.0.1/8 scope host lo
16        valid_lft forever preferred_lft forever
17     inet6 ::1/128 scope host 
18        valid_lft forever preferred_lft forever
19 38: veth0@if39: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state LOWERLAYERDOWN group default qlen 1000
20     link/ether d2:62:7c:c0:44:7f brd ff:ff:ff:ff:ff:ff link-netnsid 0
21 [root@localhost ~]# ip netns exec ns0 ip addr add 1.1.1.1/24 dev veth0    #   给veth0手动配一个ip
22 [root@localhost ~]# ip netns exec ns0 ip a
23 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
24     link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
25     inet 127.0.0.1/8 scope host lo
26        valid_lft forever preferred_lft forever
27     inet6 ::1/128 scope host 
28        valid_lft forever preferred_lft forever
29 38: veth0@if39: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state LOWERLAYERDOWN group default qlen 1000
30     link/ether d2:62:7c:c0:44:7f brd ff:ff:ff:ff:ff:ff link-netnsid 0
31     inet 1.1.1.1/24 scope global veth0     #此时已经有ip
32        valid_lft forever preferred_lft forever
33 [root@localhost ~]# ip link show    #  把veht0给了ns0,所以真机这里就没有了
34 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
35     link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
36 2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
37     link/ether 00:0c:29:bc:11:bf brd ff:ff:ff:ff:ff:ff
38 3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN mode DEFAULT group default 
39     link/ether 02:42:e7:69:ef:af brd ff:ff:ff:ff:ff:ff
40 39: veth1@if38: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
41     link/ether 7e:b1:dd:27:56:87 brd ff:ff:ff:ff:ff:ff link-netns ns0
42 [root@localhost ~]# ip link set veth1 up  #  激活veth1
43 [root@localhost ~]# ip addr add 1.1.1.2/24 dev veth1  #   给veth1设置ip
44 [root@localhost ~]# ping 1.1.1.1   #   ping的通
45 PING 1.1.1.1 (1.1.1.1) 56(84) bytes of data.
46 64 bytes from 1.1.1.1: icmp_seq=1 ttl=64 time=17.3 ms
47 64 bytes from 1.1.1.1: icmp_seq=2 ttl=64 time=0.057 ms
48 [root@localhost ~]# ip link set veth1 netns ns1   #  把veth1给ns1用
49 [root@localhost ~]# ip netns exec ns1 ip a
50 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
51     link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
52     inet 127.0.0.1/8 scope host lo
53        valid_lft forever preferred_lft forever
54     inet6 ::1/128 scope host 
55        valid_lft forever preferred_lft forever
56 39: veth1@if38: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000   #  移过的时候会禁用掉,ip也没了
57     link/ether 7e:b1:dd:27:56:87 brd ff:ff:ff:ff:ff:ff link-netns ns0
58  [root@localhost ~]# ip netns exec ns1 ip link set veth1 up  #  启动veth1
59 [root@localhost ~]# ip netns exec ns1 ip addr add 1.1.1.2/24 dev veth1    #   给veth1配置ip
60 [root@localhost ~]# ip netns exec ns1 ip a
61 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
62     link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
63     inet 127.0.0.1/8 scope host lo
64        valid_lft forever preferred_lft forever
65     inet6 ::1/128 scope host 
66        valid_lft forever preferred_lft forever
67 39: veth1@if38: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
68     link/ether 7e:b1:dd:27:56:87 brd ff:ff:ff:ff:ff:ff link-netns ns0
69     inet 1.1.1.2/24 scope global veth1    #  此时veth有ip了
70        valid_lft forever preferred_lft forever
71     inet6 fe80::7cb1:ddff:fe27:5687/64 scope link 
72        valid_lft forever preferred_lft forever
73 [root@localhost ~]# ip netns exec ns1 ping 1.1.1.1   #  进到ns1,去ping1.1.1.1,能通说明ns1和ns0可以通信
74 PING 1.1.1.1 (1.1.1.1) 56(84) bytes of data.
75 64 bytes from 1.1.1.1: icmp_seq=1 ttl=64 time=6.30 ms
76 64 bytes from 1.1.1.1: icmp_seq=2 ttl=64 time=0.076 ms
77 64 bytes from 1.1.1.1: icmp_seq=3 ttl=64 time=0.077 ms

veth设备重命名

 1 [root@localhost ~]# ip netns exec ns0 ip link show   #  两个veth的设备名字不一样
 2 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
 3     link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
 4 38: veth0@if39: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
 5     link/ether d2:62:7c:c0:44:7f brd ff:ff:ff:ff:ff:ff link-netns ns1
 6 [root@localhost ~]# ip netns exec ns1 ip link show
 7 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
 8     link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
 9 39: veth1@if38: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
10     link/ether 7e:b1:dd:27:56:87 brd ff:ff:ff:ff:ff:ff link-netns ns0
11 [root@localhost ~]# ip netns exec ns0 ip link set veth0 down   #  停掉veth0  才能操作改名
12 [root@localhost ~]# ip netns exec ns0 ip link set dev veth0 name eth0    #   把veth0的名字改成eth0
13 [root@localhost ~]# ip netns exec ns0 ip link set eth0 up   #  启动eth0
14 [root@localhost ~]# ip netns exec ns1 ip link set veth1  down  #  停掉veth1
15 [root@localhost ~]# ip netns exec ns1 ip link set dev veth1 name eth0   # 把veth1的名字改成eth0
16 [root@localhost ~]# ip netns exec ns1 ip link set eth0 up    # 启动
17 [root@localhost ~]# ip netns exec ns1 ping 1.1.1.1    # 也能通
18 PING 1.1.1.1 (1.1.1.1) 56(84) bytes of data.
19 64 bytes from 1.1.1.1: icmp_seq=1 ttl=64 time=0.121 ms
20 64 bytes from 1.1.1.1: icmp_seq=2 ttl=64 time=0.103 ms
21 64 bytes from 1.1.1.1: icmp_seq=3 ttl=64 time=0.067 ms
22      #    改名字不会影响设置的ip,但是需要先停掉,改好再启动。容器会自动分配ip,并且和docker0网桥在同一个网段,会虚拟一对veth设备一个放在容器,一个放在我们的真机上。
23 
24     

四种网络模式配置

bridge模式配置(桥接模式)

 1 [root@localhost ~]# docker run -it --rm busybox    # 桥接是默认的,不用network也可以
 2 / # ifconfig 
 3 eth0      Link encap:Ethernet  HWaddr 02:42:AC:11:00:02  
 4           inet addr:172.17.0.2  Bcast:172.17.255.255  Mask:255.255.0.0
 5           UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
 6           RX packets:9 errors:0 dropped:0 overruns:0 frame:0
 7           TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
 8           collisions:0 txqueuelen:0 
 9           RX bytes:806 (806.0 B)  TX bytes:0 (0.0 B)
10 
11 lo        Link encap:Local Loopback  
12           inet addr:127.0.0.1  Mask:255.0.0.0
13           UP LOOPBACK RUNNING  MTU:65536  Metric:1
14           RX packets:0 errors:0 dropped:0 overruns:0 frame:0
15           TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
16           collisions:0 txqueuelen:1000 
17           RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)
18 [root@localhost ~]# docker run -it --network bridge busybox
19 / # ifconfig 
20 eth0      Link encap:Ethernet  HWaddr 02:42:AC:11:00:02  
21           inet addr:172.17.0.2  Bcast:172.17.255.255  Mask:255.255.0.0
22           UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
23           RX packets:10 errors:0 dropped:0 overruns:0 frame:0
24           TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
25           collisions:0 txqueuelen:0 
26           RX bytes:876 (876.0 B)  TX bytes:0 (0.0 B)
27 
28 lo        Link encap:Local Loopback  
29           inet addr:127.0.0.1  Mask:255.0.0.0
30           UP LOOPBACK RUNNING  MTU:65536  Metric:1
31           RX packets:0 errors:0 dropped:0 overruns:0 frame:0
32           TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
33           collisions:0 txqueuelen:1000 
34           RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

none模式配置(孤岛模式)

[root@localhost ~]# docker run -it --rm --network none 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)
     #   指定none模式就只有一块lo网卡,没有其他网卡和ip,无法和外界通信

container模式配置 (容器模式)

启动第一个容器

 1 [root@localhost ~]# docker run -it --rm --name b1 busybox  
 2 / # ip a
 3 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
 4     link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
 5     inet 127.0.0.1/8 scope host lo
 6        valid_lft forever preferred_lft forever
 7 50: eth0@if51: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
 8     link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
 9     inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
10        valid_lft forever preferred_lft forever
11 #   先启动一个正常的容器取名b1,然后在启动一个容器指定容器模式
12 和b1一样。
13 [root@localhost ~]# docker run -it --rm --network container:b1 busybox
14 / # ip a
15 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
16     link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
17     inet 127.0.0.1/8 scope host lo
18        valid_lft forever preferred_lft forever
19 50: eth0@if51: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
20     link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
21     inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
22        valid_lft forever preferred_lft forever
 1 没有名字的容器下面创建一个data目录
 2 / # ls
 3 bin   dev   etc   home  proc  root  sys   tmp   usr   var
 4 / # mkdir data
 5 / # ls
 6 bin   data  dev   etc   home  proc  root  sys   tmp   usr   var
 7 / # 
 8 b1容器查看不到
 9 / # ls
10 bin   dev   etc   home  proc  root  sys   tmp   usr   var
11 共享IP,但不共享文件系统,因为文件系统是处于隔离状态,仅仅是共享了网络而已
12 / # echo 'hello world' > data/index.html   #  没有名字的容器里再跑一个容器
13 / # /bin/httpd -h /data
14 / # netstat -antl
15 Active Internet connections (servers and established)
16 Proto Recv-Q Send-Q Local Address           Foreign Address         State       
17 tcp        0      0 :::80                   :::*                    LISTEN      
18 / # wget -O - -q 127.0.0.1  # b1可以访问到,应为他们用的是同一个ip
19 hello world

host模式配置(主机模式)

启动容器时直接指明模式为host

[root@localhost ~]# docker run -it --rm --network host busybox
/ # ip a   #  指定主机模式用的都是主机的ip
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 fq_codel qlen 1000
    link/ether 00:0c:29:bc:11:bf brd ff:ff:ff:ff:ff:ff
    inet 192.168.149.130/24 brd 192.168.149.255 scope global noprefixroute ens33
       valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue 
    link/ether 02:42:e7:69:ef:af 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:e7ff:fe69:efaf/64 scope link 
       valid_lft forever preferred_lft forever
/ # 

此时如果我们在这个容器中启动一个http站点,我们就可以直接用宿主机的IP直接在浏览器中访问这个容器中的站点了。

 

容器的常用操作

查看容器的主机名

1 [root@localhost ~]# docker run -it --rm  busybox
2 / # hostname   #查看主机名  默认情况下主机名和容器id一样 ,容器里面是只读层,改不了名字,只能在容器启动的时候注入主机名
3 6bd0cb733cbf
4 [root@localhost ~]# docker ps -a
5 CONTAINER ID   IMAGE     COMMAND   CREATED          STATUS          PORTS     NAMES
6 6bd0cb733cbf   busybox   "sh"      36 seconds ago   Up 35 seconds             inspiring_margulis
7   

在容器启动时注入主机名

 1 [root@localhost ~]# docker run -it --rm --hostname node1 busybox
 2 / # hostname
 3 node1
 4 / # cat /etc/hostname 
 5 node1
 6 / # cat /etc/hosts
 7 127.0.0.1    localhost
 8 ::1    localhost ip6-localhost ip6-loopback
 9 fe00::0    ip6-localnet
10 ff00::0    ip6-mcastprefix
11 ff02::1    ip6-allnodes
12 ff02::2    ip6-allrouters
13 172.17.0.2    node1
14 / # mkdir data
15 / # echo 'hello world' > /data/index.html
16 / # /bin/httpd -h /data/
17 / # netstat -antl
18 Active Internet connections (servers and established)
19 Proto Recv-Q Send-Q Local Address           Foreign Address         State       
20 tcp        0      0 :::80                   :::*                    LISTEN   
21 / # wget -O - -q node1    #  用主机名也可以访问,因为有映射关系
22 hello world

 

手动指定容器要使用的DNS

1 / # cat /etc/resolv.conf    #  默认的dns
2 # Generated by NetworkManager
3 nameserver 114.114.114.114
4 [root@localhost ~]# docker run -it --rm --hostname node1 --dns 8.8.8.8 busybox   #  手动设置改变dns
5 / # cat /etc/resolv.conf 
6 nameserver 8.8.8.8

  7 / # mkdir /data
  8 / # echo 'hello world' > data/index.html
  9 / # /bin/httpd -f -h /data/

 

手动往/etc/hosts文件中注入主机名到IP地址的映射

[root@localhost ~]# docker run -it --rm --hostname node2 --add-host node1:172.17.0.2 busybox  # 注入主机名ip地址的映射
/ # cat /etc/hosts  
127.0.0.1    localhost
::1    localhost ip6-localhost ip6-loopback
fe00::0    ip6-localnet
ff00::0    ip6-mcastprefix
ff02::1    ip6-allnodes
ff02::2    ip6-allrouters
172.17.0.2    node1    # 有映射关系了
172.17.0.3    node2
/ # wget -O - -q http://node1   #  可以用主机名访问
hello world
[root@localhost ~]# docker run -it --rm --hostname node2 --add-host node1:172.17.0.2 --add-host test1:1.1.1.1 --add-host test2:2.2.2.2 busybox  #   也可以做多个映射关系
/ # cat /etc/hosts
127.0.0.1    localhost
::1    localhost ip6-localhost ip6-loopback
fe00::0    ip6-localnet
ff00::0    ip6-mcastprefix
ff02::1    ip6-allnodes
ff02::2    ip6-allrouters
172.17.0.2    node1
1.1.1.1    test1
2.2.2.2    test2
172.17.0.3    node2

开放容器端口

执行docker run的时候有个-p选项,可以将容器中的应用端口映射到宿主机中,从而实现让外部主机可以通过访问宿主机的某端口来访问容器内应用的目的。

-p选项能够使用多次,其所能够暴露的端口必须是容器确实在监听的端口。

-p选项的使用格式:

  • -p <containerPort>
    • 将指定的容器端口映射至主机所有地址的一个动态端口
  • -p <hostPort>:<containerPort>
    • 将容器端口<containerPort>映射至指定的主机端口<hostPort>
  • -p <ip>::<containerPort>
    • 将指定的容器端口<containerPort>映射至主机指定<ip>的动态端口
  • -p <ip>:<hostPort>:<containerPort>
    • 将指定的容器端口<containerPort>映射至主机指定<ip>的端口<hostPort>

动态端口指的是随机端口,具体的映射结果可使用docker port命令查看。

[root@localhost ~]# docker run -d --rm --name web -p 80 httpd
04fde3b15e0c79356371ed6fd460c707b3d880f196a7452267fdf1bfa3bf9c23
[root@localhost ~]# docker ps
CONTAINER ID   IMAGE     COMMAND              CREATED         STATUS         PORTS                                     NAMES
04fde3b15e0c   httpd     "httpd-foreground"   8 seconds ago   Up 7 seconds   0.0.0.0:49153->80/tcp, :::49153->80/tcp   web
 将指定的容器端口映射至主机所有地址的一个动态端口
[root@localhost ~]# docker run -d --rm --name web -p 80:80 httpd
71765be95b82e4fceb1a9c59a69c1097288e849f159326140016faa0d8803d0b
[root@localhost ~]# docker ps
CONTAINER ID   IMAGE     COMMAND              CREATED         STATUS         PORTS                               NAMES
71765be95b82   httpd     "httpd-foreground"   6 seconds ago   Up 4 seconds   0.0.0.0:80->80/tcp, :::80->80/tcp   web
将容器80端口号映射到主机80端口号
[root@localhost ~]# ip addr add 192.168.149.250/24 dev ens33
[root@localhost ~]# ip a    #  在ens33上增加一个250的ip,现在有两个
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default 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 fq_codel state UP group default qlen 1000
    link/ether 00:0c:29:bc:11:bf brd ff:ff:ff:ff:ff:ff
    inet 192.168.149.130/24 brd 192.168.149.255 scope global noprefixroute ens33
       valid_lft forever preferred_lft forever
    inet 192.168.149.250/24 scope global secondary ens33
       valid_lft forever preferred_lft forever
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:e7:69:ef:af 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:e7ff:fe69:efaf/64 scope link 
       valid_lft forever preferred_lft forever
65: veth558e8bf@if64: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default 
    link/ether 9e:42:d0:82:60:31 brd ff:ff:ff:ff:ff:ff link-netnsid 2
    inet6 fe80::9c42:d0ff:fe82:6031/64 scope link 
       valid_lft forever preferred_lft forever
[root@localhost ~]# docker run -d --name web --rm -p 192.168.149.130::80 httpd      # 只暴露在130ip上,随机的
741e0771eb296333442514b508ee3476898820b44de58093c0147bd205331771
[root@localhost ~]# ss -antl
State            Recv-Q            Send-Q                         Local Address:Port                        Peer Address:Port           Process           
LISTEN           0                 128                                  0.0.0.0:22                               0.0.0.0:*                                
LISTEN           0                 128                          192.168.149.130:49153                            0.0.0.0:*                                
LISTEN           0                 128                                     [::]:22                                  [::]:* 
将指定的容器端口<containerPort>映射至主机指定<ip>的动态端口
[root@localhost ~]# docker run -d --name web --rm -p 192.168.149.130:8080:80 httpd 
c4e8aa8ea2456d8503e1d305dfa24c3aa3ada4b19d24e68b82ffac442a3988a1
[root@localhost ~]# ss -antl
State             Recv-Q            Send-Q                         Local Address:Port                       Peer Address:Port           Process           
LISTEN            0                 128                          192.168.149.130:8080                            0.0.0.0:*                                
LISTEN            0                 128                                  0.0.0.0:22                              0.0.0.0:*                                
LISTEN            0                 128                                     [::]:22                                 [::]:*
将指定的容器端口<containerPort>映射至主机指定<ip>的端口<hostPort>

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

以上命令执行后会一直占用着前端,我们新开一个终端连接来看一下容器的80端口被映射到了宿主机的什么端口上

[root@localhost ~]# docker port web
80/tcp -> 0.0.0.0:32769


这篇关于docker容器网络配置的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程