【Docker第四篇】Docker容器网络相关知识全解析

网友投稿 1392 2022-09-30

【Docker第四篇】Docker容器网络相关知识全解析

【Docker第四篇】Docker容器网络相关知识全解析

文章目录

​​一、前言​​​​二、计算机网络​​

​​2.1 计算机网络理论知识​​​​2.2 Linux网卡灵活操作​​

​​2.2.1 网卡配置文件​​​​2.2.2 网卡上增删IP地址​​​​2.2.3 网卡状态:UP DOWN UNKNOWN​​

​​三、Network Namespace​​

​​3.1 Network Namespace​​​​3.2 从 Network Namespace 转到 Docker Container​​​​3.3 自定义Network Namespace​​​​3.4 不同network namespace通信​​​​3.5 通过名称访问​​​​3.6 端口映射:容器的端口映射到的centos​​

​​四、其他两种类型的网络:host和null​​​​五、两个机器/机器间 container运行在不同的centos中​​​​六、总结全文学到的命令操作​​

​​6.1 linux操作 (ip和网卡)​​​​6.2 network namespace操作​​​​6.3 docker container 的桥接网络相关操作​​​​6.4 单机 docker container 的其他两种网络通信方式(host null)​​

​​七、尾声​​

一、前言

二、计算机网络

2.1 计算机网络理论知识

对于软件工程来说,只能接触到上层的网络协议,包括应用层和传输层,一般是 dns tcp udp

对于网络工程来说,一般接触到下层的网络协议,包括网络层和数据链路层

网卡是计算机网络通信的基础,linux上,通过 ​​ifconfig​​​ 或者 ​​ip a​​ 查看Linux上的网卡,查看网卡的ip

lo 本地网络 eth0 与互联网通信的网卡 eth1 与局域网通信的网卡 docker docker的网卡

2.2 Linux网卡灵活操作

2.2.1 网卡配置文件

各个网卡的作用:计算机能与外界通信的硬件支持,每个网卡有唯一的MAC地址。 各个网卡的配置文件(该配置文件可以修改):在Linux中网卡对应的其实就是文件,所以找到对应的网卡文件即可,比如:cat /etc/sysconfig/network-scripts/ifcfg-eth0

cd

2.2.2 网卡上增删IP地址

这里 lo 是本地网卡,ens33是与互联网通信的网卡,同一个网卡上可以挂多个IP地址的,现在我们在 ens33

cat /etc/sysconfig/network-scripts/ifcfg-ens33

# IP地址的查看、新增和删除操作ip addrip addr add 192.168.100.251/24 dev ens33ip addr delete 192.168.100.251/24 dev ens33

ip addr delete 192.168.100.251/24 dev ens33

2.2.3 网卡状态:UP DOWN UNKNOWN

ifdown ens33ifup

小结:关于Linux上网卡操作,包括 (1) 网卡配置文件 (2) 网卡绑定IP地址 (3) 网卡状态:UP DOWN UNKNOWN

三、Network Namespace

3.1 Network Namespace

docker = 网卡 + namespace

每个docker container 通过 namespace/cgroup 来实现隔离,network namespace的管理:

ip netns list # 查看本机docker的network namespace列表ip netns add ns1 # 新增本机docker的network namespaceip netns delete ns1 # 删除本机docker的network namespaceip netns exec ns1 ip a # 查看本机docker的network namespace上面的IP列表

查看一下新建network namespace,这里发现会默认自带一个 lo 本地网卡

ip netns exec ns1 ip

Docker中的network namespace 上面的本地网卡 lo 就是根据 linux 上的本地网卡 lo 创建的

所以,如下,网络隔离出来了(linux的网络隔离和 network namespace (ns1) 的网络隔离)

ip netns exec ns1 ip link

无论是linux还是 docker network namespace ,lo 都是表示 回环地址/本地地址

network namespace 创建就默认带了一个 lo 本地回环地址

