[TOC]
背景:在容器网络,docker容器一般都是一个与宿主机不同网段的IP,假设某个docker容器的IP为172.17.0.2,它所在的宿主机的IP为192.168.2.103,那么这个docker容器如何能够ping通公网比如114呢?
本文,我们将介绍连接跟踪是如何使得docker容器能ping通公网的。
首先,在主机103上,docker会在iptables的POSTROUTING链上生成如何的一条规则:
```
$ iptables -t nat -nL POSTROUTING
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
MASQUERADE all -- 172.17.0.0/16 0.0.0.0/0
```
这条规则的意思是,容器的包从宿主机出去的时候,会进行MASQUERADE操作(类似SNAT),也就是说,容器的包从宿主机出去后,源IP变成了宿主机的IP,这样外网回复的包就能到达宿主机。
那么问题又来了,外网回复的包到达宿主机时,目的地址为宿主机的IP,宿主机如何知道把这个包转发给容器呢,而且如何把目的地址转换成容器的IP呢?
这个,就和linux的连接跟踪有关了。
我们从容器中ping一个不通的IP
```
$ ping -c 1 114.114.114.115
```
发送一个ping包后,我们查看连接跟踪表中的内容:
```
$ cat /proc/net/nf_conntrack
ipv4 2 icmp 1 28 src=172.17.0.2 dst=114.114.114.115 type=8 code=0 id=33 [UNREPLIED] src=114.114.114.115 dst=192.168.2.103 type=0 code=0 id=33 mark=0 secctx=system_u:object_r:unlabeled_t:s0 zone=0 use=2
...
```
一般这个文件中会有很多内容,很难找到这一行,所以我们一般用conntrack命令(需要安装conntrack-tools)来过滤:
```
$ conntrack -L --proto icmp --orig-src 172.17.0.2
icmp 1 27 src=172.17.0.2 dst=114.114.114.115 type=8 code=0 id=14 [UNREPLIED] src=114.114.114.115 dst=192.168.2.103 type=0 code=0 id=14 mark=0 secctx=system_u:object_r:unlabeled_t:s0 use=1
```
上面这条记录的意思是:如果宿主机收到了回复包`114.114.114.115 -> 192.168.2.103`,那么要把这个包的转换成`114.114.114.115 -> 172.17.0.2`。
我们来详细地分析一下上面的这一条连接跟踪记录,在这条记录中:
* 第一列`icmp`表示协议,第二列`1`表示协议号
* 第三列表示这条连接跟踪记录的生存时间(TTL),这里只剩27秒了,它的默认值是在`/proc/sys/net/ipv4/netfilter/ip_ct_icmp_timeout`中
* 第四行和第五列表示原始包的源IP与目的IP,`[UNREPLIED]`后面的表示回复包的源IP与目的IP
* 第六、七、八列`type=8 code=0 id=14`以及`[UNREPLIED]`后面几个对应字段是ICMP协议的一些信息。我们举个例子来说明几个字段的用途:
比如我们在容器内同时运行两个ping,那么如何判断回复包是哪个Ping的?请求包中`type=8`表示这是一个`echo request`(即ping发送的包)类型的包,`id=14`表示ping的id为`14`(每个ping命令都会有一个id);回复包中`type=0`表示包的类型为`echo reply`(即ping的回复包)。后半部分的意思是:只有当收到的包,它的协议为ICMP、类型为`echo reply`(`type=0`)、id为`14`,才会把目的地址转换为容器地址
到这里,我们就大概了解,容器为什么能连通外网了。
- 应用层
- HTTP
- Cookie
- Session
- HTTP报文格式
- HTTP的Header字段
- HTTPS
- 简介
- 原理
- RSA加密与解密
- 证书签名与验证
- TLS双向认证
- openssl命令汇总
- DNS
- DNS的记录类型
- DNS的报文格式
- FAQ
- 传输层
- TCP
- CloseWait
- 网络层
- IPv6
- 链路层
- 链接层基础知识
- VLAN
- FAQ
- Linux网络收发包
- 网卡收包
- 网卡发包
- 收发包FAQ
- LVS
- 安装-DR模式
- 基本原理
- Ipvsadm命令
- Netfilter
- Netfilter简介
- 注册钩子函数
- Netfilter中数据包流向
- Iptables的数据结构
- 连接跟踪
- 初识连接跟踪
- 连接跟踪详解
- 连接跟踪数据结构
- 数据包与连接的状态
- NAT
- IPVS
- KubeProxy的IPVS模式
- Linux虚拟网络设备
- 虚拟网络设备简介
- Tap
- VethPair
- Vlan
- Vxlan
- Flannel的VXLAN原理
- Openstack的VXLAN原理
- VXLAN总结
- Bridge
- 给容器设置主机网段IP
- Macvlan
- Ipvlan
- IPIP
- IPIP使用介绍
- IPIP源码分析
- Limdiag网络
- 详细设计
- kubeovn
- IP命令
- Calico
- Calico常见问题
- ARP无响应
- 其他