安装工具:
apt install bridge-utils net-tools 容器与宿主机的通信 创建一个新的网络命名空间,这里模拟容器内部的网络
$ ip netns add net1 # net1为该网络空间(容器内部网络空间)的名称 查看命名空间的iptable, 路由表,设备
$ ip netns exec net1 route # 查看容器内部路由表 Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface $ ip netns exec net1 iptables -L # 查看容器内部iptable Chain INPUT (policy ACCEPT) target prot opt source destination Chain FORWARD (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination $ ip netns exec net1 ip link list # 查看容器内部设备 1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 # 目前只有本地回环设备, 并且状态为DOWN(未启动) 创建一对veth,并将veth的一头添加到net1中...
flannel项目本身只是一个框架,真正实现容器网络容器功能的,是Flannel的后端实现,目前,Flannel推荐的后端实现有四种,分别是:
VXLAN host-gw WireGuard UDP 此外还有一些实验性的后端实现
UDP模式 UDP 模式,是最直接、也是最容易理解的容器跨主网络实现。
假设有两台宿主机:
宿主机 Node 1 上有一个容器 container-1,它的 IP 地址是 100.96.1.2,对应的 docker0 网桥的地址是:100.96.1.1/24。 宿主机 Node 2 上有一个容器 container-2,它的 IP 地址是 100.96.2.3,对应的 docker0 网桥的地址是:100.96.2.1/24。 现在的任务是:让container-1访问container-2。此时访问container-2的这个IP包的源地址为100.96.1.2,目的地址为100.96.2.1。按照上篇所述,首先这个IP包会通过veth对来到docker0网桥,而此时docker0网桥上并没有插入IP为100.96.1.2的设备,因此会走默认路由规则,出现在宿主机上。此时如果机器上已经安装了flannel,那么flannel会为宿主机创建出一系列路由规则,如:
# 在Node 1上 $ ip route default via 10.168.0.1 dev eth0 100.96.0.0/16 dev flannel0 proto kernel scope link src 100.96.1.0 100.96.1.0/24 dev docker0 proto kernel scope link src 100.96.1.1 10.168.0.0/24 dev eth0 proto kernel scope link src 10....
安装工具:
apt install bridge-utils net-tools 创建一个新的网络命名空间
$ ip netns add net1 # net1为该网络空间的名称 查看命名空间的iptable, 路由表,设备
$ ip netns exec net1 route # 查看路由表 Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface $ ip netns exec net1 iptables -L # 查看iptable Chain INPUT (policy ACCEPT) target prot opt source destination Chain FORWARD (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination $ ip netns exec net1 ip link list # 查看设备 1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 # 目前只有本地回环设备, 并且状态为DOWN(未启动) 创建一对veth,并将veth的一头添加到net1中...
容器具有自己的Network Namespace.
eht0是这个Network Namespace里的网络接口。而宿主机上也有自己的 eth0,宿主机上的 eth0 对应着真正的物理网卡,可以和外面通讯
要让容器 Network Namespace 中的数据包最终发送到物理网卡上,需要以下两步:
将数据包从容器的 Network Namespace 发送到 Host Network Namespace 上 数据包从宿主机的eth0发送出去 要想让容器从自己的Network Namespace连接到Host Namespace,一般来说就只有两类设备接口,一是veth,另外是macvlan/ipvlan.
veth是一个虚拟的网络设备,一般是成对建立,而且这对设备是相互连接的。当每个设备在不同的 Network Namespaces 的时候,Namespace 之间就可以用这对 veth 设备来进行网络通讯了。
到这里,解决了第一步,下一步需要将数据包从宿主机的eth0发送出去。
Docker 程序在节点上安装完之后,就会自动建立了一个 docker0 的 bridge interface。所以我们只需要把第一步中建立的 veth_host 这个设备,接入到 docker0 这个 bridge 上。
容器和docker0组成了一个子网,docker0上的IP就是这个子网的网关IP。
然后docekr0通过nat或route的方式,经过eth0将数据包向外发送。
Reference https://time.geekbang.org/column/article/323325
http://icyfenix.cn/immutable-infrastructure/network/linux-vnet.html
https://morven.life/posts/networking-4-docker-sigle-host/
https://network.51cto.com/article/708901.html
1. 分层的镜像 在我们启动一个容器之前,通常需要下载这个容器对应的镜像,以这个镜像为基础启动容器。镜像中包含了对应的程序的二进制文件与其所依赖的文件,程序在启动后看到的rootfs只是这个镜像中存在的文件。这样,我们就可以为容器中的进程提供一个干净的文件系统。
创建一个镜像(image)的最简单方法是使用Dockerfile。
FROMscratchCOPY hello /CMD ["/hello"]scratch是docker为我们提供的一个空镜像,我们可以在此基础上构建任何我们想要的镜像。
在书写Dockerfile时,想必你听说过这么一句话,不要在Dockerfile中创建太多层.
在Dockerfile中,每一个指令都会创建一个新的“层”,这里的层,指的是UnionFS中的一个文件目录。当我们创建了过多的层,会导致镜像体积变大,除此之外,Union FS 也会有最大层数限制。
因此对于如下的Dockerfile文件写法,应尽量避免:
FROMdebian:stretchRUN apt-get updateRUN apt-get install -y gcc libc6-dev make wgetRUN wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz"RUN mkdir -p /usr/src/redisRUN tar -xzf redis.tar.gz -C /usr/src/redis --strip-components=1RUN make -C /usr/src/redisRUN make -C /usr/src/redis install可优化为如下写法
FROMdebian:stretchRUN set -x; buildDeps='gcc libc6-dev make wget' \ && apt-get update \ && apt-get install -y $buildDeps \ && wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz" \ && mkdir -p /usr/src/redis \ && tar -xzf redis....