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实现 LeetCode 718 最长重复子数组(动态规划)
718. 最长重复子数组 给两个整数数组 A 和 B ,返回两个数组中公共的.长度最长的子数组的长度. 示例 1: 输入: A: [1,2,3,2,1] B: [3,2,1,4,7] 输出: 3 解释 ...
- Java实现 LeetCode 427 建立四叉树
427. 建立四叉树 我们想要使用一棵四叉树来储存一个 N x N 的布尔值网络.网络中每一格的值只会是真或假.树的根结点代表整个网络.对于每个结点, 它将被分等成四个孩子结点直到这个区域内的值都是相 ...
- Java实现 LeetCode 208 实现 Trie (前缀树)
208. 实现 Trie (前缀树) 实现一个 Trie (前缀树),包含 insert, search, 和 startsWith 这三个操作. 示例: Trie trie = new Trie() ...
- java实现洛谷P3376【模板】网络最大流
题目描述 如题,给出一个网络图,以及其源点和汇点,求出其网络最大流. 输入格式 第一行包含四个正整数N.M.S.T,分别表示点的个数.有向边的个数.源点序号.汇点序号. 接下来M行每行包含三个正整数u ...
- Python报错:SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in position 2-3: truncated \UXXXXXXXX escape
运行python文件的时候报错: SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in position 2 ...
- Windows环境下PHP安装pthreads多线程扩展
一.判断PHP是ts还是nts版 通过phpinfo(); 查看其中的 Thread Safety 项,这个项目就是查看是否是线程安全,如果是:enabled,一般来说应该是ts版,否则是nts版. ...
- 防止暴力破解-DenyHosts应用
当你的linux服务器暴露在互联网之中,该服务器将会遭到互联网上的扫描软件进行扫描,并试图猜测SSH登录口令. 你会发现,每天会有多条SSH登录失败纪录.那些扫描工具将对你的服务器构成威胁,你必须 ...
- 安装 zabbix
目标在centos8下安装部署zabbix 4.4 zabbix介绍zabbix由2部分构成,zabbix server与可选组件zabbix agent.zabbix server可以通过SNMP, ...
- 获取ul下面最后一个li或ul中有多少个li
获取ul下面最后一个li或ul中有多少个li 先获取ul的对象,再通过这个对象获取li的list用for循环取值text之类的 def set_city(self, base_info): quali ...
- 键盘侠Linux教程(四)| 常用命令
前言 Linux命令并不可怕,只要熟悉日常的操作命令即可,其他不熟悉的命令,需要用到的时候可以查阅资料,熟能生巧. Linux常用操作命令 命令的基本格式 命令的提示符 [root@localhost ...