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 ...
随机推荐
- 这才是你需要的最基础的.Net基础面试题(通俗易懂,最基础的.Net)2
51. 委托回调静态方法和实例方法有何区别? 当一个实例方法被调用时,需要通过实例对象来访问,绑定一个实例方法到委托必须同时让委托得到实例方法的代码段和实例对象的信息,这样在委托被回调时候.NET才能 ...
- (Java实现)洛谷 P2095 营养膳食
题目描述 Mr.L正在完成自己的增肥计划. 为了增肥,Mr.L希望吃到更多的脂肪.然而也不能只吃高脂肪食品,那样的话就会导致缺少其他营养.Mr.L通过研究发现:真正的营养膳食规定某类食品不宜一次性吃超 ...
- Java实现 LeetCode 373 查找和最小的K对数字
373. 查找和最小的K对数字 给定两个以升序排列的整形数组 nums1 和 nums2, 以及一个整数 k. 定义一对值 (u,v),其中第一个元素来自 nums1,第二个元素来自 nums2. 找 ...
- java实现南北朝时
南北朝时,我国数学家祖冲之首先把圆周率值计算到小数点后六位,比欧洲早了 1100 年! 他采用的是称为"割圆法"的算法,实际上已经蕴含着现代微积分的思想. 如图[1.jpg]所示, ...
- Python脚本批量修改服务器密码
搭建环境 centos 7.4 使用脚本 python 批量修改connect用户的密码 生成密码为随机密码 保存为xls文档 passwd_chang #!/usr/bin/env python ...
- 4k壁纸
4k
- 实验二 Linux系统简单文件操作命令
项目 内容 这个作业属于哪个课程 班级课程的主页链接 这个作业的要求在哪里 作业要求链接接地址 学号-姓名 17041428-朱槐健 作业学习目标 1.学习在Linux系统终端下进行命令行操作 2.掌 ...
- x memory pool c语言 内存池
#ifndef X_MEMORY_H #define X_MEMORY_H #include <stdlib.h> #include <stdio.h> #include &l ...
- kafka架构、基本术语、消息存储结构
1.kafka架构 kafka处理消息大概流程 生产者发送消息给kafka服务器 消费者从kafka服务器(broker)读取消息 kafka服务器依靠zookeeper集群进行服务协调管理 2.ka ...
- Java学习之IO流及网络编程
一.字节 1.1字节输入流(java.io.InputStream) 此抽象类是表示字节输入流的所有类的超类 1.1.1定义了所有子类共性的方法: int read() 从输入流中读取数据的下 ...