docker第四篇docker容器网络相关知识全解析(代码片段)

毛奇志 毛奇志     2022-11-30     523

关键词:

文章目录

一、前言

二、计算机网络

2.1 计算机网络理论知识

对于软件工程来说,只能接触到上层的网络协议,包括应用层和传输层,一般是 http 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  /etc/sysconfig/network-scripts/

2.2.2 网卡上增删IP地址

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

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

# IP地址的查看、新增和删除操作

ip addr
ip addr add 192.168.100.251/24 dev ens33
ip 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 ens33
ifup ens33

小结:关于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 namespace
ip netns delete ns1  # 删除本机docker的network namespace
ip netns exec ns1 ip a  # 查看本机docker的network namespace上面的IP列表

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

ip netns exec ns1 ip a

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

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

ip netns exec ns1 ip link show

无论是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-ns2
ip link show

创建好了,分配

ip link show
ip link set veth-ns1 netns ns1
ip link show
ip netns exec ns1 ip link

继续,将 veth-ns2 分配给 ns2

ip link show
ip link set veth-ns2 netns ns2
ip link show
ip 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-ns1
ip netns exec ns1 ip a
# 给network namespace ns1 启用网卡 veth-ns1
ip netns exec ns1 ip link set veth-ns1 up
ip netns exec ns1 ip a

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

同样给 ns2 也加上

ip netns exec ns2 ip addr add 192.168.100.12/24 dev veth-ns2
ip netns exec ns2 ip a
ip netns exec ns2 ip link set veth-ns2 up
ip netns exec ns2 ip a

好了 ip地址有了

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

ip netns exec ns1 ping 192.168.100.12
ip 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 tomcat
docker run -d --name tomcat02 -p 8082:8080 tomcat
docker 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 a 

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

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


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

yum install bridge-utils
brctl show
ip a

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

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

验证一下

docker run -d --name tomcat03 -p 8083:8080 tomcat  # linux执行,运行tomcat03
docker exec -it tomcat03 bash  # linux执行,进入tomcat03
apt-get update   # tomcat03容器内执行,更新apt-get
apt-get install net-tools  # tomcat03容器内执行,安装ifconfig命令
apt-get install iputils-ping  # tomcat03容器内执行,安装ping命令
ifconfig      # tomcat03容器内执行,查看tomcat03的ip地址
ping 172.17.0.2  # tomcat03容器内执行:ping tomcat01
ping 172.17.0.3  # tomcat03容器内执行:ping tomcat02
ip 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 ls
docker network inspect bridge

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

docker network ls
docker network create my-net
docker network ls

docker network inspect my-net

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

docker network create tomcat-net
docker network ls
docker run -d --name custom-net-tomcat --network tomcat-net tomcat
docker exec -it custom-net-tomcat bash
apt-get update
apt-get install net-tools
apt-get install iputils-ping
exit
docker exec -it custom-net-tomcat ifconfig
docker network ls
docker network inspect tomcat-net


默认生成的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 namespace
docker network connect tomcat-net tomcat01
docker network ls
docker network inspect tomcat-net
docker exec -it custom-net-tomcat ping 172.19.0.3
docker 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

http://192.168.100.151:8081
http://192.168.100.151:8082
http://192.168.100.151:8083

四、其他两种类型的网络:host和null



host : 该容器的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 ens33
ip addr delete 192.168.100.251/24 dev ens33

# 网卡配置文件(一个网卡一个配置文件)
cd  /etc/sysconfig/network-scripts/  (查看配置文件,白色是文件,绿色可执行文件,蓝色目录)

# 网卡的启用和停止 (网卡三种状态 up down unknown)
ifdown ens33
ifup ens33

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 namespace
ip netns delete ns1  # 删除本机docker的network namespace
ip 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 xxx
ip 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-ns1
ip 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-utils
brctl show
ip a
# 命令是docker network,可以查询列表,可以新建和删除,还可以查询这个network里面有哪些container
docker network ls
docker network create my-net
docker network ls
docker network inspect my-net
docker run -d --name tomcat03 -p 8083:8080 tomcat  # linux执行,运行tomcat03
docker exec -it tomcat03 bash  # linux执行,进入tomcat03
apt-get update   # tomcat03容器内执行,更新apt-get
apt-get install net-tools  # tomcat03容器内执行,安装ifconfig命令
apt-get install iputils-ping  # tomcat03容器内执行,安装ping命令
ifconfig      # tomcat03容器内执行,查看tomcat03的ip地址
ping 172.17.0.2  # tomcat03容器内执行:ping tomcat01
ping 172.17.0.3  # tomcat03容器内执行:ping tomcat02
ip 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 container
docker network list   # 有实用性,表示的是网关列表/网络命名空间列表,每个网关下面可以有多个docker container
ip netns list   # 无实用性,表示的网关列表/网络命名空间列表,与docker container关闭不紧密

network namespace 单独使用,不接入到docker container,没有三种网络类型之说
接入到docker container,就有了 bridge host null 三种类型

增加或删除一个桥接,其实就是增加或删除一个网络命名空间
同一桥接内可以通信,就是同一网络命名空间内可以通信,就是同一网关可以通信,就是同一子网内可以通信,这是可以解释的通的

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

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

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

docker network ls
docker network create my-net
docker network ls
docker network inspect my-net

brctl 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容器网络相关知识全解析,完成了。

docker_04_docker容器网络相关知识全解析(代码片段)

...NKNOWN三、NetworkNamespace3.1NetworkNamespace3.2从NetworkNamespace转到DockerContainer3.3自定义NetworkNamespace3.4不同net 查看详情