网卡是开发人员能接触的操作网络的单元,需要增加一个通信的网卡,将两个 network namespace , ns1 ns2 实现通信,即如下效果

这种技术就是 veth pair ,英文全称 Vitual Ethernet Pair ,使用这样创建出来就是默认能够连通的,表示一次创建成对的两个可以通信的网卡,分别给 ns1 ns2,即如下:

创建一对(两个)可以通信网卡,分别给ns1 和 ns2 ,这两个 network namespace 就可以通信了

创建一个pair 然后分配给ns

ip link add veth-ns1 type veth peer name veth-ns2ip link

创建好了,分配

ip link showip link set veth-ns1 netns ns1ip link showip netns exec ns1 ip link

继续,将 veth-ns2 分配给 ns2

ip link showip link set veth-ns2 netns ns2ip link showip netns exec ns2 ip link

完成了,pair技术

开始给ns1 ns2 新增的 veth-pair 网卡 新增 ip 地址,如下:

# 给network namespace ns1 添加 IP 地址 (IP地址和设备名/网卡名)ip netns exec ns1 ip addr add 192.168.100.11/24 dev veth-ns1ip netns exec ns1 ip a# 给network namespace ns1 启用网卡 veth-ns1ip netns exec ns1 ip link set veth-ns1 upip netns exec ns1 ip

ip link # 查看简要IP信息ip a # 查看详细IP信息

同样给 ns2 也加上

ip netns exec ns2 ip addr add 192.168.100.12/24 dev veth-ns2ip netns exec ns2 ip aip netns exec ns2 ip link set veth-ns2 upip netns exec ns2 ip

好了 ip地址有了

/24 前面就是具体的全的ip地址,不是三位

ip netns exec ns1 ping 192.168.100.12ip netns exec ns2 ping 192.168.100.11

两个ip地址 ping ,ping通了

完成这个图片的需求,如下:

3.2 从 Network Namespace 转到 Docker Container

docker run -d --name tomcat01 -p 8081:8080 tomcatdocker run -d --name tomcat02 -p 8082:8080 tomcatdocker stop container-id # docker ps 查看 container-id docker rm container-id # docker ps 查看 container-id

两个独立的容器可以ping通 底层是network namespace支持的

解释:创建的容器默认带了一个 network namespace

两个docker容器,虽然网络可以通,但是不是 pair 技术。

理由:两个容器内使用 ​​ip a​​ 查看,发现两个tomcat 的网卡不同,所以是两个network namespace ,如下图

这里使用的是 docker exec -it tomcat01 ifconfig 和 docker exec -it tomcat02 ifconfig ,查看到的是两个container的ip,也可以使用 docker exec -it tomcat01 ip a 和 docker exec -it tomcat02 ip a ,查看两个container的网卡

docker exec -it tomcat01 ip a docker exec -it tomcat02 ip

对于 veth-pair 技术来说,网卡一定名称是连续的才是一对,比如,这就是一对pair的组件

则两个container 建立计算机网络通信是通过linux中转的(而不是像两个network namespace一样,直接通信),如下:

我们开始验证一下上图,即 两个container 建立计算机网络通信是通过linux中转的 。

yum install bridge-utilsbrctl showip

所以,docker0 tomcat01 mysql tomcat02 四个的ip地址应该是同一网段的,下图是 Docker 通信的精髓

如果在增加一个 mysql或者tomcat03 ,那么 linux 的 docker0 上应该再增加一个网卡,一个 veth-pair 对

验证一下

docker run -d --name tomcat03 -p 8083:8080 tomcat # linux执行,运行tomcat03docker exec -it tomcat03 bash # linux执行,进入tomcat03apt-get update # tomcat03容器内执行,更新apt-getapt-get install net-tools # tomcat03容器内执行,安装ifconfig命令apt-get install iputils-ping # tomcat03容器内执行,安装ping命令ifconfig # tomcat03容器内执行,查看tomcat03的ip地址ping 172.17.0.2 # tomcat03容器内执行:ping tomcat01ping 172.17.0.3 # tomcat03容器内执行:ping tomcat02ip a # linux执行,查看linux上的网卡是不是增加了一个brctl show # linux执行,查看linux的桥接docker0下面的网卡是不是增加了一个docker network ls # linux执行,查看linux的network namespace

