• Docker网络(5)


    一、docker网络介绍

      大量的互联网应用服务需要多个服务组件,这往往需要多个容器之间通过网络通信进行相互配合

      docker 网络从覆盖范围可分为单个 host 上的容器网络跨多个 host 的网络

      docker 目前提供了映射容器端口到宿主主机和容器互联机制来为容器提供网络服务,在启动容器的时候,如果不指定参数,在容器外部是没有办法通过网络来访问容器内部的网络应用和服务的

      docker 安装时会自动在host上创建三个网络,我们查看一下docker网络:

    [root@ren8 ~]# docker network ls
    NETWORK ID          NAME                DRIVER              SCOPE
    5ada5821d5d1        bridge              bridge              local
    011f63e62210        host                host                local
    12362c774cf8        none                null                local

    docker有四种网络模式:

      (1)bridge模式

      docker网络隔离基于网络命名空间,在物理机上创建docker容器时会为每一个docker容器分配网络命名空间,并且把容器IP桥接到物理机的虚拟网桥上。

      (2)none模式

      此模式下创建容器是不会为容器配置任何网络参数的,如:容器网卡、IP、通信路由等,全部需要自己去配置。

      (3)host模式

      此模式创建的容器没有自己独立的网络命名空间,是和物理机共享一个Network Namespace,并且共享物理机的所有端口与IP,并且这个模式认为是不安全的。

      (4)container模式(用户自定义网络)

      此模式和host模式很类似,只是此模式创建容器共享的是其他容器的IP和端口而不是物理机,此模式容器自身是不会配置网络和端口,创建此模式容器进去后,你会发现里边的IP是你所指定的那个容器IP并且端口也是共享的,而且其它还是互相隔离的,如进程等。

    二、docker --- none 网络

      none 网络就是什么都没有的网络。挂在这个网络下的容器除了 lo,没有其他任何网卡。容器创建时,可以通过 --network=none 指定使用 none 网络。

    [root@ren8 ~]# docker run -it --network=none 192.168.11.7:5000/busybox:latest
    / # 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
    / #

    none 网络的应用

      封闭的网络意味着隔离,一些对安全性要求高并且不需要联网的应用可以使用 none 网络。

      比如某个容器的唯一用途是生成随机密码,就可以放到 none 网络中避免密码被窃取。

    三、docker --- host 网络

      连接到 host 网络的容器共享 docker host 的网络栈,容器的网络配置与 host 完全一样。可以通过 --network=host 指定使用 host 网络

    [root@ren8 ~]# docker run --rm -it --network=host 192.168.11.7:5000/busybox:latest 
    / #  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:14:ac:76 brd ff:ff:ff:ff:ff:ff
        inet 192.168.11.8/24 brd 192.168.11.255 scope global ens33
           valid_lft forever preferred_lft forever
        inet6 fe80::20c:29ff:fe14:ac76/64 scope link 
           valid_lft forever preferred_lft forever
    3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue 
        link/ether 02:42:cb:36:e1:bf 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

      在容器中可以看到 host 的所有网卡,并且连 hostname 也是 host 的。host 网络的使用场景又是什么呢?

      直接使用 Docker host 的网络最大的好处就是性能如果容器对网络传输效率有较高要求,则可以选择 host 网络。当然不便之处就是牺牲一些灵活性,比如要考虑端口冲突问题,Docker host 上已经使用的端口就不能再用了。

      Docker host 的另一个用途是让容器可以直接配置 host 网路。比如某些跨 host 的网络解决方案,其本身也是以容器方式运行的,这些方案需要对网络进行配置,比如管理 iptables

    四、docker --- bridge 网络

      docker 安装时会创建一个 命名为 docker0 的 linux bridge。如果不指定--network,创建的容器默认都会挂到 docker0 上:

    [root@ren7 ~]# brctl show
    bridge name    bridge id        STP enabled    interfaces
    docker0        8000.0242b89f778c    no        

      当前 docker0 上没有任何其他网络设备,我们创建一个容器看看有什么变化:

    [root@ren7 ~]# docker run -d mirrorgooglecontainers/pause-amd64:3.1
    26e1529c8d5cb206ca6c6ec47adde1ef29e35f46159615225453246dab7eb30a
    [root@ren7 ~]# brctl show
    bridge name    bridge id        STP enabled    interfaces
    docker0        8000.0242b89f778c    no        veth4506620

      一个新的网络接口 veth4506620 被挂到了 docker0 上,veth4506620就是新创建容器的虚拟网卡。

      进入刚才运行的容器查看网络,容器有一个网卡 eth0@if34

      实际上 eth0@if34 和 veth4506620是一对 veth pair

      veth pair 是一种成对出现的特殊网络设备,可以把它们想象成由一根虚拟网线连接起来的一对网卡,网卡的一头(eth0@if34)在容器中,另一头(veth4506620)挂在网桥 docker0 上,其效果就是将 eth0@if34 也挂在了 docker0 上

      eth0@if34 已经配置了 IP 172.17.0.2,为什么是这个网段呢?
      看一下 bridge 网络的配置信息:

    docker network inspect bridge

      bridge 网络配置的 subnet 就是 172.17.0.0/16,并且网关是 172.17.0.1,在docker0上

      容器创建时,docker 会自动从 172.17.0.0/16 中分配一个 IP,这里 16 位的掩码保证有足够多的 IP 可以供容器使用

    五、创建 user --- defined 网络

    我们可通过 bridge 驱动创建类似前面默认的 bridge 网络

    (1)利用bridge驱动创建名为my-net2网桥(docker会自动分配网段):

    docker network create --driver brigde my-net2

    (2)查看一下当前 host 的网络结构变化:

    docker network ls

    (3)查看容器bridge网桥配置(bridge就是容器和网桥形成一对veth pair

    docker network inspect bridge

    (4)利用bridge驱动创建名为my-net3网桥(user-defined网段及网关)

    docker network create --driver brigde --subnet 172.22.1.0/24 --gateway 172.22.1.1 my-net3 

    (5)启动容器使用新建的my-net3网络

    docker run -it --network=my-net3 httpd 

    (6)启动容器使用my-net3网络并指定ip(只有使用 --subnet 创建的网络才能指定静态 IP,如果是docker自动分配的网段不可以指定ip)

    docker run -it --network=my-net3 --ip 172.22.1.10 httpd

    (7)让已启动不同vlan的ningx容器连接到my-net2(其实在ningx中新建了my-net2的网卡)

    docker run -it --network=my-net3 ningx
    docker network connect my-net2 ningx

    (8)使用--name指定启动容器名字,可以使用docker自带DNS通信,但只能工作在user-defined 网络,默认的 bridge 网络是无法使用 DNS 的

    docker run -it --network=my_net2 --name=bbox1 busybox
    docker run -it --network=my_net2 --name=bbox2 busybox

    (9)容器之间的网络互联

      a). 首先创建一个 db 容器

    docker run -dti --name db centos:7.0

      b). 创建一个 web 容器,并使其连接到 db

    docker run -dti --name web --link db:dblink centos:7.0/bin/bash

      --link db:dblink 实际是连接对端的名字和这个链接的名字,也就是和 db 容器建立一个叫做 dblink 的链接

      c). 查看链接的情况

    docker ps -a

      d). 使用 ping 命令来测试网络链接的情况

    (10)容器端口映射

      在启动容器的时候,如果不指定参数,在容器外部是没有办法通过网络来访问容器内部的网络应用和服务的

      当容器需要通信时,我们可以使用 -P (大) &&-p (小)来指定端口映射

      -P : Docker 会随机映射一个 49000 ~ 49900 的端口到容器内部开放的网络端口
      -p :则可以指定要映射的端口,并且在一个指定的端口上只可以绑定一个容器。

      支持的格式有

      IP : HostPort : ContainerPort
      IP : : ContainerPort
      IP : HostPort :

      查看映射:

    docker port

      a)映射所有接口地址,此时绑定本地所有接口上的 5000 到容器的 5000 接口,访问任何一个本地接口的 5000 ,都会直接访问到容器内部

    docker run -dti -p 5000:5000 centos:7.0 /bin/bash

      b)多次使用可以实现多个接口的映射

    docker run -dti -p 5000:5000 -p 5022:22 centos:7.0 /bin/bash

      c)映射到指定地址的指定接口

      此时会绑定本地 192.168.4.169 接口上的 5000 到容器的 5000 接口

    docker run -dti -p 192.168.4.169:5000:5000 centos:7.0 /bin/bash

      d) 映射到指定地址的任意接口

      此时会绑定本地 192.168.4.169 接口上的任意一个接口到容器的 5000 接口

    docker run -dti -p 192.168.4.169::5000 centos:7.0 /bin/bash

      e) 使用接口标记来指定接口的类型

    docker run -dti -p 192.168.4.169::5000/UDP centos:7.0 /bin/bash

    (11)实验:通过端口映射实现访问本地的 IP:PORT 可以访问到容器内的 web

      a)将容器80端口映射到主机8080端口

    docker run -itd -p 8080:80 --name http-test httpd 

      b) 查看刚运行docker

    docker ps

      c) 进入容器

    docker exec -it httpd-test

      d) 容器内部编辑网页文件 index.html

    ********#echo “hhhhhhhhhhhh” > /var/www/html/index.html

      e)到宿主机上打开浏览器输入 IP:PORT 访问验证

      http://192.168.4.170:8080

      网络排排查命令:

    iptables -t nat -L
    ip r
    tcpdump -i docker0 -n icmp
    tcpdump -i eth0 -n icmp
  • 相关阅读:
    java异常笔记
    CORBA IOR学习
    CORBA GIOP消息格式学习
    一个简单的CORBA例子
    Chrome 调试动态加载的js
    Android高效加载大图、多图解决方案,有效避免程序OOM(转)
    安卓开发笔记——打造万能适配器(Adapter)
    安卓开发笔记——个性化TextView(新浪微博)
    安卓开发笔记——关于Handler的一些总结(上)
    安卓开发笔记——关于AsyncTask的使用
  • 原文地址:https://www.cnblogs.com/renyz/p/11722318.html
Copyright © 2020-2023  润新知