docker网络原理详解02(代码片段)

我的紫霞辣辣 我的紫霞辣辣     2022-12-16     509

关键词:

Docker网络网络基础

Docker 使用到的与 Linux 网络有关的技术分别有:网络名称空间VethIptables网桥路由

网络名称空间

为了支持网络协议栈的多个实例,Linux 在网络协议栈中引入了网络名称空间(Network Namespace),
这些独立的协议栈被隔离到不同的命名空间中。处于不同的命名空间的网络协议栈是完全隔离的,彼此之间无法进行网络通信,就好像两个"平行宇宙"。

通过这种对网络资源的隔离,就能在一个宿主机上虚拟多个不同的网络环境,
而 Docker 正是利用这种网络名称空间的特性,实现了不同容器之间的网络隔离。
在 Linux 的网络命名空间内可以有自己独立的 Iptables 来转发、NAT及 IP 包过滤等功能。

Linux 的网络协议栈是十分复杂的,为了支持独立的协议栈,相关的这些全局变量都必须修改为协议栈私有。
最好的办法就是让这些全局变量成为一个 Net Namespace 变量的成员,然后为了协议栈的函数调用加入一个Namespace 参数。
这就是 Linux 网络名称空间的核心。所以的网络设备都只能属于一个网络名称空间。
当然,通常的物理网络设备只能关联到 root 这个命名空间中。
虚拟网络设备则可以被创建并关联到一个给定的命名空间中,而且可以在这些名称空间之间移动。

自定义Veth-pair

Veth 设备

引入 Veth 设备对是为了在不同的网络名称空间之间进行通信,利用它可以直接将两个网络名称空间链接起来。由于要连接的两个网络命名空间,所以 Veth 设备是成对出现的,很像一对以太网卡,并且中间有一根直连的网线。既然是一对网卡,那么我们将其中一端称为另一端的 peer。在 Veth 设备的一端发送数据时,它会将数据直接发送到另一端,并触发另一端的接收操作。

创建一个命名空间

[root@docker01 ~]# ip netns add test01
[root@docker01 ~]# ip netns add test02
[root@docker01 ~]# ip netns list
test02
test01

创建 Veth 设备对

# 创建 Veth 设备对
[root@docker01 ~]# ip link add name veth01 type veth peer name veth02

# 查看宿主机的网络
[root@docker01 ~]# ip link show
...
5: veth02@veth01: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether da:01:99:1f:69:14 brd ff:ff:ff:ff:ff:ff
6: veth01@veth02: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether fe:3c:0a:4e:31:81 brd ff:ff:ff:ff:ff:ff

- 生成了两个veth设备,互为对方的peer

将 veth设备对的一个设备 绑定命名空间

# 将veth01设备绑定给test01名称空间内
[root@docker01 ~]# ip link set veth01 netns test01
[root@docker01 ~]# ip link show | grep veth
5: veth02@if6: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000


已经查看不到veth01虚拟网卡,当我们进入 test01 命名空间之后,就可以查看veth01虚拟网卡
# 经入test01名称空间内
[root@docker01 ~]# ip netns exec test01 bash
[root@docker01 ~]# ip link show
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
6: veth01@if5: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
    link/ether fe:3c:0a:4e:31:81 brd ff:ff:ff:ff:ff:ff link-netnsid 0

给 Veth设备 分配 IP

- 为 test01 名称空间内的网卡 veth01 设置ip地址
# 将ip地址 172.16.0.80/20 绑定给test01名称空间内的虚拟网卡veth01
[root@docker01 ~]# ip netns exec test01 ip addr add 172.16.0.80/20 dev veth01
# 启动虚拟网卡veth01
[root@docker01 ~]# ip netns exec test01 ip link set dev veth01 up
# 查看test01名称空间内的虚拟网卡
[root@docker01 ~]# ip netns exec test01 ip a
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
6: veth01@if5: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state LOWERLAYERDOWN group default qlen 1000
    link/ether fe:3c:0a:4e:31:81 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.16.0.80/20 scope global veth01
       valid_lft forever preferred_lft forever
[root@docker01 ~]# exit
exit

- 为对端主机的网卡 veth02 设置ip地址
# 将ip地址 172.16.0.890/20 绑定给主机的虚拟网卡veth02
[root@docker01 ~]# ip addr add 172.16.0.90/20 dev veth02
# 重启主机veth02的网卡
[root@docker01 ~]# ip link set dev veth02 down
[root@docker01 ~]# ip link set dev veth02 up

