代码编织梦想

一.网络基础

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)”"

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 本文链接: https://blog.csdn.net/songhaixing2/article/details/111099060

Java Socket编程——TCP/UDP-爱代码爱编程

Java Socket编程——TCP/UDP 什么是Socket?1、基于TCP的Socket编程1.1、Client端2.2、Server端2、基于UDP的Socket编程2.1、Server端2.2、Client端 什么是Socket? Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket

高级计算机网络(习题三加解析)-爱代码爱编程

个性不要个体;独立不要孤立;自由不要自私;浪漫不要散漫 路漫漫其修远兮,吾将上下而求索—屈原 离骚 文章介绍: 这是计算机网络老师布置的课后作业,参考文章:习题一 , 习题二 , 持续更新… 题目都很新型,网上很难能够找出所有答案,今天分享出来,希望能够帮助有需要的人,一起学习进步! # 本文章分享由小亮子整理汇总,如有转载,请注明出处!!

虚拟机与电脑主机网络配置-爱代码爱编程

下面主要分享记录我的虚拟机网络配置过程以及遇到网络不通问题的解决办法: 1、配置:在虚拟机上将网络连接配置成NAT模式,当然桥接模式也行,我是使用NAT模式,如下图: 然后再在终端中查看网络地址等信息,虚拟机中使用如下命令: ifconfig 其中ens33为我们使用到的网卡,虚拟机的IP地址为192.168.229.128,当然每个人的不一样。 再

华三 h3c super vlan配置-爱代码爱编程

Super vlan配置   想在此基础上、SWB上面配置静态路由,实现PC和SWB的互通 [SWA]vlan 2 [SWA-vlan2]port g1/0/1 [SWA]vlan 3 [SWA-vlan3]port g1/0/2 [SWA]vlan 10 [SWA-vlan10]supervlan----------super vlan

Dockerfile构建-爱代码爱编程

一.什么是 Dockerfile Dockerfile 是用来构建 Docker 镜像的构建文件, 是由一系列的命令和参数构成的脚本通过指令的方式构建镜像二.构建Dockerfile步骤 编写 Dockerfile 文件docker built 构建镜像docker run 创建容器三.Dockfile 文件的注意事项 每条保留字指令都必须是大写字母

Docker 简介-爱代码爱编程

一.为什么要有Docker 1.一个软件从开发到部署的问题 : 运行环境和配置 2.软件是否可以带环境安装 : 安装时将开发的环境一模一样的复制过来 一款产品从开发到上线,从操作系统,到运行环境,再到应用配置 作为开发 + 运维之间的协作我们需要关心很多东西,这也是很多互联网公司都不得不面对的问题 特别是各种版本的迭代之后,不同版本环境的兼容,对运维

Dockers 安装-爱代码爱编程

CentOS 7 安装 Docker 官方中文安装参考手册:https://docs.docker-cn.com/engine/installation/linux/docker-ce/centos/#prerequisites 一.先确定是否 Centos 7及以上的版本 cat /etc/redhat-release 二.查看是否 ping

docker新手入门指南-爱代码爱编程

很多新手可能对docker感觉比较神秘,其实这个类似与一个maven容器,但是比它更加强大,可以支持把一整套环境都打成包放到仓库,其他人如果有安装docker的话,可以直接通过网络连接你仓库镜像,拉下来直接可以运行。 下面我整理下如何在windows 10下安装docker的步骤。 1、安装 Hyper-V 如果是部分的家庭版,可能没这个插件;以下是

图文讲解在docker中部署gitlab-爱代码爱编程

准备docker环境 如果你使用的是windows或者mac建议直接下载对应的客户端。具体的完全可以按照官方的步骤来。下载地址配置加速 拉取docker镜像 $ docker pull gitlab/gitlab-ce 以上ce是指社区版,这将会拉取社区版的最新镜像到本机。 运行 $ docker run -d -p 443:443 -p 8

Docker教程-安装(一)-爱代码爱编程

一、docker安装 参考官方教程:https://docs.docker.com/install/linux/docker-ce/centos/ 操作系统:Centos7云平台:腾讯云1.1卸载旧版本:确保你的服务器没有剩余服务 sudo yum remove docker \ docker-client \