docker 各个container 通过这个docker0 通信,桥接两结果 (底层 veth-pair 技术) (1) linux 到 container可以通 (2) container1 到 container2 可以通

3.3 自定义Network Namespace

docker0 使用的是 桥接的网络的,是桥接在linux上的打点

docker0 是一个bridge类型

docker network lsdocker

也可以自己创建一个 bridge类型的

docker network lsdocker network create my-netdocker network ls

docker

使用刚刚新建的自定义的network namespace,如下

docker network create tomcat-netdocker network lsdocker run -d --name custom-net-tomcat --network tomcat-net tomcatdocker exec -it custom-net-tomcat bashapt-get updateapt-get install net-toolsapt-get install iputils-pingexitdocker exec -it custom-net-tomcat ifconfigdocker network lsdocker

默认生成的docker0 是一个bridge类型的网络,如果 docker run 这里的 --network 不指定就是docker0

两个container不是同一个linux网卡,一个是默认网卡bridge,一个是自定义网卡 tomcat-net ,这种情况下相互ping不通

docker exec -it custom-net-tomcat ping 172.17.0.3

一个是docker0(即bridge) 一个custom-net-tomcat

3.4 不同network namespace通信

如果容器太多了,这个网段下面放满了, 一个 bridge 不够用,应该怎么办

重新创建另一个 bridge ,但是这个bridge 上的container 和 之前bridge 上的container 是网络不通的

ping ip 这种只有一行就是不通,control+c 会得到 100% loss ping 域名 这种只有一行是域名解析对了,只是 ip 网络不同而已

上图中,两个红色的表示 linux 上的两个 bridge,白色表示 docker container 容器

# docker network connect 是 network 添加命令,写死 (docker network 是命令,加上connnet表示添加)# 第一个参数 tomcat-net 表示network namespace,第二个参数 tomcat01 表示 containr-name # 表示将 container-name 使用这个 network namespacedocker network connect tomcat-net tomcat01docker network lsdocker network inspect tomcat-netdocker exec -it custom-net-tomcat ping 172.19.0.3docker exec -it tomcat01 ifconfig

3.5 通过名称访问

不是网络不通,是域名解析不了,默认的桥接 bridge/docker0 是不带域名解析能力的,但是自定义/自己创建的network namespace是带有域名解析能力的

用 自定义的 network namespace 新建两个容器,发现可以根据名称 ping 通

同一桥接,docker0里面的两个container 名字解析不了

但是自定义的桥接,里面的两个container 名字可以解析 自定义的bridge默认增加一条dns解析在默认的 docker0 里面,可以用 --link 这种单向的

小结:生产上更加推荐 自定义bridge ,而不是 docker0 + 单向link 来完成 自定义bridge 类似于 k8s 的namespace,可以按 名字 来访问 局限:所有的docker都在同一台 centos 机器上

一个容器可以绑定两个bridge ,完成与另一个 bridge 的container 通信

3.6 端口映射:容器的端口映射到的centos

现在所有的网络通信都是 (1) centos 与 容器container 的通信(ping) (2) 容器container 与 容器container 的通信(ping)

现在还需要 外网windows 与 容器container 的通信,我们知道,外网windows和宿主机centos是可以通信的,要想和container通信,就是需要将container的端口映射到centos就可以了

实际上我们已经做了

docker run -d --name tomcat01 -p 8081:8080 tomcat docker run -d --name tomcat02 -p 8082:8080 tomcat docker run -d --name tomcat03 -p 8083:8080 tomcat

​​: 该容器的ip 直接将 宿主机的ip 抄袭过来

