文章目录
一、前言
二、计算机网络
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 网络命名空间。