Linux虚拟网络:Docker网络知识之基础篇
我们在工作中应用了docker容器化技术,服务的部署、维护和扩展都方便了很多。然而,近期在私有化部署过程中,由于不同服务器环境的复杂多变,常常遇到网络方面的问题,现象为容器服务运行正常,但宿主机、容器之间网络不通。
本篇博客旨在总结:
- Linux虚拟网络及docker网络的基础知识
- 遇到网络问题时排查问题思路
- 常用指令和工具的使用
以上三部分作为之后的参考,本篇文章也将会在日后实践过程中逐渐补充。本篇为第一篇,主要介绍基础知识
Linux网络虚拟化基础
Network Namespace
网络命名空间,是Linux 2.6.x内核版本之后提供的功能,主要用于资源的隔离。namespace是实现网络虚拟化的重要功能,使用它,一个Linux系统可以抽象出多个网络子系统,各个子系统都有自己独立的网卡、路由表、iptables、协议栈等网络资源。不管是虚拟机还是容器,运行时仿佛自己都在独立的网络中。
ip netns命令用于完成对ns的各种操作,ip netns exec子命令用于在namespace执行指令。
Veth Pair(Virtual Ethernet Pair)
成对虚拟设备端口。它总是成对出现,一端连着协议栈,一端彼此连着。从其中一个端口发出的数据包,可以直接出现在与它对应的另一个端口上,即使它们在不同的namespace中。

如上图,一对veth-pair直接将两个namespace连接在一起。
- 使用如下图所示命令,测试veth pair功能

Bridge 网桥
veth pair打破了Network Namespace的限制,实现了不同Network Namespace之间的通信。但是veth pair的局限性也很明显,只能实现两个网络接口的通信。
Linux中引入网桥来实现多个网络接口之间的通信,可以将一台机器上的若干接口连通起来。在OSI网络模型中,网桥属于数据链路层。

和网桥相关的操作使用命令brctl,需要先安装bridge-utils工具包。安装指令:
yum install bridge-utils
iptables/Netfilter
Docker网络基础
Docker支持四种网络模式:host模式,container模式,none模式和bridge模式。默认使用的是桥接模式。
使用docker network ls指令可以查看到宿主机上所有的Docker网络:

Bridge 桥接模式
Docker在启动时,默认会自动创建网桥设备docker0,Docker在运行时,守护进程通过docker0为docker的容器提供网络通信服务。
当Docker启动容器时,会创建一对Veth Pair,并将其中一个veth网络设备附加到网桥docker0,另一个加入容器的network namespace中。
根据上一节中关于网桥的定义,我们很容易画出示意图:

由上图可得,容器可以通过网桥互相通信。如果不想使用默认的网桥设备,也可以在启动docker daemon的时候使用 --bridge==BRIDGE参数指定其他网桥。
然而这还不够,Docker容器还需要与外网进行相互通信。这里涉及到NAT相关知识。
- NAT
网络地址转换,就是替换IP报文头部的地址信息。NAT通常部署在一个组织的网络出口位置,通过将内部网络IP地址替换为出口的IP地址,提供公网可达性和上层协议的链接地址。(请参考:NAT相关科普)- SNAT
源地址转换即内网地址向外访问时,发起访问的内网ip地址转换为指定的ip地址(可指定具体的服务以及相应的端口或端口范围),这可以使内网中使用保留ip地址的主机访问外部网络,即内网的多部主机可以通过一个有效的公网ip地址访问外部网络。
使用iptables -t nat -vnL指令查看宿主机NAT表。

查看规则:
2051 125K MASQUERADE all -- * !docker0 172.17.0.0/16 0.0.0.0/0
这条规则就关系着Docker容器与外界的通信,含义为将源地址为172.17.0.0/16的数据包(就是docker容器中发出的数据),如果不是从docker0网卡发出时,做SNAT转换,将IP包的源地址替换为相应网卡的地址。
对于外界来说,从docker容器内发出的请求,和宿主机发出的请求相同。
外界想要访问Docker容器的服务呢?
在启动docker容器时,我们使用 -p参数指定端口,这时其实是在iptables中添加了规则,如下图所示:

