Docker 容器虚拟化

发布时间 - 2025-07-18 00:00:00    点击率:

docker容器虚拟化1、虚拟化网络

Network Namespace 是 Linux 内核提供的一种功能,是实现网络虚拟化的关键,它能够创建多个隔离的网络空间,每个空间拥有独立的网络栈信息。无论是虚拟机还是容器,在运行时都仿佛处于独立的网络中。不同Network Namespace的资源是相互不可见的,因此它们之间无法直接通信。

实例1

假设一台物理机有4块物理网卡,可以创建4个名称空间(NS),每个网卡设备可以单独关联到一个特定的名称空间中。

这4个网卡分别对应一个唯一的名称空间。各名称空间相互隔离,彼此不可见,因此一个设备对应一个名称空间。

因为与物理网卡绑定,每个名称空间可以直接连接外网,并配置IP地址。

# 容器端网卡if5,ip
[root@localhost ~]# docker run -it --rm busybox/ 
# ip a
1: lo:  mtu 65536 qdisc noqueue 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
4: eth0@if5:  mtu 1500 qdisc noqueue 
     link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever
# 宿主机网卡if4,ip
[root@localhost ~]# ip a
......
5: veth2d6f8e9@if4:  mtu 1500 qdisc noqueue master docker0 state UP group default 
     link/ether 1a:66:5e:d2:c1:66 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet6 fe80::1866:5eff:fed2:c166/64 scope link 
        valid_lft forever preferred_lft forever 
       # ping外网测试
[root@localhost ~]# docker run -it --rm busybox/ 
# ping www.baidu.com
PING www.baidu.com (182.61.200.7): 56 data bytes
64 bytes from 182.61.200.7: seq=0 ttl=127 time=22.262 ms
64 bytes from 182.61.200.7: seq=1 ttl=127 time=22.218 ms
^C--- www.baidu.com ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 22.218/22.240/22.262 ms

实例2

如果名称空间的数量超过物理网卡的数量,我们可以使用虚拟网卡设备,通过纯软件的方式来模拟一组设备。

Linux内核支持两种级别的设备模拟:二层设备(交换机)和三层设备(路由器)。

Linux内核模拟的二层设备的网络接口设备是成对出现的;Linux内核原生支持二层虚拟网桥设备,即用软件虚拟交换机的功能。如下图所示:

此时再创建一个名称空间,并配置相同网段,这两个名称空间可以相互通信,如下图所示:

从网络通信的物理设备到网卡都是用纯软件的方式来实现,这种实现方式称为虚拟化网络。

2、单节点容器间通信

如果同一台物理机上的两个容器需要通信,我们可以在该主机上建立一个虚拟交换机,然后让两个容器各自通过纯软件的方式创建一对虚拟网卡,一半在容器上,一半在虚拟交换机上,从而实现通信。如下图所示:

# 创建两个容器
[root@localhost ~]# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED          STATUS          PORTS     NAMES
323d804ed27e   busybox   "sh"      3 seconds ago    Up 2 seconds              bus2
2c791ac9dba2   busybox   "sh"      16 seconds ago   Up 16 seconds             bus1
# 查看容器bus1的ip
[root@localhost ~]# docker exec -it bus1 /bin/sh
/ # ip a
1: lo:  mtu 65536 qdisc noqueue 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
6: eth0@if7:  mtu 1500 qdisc noqueue 
     link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever
# 查看容器bus2的ip
[root@localhost ~]# docker exec -it bus2 /bin/sh
/ # ip a
1: lo:  mtu 65536 qdisc noqueue 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
8: eth0@if9:  mtu 1500 qdisc noqueue 
     link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.3/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever
# 用容器bus2ping容器bus1
/ # ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2): 56 data bytes
64 bytes from 172.17.0.2: seq=0 ttl=64 time=0.100 ms
64 bytes from 172.17.0.2: seq=1 ttl=64 time=0.081 ms
^C--- 172.17.0.2 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.081/0.090/0.100 ms

如果容器需要跨交换机通信,该如何操作呢?

我们可以创建两个虚拟交换机,每个交换机连接不同的容器,如下图所示。如果要让C1和C3通信,可以通过名称空间创建一对网卡,一端连接SW1,另一端连接SW2,这样两个交换机就连起来了,C1和C3这两个位于不同交换机的容器就可以实现通信。

然而,如果C1和C3不在同一网络中呢?

如果不在同一网络,我们必须通过路由转发才能使其通信,也就是在两台交换机之间添加一个路由器。Linux内核本身支持路由转发,只需启用路由转发功能即可。我们可以启动一个容器,在该容器内运行一个内核,并启用其转发功能,这样就模拟了一台路由器,通过这台路由器实现路由转发。如下图所示:

