Kubernetes_容器网络_Docker_01_从Linux网卡到Docker网络命名空间

本文深入探讨了计算机网络和Docker容器的网络通信原理。介绍了Linux网络命名空间、网卡配置、IP地址的增删以及Docker的桥接网络类型。通过实践展示了如何在Linux上创建和管理网络命名空间,以及如何在Docker中使用桥接网络进行容器间的通信。同时,讨论了Docker的host和null网络类型,并提到了Kubernetes网络模型。
摘要由CSDN通过智能技术生成

一、前言

二、计算机网络

2.1 计算机网络理论知识

对于软件工程来说,只能接触到上层的网络协议,包括应用层和传输层,一般是 http dns tcp udp
对于网络工程来说,一般接触到下层的网络协议,包括网络层和数据链路层(下面这些对于应用软件没太大用)
在这里插入图片描述

在这里插入图片描述

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

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

2.2 Linux网卡灵活操作

2.2.1 网卡配置文件

各个网卡的作用:计算机能与外界通信的硬件支持,每个网卡有唯一的MAC地址。【一个机器多个网卡,一个网卡多个IP地址,但是一个网卡一个唯一的MAC地址。】

各个网卡的配置文件(该配置文件可以修改):在Linux中网卡对应的其实就是文件,所以找到对应的网卡文件即可,比如:cat /etc/sysconfig/network-scripts/ifcfg-eth0

cd  /etc/sysconfig/network-scripts/

在这里插入图片描述

2.2.2 网卡上增删IP地址(实践类)

这里 lo 是本地网卡,ens33是与互联网通信的网卡,同一个网卡上可以挂多个IP地址的,现在我们在 ens33 ,IP地址是 192.168.100.151/24
在这里插入图片描述

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

在这里插入图片描述

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

ip addr   # Ip地址查看,也可以写成 ip a
ip addr add 192.168.100.251/24 dev ens33  # ens33网卡上增加 19.168.100.251 这个ip 地址,子网掩码是24位
ip addr delete 192.168.100.251/24 dev ens33  # ens33网卡上删除 19.168.100.251 这个ip 地址,子网掩码是24位

在这里插入图片描述

增加这个ip之后,能够ip a 查看到,也能够在 windows 上 ping 到,就说明生效了

在这里插入图片描述

好了,删掉这个ip

ip addr delete 192.168.100.251/24 dev ens33

这个ip没有了,就ping不到了
在这里插入图片描述

2.2.3 网卡状态:UP DOWN UNKNOWN

ifdown ens33
ifup ens33

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

Linux和网络相关的知识点包括三个:ip、route、防火墙(firewalld和iptables),本文只介绍 ip 就可以了(网卡上增加/删除ip地址),有了Linux 网络ip的基础,下面开始看 Docker Network Namespace。

三、详解Docker的桥接bridge网络类型

(1) 新建两个网络命名空间ns1 和 ns2,给这个两个网络命名空间分别绑定上 veth-ns1 和 veth-ns2,然后给这两个 网卡绑定ip地址 192.168.100.11/24 192.168.100.12/24,然后分配能够ping到
(2) Docker Container直接网络通信底层就是两个veth-pair对,即 container1 <-> linux <-> container2 , 在 linux 上使用 brctl show 可以看到
(3) docker0 使用的是 桥接的网络的,是桥接在linux上的打点,docker network create tomcat-net 新建网络/新建网关/新建桥接bridge(默认桥接),并使用网络新建容器container,不同网关的创建的container是网络不通的 (docker network inspect tomcat-net);解决办法是:不同 网络命名空间/网关/bridge 通信,需要使用 docker network connet 将不能达到的目标container 加入到这个网络命名空间/网关/bridge 里面来
(4) 默认的桥接 bridge/docker0 是不带域名解析能力的,需要docker run 命令中加上单向link,但是自定义/自己创建的network namespace是带有域名解析能力的
(5) 外网windows和宿主机centos是可以通信的,宿主机和容器是可以通信的,所以,外网要想和container通信,就是需要将container的端口映射到宿主机centos就可以了

3.1 Linux 的 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列表

先看本机docker的network namespace的查询、新增、删除操作,如下:

在这里插入图片描述

刚刚新建了一个namespace,名为ns1,查看一下新建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 # docker network namespace 的 ns1 网络展示
ip link show  # linux网络展示

在这里插入图片描述

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

ip netns add ns2  # 新增一个名为 ns2 的network namespace
ip netns exec ns2 ip a  # 查看 ns2 的 network namespace 的ip addr (就是 ip a 命令)
ip netns exec ns2 ipup lo # ns2 上执行 (ipup lo 就是将lo网卡启动起来)
ip netns exec ns2 ip a  # ns2 上执行查看命令 (ip a 就是执行查看)