优点:不需要 端口映射了 host = bridge + 端口映射 缺点:centos 端口是有限的,不需要暴露出来的,就不要使用 host

null: 只有本地回环地址,这个docker container从来不与外界通信

五、两个机器/机器间 container运行在不同的centos中

需求:container运行在不同的centos中,两个机器/机器间 docker container的通信

同一机器:network namespace,三种网络方式 bridge host null 不同机器:NAT 网络地址转换 vxlan

vxlan 多机网络通信的问题,底层的一个实现技术是:overlay

docker 上第四种网络技术 overlay vxlan,如下图:

六、总结全文学到的命令操作

总结一下和计算机网络网络有关的linux命令和docker命令,如下:

6.1 linux操作 (ip和网卡)

# ip地址的查看、新增、删除ifconfig ip addr (也可以写成 ip a,ip a是简写)ip addr add 192.168.100.251/24 dev ens33ip addr delete 192.168.100.251/24 dev ens33# 网卡配置文件(一个网卡一个配置文件)cd /etc/sysconfig/network-scripts/ (查看配置文件,白色是文件,绿色可执行文件,蓝色目录)# 网卡的启用和停止 (网卡三种状态 up down unknown)ifdown ens33ifup

6.2 network namespace操作

docker ( 从network namespace 到 docker container 的桥接网络,底层技术都是 veth-pair 这种一对网卡的方式,前者network namespace之间是直接通,后者docker container之间是通过linux实现网络通信)

# network namespace ip netns list # 查看本机docker的network namespace列表ip netns add ns1 # 新增本机docker的network namespaceip netns delete ns1 # 删除本机docker的network namespaceip netns exec ns1 ip a # 查看本机docker的network namespace上面的IP列表(简要)(默认自带一个 lo 本地网卡)ip netns exec ns1 ip link show # 查看本机docker的network namespace上面的IP列表(简要)(默认自带一个 lo 本地网卡)

小结:network namespace的命令都是 ip netns 固定开头,然后就是 list 查询列表,add 新增, delete 删除,还有 exec ns-name 表示查看某个网络命名空间的具体信息 (ip addr是详细(包含ip),ip link show是简要(不包含ip))

# 创建一个 veth-pair 对,包含两个网卡,这两个网卡可以相互通信,将这两个网卡分配给两个network namespace# 在linux机器上,新建一个 veth-pair 关键字是 add xxx type xxx name xxxip link add veth-ns1 type veth peer name veth-ns2 ip link show # 查看linux上的网卡信息,ip addr (ip a)/ ip link show (ip link)/ ifconfig ip link show # 查看linux上的网卡信息,ip addr (ip a)/ ip link show (ip link)/ ifconfig ip link set veth-ns1 netns ns1 # 将linux的网卡 veth-ns1 使用到 网络命名空间 ns1 上ip link show # 查看linux上的网卡信息,ip addr (ip a)/ ip link show (ip link)/ ifconfig ip netns exec ns1 ip link # 查询指定命名网络命名空间的简要信息ip link show # 查看linux上的网卡信息,ip addr (ip a)/ ip link show (ip link)/ ifconfig ip link set veth-ns2 netns ns2 # 将linux的网卡 veth-ns2 使用到 网络命名空间 ns2 上ip link show # 查看linux上的网卡信息,ip addr (ip a)/ ip link show (ip link)/ ifconfig ip netns exec ns2 ip link # 查询指定命名网络命名空间的简要信息# 给network namespace ns1 添加 IP 地址 (IP地址和设备名/网卡名)ip netns exec ns1 ip addr add 192.168.100.11/24 dev veth-ns1 # 指定网络命名空间指定网卡上听添加IP地址ip netns exec ns1 ip a # 查询指定命名网络命名空间的详细信息# 给network namespace ns1 启用网卡 veth-ns1ip netns exec ns1 ip link set veth-ns1 up # 指定网络命名空间启用网卡ip netns exec ns1 ip a # 查询指定命名网络命名空间的详细信息ip netns exec ns2 ip addr add 192.168.100.12/24 dev veth-ns2 # 指定网络命名空间指定网卡上听添加IP地址ip netns exec ns2 ip a # 查询指定命名网络命名空间的详细信息ip netns exec ns2 ip link set veth-ns2 up # 指定网络命名空间启用网卡ip netns exec ns2 ip a # 查询指定命名网络命名空间的详细信息

