Docker笔记:配置docker网络与不通网络之间的通信及跨主机通信

配置 docker 网络

1 ) Docker0 网络

  • 默认启动的所有容器,都会加入到这个网络中
  • 在有docker环境的 centos 中, 通过 $ ip addr 可以看到Docker0网络相关信息
  • 多个容器都在Docker0 网络中就属于同一个局域网了,就可以通信了
  • 启动三个容器,测试网络的互通
    • 1 ) $ docker run -itd --name centos1 centos /bin/bash
    • 2 ) $ docker run -itd --name centos2 centos /bin/bash
    • 3 ) $ docker run -itd --name centos3 centos /bin/bash
    • 在物理机上看 $ ip addr, 又多了 3 条
  • 进入第1个容器
    • $ docker exec -it centos1 ip addr 查看ip地址
  • 进入第2个容器
    • $ docker exec -it centos2 ip addr 查看ip地址
  • 进入第3个容器
    • $ docker exec -it centos3 ip addr 查看ip地址
  • 可以发现三个容器的ip地址在一个局域网内, 是可以互联的
  • 并且在物理机上,也是可以和上面三个容器通信

2 )通信原理

  • 每启动一个Docker容器,Docker就会给Docker容器分配一个ip
  • 我们只要安装了Docker,就会有一个网卡 docker0
  • docker0 使用的是桥接模式,使用的技术是 veth-pair 技术

3 )查看网络

  • $ docker network --h

    Flag shorthand -h has been deprecated, please use --help
    
    Usage:  docker network COMMAND
    
    Manage networks
    
    Commands:
      connect     Connect a container to a network
      create      Create a network
      disconnect  Disconnect a container from a network
      inspect     Display detailed information on one or more networks
      ls          List networks
      prune       Remove all unused networks
      rm          Remove one or more networks
    
    Run 'docker network COMMAND --help' for more information on a command.
    
  • $ docker network ls

    • 这里需要启动docker服务或打开 docker desktop
      NETWORK ID     NAME      DRIVER    SCOPE
      1abcdbddaf9d   bridge    bridge    local
      64c08dba087e   host      host      local
      9b5e3b4957b1   none      null      local
      
    • 1abcdbddaf9d bridge bridge local 是docker0对应的网络
  • $ docker network inspect bridge

    • 可查看docker网络详细信息

4 )使用默认网络的问题

  • 没法实现网络隔离
    • 多个程序都跑在docker0网络里面,会很乱,不好管理
  • 没法使用计算机主机名实现通信
    • 参考下面微服务通信的问题

5 )关于微服务通信

  • 微服务中的通信是主机名之间的通信,不是ip地址之间的通信,因为ip地址会发生变化
  • 但是默认情况下的主机名是无法和另一台相通的
    • 假设 centos1 和 centos2 是启动状态
    • $ docker exec -it centos2 /bin/bash
      • $ ping centos1 发现ping不通

6 )解决方案

  • 要解决默认网络的问题,就需要自定义网络

  • 创建自己的网络

    • $ docker network create --help
      Usage:  docker network create [OPTIONS] NETWORK
      
      Create a network
      
      Options:
            --attachable           Enable manual container attachment
            --aux-address map      Auxiliary IPv4 or IPv6 addresses used by
                                  Network driver (default map[])
            --config-from string   The network from which to copy the configuration
            --config-only          Create a configuration only network
        -d, --driver string        Driver to manage the Network (default "bridge")
            --gateway strings      IPv4 or IPv6 Gateway for the master subnet
            --ingress              Create swarm routing-mesh network
            --internal             Restrict external access to the network
            --ip-range strings     Allocate container ip from a sub-range
            --ipam-driver string   IP Address Management Driver (default "default")
            --ipam-opt map         Set IPAM driver specific options (default map[])
            --ipv6                 Enable IPv6 networking
            --label list           Set metadata on a network
        -o, --opt map              Set driver specific options (default map[])
            --scope string         Control the network's scope
            --subnet strings       Subnet in CIDR format that represents a
                                  network segment
      
  • 通过上述命令创建好网络后,启动容器并加入该网络

    • $ docker network create --driver bridge --subnet 192.168.1.0/24 --gateway 192.168.1.1 docker1 创建docker1网络
    • $ docker network create --driver bridge --subnet 192.168.2.0/24 --gateway 192.168.2.1 docker2 创建docker2网络
    • $ docker run -tid --name centos1 --net docker1 centos /bin/bash 将cenos1加入docker1网络
    • $ docker run -tid --name centos2 --net docker1 centos /bin/bash 将cenos2加入docker1网络
    • $ docker run -tid --name centos3 --net docker2 centos /bin/bash 将cenos3加入docker2网络
    • $ docker exec -it centos1 ping centos2 同一网络下的 centos1 和 centos2 两个容器可以 ping 通
    • $ docker exec -it centos1 ping centos3 不同网络下的 centos1 和 centos3 两个容器实现了网络隔离(ping 不通)
  • 关于 /16 和 /24

    • 192.168.0.0/16 的范围在 (192.168.0.1 ~ 192.168.255.255) 这个范围比较大
    • 192.168.1.0/24 的范围在 (192.168.1.1 ~ 192.168.1.255) 这个范围比较小
  • 上面创建网络时,需要制定网络类型,网络类型,有如下四种