- 测试主机的虚拟网卡veth02连接test01名称空间内的虚拟网卡veth01,连接成功。
[root@docker01 ~]# ping 172.16.0.80
PING 172.16.0.80 (172.16.0.80) 56(84) bytes of data.
64 bytes from 172.16.0.80: icmp_seq=1 ttl=64 time=0.049 ms
64 bytes from 172.16.0.80: icmp_seq=2 ttl=64 time=0.072 ms

结论 :
网络连接设备比较小众的情况下,使用Veth pair进行直接连接(一对一进行连接,效率更高);
网络连接设备比较多的情况下,使用网桥进行连接(多了一个类似于路由器一样的设备进行转发)。

Iptables/Netfilter

  • Linux协议栈非常高效且复杂。
    如果我们想要在数据处理过程中对关心的数据进行一些操作,则需要Linux提供一套相应的机制帮助用户实现自定义的数据包处理过程。

  • 在Linux网络协议栈有一组网络回调函数挂接点,通过这些挂接点函数挂接的钩子函数可以在Linux网络栈处理数据包的过程中对数据包一些操作,例如过滤、修改、丢弃等。整个挂接点技术叫做Iptables和Netfilter。

  • Netfilter负责在内核中执行各种各样的挂接规则,运行在内核模式中。
    而Iptables是在用户模式下运行的进程,负责协助维护内核中Netfilter的各种规则表。
    通过二者的配合来实现整个Linux网络协议栈中灵活的数据包处理机制。

总结

设备作用总结
network namespace主要提供了关于网络资源的隔离,包括网络设备、IPv4 和 IPv6 协议栈、IP 路由表、防火墙、/proc/net 目录、/sys/class/net 目录、端口(socket)等。
linux Bridge功能相当于物理交换机,为连在其上的设备(容器)转发数据帧。如 docker0 网桥。
iptables主要为容器提供 NAT 以及容器网络安全
veth pair两个虚拟网卡组成的数据通道。在 Docker 中,用于连接 Docker 容器和 Linux Bridge。一端在容器中作为 eth0 网卡,另一端在 Linux Bridge 中作为网桥的一个端口。

Docker 四种网络模式

Docker网络模式

Docker 使用 Linux 桥接的方式,在宿主机虚拟一个 Docker 容器网桥(docker0)。
Docker 启动一个容器时会 根据 Docker 网桥的网段分配给容器一个 IP 地址,称为 Container-IP。
同时 Docker 网桥是每个容器的默认网关。
因为在同一宿主机内的容器都接入同一个网桥,这样容器之间就能够通过容器的 Container-IP 直接通信。

Docker 网桥是宿主机虚拟出来的,并不是真实存在的网络设备,外部网络是无法寻址到的。
这也意味着外 部网络无法通过直接 Container-IP 访问到容器。
如果容器希望外部访问能够访问到,可以通过映射容器端口到 宿主主机(端口映射),
即 docker run 创建容器时候通过 -p 或 -P 参数来启用,访问容器的时候就通过[宿主机 IP]:[容器端口]访问容器。

host 模式


指定容器的网络模式为host模式:

  docker run -d --network=host nginx
# 启动一个容器,指定模式为host模式
[root@docker01 ~]# docker run -d --network=host nginx
5afb9b8df8c311609677aaf7f6bff11467a34bb5b804f8eb9498232ee018d756

浏览器输入主机的ip地址: http://192.168.15.80/
可以正常访问到nginx

结论:容器和宿主机共享Network namespace,公用宿主机网卡。

Containe 模式


指定容器的网络模式为host模式(容器与容器之间的端口号不能重复!!!):

docker run -d --network="container:容器id" nginx
容器A:
# 启动一个centos容器,指定网络模式为host模式,公用宿主机的网卡
[root@docker01 ~]# docker run -it --network=host centos
# 查看网卡信息
[root@docker01 /]# ip a
...
4: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group defaul
    link/ether 02:42:aa:7b:f5:2d brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:aaff:fe7b:f52d/64 scope link 
       valid_lft forever preferred_lft forever

容器B:       
# 再次启动一个centos容器,指定网络模式为container,id指定为第一个容器A的centos网卡
[root@docker01 ~]# docker run -it --network="container:82e5e0944002" centos
# 网卡信息与容器A一致,说明跟容器A公用一个网卡(都是使用的是宿主机的网卡)
[root@docker01 /]# ip a
...
4: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group defaul
    link/ether 02:42:aa:7b:f5:2d brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:aaff:fe7b:f52d/64 scope link 
       valid_lft forever preferred_lft forever

# 再打开一个终端,查看正在运行的容器
[root@docker01 ~]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS     NAMES
fc553578de82   centos    "/bin/bash"              3 minutes ago    Up 3 minutes              happy_euclid
82e5e0944002   centos    "/bin/bash"              6 minutes ago    Up 6 minutes              busy_hoover