小结:一个linux机器上,有多个网络命名空间 (网络命名空间可以新建删除查询列表,并可以查询每个网络命名空间的详细和简要信息);一个网络命名空间可以挂上多个网卡,一个 veth-pair 对是两个网卡,可以通信的两个网卡;一个网卡可以有多个IP地址。

小结:linux – 网络命名空间 – 网卡 – IP地址

6.3 docker container 的桥接网络相关操作

yum install bridge-utilsbrctl showip

# 命令是docker network,可以查询列表,可以新建和删除,还可以查询这个network里面有哪些containerdocker network lsdocker network create my-netdocker network lsdocker

docker run -d --name tomcat03 -p 8083:8080 tomcat # linux执行,运行tomcat03docker exec -it tomcat03 bash # linux执行,进入tomcat03apt-get update # tomcat03容器内执行,更新apt-getapt-get install net-tools # tomcat03容器内执行,安装ifconfig命令apt-get install iputils-ping # tomcat03容器内执行,安装ping命令ifconfig # tomcat03容器内执行,查看tomcat03的ip地址ping 172.17.0.2 # tomcat03容器内执行:ping tomcat01ping 172.17.0.3 # tomcat03容器内执行:ping tomcat02ip a # linux执行,查看linux上的网卡是不是增加了一个brctl show # linux执行,查看linux的桥接docker0下面的网卡是不是增加了一个docker network ls # linux执行,查看linux的network namespace

# 都是network namespace,只是前者是在docker里面的network namespace,后者是不在docker里面的network namespace# 一个网络命名空间network namespace就是表示一个网关,下面可以有多个docker containerdocker network list # 有实用性,表示的是网关列表/网络命名空间列表,每个网关下面可以有多个docker containerip netns list # 无实用性,表示的网关列表/网络命名空间列表,与docker container关闭不紧密

一个linux机器上可以有多个桥接/多个网络命名空间,一个桥接可以有多个网卡,一个网卡可以有多个IP地址

linux – 桥接(网络命名空间) – 网卡 – IP

桥接增删查改 (就是网络命名空间的增删查改)

docker network lsdocker network create my-netdocker network lsdocker network inspect my-netbrctl show # 查看桥接列表(一个桥接可以有多个网卡)

网卡增删查改 (这里指linux上的网卡增删查改,主要是查)

查看linux上的网卡信息ip addr (ip a)/ ip link show (ip link)/ ifconfig

每次增加一个容器 tomcat03 ,就会增加 一个 veth-pair ,两个网卡,一个在tomcat03上,一个在linux上,此时 ​​brctl show​​ 列表也可以看到多了一个网卡,就是linux上增加的那个网卡, ip addr 也可以看到多了一个网卡,就就是 linux 上增加的那个网卡 (但是不会增加一个桥接,所以 docker network list 不会增加,brctl show 也不会增加)

6.4 单机 docker container 的其他两种网络通信方式(host null)

host : 该容器的ip 直接将 宿主机的ip 抄袭过来

优点:不需要 端口映射了 host = bridge + 端口映射 缺点:centos 端口是有限的,不需要暴露出来的,就不要使用 host

null: 只有本地回环地址,这个docker container从来不与外界通信

七、尾声

Docker容器网络相关知识全解析,完成了。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:基于串级 PID 控制算法的四旋翼无人机控制系统设计与实现
下一篇:修改小程序单页面的背景颜色
相关文章

 发表评论

暂时没有评论,来抢沙发吧~