在这里插入图片描述

ip netns exec ns1 ip a
ip netns exec ns1 ifup lo 
ip netns exec ns1 ip a

在这里插入图片描述

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

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

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

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

创建一个pair 然后分配给ns

# 三个:add veth-ns1 / type veth peer / name veth-ns2 
ip link add veth-ns1 type veth peer name veth-ns2  
ip link show

在这里插入图片描述

创建好了两个 ip link,veth-ns1@veth-ns2 和 veth-ns2@veth-ns1 ,现在讲这两个绑定到 network namespace 的 ns1 ns2 上面去,就是 ns1 和 ns2 这两个网络命名空间都加一个两个网卡,分别是 veth-ns1 和 veth-ns2

ip link show
ip link set veth-ns1 netns ns1  # 将 ns1 和 veth-ns1 绑定在一起
ip link show
ip netns exec ns1 ip link  # 对 ns1 查看 ip link

在这里插入图片描述

继续,将 veth-ns2 分配给 ns2

ip link show
ip link set veth-ns2 netns ns2  # 将 ns2 和 veth-ns2 绑定在一起
ip link show
ip netns exec ns2 ip link  # 对 ns2 查看 ip link

在这里插入图片描述

注意:ip a 、ip a show、ip link、ip link show 四个命令是一样的,前面两条是查看详细信息,后面两条是查看简要信息

在这里插入图片描述

完成了,现在两个 network namespace , ns1 和n2 分别绑定了 veth-ns1 和 veth-ns2,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

在这里插入图片描述

同样给 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地址有了,两个 network namespace 网络命名空间 ns1 ns2 ,都加上了一个网卡 veth-ns1 和 veth-ns2,而且这个网卡还绑定好了ip,分别是 192.168.100.11/24 和 192.168.100.12/24

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

ip netns exec ns1 ping 192.168.100.12  # 在ns1上面ping 19.168.100.12 (ns2的veth-ns2网卡)
ip netns exec ns2 ping 192.168.100.11  # 在ns2上面ping 19.168.100.11 (ns1的veth-ns1网卡)

在这里插入图片描述

两个ip地址 ping ,ping通了

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

在这里插入图片描述

好了 新建两个网络命名空间ns1 和 ns2,给这个两个网络命名空间分别绑定上 veth-ns1 和 veth-ns2,然后给这两个 网卡绑定ip地址 192.168.100.11/24 192.168.100.12/24,然后分配能够ping到

3.2 Docker Container直接网络通信底层就是两个veth-pair对

Docker Container直接网络通信底层就是两个veth-pair对,即 container1 <-> linux <-> container2 , 在 linux 上使用 brctl show 可以看到

# 本节需要执行的命令

# docker run运行两个容器
docker run -d --name tomcat01 -p 8081:8080 tomcat  # 启动tomcat01 容器
docker run -d --name tomcat02 -p 8082:8080 tomcat  # 启动tomcat02 容器
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 对

在这里插入图片描述

验证一下

# linux执行
docker run -d --name tomcat03 -p 8083:8080 tomcat  # linux执行,运行tomcat03
docker exec -it tomcat03 bash  # linux执行,进入tomcat03

# 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

# linux执行
ip a   # linux执行,查看linux上的网卡是不是增加了一个
brctl show   # linux执行,查看linux的桥接docker0下面的网卡是不是增加了一个
docker network ls  # linux执行,查看linux的network namespace

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

值得注意的是,正常的kubeadm安装的k8s集群,使用calico cni插件,使用的calico ippool那一套,不是docker network ns
Pod IP网段是 calico ippool 分配的,不是docker
route 路由也是 calixxx
brctl show 也找不到 docker0 相关联的网卡
在这里插入图片描述

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

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
小结:Docker Container直接网络通信底层就是两个veth-pair对,即 container1 <-> linux <-> container2 , 在 linux 上使用 brctl show 可以看到

3.3 不同network namespace网络命名空间的container通信

docker0 使用的是 桥接的网络的,是桥接在linux上的打点,docker network create tomcat-net 新建网络/新建网关/新建桥接bridge(默认桥接),并使用网络新建容器container,不同网关的创建的container是网络不通的 (docker network inspect tomcat-net)

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
在这里插入图片描述

在这里插入图片描述

什么时候会出现不同网络命名空间中的container通信?

那就是如果容器太多了,这个网段下面放满了, 一个 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.4 通过名称访问 (默认网络命名空间无法域名解析)

概述:默认的桥接 bridge/docker0 是不带域名解析能力的,需要docker run 命令中加上单向link,但是自定义/自己创建的network namespace是带有域名解析能力的

在这里插入图片描述

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

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