Docker 网络模式 配置 说明
host 模式 --net=host 容器和宿主机共享 Network namespace
container 模式 --net=container:NAMEorID 容器和另外一个容器共享 Network namespace。kubernetes中的pod就是多个容器共享一个Network namespace
none 模式 --net=none 容器有独立的Network namespace, 但并没有对其进行任何网络设置,如分配 veth pair 和网桥连接,配置IP等
bridge 模式 --net=bridge (默认为该模式)

不同网络的连接

  • 基于以上信息,docker0, docker1, docker2 属于不同的网络,没法直接通信
  • 上面 centos1, centos2 都在 docker1网络中,可以直接通信; centos3 在docker2网络中,这样实现了网路隔离
  • 现在要求,centos2 需要连接上 centos 3,实现 centos2既能连接centos1, 又能连接centos3
  • 这样,可以把 centos2 再加入到 docker2 网络中,就实现了上述要求
  • $ docker network connect --help
    Usage:  docker network connect [OPTIONS] NETWORK CONTAINER
    
    Connect a container to a network
    
    Options:
          --alias strings           Add network-scoped alias for the container
          --driver-opt strings      driver options for the network
          --ip string               IPv4 address (e.g., "172.30.100.104")
          --ip6 string              IPv6 address (e.g., "2001:db8::33")
          --link list               Add link to another container
          --link-local-ip strings   Add a link-local address for the container
    
  • $ docker network connect docker2 centos2 把centos2容器加入docker2网络中
  • $ docker exec -it centos2 ping centos3 发现ping通

docker 容器跨主机通信

  • 在多台服务器上部署 docker 容器,实现跨主机通信
  • 主机1, hostIP: 192.168.220.110
    • c1 容器
  • 主机2, hostIP: 192.168.220.111
    • c2 容器
  • 可见,主机1和主机2在同一个网段,两台主机是可以互通的,主机1和c1容器是互通的,主机2与c2容器是互通的
  • 但是,默认情况,c1 和 c2 是无法通信的,即使主机在同一个网段也是隔离的
  • 要给 c1 和 c2 分配不同的子网
    • 主机1上 : $ docker network create --driver bridge --subnet 192.168.1.0/24 --gateway 192.168.1.1 dockerNet1
    • 主机2上 : $ docker network create --driver bridge --subnet 192.168.2.0/24 --gateway 192.168.2.1 dockerNet2
    • c1 加入 dockerNet1: $ docker run -it --name c1 --net dockerNet1 centos /bin/bash
    • c2 加入 dockerNet2: $ docker run -it --name c2 --net dockerNet2 centos /bin/bash
  • 之后,要达到 1.0 的网段和 2.0 的网段进行通信,就需要在linux上配置 路由表了
  • 在主机1上演示, $ route 可查看路由表
  • 在主机1上访问 192.168.2.0 网段时,转发到主机2的服务器
    • $ route add -net 192.168.2.0 netmask 255.255.255.0 gw 192.168.220.111
    • 这样,在主机1访问 192.168.2.0 网段时,会转发到主机2上
  • 在主机2上访问 192.168.1.0 网段时,转发到主机1的服务器
    • $ route add -net 192.168.1.0 netmask 255.255.255.0 gw 192.168.220.110
    • 这样,在主机1访问 192.168.1.0 网段时,会转发到主机1上
  • 在两台主机上执行,$ route 发现多了路由的规则
  • 接着,需要配置 iptables 规则
    • 主机1上: $ iptables -t nat -I PREROUTING -s 192.168.1.0/24 -d 192.168.2.0/24 -j DNAT --to 192.168.1.1
    • 主机2上: $ iptables -t nat -I PREROUTING -s 192.168.2.0/24 -d 192.168.1.0/24 -j DNAT --to 192.168.2.1
    • 说明
      • -s 本主机配置的网段
      • -d 目标主机的网段
      • -j 地址转换
      • --to 本主机网关
  • 测试在主机1的c1 ping 主机2的c2容器
    • $ docker exec -it c1 ping c2 可以畅通
  • 测试在主机2的c2 ping 主机1的c1容器
    • $ docker exec -it c2 ping c1 可以畅通
  • 至此,c1 和 c2 已经顺利连通
  • 基于此,可配置N台主机进行互相连通

你可能感兴趣的:(Git,Github,Linux,Docker,docker)