Docker 网络知识

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
  • 添加:

    扫描二维码关注公众号,回复: 5084289 查看本文章
    • 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-test1IP地址:

    • ip netns exec test1 ip addr add 192.168.1.1/24 dev veth-test1
  • 设置test2中的veth-test2IP地址:

    • 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时他没有独立的网络,它是跟我们主机共享一套网络的,不建议使用,因为可能会出现端口有冲突的问题。

猜你喜欢

转载自blog.csdn.net/Fe_cow/article/details/86363230