Docker 容器虚拟化
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: <LOOPBACK,UP,LOWER_UP> 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: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> 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: <BROADCAST,MULTICAST,UP,LOWER_UP> 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内核级支持2种级别设备的模拟,一种是二层设备(交换机),一种是三层设备(路由器)。
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: <LOOPBACK,UP,LOWER_UP> 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: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> 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: <LOOPBACK,UP,LOWER_UP> 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: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> 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。
Docker 容器虚拟化的更多相关文章
- 【linxu】部署docker容器虚拟化平台
实验所涉内容 Docker 概述 部署 docker 容器虚拟化平台 docker 平台基本使用方法 创建docker镜像和发布镜像方法 Container 容器端口映射 一 Docker 概述 Do ...
- Linux高级运维 第八章 部署docker容器虚拟化平台
8.1 Docker概述 实验环境: CENTOS7.4-63 64位 Dcoker概述 Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到 ...
- Docker容器虚拟化
Docker容器虚拟化 目录 Docker容器虚拟化 虚拟化网络 单节点容器间通信 不同节点容器间通信 虚拟化网络 Network Namespace 是 Linux 内核提供的功能,是实现网络虚拟化 ...
- docker容器虚拟化技术
简单来说,在Windows系统下安装各种运行环境的坑简直不要太多了(● ̄(エ) ̄●),并不仅限于docker.Nginx.PHP.Python等等,我会尽详细写出实际过程中遇到的各种各样的奇葩问题 1 ...
- Docker 学习4 Docker容器虚拟化网络概述
一.docker 虚拟化网络概述 1.OVS: OpenVSwitch,不仅能模拟二层网络,还能模拟三层网络,或者VLAN,VXLAN,流控 SDN软件定义网络技术等. 2.overlay netwo ...
- docker(二)部署docker容器虚拟化平台
yum安装方法参考:https://www.cnblogs.com/yufeng218/p/8370670.html https://www.cnblogs.com/straycats/p/84112 ...
- docker容器虚拟化网络
linux内核支持六种名称空间 1.主机名和域名 -------> UTS 2.用户 --------> User 3.文件挂载系统 -------> mount 4. ...
- docker容器日志收集方案汇总评价总结
docker日志收集方案有太多,下面截图罗列docker官方给的日志收集方案(详细请转docker官方文档).很多方案都不适合我们下面的系列文章没有说. 经过以下5篇博客的叙述简单说下docker容器 ...
- Docker容器(一)——Docker的介绍与部署
(1).Docker概述 Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的Linux或Windows机器上,也可以实现虚拟化.容器是 ...
随机推荐
- 浅析kubernetes中client-go structure01
Prepare Introduction 从2016年8月起,Kubernetes官方提取了与Kubernetes相关的核心源代码,形成了一个独立的项目,即client-go,作为官方提供的go客户端 ...
- 每天一个 HTTP 状态码 103
103 Early Hints 103 Earyly Hints 是被用于在最终 HTTP 消息前返回一些响应头,常和 HTTP Header: Link 一起使用,让客户端在服务器还在准备(当前的这 ...
- 使用docker创建和运行跨平台的容器化的mssql数据库
我们一般启用sql server数据库要么选择安装SQL Server实例和管理工具(SSMS),要么用vs自带的数据库.如今net跨平台成为趋势,今天给大家介绍另一种我最近在玩的方式,即使用dock ...
- Python使用EasyOCR库对行程码图片进行OCR文字识别介绍与实践
关注「WeiyiGeek」点我,点我 设为「特别关注」,每天带你在B站玩转网络安全运维.应用开发.物联网IOT学习! 希望各位看友[关注.点赞.评论.收藏.投币],助力每一个梦想. 文章目录 0x00 ...
- redis客户端打不开 提示cannot connect to server dev.check log for details
我当前状况是redis客户端打不开,之前一直好好的(虽然作为一个程序员我不配说这句话,哈哈),但是我排查了我觉得所有的可能性,我用的阿里云的redis(还没有到购买到期时间),然后我就关闭了防火墙,你 ...
- SQL Server 2008~2019版本序列号/密钥/激活码 汇总
SQL Server 2019 Enterprise:HMWJ3-KY3J2-NMVD7-KG4JR-X2G8G Strandard:PMBDC-FXVM3-T777P-N4FY8-PKFF4 SQL ...
- 获取mybatis注解方式新增数据时非自增插入的主键
场景:插入数据的时候,获取不到非自增的主键.原因:对象中没有主键的值,插入后主键才有值. 解决方案:使用 @SelectKey @SelectKey中: statement是要运行的SQL语句,即查询 ...
- jenkins安装配置及发布
1. yum install -y lrzsz vim net-tools 2. 下载jdk-8u131-linux-x64.tar.gz http://www.oracle.com/technetw ...
- 【python基础】第08回 流程控制 for循环
本章内容概要 1.循环结构之 for 循环 本章内容详解 1.循环结构之for循环 1.1 语法结构 for 变量名 in 可迭代对象: #字符串 列表 字典 元组 for 循环的循环体代码 针对变量 ...
- 使用.NetCore自带的后台作业,出入队简单模拟生产者消费者处理请求响应的数据
环境:Core:3.1的项目 说明:由于该方案为个人测试项目,重启时队列中的部分数据很可能会丢失, 对数据有要求的该方案不适用,不能照搬需要持久化处理, 另外发布到Linux Docker中通常不会自 ...