注意:使用container模式,容器与容器之间的端口号不能重复。

none 模式


指定容器的网络模式为none模式:

docker run -it --network=none nginx
# 启动一个nginx容器,指定网络模式为none模式
[root@docker01 ~]# docker run -it --network=none centos
# 查看容器ip信息,容器拥有自己独立的名称空间,但是默认的ip地址只有本地回环地址。
[root@ee42ffce97ef /]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever

bridge模式

当 Docker 进程启动时,会在主机上创建一个名为 docker0 的虚拟网桥,dokcer创建容器默认的模式为bridge模式。

bridge模式相关命令

# bridge模式常用命令
[root@docker01 ~]# docker network --help

Usage:  docker network COMMAND

Manage networks

Commands:
  connect     Connect a container to a network
  create      Create a network
  disconnect  Disconnect a container from a network
  inspect     Display detailed information on one or more networks
  ls          List networks
  prune       Remove all unused networks
  rm          Remove one or more networks

Run 'docker network COMMAND --help' for more information on a command.
-- 创建一个网桥: create
# --driver		指定网络模式
# --subnet 		指定子网地址
# --gateway 	指定网关地址
[root@docker01 ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet

-- 查看网桥列表: ls
[root@docker01 ~]# docker network ls

-- 查看网桥基本信息: inspect
[root@docker01 ~]# docker network inspect mynet

-- 添加一个容器到网桥,网桥默认会给新添加的容器分配同一个网段的ip: connect
# 启动一个nginx容器,默认的网桥是docker0
[root@docker01 ~]# docker run -d nginx

# 启动一个centos容器,并进入容器内,指定为自定义网桥mynet
[root@docker01 ~]# docker run -it network=mynet centos

# 不同的网桥之间默认是无法连接的,在centos容器内是连接不上nginx容器的
[root@8a8088cfa5fd /]# curl 9a475eeeb3e9
curl: (6) Could not resolve host: 9a475eeeb3e9

# 将nginx的容器id添加至mynet网桥
[root@docker01 ~]# docker network connect mynet 9a475eeeb3e9	

# 在centos镜像内重新访问连接nginx,测试成功
[root@8a8088cfa5fd /]# curl 9a475eeeb3e9
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...

-- 删除网桥内的一个容器: disconnect
[root@docker01 ~]# docker network disconnect mynet 9a475eeeb3e9

[root@8a8088cfa5fd /]# curl 9a475eeeb3e9
curl: (6) Could not resolve host: 9a475eeeb3e9

-- 清空所有当前没有正在使用的网桥: prune (docker默认的网桥是无法被清理的)
# 创建两个网桥
[root@docker01 ~]# docker network create test01
[root@docker01 ~]# docker network create test02

# 查看网桥列表
[root@docker01 ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
f1de61811860   bridge    bridge    local
e185b787c28e   host      host      local
0a046b8f5a42   mynet     bridge    local
01c19cbebe06   none      null      local
91b6a150a909   test01    bridge    local
ce6b6e692235   test02    bridge    local

# 清理未被使用的网桥
[root@docker01 ~]# docker network prune
WARNING! This will remove all custom networks not used by at least one container.
Are you sure you want to continue? [y/N] y
Deleted Networks:
test01
test02

-- 删除指定的网桥: rm
[root@docker01 ~]# docker network rm test01

强力的应用容器引擎——docker网络部分详解(代码片段)

Docker网络部分详解一、docker网络概述1.1docker网络实现的原理1.2docker的网络模式二、docker网络模式详解2.1host模式2.2container模式2.3none模式2.4bridge模式2.5自定义网络模式自定义网络模式创建步骤一、docker网络概述1.1docker网络实现的原... 查看详情

docker网络详解(hostcontainernonebridge网络模式大解析)(代码片段)

Docker网络详解(host、container、none、Bridge网络模式大解析)前言一、Docker网络实现原理二、Docker的网络模式1、安装Docker时,它会自动创建三个网络,bridge(创建容器默认连接到此网络)、none、host2、使用doc... 查看详情

docker网络详解(代码片段)

Docker网络Docker网络架构libnetwork中的5种内置驱动Docker原生网络bridge模式host模式none模式Docker自定义网络创建自定义网桥bridge如何让不同网段的容器可以相互通信Docker基础知识可点击查看之前文章Docker网络架构Docker有自己的网络库&#... 查看详情

kubernetes之docker网络详解(代码片段)

...去,但是不能NAT桥:NAT连接追踪实现主机与外部互相通信docker常见的网络类型桥网络:bridge,docker0实现NAT联盟式网络:共享NET,IPC,UTShost网络:容器共享宿主机网络none网络:封闭式网络docker四类网络实践none封闭式网 查看详情

docker网络(代码片段)

目录一、Docker网络1、Docker网络实现原理2、Docker的网络模式3、网络模式详解1.host模式2.container模式3.none模式4.Bridge模式5.自定义网络二、资源控制1.CPU资源控制2.对内存使用的限制3.对磁盘I... 查看详情

docker网络(代码片段)

Docker网络ipaddr查看当前linux虚拟机的ip地址启动tomcat容器,查看其ip地址原理创建tomcat01和tomcat02,测试发现两个容器之间可以相互ping通小结Docker--link:添加主机名和ip的映射--link命令指定别名自定义网络查看所有的docker网络... 查看详情

docker网络及资源管理(代码片段)

Docker网络及资源管理一、Docker网络实现原理二、Docker的网络模式安装Docker时,它会自动创建三个网络,bridge(创建容器默认连接到此网络)、none、host使用dockerrun创建Docker容器时,可以用--net或--network选项指定... 查看详情

docker网络及资源管理(代码片段)

Docker网络及资源管理一、Docker网络实现原理二、Docker的网络模式安装Docker时,它会自动创建三个网络,bridge(创建容器默认连接到此网络)、none、host使用dockerrun创建Docker容器时,可以用--net或--network选项指定... 查看详情

docker-04-docker单机网络详解(代码片段)

一、docker的网络模式概述1.1单机模式bridge默认模式,此模式会为每一个容器分配、设置IP等,并将容器连接到一个docker0虚拟网桥,通过docker0网桥以及Iptablesnat表配置与宿主机通信。host容器将不会虚拟出自己的网卡,配置自己的IP... 查看详情

flannel配置详解(代码片段)

...3.3、安装Flannel3.4、启动Flannel3.5、验证Flannel网络3.6、配置Docker3.7、验证容器互通3.8、配置backend为host-gw1、简介Flannel是一种基于overlay网络的跨主机容器网络解决方案,也就是将TCP数据包 查看详情

docker—网络与性能资源的分配(代码片段)

docker一、docker的网络部分1.1概述1.2Docker网络实现原理1.3Docker的网络模式使用dockerrun创建Docker容器时,可以用--net或--network选项指定容器的网络模式1.4网络模式详解host模式container模式none模式Bridge模式自定义网络二、docker资源控... 查看详情

docker网络和资源限制(代码片段)

目录前言一、Docker网络实现原理1.1Docker的网桥与容器IP1.2查看容器的IP地址1.3宿主机访问容器1.4Docker的网络模式:指定网络模式:详解网络模式:1.4.1Host模式1.4.2Container模式查看容器的进程号根据容器进程ID查看容器命名空... 查看详情

docker学习总结(75)——docker三种网络驱动bridgemacvlanoverlay详解(代码片段)

一、自定义桥接(bridge)网络这个网桥类似于默认网络中的bridge,创建自定义网络命令:dockernetworkcreate$dockernetworkcreate--driverbridge--subnet172.19.0.0/16--gateway172.19.0.1mybridge_net参数解释:--driverbridge表示使用桥接模式--subnet172.19.0.0/16 查看详情

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

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

docker容器原理详解(代码片段)

Linux部署服务的形式1.纯物理机的服务器部署2.虚拟化的部署形式相比纯物理机的部署形式,虚拟机的部署形式解决了哪些问题控制了成本节约了一定的资源迁移和扩展也得到了优化,可以利用虚拟机的模板功能,vmware... 查看详情

“深入浅出”来解读docker网络核心原理(代码片段)

...之前笔者写了有些关于dokcer的各种相关技术的文章,唯独Docker网络这一块没有具体的来分享。后期笔者会陆续更新Docker集群以及Docker高级实践的文章,所以在此之前必须要和大家一起来解读一下Docker网络原理。认真看下去你会有... 查看详情

docker网络原理,k8s网络原理(代码片段)

我们知道docker安装完之后,每个docker容器里面都有自己单独的网络,那么docker的网络是怎么工作的呢?首先我们需要了解的是Linux提供了基于NameSpace的隔离机制,主要包含如下NameSpace隔离:MountNamespace隔离了一... 查看详情

docker网络(代码片段)

文章目录一、Docker网络简介(1)查看Docker网络二、Docker的bridge网络(1)创建使用bridge网络的容器(2)修改容器的默认网段三、none网络四、host网络五、自定义网络(1)自定义bridge网络(2)... 查看详情