DNAT规则,将发送到宿主机的流量转发到真正提供服务的容器IP端口上。
host模式
Docker容器与宿主机使用相同的网络环境,直接使用宿主机的IP和端口及其他网络设备。这样虽然避免了很多桥接带来的网络问题,但同时也容易造成网络环境的混淆和冲突,比如端口被占用等。不推荐。
container
指定与某一容器共享网络。
none
不配置任何网络。
--link
docker容器之间还可以通过--link阐述进行通信,当提供服务的容器只希望个别容器能够访问时,我们可以使用该指令,提供更为高效、安全的连接方式。
小结
对Linux虚拟网络基础知识的简单学习后,有助于理清楚下一步排查问题思路。
下一篇博客将介绍目前遇到问题时的排查思路和解决方案,并列举一些常用工具。
Linux虚拟网络:Docker网络知识之基础篇的更多相关文章
- Docker虚拟化实战学习——基础篇(转)
Docker虚拟化实战学习——基础篇 2018年05月26日 02:17:24 北纬34度停留 阅读数:773更多 个人分类: Docker Docker虚拟化实战和企业案例演练 深入剖析虚拟化技 ...
- Retrofit + RxJava + OkHttp 让网络请求变的简单-基础篇
https://www.jianshu.com/p/5bc866b9cbb9 最近因为手头上的工作做完了,比较闲,想着做一些优化.看到以前用的那一套网络框架添加一个请求比较麻烦,并且比较难用,所以想改 ...
- 新一代Java程序员必学的Docker容器化技术基础篇
Docker概述 **本人博客网站 **IT小神 www.itxiaoshen.com Docker文档官网 Docker是一个用于开发.发布和运行应用程序的开放平台.Docker使您能够将应用程序与 ...
- ESXi5 中克隆Linux虚拟主机的网络配置
虚拟化技术果然非常方便,尤其是windows主机,克隆后在网络管理中改一下IP即可. 但对于Linux来说就有点麻烦,只修改IP还不行,还有MAC地址,网卡指定等,这个规程对应新手来说没有大半天搞不定 ...
- Linux ubuntu下docker容器安装和基础命令
Docker介绍: 云计算就好比大货轮,docker就是集装箱虚拟机虽然可以隔离出很多"子电脑",但占用空间更大,启动更慢,虚拟机软件可能还要花钱(例如VMWare). 而容器技术 ...
- C#网络编程(一)基础篇
简介: C#网络编程API包含在System.Net和System.Net.Sockets命名空间下,大部分网络操作都可以在其中找到相应的类来实现:包括Socket的创建和连接,网络流收发方法的封装, ...
- docker进阶之路-基础篇 | 二:portainer安装与基本使用
转载请注明作者及出处: 作者:银河架构师 原文链接:https://www.cnblogs.com/luas/p/12061755.html 简介 Portainer 是轻量级,跨平台,开源的管理D ...
- docker进阶之路-基础篇 | 一:环境搭建
转载请注明作者及出处: 作者:银河架构师 原文链接:https://www.cnblogs.com/luas/p/12061747.html 一.准备工作 查看内核 Docker 要求 CentOS ...
- cocos2d-x知识巩固-基础篇(1)
有段时间没有学习cocos2dx了,作为新人,自己觉得还是要稳扎稳打,一点点的去积累,梳理好每一个知识点,这样对自己的成长能够有一个更清晰的认识,以便做更好的提高. 从2013年8月开始接触cocos ...
随机推荐
- 面试官:兄弟,说说Java的static关键字吧
读者乙在上一篇我去系列文章里留言说,"我盲猜下一篇标题是,'我去,你竟然不知道 static 关键字'".我只能说乙猜对了一半,像我这么有才华的博主,怎么可能被读者猜中了心思呢,必 ...
- Java实现 LeetCode 773 滑动谜题(BFS)
773. 滑动谜题 在一个 2 x 3 的板上(board)有 5 块砖瓦,用数字 1~5 来表示, 以及一块空缺用 0 来表示. 一次移动定义为选择 0 与一个相邻的数字(上下左右)进行交换. 最终 ...
- Java实现 LeetCode 749 隔离病毒(DFS嵌套)
749. 隔离病毒 病毒扩散得很快,现在你的任务是尽可能地通过安装防火墙来隔离病毒. 假设世界由二维矩阵组成,0 表示该区域未感染病毒,而 1 表示该区域已感染病毒.可以在任意 2 个四方向相邻单元之 ...
- Java实现 蓝桥杯 历届试题 斐波那契
试题 历届试题 斐波那契 资源限制 时间限制:1.0s 内存限制:256.0MB 问题描述 斐波那契数列大家都非常熟悉.它的定义是: f(x) = 1 - (x=1,2) f(x) = f(x-1) ...
- springmvc使用<mvc:default-servlet-handler/>导致的handler失效
使用springmvc时,会在web.xml中配置对所有请求进行拦截 <!-- 配置springmvc拦截的请求--> <servlet-mapping> <servle ...
- Flask g 对象
1.什么是g对象? 在 flask 中,有一个专门用来存储用户信息的 g 对象,g的全称的为global. g 对象在一次请求中的所有的代码的地方,都是可以使用的. 赋值方式 from flask i ...
- 宝塔面板如何有效的清除SSL证书以及缓存
一:关闭SSL 我们先关闭SSL证书,这个大家都会的吧.如图: 二:证书夹 网站配置的证书夹,我们删除掉,如图: 三:寻找SSL证书路径 网站配置里有一路径我们看下:如下 ssl_certificat ...
- 了解JSON Web令牌(JWT)
JSON Web Token(JWT)是目前最流行的跨域身份验证解决方案. (一) 跨域身份验证 Internet服务无法与用户身份验证分开. 用户向服务器发送用户名和密码. 验证服务器后,相关数据( ...
- MATLAB作图之一
问题 在使用MATLAB当中的imagesc作图的时候,如果数据矩阵元素太少,得到的图看起来会很"粗糙"(图1).那么如何得到更为"圆润"的图像呢? A = r ...
- (五)TestNG测试的并发执行详解
原文链接:https://blog.csdn.net/taiyangdao/article/details/52159065 TestNG在执行测试时,默认suitethreadpoolsize=1, ...