zoukankan      html  css  js  c++  java
  • 🐳Docker网络

    一.网络基础

    Docker 使用到的与 Linux 网络有关的技术分别有:网络名称空间、Veth、Iptables、网桥、路由

    1.什么是网络名称空间

    • 为了支持网络协议栈的多个实例,Linux 在网络协议栈中引入了网络名称空间(Network Namespace)
    • 这些独立的协议栈被隔离到不同的命名空间中
    • 处于不同的命名空间的网络协议栈是完全隔离的,彼此之间无法进行网 络通信,就好像两个“平行宇宙”
    • 通过这种对网络资源的隔离,就能在一个宿主机上虚拟多个不同的网络环境

    image-20201203095835616

    ps : 如果不同网络名称空间之间要进行通信该怎么办呢?

    2.Veth 设备对

    • 引入 Veth 设备对就是为了在不同的网络名称空间之间进行通信
    • 利用它可以直接将两个网络名称空间链接起来, Veth 设备是成对出现
    • 像一对网卡, 我们将其中一端称为另一端的 peer

    image-20201203100041308

    2.1.底层原理实验示例

    • 需求 : 建立两个名称空间, 并实现相互 ping
    • 查看, 添加, 删除 namespace 命令
    ip netns list                # 查看
    ip netns add [namespace]     # 添加
    ip netns delete [namespace]  # 删除
    
    • 建立两个名称空间
    [root@shawn ~]#ip netns add test1
    [root@shawn ~]#ip netns add test2
    [root@shawn ~]#ip netns list
    test2
    test1
    
    • 建立一对 veth
    [root@shawn ~]#ip link add veth1 type veth peer name veth2
    [root@shawn ~]#ip link
    

    image-20201203100822449

    • 创建 veth 后, 我们将 veth 分别添加到名称空间 test1test2
    [root@shawn ~]#ip link set veth1 netns test1
    [root@shawn ~]#ip link set veth2 netns test2
    
    • 查看一下是否已经添加成功了
    [root@shawn ~]#ip netns exec test1 ip link
    [root@shawn ~]#ip netns exec test2 ip link
    

    image-20201203101119038

    image-20201203101141390

    • 添加完成后我们就需要为其设置 IP 了, 并将其状态 up
    [root@shawn ~]#ip netns exec test1 ip addr add 172.17.0.111/20 dev veth1
    [root@shawn ~]#ip netns exec test2 ip addr add 172.17.0.112/20 dev veth2
    [root@shawn ~]#ip netns exec test1 ip link set dev veth1 up
    [root@shawn ~]#ip netns exec test2 ip link set dev veth2 up
    
    • 查看 IP 是否设置成功
    [root@shawn ~]#ip netns exec test1 ip a
    [root@shawn ~]#ip netns exec test2 ip a
    

    image-20201203101635359

    image-20201203101654298

    • 最后, 检测一下是否能相互 ping
    [root@shawn ~]#ip netns exec test1 ping 172.17.0.112
    [root@shawn ~]#ip netns exec test2 ping 172.17.0.111
    

    image-20201203101901104

    image-20201203101912789

    • 成功

    3.网桥(Bridge)

    • Linux 可以支持多个不同的网络,它们之间能够相互通信,就需要一个网桥, 网桥就是二层的虚拟网络设备
    • 它是把若干个网络接口“连接”起来,从而报文能够互相转发

    image-20201203103048745

    • 网桥命令格式 : docker network [命令参数]
    ⚽查看当前系统有哪些网桥 "ls"
    [root@shawn ~]#docker network ls
    '''
    NETWORK ID          NAME                DRIVER              SCOPE
    befd59194a71        bridge              bridge              local
    94f8e35f3357        host                host                local
    79fb28a9a12e        none                null                local
    '''
    
    ⚽创建网桥 "create"
    [root@shawn ~]#docker network create shawn
    ffac93578a0ce40395936d226bd097fd049ad077022419a9b6b074b6fe2f892b
    [root@shawn ~]#docker network ls
    '''
    NETWORK ID          NAME                DRIVER              SCOPE
    befd59194a71        bridge              bridge              local
    94f8e35f3357        host                host                local
    79fb28a9a12e        none                null                local
    ffac93578a0c        shawn               bridge              local  #新建的网桥
    '''
    
    ⚽查看网桥信息,格式 : "docker network inspect [网桥的名称|网桥ID]"
    [root@shawn ~]#docker network inspect shawn
    '''
    [
        {
            "Name": "shawn",
            "Id": "ffac93578a0ce40395936d226bd097fd049ad077022419a9b6b074b6fe2f892b",
            "Created": "2020-12-03T11:56:35.554136022+08:00",
            "Scope": "local",
            "Driver": "bridge",
            "EnableIPv6": false,
            "IPAM": {
                "Driver": "default",
                "Options": {},
                "Config": [
                    {
                        "Subnet": "172.18.0.0/16",
                        "Gateway": "172.18.0.1"
                    }
                ]
            },
            "Internal": false,
            "Attachable": false,
            "Ingress": false,
            "ConfigFrom": {
                "Network": ""
            },
            "ConfigOnly": false,
            "Containers": {},
            "Options": {},
            "Labels": {}
        }
    ]
    '''
    
    ⚽删除网桥 "rm"
    [root@shawn ~]#docker network rm shawn
    shawn
    [root@shawn ~]#docker network ls
    '''
    NETWORK ID          NAME                DRIVER              SCOPE
    befd59194a71        bridge              bridge              local
    94f8e35f3357        host                host                local
    79fb28a9a12e        none                null                local
    ''' # "Shawn"被删除了
    
    ⚽清理网桥 "prune", 我们先创建多个网桥,然后一次性清除
    [root@shawn ~]#docker network create shawn1
    f4d2f2b57b48cd35b3cc9eddad0377cae95d213032ed0d6a92e9de9571adeb4e  #创建成功
    [root@shawn ~]#docker network create shawn2
    ea66ed0d06adbe7f5211f3ae38b6edeb47dffac0f53240e9204fd3dcaf4670d5  #创建成功
    [root@shawn ~]#docker network create shawn3
    222d6e298d6091cea0a6229e19c84825a41ea92b7c0b512db47c858dde7259f0  #创建成功
    [root@shawn ~]#docker network prune
    WARNING! This will remove all custom networks not used by at least one container.
    Are you sure you want to continue? [y/N] y  # 问你是否要这样做"yes"
    Deleted Networks:  # 将要删除以下网桥
    shawn1
    shawn2
    shawn3
    [root@shawn ~]#docker network ls
    '''
    NETWORK ID          NAME                DRIVER              SCOPE
    befd59194a71        bridge              bridge              local
    94f8e35f3357        host                host                local
    79fb28a9a12e        none                null                local
    '''  # 发现并没有 "shawn"系列的网桥	
    
    

    4.Iptables

    • iptables是 linux 系统自带的优秀且完全免费的基于包过滤的防火墙工具、它的功能十分强大、使用非常灵活、可以对流入、流出及流经服务器的数据包进行精细的控制

    5.总结

    network namespace 主要提供了关于网络资源的隔离,包括网络设备、IPv4 和 IPv6 协议栈、IP 路由 表、防火墙、/proc/net 目录、/sys/class/net 目录、端口(socket)等
    linux Bridge 功能相当于物理交换机,为连在其上的设备(容器)转发数据帧。如 docker0 网桥
    iptables 主要为容器提供 NAT 以及容器网络安全
    veth pair 两个虚拟网卡组成的数据通道。在 Docker 中,用于连接 Docker 容器和 Linux Bridge。一端在容器中作为 eth0 网卡,另一端在 Linux Bridge 中作为网桥的一 个端口

    二.Docker网络模式

    安装Docker时,它会自动创建三个网络,bridge(创建容器默认连接到此网络)、 none 、host

    • docker network ls : 查看当前系统有哪些网络(网桥)
    [root@shawn ~]#docker network ls
    NETWORK ID          NAME                DRIVER              SCOPE
    befd59194a71        bridge              bridge              local
    94f8e35f3357        host                host                local
    79fb28a9a12e        none                null                local
    

    1.原理

    • Docker使用Linux桥接,在宿主机虚拟一个Docker容器网桥(docker0)
    • Docker启动一个容器时会根据Docker网桥的网段分配给容器一个IP地址,称为Container-IP, 同时Docker网桥是每个容器的默认网关
    • 因为在同一宿主机内的容器都接入同一个网桥,这样容器之间就能够通过容器的Container-IP直接通信
    • Docker网桥是宿主机虚拟出来的,并不是真实存在的网络设备,外部网络是无法寻址到的,这也意味着外部网络无法通过直接Container-IP访问到容器
    • 如果容器希望外部访问能够访问到,可以通过映射容器端口到宿主主机(端口映射),即docker run创建容器时候通过 -p-P 参数来启用,访问容器的时候就通过 [宿主机IP]:[容器向外暴露的端口] 访问容器

    2.四类网络模式

    网络模式 设置方法 简介
    Host --network host 容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口
    Bridge --network bridge(默认此模式) 此模式会为每一个容器分配、设置IP等,并将容器连接到一个docker0虚拟网桥,通过docker0网桥以及Iptables nat表配置与宿主机通信
    None -- network none 该模式关闭了容器的网络功能(只提供回环)
    Container --network "container:[共享容器名称]" 创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围

    2.1、Host 模式

    • 相当于Vmware中的桥接模式,与宿主机在同一个网络中,但没有独立IP地址, 容易造成端口冲突
    • 但是,容器的其他方面,如文件系统、进程列表等还是和宿主机隔离的
    • 格式 : docker run --network host [镜像名称或ID]
    [root@shawn ~]#docker run -d --network host nginx:latest
    

    img

    2.2、Container 模式

    • 这个模式指定新创建的容器和已经存在的一个容器共享一个Network Namespace,而不是和宿主机共享
    • 新创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围等
    • 同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过lo网卡设备通信
    • 格式 : docker run --network "containe:[共享容器名称]" [镜像名称或ID]
    • 实验:
    ⚽创建共享容器 "cont01"
    [root@shawn ~]#docker run -dit --name cont01 busybox:latest sh
    
    ⚽创建链接容器 "cont02", 并指定网络模式 "container"
    [root@shawn ~]#docker run -dit --name cont02 --network "container:cont01" busybox:latest sh
    
    ⚽查看两个容器的 "ip", 发现一样
    [root@shawn ~]#docker exec cont01 ip a
    [root@shawn ~]#docker exec cont02 ip a
    

    image-20201203114012145

    image-20201203114036897

    img

    2.3、None 模式

    • 该模式将容器放置在它自己的网络栈中,但是并不进行任何配置, 只提供回环
    • 该模式关闭了容器的网络功能 , 一般是因为容器并不需要网络(例如只需要写磁盘卷的批处理任务)
    • 格式 : docker run --network none [镜像名称或ID]
    [root@shawn ~]#docker run -dit --network none --name none_test busybox:latest sh
    

    img

    2.4、Bridge 网桥模式

    • 相当于Vmware中的Nat模式,容器使用独立network Namespace,并连接到docker0虚拟网卡(默认模式)
    • 虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中
    • bridge模式是docker的默认网络模式,不写 --network 参数,就是bridge模式
    • 使用docker run -p时,docker实际是在iptables做了DNAT规则,实现端口转发功能

    image-20201203115027432

    • 相关操作

    相关操作在文章第一段第三小章 ""网桥(Bridge)""

  • 相关阅读:
    IBinder介绍
    Android组成部分
    Android中handler,looper与messageQueue的代码解析
    JS
    设计模式
    冒泡排序
    战斗逻辑
    mongo数据库基础
    JS闭包
    c/c++
  • 原文地址:https://www.cnblogs.com/songhaixing/p/14078843.html
Copyright © 2011-2022 走看看