在这里插入图片描述
在这里插入图片描述
同一桥接,docker0里面的两个container 名字解析不了
但是自定义的桥接,里面的两个container 名字可以解析 自定义的bridge默认增加一条dns解析

在默认的 docker0 里面,可以用 --link 这种单向的

# 之前
docker run -d --name tomcat01 tomcat
docker exec -it tomcat01 ping tomcat02

# 现在(docker run启动增加单向link用于解析 tomcat02 这个域名)
docker run -d --name tomcat01 --link tomcat02 tomcat
docker exec -it tomcat01 ping tomcat02

在这里插入图片描述

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

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

3.5 端口映射:容器的端口映射到的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

小结:外网windows和宿主机centos是可以通信的,宿主机和容器是可以通信的,所以,外网要想和container通信,就是需要将container的端口映射到宿主机centos就可以了

四、其他两种类型的网络: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 network

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从来不与外界通信

七、尾声

对于linux而言,网络包括 ip、route、防火墙(firewalld和iptables),本文只介绍 ip 就可以了(网卡上增加/删除ip地址),有了Linux 网络ip的基础,下面开始看 Docker Network Namespace。

(1) Linux的网络命名空间:新建两个网络命名空间ns1 和 ns2,给这个两个网络命名空间分别绑定上 veth-ns1 和 veth-ns2,然后给这两个 网卡绑定ip地址 192.168.100.11/24 192.168.100.12/24,然后分配能够ping到
(2) Docker container通信利用了Linux的veth-pair资源:Docker Container直接网络通信底层就是两个veth-pair对,即 container1 <-> linux <-> container2 , 在 linux 上使用 brctl show 可以看到
(3) docker0 使用的是 桥接的网络的,是桥接在linux上的打点,docker network create tomcat-net 新建网络/新建网关/新建桥接bridge(默认桥接),并使用网络新建容器container,不同网关的创建的container是网络不通的 (docker network inspect tomcat-net);解决办法是:不同 网络命名空间/网关/bridge 通信,需要使用 docker network connet 将不能达到的目标container 加入到这个网络命名空间/网关/bridge 里面来
(4) 默认的桥接 bridge/docker0 是不带域名解析能力的,需要docker run 命令中加上单向link,但是自定义/自己创建的network namespace是带有域名解析能力的
(5) 外网windows和宿主机centos是可以通信的,宿主机和容器是可以通信的,所以,外网要想和container通信,就是需要将container的端口映射到宿主机centos就可以了

Linux有一个网络命名空间资源,这个网路命名空间上可以新建网卡,然后Linux上有一个 veth-pair 资源,然后新建好的网络命名空间上的网卡,可以和新建上好的 veth-pair 关联,然后不同网络命名空间的网卡就可以通信了

Docker container通信利用了Linux的veth-pair资源,但是并没有利用 linux 网络命名空间,更没有利用linux网络命名空间上的网卡,仅仅只是利用了Linux的veth-pair资源。Docker有自己的网络命名空间/网关/bridge,新建container的时候是必须使用 docker网络命名空间/网关/bridge 的,然后就是两种:一是同一个docker网络命名空间的container之间网络通信,二是不同docker网络命名空间的container之间网络通信。 【Docker网络命名空间172.17.0.0/16,网关为 172.17.0.1;Docker网络命名空间172.18.0.0/16,网关为 172.18.0.1】

在这里插入图片描述

k8s pod里面运行container,但是pod的网段是calico里面的ip-pool确定的,svc的网段是kube-apiserver.yaml确定的,和 docker 网络命名空间无关

在这里插入图片描述

另外:
docker是为了解决同一个pod里面container之间网络通信,就是docker ps | grep pod-name中的那个pause的容器(例如:docker ps | grep apiserver);
calico是解决两种:一是同一个node上的pod之间的通信(仅calixxx网卡,本机器上处理),二是不同一个node上的pod之间的通信(tul0网卡和calixxx网卡)

网络命名空间(同一个pod里面的container之间的网络通信)
(1) linux层面: linux上的可以新建两个网络命名空间,然后两个命名空间都绑定上一张网卡,然后给两个网卡绑定都变成了一个 veth,就是一对 veth-pair,然后两个不同网络命名空间上的网卡可以ping到了,即 ns1 <=> veth-pair <=> ns2。
(2) docker层面:docker同一个node上不同container之间网络通信的底层原理(docker使用了linux的veth-pair,但是没有使用网络命名空间),不过稍微复杂些,是 container1 <=> veth-pair <=> linux <=> veth-pair <=> container2 (docker network没用到linux network ns ,但是用到 veth-pair)。再高一层。
(3) k8s层面:k8s pod中的pause容器,可以让同一个pod里面的container,共享网络,就是因为使用同一个 network 网络命名空间。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

祖母绿宝石

打赏一下

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值