• 设为首页
  • 收藏本站
  • 积分充值
  • VIP赞助
  • 手机版
  • 微博
  • 微信
    微信公众号 添加方式:
    1:搜索微信号(888888
    2:扫描左侧二维码
  • 快捷导航
    福建二哥 门户 查看主题

    Docker中的容器网络以及其配置说明

    发布者: 网神之王 | 发布时间: 2025-6-17 08:14| 查看数: 84| 评论数: 0|帖子模式

    Docker中的容器网络及其配置


    docker容器网络

    Docker在安装后自动提供3种网络, 可以使用 docker network ls 命令查看
    1. [root@Master ~]# docker network ls
    2. NETWORK ID          NAME                DRIVER              SCOPE
    3. 1924254a040a        bridge              bridge              local
    4. 13346f3bc032        host                host                local
    5. c41bdf0688fe        none                null                local
    复制代码
    Docker使用 Linux 桥接, 在宿主机虚拟一个 Docker 容器网桥(docker0) , Docker 启动一个容器时会根据 Docker 网桥的网段分配给容器一个 IP 地址, 称为 Container-IP, 同时 Docker 网桥是每个容器的默认网关。因为在同一宿主机内的容器都接入同一个网桥, 这样容器之间就能够通过容器的 Container-IP 直接通信。

    docker的4种网络模式

    网络模式配置说明host–network host容器和宿主机共享Network namespacecontainer–network container:NAMEORID容器和另外一个容器共享Network namespacenone–network none容器有独立的Network namespace,但并没有对其进行任何网络设置,如分配veth pair和网桥连接,配置IP等bridge–networkbridge默认模式



    bridge 模式

    当 Docker 进程启动时, 会在主机上创建一个名为 docker0 的虚拟网桥, 此主机上启动的 Docker 容器会连接到这个虚拟网桥上。虚拟网桥的工作方式和物理交换机类似, 这样主机上的所有容器就通过交换机连在了一个二层网络中。
    从 docker0 子网中分配一个IP给容器使用, 并设置 docker0 的IP地址为容器的默认网关。在主机上创建一对虚拟网卡 veth pair设备,Docker将 veth pair 设备的一端放在新创建的容器中,并命名为 eth0(容器的网卡),另一端放在主机中,以 vethxxx 这样类似的名字命名,并将这个网络设备加入到 docker0 网桥中。可以通过 brctl show 命令查看。
    bridge 模式是 docker的默认网络模式,不写 --network 参数,就是 bridge 模式。使用 docker run -p 时,docker实际是在 iptables 做了 DNAT 规则,实现端口转发功能。可以使用 iptables -t nat -vnL 查看。
    bridge 模式如下图所示:

    假设上图的 Container2 中运行了一个nginx,大家来想几个问题:

    • 同主机间两个容器间是否可以直接通信?比如在 Container1 上能不能直接访问到 Container2 的 nginx 站点?
    • 在宿主机上能否直接访问到 Container2 的 nginx战点?
    • 在另一台主机上如何访问 node1 上的这个nginx站点呢? DNAT发布?
    Docker网桥是宿主机虚拟出来的,并不是真实存在的网络设备,外部网络是无法寻址到的,这也意味着外部网络无法通过直接通过 Container-IP访问到容器。如果容器希望外部访问能够访问到,可以通过映射容器端口到宿主主机(端口映射),即docker run 创建容器时候通过 -p 或 -P参数来启用,访问容器的时候就通过【宿主机 IP】:【容器端口】访问容器。

    container模式

    这个模式指定新创建的容器和已经存在的一个容器共享一个 Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡、配置自己的IP,而是和一个指定的容器共享IP、端口范围等。同样,两个容器除了网络方面,其它的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过IO网卡设备通信。


    host 模式

    如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立的 Network Namespace,而是和宿主机共用一个 Network Namespace。容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。但是,容器的其它方面,如文件系统、进程列表等还是和宿主机隔离的。
    使用host模式的容器可以直接使用宿主机的IP地址与外界通信,容器内部的服务端口也可以使用宿主机的端口,不需要进行NAT,host最大的优势就是网络性能比较好,但是 docker host上已经使用的端口就不能再使用了,网络的隔离性不好。
    Host模式如下图所示:


    none 模式

    使用none模式,Docker容器拥有自己的 Network Namespace,但是,并不为 Docker容器进行任何网络配置。也就是说,这个Docker容器没有网卡、IP、路由等信息。需要我们自己为Docker容器添加网卡、配置IP等。
    这种网络模式下 容器只有IO回环网络,没有其它网卡。none模式可以再容器创建时通过 --network none来指定。这种类型的网络没有办法联网,封闭的网络能很好的保证容器的安全性。

    应用场景


    • 启动一个容器处理数据,比如转换数据格式
    • 一些后台的计算和处理任务
    none 模式如下图所示:
    1. [root@Master ~]# docker network inspect bridge  #查看bridge网络的详细配置
    2. [
    3.     {
    4.         "Name": "bridge",
    5.         "Id": "78cf421b5c970fe40d93582e377187001a352e649ed7edd1e7fcd2f8fb28b8a8",
    6.         "Created": "2024-07-01T19:59:06.063808169+08:00",
    7.         "Scope": "local",
    8.         "Driver": "bridge",
    9.         "EnableIPv6": false,
    10.         "IPAM": {
    11.             "Driver": "default",
    12.             "Options": null,
    13.             "Config": [
    14.                 {
    15.                     "Subnet": "172.17.0.0/16",
    16.                     "Gateway": "172.17.0.1"
    17.                 }
    18.             ]
    19.         },
    20.         "Internal": false,
    21.         "Attachable": false,
    22.         "Ingress": false,
    23.         "ConfigFrom": {
    24.             "Network": ""
    25.         },
    26.         "ConfigOnly": false,
    27.         "Containers": {
    28.             "1144c912e93254a920172d234311826e8a60f21b475032c6a19d78336597004a": {
    29.                 "Name": "rancher-2.6.5",
    30.                 "EndpointID": "b4ddc0d583862afa0da44e3f29f32456d965c6eeb8dbb9e3cfaa30bb3b78e10a",
    31.                 "MacAddress": "02:42:ac:11:00:02",
    32.                 "IPv4Address": "172.17.0.2/16",
    33.                 "IPv6Address": ""
    34.             }
    35.         },
    36.         "Options": {
    37.             "com.docker.network.bridge.default_bridge": "true",
    38.             "com.docker.network.bridge.enable_icc": "true",
    39.             "com.docker.network.bridge.enable_ip_masquerade": "true",
    40.             "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
    41.             "com.docker.network.bridge.name": "docker0",
    42.             "com.docker.network.driver.mtu": "1500"
    43.         },
    44.         "Labels": {}
    45.     }
    46. ]
    复制代码
    docker 容器网络配置


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

    ip netns 命令
    可以借助 ip netns 命令来完成对 Network Namespace 的各种操作。ip netns 命令来自于 iproute 安装包,一般系统会默认安装,如果没有的话,请自行安装。
    注意:ip netns 命令修改网络配置时需要 sudo 权限。
    可以通过 ip netns 命令完成对 Network Namespace 的相关操作,可以通过 ip netns help 查看命令帮助信息:
    1. [root@Master ~]# ip netns help
    2. Usage: ip netns list
    3.        ip netns add NAME
    4.        ip netns set NAME NETNSID
    5.        ip [-all] netns delete [NAME]
    6.        ip netns identify [PID]
    7.        ip netns pids NAME
    8.        ip [-all] netns exec [NAME] cmd ...
    9.        ip netns monitor
    10.        ip netns list-id
    复制代码
    默认情况下,Linux系统中是没有任何 Network Namespace的,所以 ip netns list 命令不会返回任何信息。
    1. [root@Master ~]# ip netns list
    2. [root@Master ~]#
    复制代码
    创建 Network Namespace

    通过命令创建一个名为ns0的命名空间:
    1. [root@Master ~]# ip netns list
    2. [root@Master ~]# ip netns add ns0[root@Master ~]# ip netns listns0
    复制代码
    新创建的 Network Namespace 会出现在 /var/run/netns/目录下。如果相同名字的 namespace已经存在,命令会报 Cannot create namespace file “/var/run/netns/ns0”: File exists的错误。
    1. [root@Master netns]# cd /var/run/netns/
    2. [root@Master netns]# ll
    3. 总用量 0
    4. -r--r--r-- 1 root root 0 7月   2 09:07 ns0
    5. [root@Master netns]# ip netns add ns0
    6. Cannot create namespace file "/var/run/netns/ns0": File exists
    7. [root@Master netns]#
    复制代码
    对于每个 Network Namespace 来说,它会有自己独立的网卡、路由表、ARP表、iptables等和网络相关的资源。

    操作 Network Namespace

    ip 命令提供了 ip netns exec 子命令可以在对应的 Network Namespace 中执行命令。
    查看新创建 Network Namespace 的网卡信息
    1. [root@Master ~]# ip netns exec ns0 ip addr
    2. 1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
    3.     link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    复制代码
    可以看到,新创建的 Network Namespace 中会默认创建一个 lo 回环网卡,此时网卡处于关闭状态。若尝试ping 该 lo 回环网卡,会提示 Network unreachable
    1. [root@Master ~]# ip netns exec ns0 ping 127.0.0.1
    2. connect: 网络不可达

    3. 127.0.0.1是默认回环网卡
    复制代码
    通过下面的命令启动 lo 回环网卡:
    1. [root@Master ~]# ip netns exec ns0 ip link set lo up
    2. [root@Master ~]# ip netns exec ns0 ping 127.0.0.1
    3. PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
    4. 64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.467 ms
    5. 64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.033 ms
    6. 64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.042 ms
    7. 64 bytes from 127.0.0.1: icmp_seq=4 ttl=64 time=0.042 ms
    8. 64 bytes from 127.0.0.1: icmp_seq=5 ttl=64 time=0.042 ms
    9. 64 bytes from 127.0.0.1: icmp_seq=6 ttl=64 time=0.035 ms
    10. ^C
    11. --- 127.0.0.1 ping statistics ---
    12. 6 packets transmitted, 6 received, 0% packet loss, time 5004ms
    13. rtt min/avg/max/mdev = 0.033/0.110/0.467/0.159 ms
    复制代码
    转移设备

    我们可以在不同的 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@Master ~]# ip link add type veth
    2. [root@Master ~]# 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. 2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    10.     link/ether 00:0c:29:6e:81:b7 brd ff:ff:ff:ff:ff:ff
    11.     inet 192.168.75.100/24 brd 192.168.75.255 scope global noprefixroute ens33
    12.        valid_lft forever preferred_lft forever
    13.     inet6 fe80::11a5:f410:75e5:dc1f/64 scope link noprefixroute
    14.        valid_lft forever preferred_lft forever
    15. 3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    16.     link/ether 02:42:2a:a0:38:5a brd ff:ff:ff:ff:ff:ff
    17.     inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
    18.        valid_lft forever preferred_lft forever
    19.     inet6 fe80::42:2aff:fea0:385a/64 scope link
    20.        valid_lft forever preferred_lft forever
    21. 4: docker_gwbridge: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
    22.     link/ether 02:42:f7:0c:15:a6 brd ff:ff:ff:ff:ff:ff
    23.     inet 172.18.0.1/16 brd 172.18.255.255 scope global docker_gwbridge
    24.        valid_lft forever preferred_lft forever
    25. 8: veth780a161@if7: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
    26.     link/ether 3e:6b:9c:85:f4:b0 brd ff:ff:ff:ff:ff:ff link-netnsid 1
    27.     inet6 fe80::3c6b:9cff:fe85:f4b0/64 scope link
    28.        valid_lft forever preferred_lft forever
    29. 9: veth0@veth1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN group default qlen 1000
    30.     link/ether 02:ba:c5:28:3b:cb brd ff:ff:ff:ff:ff:ff
    31. 10: veth1@veth0: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN group default qlen 1000
    32.     link/ether 52:8a:6f:41:d6:aa 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
    1. [root@Master ~]# ip netns add ns1
    2. [root@Master ~]# ip netns list
    3. ns1
    4. ns0
    复制代码
    然后我们将 veth0 加入到 ns0,将 veth1 加入到 ns1
    1. [root@Master ~]# ip link set veth0 netns ns0
    2. [root@Master ~]# ip link set veth1 netns ns1
    复制代码
    然后我们分别为这对 veth pair 配置上 ip 地址,并启用它们
    1. [root@Master ~]# ip netns exec ns0 ip link set veth0 up
    2. [root@Master ~]# ip netns exec ns0 ip addr add 192.0.0.1/24 dev veth0
    3. [root@Master ~]# ip netns exec ns1 ip link set veth1 up
    4. [root@Master ~]# ip netns exec ns1 ip addr add 192.0.0.2/24 dev veth1
    复制代码
    查看这对 veth pair 的状态
    1. [root@Master ~]# ip netns exec ns1 ip a
    2. 1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
    3.     link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    4. 10: veth1@if9: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    5.     link/ether 52:8a:6f:41:d6:aa brd ff:ff:ff:ff:ff:ff link-netnsid 0
    6.     inet 192.0.0.2/24 scope global veth1
    7.        valid_lft forever preferred_lft forever
    8.     inet6 fe80::508a:6fff:fe41:d6aa/64 scope link
    9.        valid_lft forever preferred_lft forever
    复制代码
    从上面可以看出,我们已经成功启用了这个 veth pair,并为每个 veth 设备分配了对应的 ip 地址。我们尝试在 ns1 中访问 ns0 中的 ip 地址
    1. [root@Master ~]# ip netns exec ns1 ping 192.0.0.1
    2. PING 192.0.0.1 (192.0.0.1) 56(84) bytes of data.
    3. 64 bytes from 192.0.0.1: icmp_seq=1 ttl=64 time=0.726 ms
    4. 64 bytes from 192.0.0.1: icmp_seq=2 ttl=64 time=0.109 ms
    5. 64 bytes from 192.0.0.1: icmp_seq=3 ttl=64 time=0.037 ms
    6. 64 bytes from 192.0.0.1: icmp_seq=4 ttl=64 time=0.118 ms
    7. 64 bytes from 192.0.0.1: icmp_seq=5 ttl=64 time=0.262 ms
    8. 64 bytes from 192.0.0.1: icmp_seq=6 ttl=64 time=0.064 ms
    9. ^C
    10. --- 192.0.0.1 ping statistics ---
    11. 6 packets transmitted, 6 received, 0% packet loss, time 5001ms
    12. rtt min/avg/max/mdev = 0.037/0.219/0.726/0.237 ms
    13. [root@Master ~]# ip netns exec ns0 ping 192.0.0.2
    14. PING 192.0.0.2 (192.0.0.2) 56(84) bytes of data.
    15. 64 bytes from 192.0.0.2: icmp_seq=1 ttl=64 time=0.378 ms
    16. 64 bytes from 192.0.0.2: icmp_seq=2 ttl=64 time=0.090 ms
    17. 64 bytes from 192.0.0.2: icmp_seq=3 ttl=64 time=0.131 ms
    18. 64 bytes from 192.0.0.2: icmp_seq=4 ttl=64 time=0.140 ms
    19. 64 bytes from 192.0.0.2: icmp_seq=5 ttl=64 time=0.138 ms
    20. 64 bytes from 192.0.0.2: icmp_seq=6 ttl=64 time=0.130 ms
    21. ^C
    22. --- 192.0.0.2 ping statistics ---
    23. 6 packets transmitted, 6 received, 0% packet loss, time 5001ms
    24. rtt min/avg/max/mdev = 0.090/0.167/0.378/0.096 ms
    复制代码
    可以看到,veth pair 成功实现了两个不同 Network Namespace 之间的网络交互。

    四种网络模式配置


    bridge 模式配置
    1. [root@Master ~]# docker run -it --name ti --rm busybox
    2. Unable to find image 'busybox:latest' locally
    3. latest: Pulling from library/busybox
    4. 5cc84ad355aa: Pull complete
    5. Digest: sha256:5acba83a746c7608ed544dc1533b87c737a0b0fb730301639a0179f9344b1678
    6. Status: Downloaded newer image for busybox:latest
    7. / # ifconfig
    8. eth0      Link encap:Ethernet  HWaddr 02:42:AC:11:00:03  
    9.           inet addr:172.17.0.3  Bcast:172.17.255.255  Mask:255.255.0.0
    10.           UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
    11.           RX packets:8 errors:0 dropped:0 overruns:0 frame:0
    12.           TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
    13.           collisions:0 txqueuelen:0
    14.           RX bytes:656 (656.0 B)  TX bytes:0 (0.0 B)

    15. lo        Link encap:Local Loopback  
    16.           inet addr:127.0.0.1  Mask:255.0.0.0
    17.           UP LOOPBACK RUNNING  MTU:65536  Metric:1
    18.           RX packets:0 errors:0 dropped:0 overruns:0 frame:0
    19.           TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
    20.           collisions:0 txqueuelen:1000
    21.           RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)
    复制代码
    在创建容器时添加 --network bridge 与不加 --network选项效果是一致的
    1. [root@Master ~]# docker run -it --name ti --network bridge --rm busybox
    2. / # ifconfig
    3. eth0      Link encap:Ethernet  HWaddr 02:42:AC:11:00:03  
    4.           inet addr:172.17.0.3  Bcast:172.17.255.255  Mask:255.255.0.0
    5.           UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
    6.           RX packets:6 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:516 (516.0 B)  TX bytes:0 (0.0 B)

    10. lo        Link encap:Local Loopback  
    11.           inet addr:127.0.0.1  Mask:255.0.0.0
    12.           UP LOOPBACK RUNNING  MTU:65536  Metric:1
    13.           RX packets:0 errors:0 dropped:0 overruns:0 frame:0
    14.           TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
    15.           collisions:0 txqueuelen:1000
    16.           RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

    17. / #
    复制代码
    none 模式配置
    1. [root@Master ~]# docker run -it --name t1 --network none --rm busybox
    2. / # ifconfig
    3. lo        Link encap:Local Loopback  
    4.           inet addr:127.0.0.1  Mask:255.0.0.0
    5.           UP LOOPBACK RUNNING  MTU:65536  Metric:1
    6.           RX packets:0 errors:0 dropped:0 overruns:0 frame:0
    7.           TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
    8.           collisions:0 txqueuelen:1000
    9.           RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

    10. / #
    复制代码
    container 模式配置

    启动第一个容器
    1. [root@Master ~]# docker run -dit --name b3 busybox
    2. 7af0fc0bafe31a7195e1a3a5c194f5cd1d38700fe8d9369f4070c4f683070c1d
    3. [root@Master ~]# docker exec -it b3 /bin/sh
    4. / # ifconfig
    5. eth0      Link encap:Ethernet  HWaddr 02:42:AC:11:00:03  
    6.           inet addr:172.17.0.3  Bcast:172.17.255.255  Mask:255.255.0.0
    7.           UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
    8.           RX packets:8 errors:0 dropped:0 overruns:0 frame:0
    9.           TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
    10.           collisions:0 txqueuelen:0
    11.           RX bytes:656 (656.0 B)  TX bytes:0 (0.0 B)

    12. lo        Link encap:Local Loopback  
    13.           inet addr:127.0.0.1  Mask:255.0.0.0
    14.           UP LOOPBACK RUNNING  MTU:65536  Metric:1
    15.           RX packets:0 errors:0 dropped:0 overruns:0 frame:0
    16.           TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
    17.           collisions:0 txqueuelen:1000
    18.           RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

    19. / #
    复制代码
    启动第二个容器
    1. [root@Master ~]# docker run -it --name b2 --rm busybox
    2. / # ifconfig
    3. eth0      Link encap:Ethernet  HWaddr 02:42:AC:11:00:04  
    4.           inet addr:172.17.0.4  Bcast:172.17.255.255  Mask:255.255.0.0
    5.           UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
    6.           RX packets:8 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:656 (656.0 B)  TX bytes:0 (0.0 B)

    10. lo        Link encap:Local Loopback  
    11.           inet addr:127.0.0.1  Mask:255.0.0.0
    12.           UP LOOPBACK RUNNING  MTU:65536  Metric:1
    13.           RX packets:0 errors:0 dropped:0 overruns:0 frame:0
    14.           TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
    15.           collisions:0 txqueuelen:1000
    16.           RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

    17. / #
    复制代码
    可以看到名为 b2 的容器 IP地址是172.17.0.4 ,与第一个容器的IP地址不是一样的,也就是说并没有共享网络,此时如果我们将第二个容器的启动方式改变一下,就可以使名为b2的容器IP与b3容器IP一致,也即共享IP,但不共享文件系统。
    1. [root@Master ~]# docker run -it --name b2 --rm --network container:b3 busybox
    2. / # ifconfig
    3. eth0      Link encap:Ethernet  HWaddr 02:42:AC:11:00:03  
    4.           inet addr:172.17.0.3  Bcast:172.17.255.255  Mask:255.255.0.0
    5.           UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
    6.           RX packets:8 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:656 (656.0 B)  TX bytes:0 (0.0 B)

    10. lo        Link encap:Local Loopback  
    11.           inet addr:127.0.0.1  Mask:255.0.0.0
    12.           UP LOOPBACK RUNNING  MTU:65536  Metric:1
    13.           RX packets:0 errors:0 dropped:0 overruns:0 frame:0
    14.           TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
    15.           collisions:0 txqueuelen:1000
    16.           RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

    17. / #
    复制代码
    此时我们在b3容器上创建一个目录
    1. [root@Master ~]# docker exec -it b3 /bin/sh
    2. / # mkdir /tmp/data
    3. / # ls /tmp/
    4. data
    5. / #
    复制代码
    到b2容器上检查/tmp目录会发现并没有这个目录,因为文件系统是处于隔离状态,仅仅是共享了网络而已。
    1. [root@Master ~]# docker run -it --name b2 --rm --network container:b3 busybox
    2. / # ls /tmp/
    3. / #
    4. / #
    复制代码
    在b2容器上部署一个站点
    1. [root@Master ~]# docker run -it --name b2 --rm --network container:b3 busybox
    2. / # ls /tmp/
    3. / #
    4. / # echo 'hello world' > /tmp/index.html/ # ls /tmp/index.html/ # httpd -h /tmp/ # netstat -antlActive Internet connections (servers and established)Proto Recv-Q Send-Q Local Address           Foreign Address         State       tcp        0      0 :::80                   :::*                    LISTEN      / #
    复制代码
    在 b3 容器上用本地地址去访问此站点
    1. / # wget -O - -q 172.17.0.3:80
    2. hello world
    3. / #
    复制代码
    host 模式配置

    启动容器时直接指明模式为host
    1. [root@Master ~]# docker run -it --name b2 --rm --network host busybox
    2. / # ifconfig
    3. docker0   Link encap:Ethernet  HWaddr 02:42:00:67:A1:74  
    4.           inet addr:172.17.0.1  Bcast:172.17.255.255  Mask:255.255.0.0
    5.           inet6 addr: fe80::42:ff:fe67:a174/64 Scope:Link
    6.           UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
    7.           RX packets:33140 errors:0 dropped:0 overruns:0 frame:0
    8.           TX packets:37022 errors:0 dropped:0 overruns:0 carrier:0
    9.           collisions:0 txqueuelen:0
    10.           RX bytes:5200713 (4.9 MiB)  TX bytes:55906242 (53.3 MiB)

    11. docker_gwbridge Link encap:Ethernet  HWaddr 02:42:E9:16:D2:A1  
    12.           inet addr:172.18.0.1  Bcast:172.18.255.255  Mask:255.255.0.0
    13.           UP BROADCAST MULTICAST  MTU:1500  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:0
    17.           RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

    18. ens33     Link encap:Ethernet  HWaddr 00:0C:29:6E:81:B7  
    19.           inet addr:192.168.75.100  Bcast:192.168.75.255  Mask:255.255.255.0
    20.           inet6 addr: fe80::11a5:f410:75e5:dc1f/64 Scope:Link
    21.           UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
    22.           RX packets:184930 errors:0 dropped:0 overruns:0 frame:0
    23.           TX packets:229473 errors:0 dropped:0 overruns:0 carrier:0
    24.           collisions:0 txqueuelen:1000
    25.           RX bytes:66831055 (63.7 MiB)  TX bytes:54247615 (51.7 MiB)

    26. lo        Link encap:Local Loopback  
    27.           inet addr:127.0.0.1  Mask:255.0.0.0
    28.           inet6 addr: ::1/128 Scope:Host
    29.           UP LOOPBACK RUNNING  MTU:65536  Metric:1
    30.           RX packets:0 errors:0 dropped:0 overruns:0 frame:0
    31.           TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
    32.           collisions:0 txqueuelen:1000
    33.           RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

    34. veth500b5c6 Link encap:Ethernet  HWaddr BA:D6:E4:4F:B2:13  
    35.           inet6 addr: fe80::b8d6:e4ff:fe4f:b213/64 Scope:Link
    36.           UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
    37.           RX packets:33140 errors:0 dropped:0 overruns:0 frame:0
    38.           TX packets:37030 errors:0 dropped:0 overruns:0 carrier:0
    39.           collisions:0 txqueuelen:0
    40.           RX bytes:5664673 (5.4 MiB)  TX bytes:55906898 (53.3 MiB)

    41. vethf7d0281 Link encap:Ethernet  HWaddr 9E:D9:64:0B:01:A4  
    42.           inet6 addr: fe80::9cd9:64ff:fe0b:1a4/64 Scope:Link
    43.           UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
    44.           RX packets:0 errors:0 dropped:0 overruns:0 frame:0
    45.           TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
    46.           collisions:0 txqueuelen:0
    47.           RX bytes:0 (0.0 B)  TX bytes:656 (656.0 B)

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

    容器的常用操作


    查看容器的主机名
    1. [root@Master ~]# docker run -it --name t1 --network bridge --rm busybox
    2. / # hostname
    3. beff0ad654d4
    4. / #
    复制代码
    在容器启动时注入主机名
    1. [root@Master ~]# docker run -it --name t1 --network bridge --hostname ljl --rm busybox
    2. / # hostname
    3. ljl
    4. / # cat /etc/hosts
    5. 127.0.0.1       localhost
    6. ::1     localhost ip6-localhost ip6-loopback
    7. fe00::0 ip6-localnet
    8. ff00::0 ip6-mcastprefix
    9. ff02::1 ip6-allnodes
    10. ff02::2 ip6-allrouters
    11. 172.17.0.4      ljl
    12. / # cat /etc/resolv.conf
    13. # Generated by NetworkManager
    14. nameserver 223.5.5.5
    15. / # ping www.baidu.com
    16. PING www.baidu.com (39.156.66.18): 56 data bytes
    17. 64 bytes from 39.156.66.18: seq=0 ttl=127 time=10.446 ms
    18. 64 bytes from 39.156.66.18: seq=1 ttl=127 time=18.426 ms
    19. 64 bytes from 39.156.66.18: seq=2 ttl=127 time=13.849 ms
    20. 64 bytes from 39.156.66.18: seq=3 ttl=127 time=11.226 ms
    21. 64 bytes from 39.156.66.18: seq=4 ttl=127 time=9.571 ms
    22. ^C
    23. --- www.baidu.com ping statistics ---
    24. 5 packets transmitted, 5 packets received, 0% packet loss
    25. round-trip min/avg/max = 9.571/12.703/18.426 ms
    26. / #
    复制代码
    手动指定容器要使用的DNS
    1. [root@Master ~]# docker run -it --name t3 --network bridge --hostname ljl --dns 114.114.114.114 --rm busybox
    2. / # cat /etc/resolv.conf
    3. nameserver 114.114.114.114
    4. / # nslookup -type=a www.baidu.com
    5. Server:         114.114.114.114
    6. Address:        114.114.114.114:53

    7. Non-authoritative answer:
    8. Name:   www.baidu.com
    9. Address: 39.156.66.14
    10. Name:   www.baidu.com
    11. Address: 39.156.66.18

    12. / #
    复制代码
    手动往 /etc/hosts 文件中注入主机名到IP地址的映射
    1. [root@Master ~]# docker run -it --name t1 --network bridge --hostname ljl --add-host www.a.com:1.1.1.1 --rm busybox
    2. / # cat /etc/hosts
    3. 127.0.0.1       localhost
    4. ::1     localhost ip6-localhost ip6-loopback
    5. fe00::0 ip6-localnet
    6. ff00::0 ip6-mcastprefix
    7. ff02::1 ip6-allnodes
    8. ff02::2 ip6-allrouters
    9. 1.1.1.1 www.a.com
    10. 172.17.0.3      ljl
    11. / #
    复制代码
    开放容器端口

    执行 docker run 的时候有个 -p 选项,可以将容器中的应用端口映射到宿主机中,从而实现让外部主机可以通过访问宿主机的某端口来访问容器内应用的目的。
    -p 选项能够使用多次,其所能够暴露的端口必须是容器确实在监听的端口。
    -p 选项的使用格式:
    1. -p containerPort
    复制代码
    将指定的容器端口映射至主机所有地址的一个动态端口

    • -p hostPort:containerPort
    • 将容器端口 containerPort 映射至指定的主机端口 hostPort
    • -p ip ;containerPort
    • 将指定的容器端口 containerPort 映射至主机指定ip的动态端口
    • -p ip :hostPort:containerPort
    • 将指定的容器端口 containerPort 映射至主机指定ip的端口 hostPort
    动态端口指定的是随机端口,具体的映射结果可以使用 docker port 命令查看。
    1. [root@Master ~]# docker run -dit --name web1 -p 192.168.75.100::80 httpd
    2. Unable to find image 'httpd:latest' locally
    3. latest: Pulling from library/httpd
    4. a2abf6c4d29d: Pull complete
    5. dcc4698797c8: Pull complete
    6. 41c22baa66ec: Pull complete
    7. 67283bbdd4a0: Pull complete
    8. d982c879c57e: Pull complete
    9. Digest: sha256:0954cc1af252d824860b2c5dc0a10720af2b7a3d3435581ca788dff8480c7b32
    10. Status: Downloaded newer image for httpd:latest
    11. ba9fa833a86cfd08d8d6456bada7da971b921caf856047af4dc8ee7e4ac8af34
    12. [root@Master ~]# docker ps
    13. CONTAINER ID        IMAGE                    COMMAND              CREATED             STATUS              PORTS                                      NAMES
    14. ba9fa833a86c        httpd                    "httpd-foreground"   7 seconds ago       Up 6 seconds        192.168.75.100:32768->80/tcp               web1
    15. 1942273f5b57        busybox                  "sh"                 About an hour ago   Up About an hour                                               t1
    16. 1144c912e932        rancher/rancher:v2.6.5   "entrypoint.sh"      6 months ago        Up 22 hours         0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp   rancher-2.6.5
    17. [root@Master ~]# ss -antl
    18. State       Recv-Q Send-Q             Local Address:Port                            Peer Address:Port              
    19. LISTEN      0      128                            *:22                                         *:*                  
    20. LISTEN      0      100                    127.0.0.1:25                                         *:*                  
    21. LISTEN      0      128               192.168.75.100:32768                                      *:*                  
    22. LISTEN      0      128                            *:111                                        *:*                  
    23. LISTEN      0      128                         [::]:80                                      [::]:*                  
    24. LISTEN      0      128                         [::]:22                                      [::]:*                  
    25. LISTEN      0      100                        [::1]:25                                      [::]:*                  
    26. LISTEN      0      128                         [::]:443                                     [::]:*                  
    27. LISTEN      0      128                         [::]:111                                     [::]:*                  
    28. [root@Master ~]#
    复制代码
    以上命令执行会一直占用着前端,我们新开一个终端连接连接来看一下容器的80端口被映射到了宿主机的什么端口上
    1. [root@Master ~]# docker port web1
    2. 80/tcp -> 192.168.75.100:32768
    复制代码
    由此可见,容器的80端口被暴露到了宿主机的 32768 端口上,此时我们在宿主机上访问一下这个端口看是否能访问到容器内的站点。
    1. [root@Master ~]# curl http://192.168.75.100:32768
    2. <html><body><h1>It works!</h1></body></html>
    复制代码
    iptables防火墙规则将随容器的创建自动生成,随容器的删除自动删除规则。
    1. [root@Master ~]# iptables -t nat -nvL
    2. Chain PREROUTING (policy ACCEPT 252 packets, 16128 bytes)
    3. pkts bytes target     prot opt in     out     source               destination         
    4.    10   520 DOCKER     all  --  *      *       0.0.0.0/0            0.0.0.0/0            ADDRTYPE match dst-type LOCAL

    5. Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
    6. pkts bytes target     prot opt in     out     source               destination         

    7. Chain OUTPUT (policy ACCEPT 37 packets, 2803 bytes)
    8. pkts bytes target     prot opt in     out     source               destination         
    9.     1    60 DOCKER     all  --  *      *       0.0.0.0/0           !127.0.0.0/8          ADDRTYPE match dst-type LOCAL

    10. Chain POSTROUTING (policy ACCEPT 38 packets, 2863 bytes)
    11. pkts bytes target     prot opt in     out     source               destination         
    12. 12192  780K MASQUERADE  all  --  *      !docker0  172.17.0.0/16        0.0.0.0/0           
    13.     0     0 MASQUERADE  all  --  *      !docker_gwbridge  172.18.0.0/16        0.0.0.0/0           
    14.     0     0 MASQUERADE  tcp  --  *      *       172.17.0.2           172.17.0.2           tcp dpt:443
    15.     0     0 MASQUERADE  tcp  --  *      *       172.17.0.2           172.17.0.2           tcp dpt:80
    16.     0     0 MASQUERADE  tcp  --  *      *       172.17.0.4           172.17.0.4           tcp dpt:80

    17. Chain DOCKER (2 references)
    18. pkts bytes target     prot opt in     out     source               destination         
    19.     0     0 RETURN     all  --  docker0 *       0.0.0.0/0            0.0.0.0/0           
    20.     0     0 RETURN     all  --  docker_gwbridge *       0.0.0.0/0            0.0.0.0/0           
    21.     0     0 DNAT       tcp  --  !docker0 *       0.0.0.0/0            0.0.0.0/0            tcp dpt:443 to:172.17.0.2:443
    22.     0     0 DNAT       tcp  --  !docker0 *       0.0.0.0/0            0.0.0.0/0            tcp dpt:80 to:172.17.0.2:80
    23.     1    60 DNAT       tcp  --  !docker0 *       0.0.0.0/0            192.168.75.100       tcp dpt:32768 to:172.17.0.4:80
    24. [root@Master ~]#
    复制代码
    将容器端口映射到指定IP的随机端口
    1. [root@Master ~]# docker run -dit --name web1 -p 192.168.75.100::80 httpd
    2. 201c8aac8bb57a3f111965fdc112385b87e64f22531489d8d7b3631279aeb822
    3. [root@Master ~]#
    复制代码
    查看端口映射情况
    1. [root@Master ~]# docker port web1
    2. 80/tcp -> 192.168.75.100:32769
    3. [root@Master ~]#
    复制代码
    自定义 docker0 网桥的网络属性信息

    自定义 docker0 网桥的网络属性信息需要修改 /etc/docker/daemon.json 配置文件
    1. [root@Master ~]# cd /etc/docker
    2. [root@Master docker]# cat daemon.json
    3. {
    4. "exec-opts": ["native.cgroupdriver=systemd"],
    5. "registry-mirrors": ["https://registry.docker-cn.com","https://s3d6l2fh.mirror.aliyuncs.com"],
    6. "bip": "192.168.1.5/24"
    7. }

    8. [root@Master docker]# systemctl daemon-reload
    9. [root@Master docker]# systemctl restart docker
    10. [root@Master docker]#
    11. [root@Master docker]# vim /lib/systemd/system/docker.service

    12. ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375

    13. [root@Master ~]# systemctl daemon-reload
    14. [root@Master ~]# systemctl restart docker
    复制代码
    在客户端上像 dockerd 直接传递 "-H|–host"选项指定要控制哪台主机上的 docker 容器
    1. [root@Master docker]# docker -H 192.168.75.100:2375 ps
    2. CONTAINER ID        IMAGE                    COMMAND             CREATED             STATUS              PORTS                                      NAMES
    3. 1144c912e932        rancher/rancher:v2.6.5   "entrypoint.sh"     6 months ago        Up 9 seconds        0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp   rancher-2.6.5
    复制代码
    创建新网络
    1. [root@Master docker]# docker network create ljl -d bridge
    2. 05e8748ed4b1ee29a743c9be2799a735685cbd7d8e03e64bcd95df7eb441016f
    3. [root@Master docker]# docker network ls
    4. NETWORK ID          NAME                DRIVER              SCOPE
    5. b7d9764c841e        bridge              bridge              local
    6. cffaf2d0d5bb        docker_gwbridge     bridge              local
    7. 13346f3bc032        host                host                local
    8. 05e8748ed4b1        ljl                 bridge              local
    9. c41bdf0688fe        none                null                local
    10. [root@Master docker]#
    复制代码
    创建一个额外的自定义桥,区别于 docker0
    1. [root@Master docker]# docker network create -d bridge --subnet "192.168.2.0/24" --gateway "192.168.2.1" br0
    2. 9565553236d3467668fce59761244051b5f53a409f9e9ce9722baaf08b99ff3d
    3. [root@Master docker]# docker network ls
    4. NETWORK ID          NAME                DRIVER              SCOPE
    5. 9565553236d3        br0                 bridge              local
    6. b7d9764c841e        bridge              bridge              local
    7. cffaf2d0d5bb        docker_gwbridge     bridge              local
    8. 13346f3bc032        host                host                local
    9. 05e8748ed4b1        ljl                 bridge              local
    10. c41bdf0688fe        none                null                local
    11. [root@Master docker]#
    复制代码
    使用新创建的自定义桥来创建容器
    1. [root@Master docker]# docker run -it --name b1 --network br0 busybox
    2. / # ifconfig
    3. eth0      Link encap:Ethernet  HWaddr 02:42:C0:A8:02:02  
    4.           inet addr:192.168.2.2  Bcast:192.168.2.255  Mask:255.255.255.0
    5.           UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
    6.           RX packets:12 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:1032 (1.0 KiB)  TX bytes:0 (0.0 B)

    10. lo        Link encap:Local Loopback  
    11.           inet addr:127.0.0.1  Mask:255.0.0.0
    12.           UP LOOPBACK RUNNING  MTU:65536  Metric:1
    13.           RX packets:0 errors:0 dropped:0 overruns:0 frame:0
    14.           TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
    15.           collisions:0 txqueuelen:1000
    16.           RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

    17. / #
    复制代码
    再创建一个容器,使用默认的bridge桥
    1. [root@Master ~]# docker run --name b2 -it busybox
    2. / # ls
    3. bin   dev   etc   home  proc  root  sys   tmp   usr   var
    4. / # ifconfig
    5. eth0      Link encap:Ethernet  HWaddr 02:42:C0:A8:01:02  
    6.           inet addr:192.168.1.2  Bcast:192.168.1.255  Mask:255.255.255.0
    7.           UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
    8.           RX packets:7 errors:0 dropped:0 overruns:0 frame:0
    9.           TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
    10.           collisions:0 txqueuelen:0
    11.           RX bytes:586 (586.0 B)  TX bytes:0 (0.0 B)

    12. lo        Link encap:Local Loopback  
    13.           inet addr:127.0.0.1  Mask:255.0.0.0
    14.           UP LOOPBACK RUNNING  MTU:65536  Metric:1
    15.           RX packets:0 errors:0 dropped:0 overruns:0 frame:0
    16.           TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
    17.           collisions:0 txqueuelen:1000
    18.           RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

    19. / #
    复制代码
    总结

    以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

    来源:https://www.jb51.net/server/339114upb.htm
    免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有账号?立即注册

    ×

    最新评论

    QQ Archiver 手机版 小黑屋 福建二哥 ( 闽ICP备2022004717号|闽公网安备35052402000345号 )

    Powered by Discuz! X3.5 © 2001-2023

    快速回复 返回顶部 返回列表