3、不同节点容器间通信

要实现c1和c5的通信,使用桥接容易产生广播风暴,因此尽量避免使用桥接方式进行通信。

如果既不能使用桥接,又需要与外部实现通信,我们只能使用NAT技术。通过DNAT将容器的端口暴露到宿主机上,通过访问宿主机的端口来实现访问容器内部的目的,而在请求端我们需要做SNAT将数据包通过宿主机的真实网卡转发出去。

由于NAT转换需要两次,因此效率较低。

此时,我们可以采用一种称为Overlay Network(叠加网络)的技术来实现不同节点间容器的相互通信功能。

Overlay Network会将报文进行隧道转发,也就是在报文发出去之前为其添加一个IP首部,如上图中的1.1和1.2部分,这里的1.1是源,1.2是目标。当宿主机2收到报文后解封装,发现目标容器是C2,于是将包转发给C2。


# linux  # docker  # ai  # 解封  # red  # 封装  # 接口  #   # Namespace  # 虚拟化  # 所示  # 我们可以  # 如下图  # 一台  # 来实现  # 机上  # 二层  # 是在  # 也就  # 这两个 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 如何在万网利用已有域名快速建站?  Python文本处理实践_日志清洗解析【指导】  韩国服务器如何优化跨境访问实现高效连接?  简单实现jsp分页  JavaScript如何实现类型判断_typeof和instanceof有什么区别  javascript基于原型链的继承及call和apply函数用法分析  制作旅游网站html,怎样注册旅游网站?  如何实现建站之星域名转发设置?  青岛网站建设如何选择本地服务器?  如何快速搭建自助建站会员专属系统?  Laravel怎么使用artisan命令缓存配置和视图  如何将凡科建站内容保存为本地文件?  Laravel怎么自定义错误页面_Laravel修改404和500页面模板  Laravel如何处理CORS跨域请求?(配置示例)  如何快速生成橙子建站落地页链接?  西安专业网站制作公司有哪些,陕西省建行官方网站?  香港代理服务器配置指南:高匿IP选择、跨境加速与SEO优化技巧  Laravel如何集成微信支付SDK_Laravel使用yansongda-pay实现扫码支付【实战】  网站图片在线制作软件,怎么在图片上做链接?  Laravel怎么配置.env环境变量_Laravel生产环境敏感数据保护与读取【方法】  Laravel怎么使用Blade模板引擎_Laravel模板继承与Component组件复用【手册】  Javascript中的事件循环是如何工作的_如何利用Javascript事件循环优化异步代码?  JS中页面与页面之间超链接跳转中文乱码问题的解决办法  laravel怎么为API路由添加签名中间件保护_laravel API路由签名中间件保护方法  怎么用AI帮你为初创公司进行市场定位分析?  浅析上传头像示例及其注意事项  Laravel路由怎么定义_Laravel核心路由系统完全入门指南  使用C语言编写圣诞表白程序  Java遍历集合的三种方式  制作无缝贴图网站有哪些,3dmax无缝贴图怎么调?  Laravel怎么使用Collection集合方法_Laravel数组操作高级函数pluck与map【手册】  制作公司内部网站有哪些,内网如何建网站?  Laravel怎么实现前端Toast弹窗提示_Laravel Session闪存数据Flash传递给前端【方法】  微博html5版本怎么弄发语音微博_语音录制入口及时长限制操作【教程】  如何在腾讯云免费申请建站?  Java垃圾回收器的方法和原理总结  微信小程序 五星评分(包括半颗星评分)实例代码  如何快速生成可下载的建站源码工具?  Laravel如何实现登录错误次数限制_Laravel自带LoginThrottles限流配置【方法】  Laravel Eloquent关联是什么_Laravel模型一对一与一对多关系精讲  Laravel怎么做缓存_Laravel Cache系统提升应用速度的策略与技巧  常州企业网站制作公司,全国继续教育网怎么登录?  Laravel如何保护应用免受CSRF攻击?(原理和示例)  微信公众帐号开发教程之图文消息全攻略  手机怎么制作网站教程步骤,手机怎么做自己的网页链接?  如何在万网自助建站中设置域名及备案?  Laravel如何设置定时任务(Cron Job)_Laravel调度器与任务计划配置  Python数据仓库与ETL构建实战_Airflow调度流程详解  Mybatis 中的insertOrUpdate操作  INTERNET浏览器怎样恢复关闭标签页_INTERNET浏览器标签恢复快捷键与方法【指南】