理解docker:docker网络

 本系列文章将介绍Docker的相关知识:(1)Docker安装及基本用法(2)Docker镜像(3)Docker容器的隔离性-使用Linuxnamespace隔离容器的运行环境(4)Docker容器的隔离性-使用cgroups限制容器使用的资源(5)Docker网络 1.Docker网络概... 查看详情

docker第四篇docker仓库管理(代码片段)

...有不同的标签(tag)二、仓库管理1、注册账号https://hub.docker.com/#在此页面注册账号,需要用户名,邮箱,密码(注:需要FQ才能注册,注册通过邮箱激活后可以通过网页登 查看详情

docker基础知识和命令使用入门(代码片段)

本文介绍了Docker相关的基础知识和命令的简单使用。基础知识部分包括Docker的用途和意义,Docker的镜像、容器、仓库、Dockerfile和DockerCompose的理解,以及Docker图形管理工具Portainer的基础功能。Docker命令的使用包括镜像使用、容器... 查看详情

docker学习总结(68)——docker数据卷相关知识总结

前言在生产环境中使用Docker,要想实现数据的持久化(所谓Docker的数据持久化即数据不随着Container的结束而结束)或者需要在多个容器之间进行数据共享,需要将数据从宿主机挂载到容器中,这就会涉及容器的数据管理操作。Doc... 查看详情

docker全解(代码片段)

目录说明docker简介为什么是docker容器与虚拟机比较容器发展简史传统虚拟机技术容器虚拟化技术docker能干什么带来技术职级的变化开发/运维(Devops)新一代开发工程师Docker应用场景whydocker?docker的优势docker和dockerHub官网Doc... 查看详情

理解docker:若干企业生产环境中的容器网络方案

 本系列文章将介绍Docker的相关知识:(1)Docker安装及基本用法(2)Docker镜像(3)Docker容器的隔离性-使用Linuxnamespace隔离容器的运行环境(4)Docker容器的隔离性-使用cgroups限制容器使用的资源(5)Docker网络(6)若干企业生... 查看详情

docker入门实战9高级网络配置

本章介绍docker的一些关于网络的高级知识,包括网络的启动和配置参数、DNS的使用配置、容器访问和端口映射的相关实现。 20.1网络启动与配置参数1.基本过程docker启动时会在主机上自动创建一个docker0虚拟网桥,实际上是一... 查看详情

docker学习笔记docker容器相关技术

Docker学习笔记(三)Docker容器相关技术 轻量级虚拟化技术命名空间:namespace,隔离系统资源,进程、网络、文件系统等隔离控制组:cgroups,为容器技术而生,分配资源,用来限制、记录、隔离进程资源使用。 命名空间... 查看详情

docker+openvswitch实现主机与容器的网络通信

...:安装openvswitchovs创建br0,br1,并启动两个不加载网络的docker容器将容器关联网桥br0,并设置ip、vlan创建veth0与veth1网卡对创建netns名称空间,并添加veth0.0和veth1.0接口,并配置相关信息将veth0.1 查看详情

docker之容器间通信配置(代码片段)

当你开始大规模使用Docker时,你会发现需要了解很多关于网络的知识。Docker作为目前最火的轻量级容器技术,有很多令人称道的功能,如Docker的镜像管理。然而,Docker同样有着很多不完善的地方,网络方面就是Docker比较薄弱的部... 查看详情

docker系列-第四篇docker镜像(代码片段)

...uniteseveraldirectoriesintoasinglevirtualfilesystem)。Union文件系统是Docker镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。特性:一次同时加载多个文件系统,但从外面看起来,只... 查看详情

docker知识点翻阅手册--docker常用命令dockererfilecompose网络等整理合集(代码片段)

文章目录一、Docker常用命令1、Docker容器信息2、镜像操作2.1、镜像查看2.2、镜像搜索2.3、镜像下载2.4、镜像删除2.5、镜像构建3、容器操作3.1、容器启动3.2、容器进程3.3、容器日志3.4、容器的进入与退出3.5、查看容器3.6、容器的停... 查看详情

docker容器相关技术

docker需要依赖的Linux内核特性:(1)Namespaces命名空间PID(ProcessID)用来隔离进程NET(Network)管理网络接口IPC(InterProcesscommunication)管理跨进程通信的访问MNT(Mount)管理挂载点UTS(UnixTimesharingSystem)隔离内核和版本标识(2)Controlgroups(cgroups)控制组... 查看详情

docker:网络模式详解

Docker作为目前最火的轻量级容器技术,牛逼的功能,如Docker的镜像管理,不足的地方网络方面。Docker自身的4种网络工作方式,和一些自定义网络模式安装Docker时,它会自动创建三个网络,bridge(创建容器默认连接到此网络)、no... 查看详情

docker的四种网络模式和相关网络命令等操作(代码片段)

Docker网络模式一、实现原理二、Docker四种网络模式三、Docker命令1、查看网络列表2、自定义网络固定IP3、暴露端口4、在宿主机环境执行容器内命令5、怎么把宿主机的文件传入到容器内部6、进入容器没有systemctl命令解决:添加--priv... 查看详情

虚拟化技术—docker容器—网络模式

Docker作为目前最火的轻量级容器技术,有很多令人称道的功能,如Docker的镜像管理。然而,Docker同样有着很多不完善的地方,网络方面就是Docker比较薄弱的部分。因此,我们有必要深入了解Docker的网络知识,以满足更高的网络需... 查看详情

云原生docker09-docker网络详解(代码片段)

【云原生|Docker】09-Docker网络详解文章目录【云原生|Docker】09-Docker网络详解前言网络详解bridge网络基于bridge网络的容器访问外部网络外部网络访问基于bridge网络的容器host网络none网络container网络自定义网络自定义bridge网络容器的... 查看详情