k8s线上集群的机器,重启iptables后,造成CI系统(drone)构建偶发失败,docker run容器无法访问外网问题排查记录

引子:

线上的k8s集群内部,每一台机器,都有2块网卡,一块儿em1(10网段),一个 em2(192网段)。然后,线上的机器,通过iptables限制为:访问192段的服务任意端口都是畅通的,而访问10段的服务端口,只有333端口可以连通。333端口,是线上机器的ssh端口。

线上集群的k8s,使用的calico网络。

线上有一个问题,就是容器访问当前宿主机192段IP的999端口不通,访问其他机器192段IP的9999端口畅通。

我们知道,当从容器访问宿主机的应用时,会重新进入iptables的INPUT链,而线上的iptables INPUT链如下:

Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination         
1    1477K 2519M cali-INPUT  all  --  *      *       0.0.0.0/0            0.0.0.0/0            /* cali:Cz_u1IQiXIMmKD4c */
2     272K   20M KUBE-SERVICES  all  --  *      *       0.0.0.0/0            0.0.0.0/0            /* kubernetes service portals */
3     273K   20M KUBE-FIREWALL  all  --  *      *       0.0.0.0/0            0.0.0.0/0           
4     263K   20M ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            state RELATED,ESTABLISHED
5        0     0 ACCEPT     icmp --  *      *       0.0.0.0/0            0.0.0.0/0           
6      393 17292 ACCEPT     all  --  lo     *       0.0.0.0/0            0.0.0.0/0           
7    11880 1019K ACCEPT     all  --  em2    *       0.0.0.0/0            0.0.0.0/0           
8        7   308 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:333
9     228 62052 REJECT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            reject-with icmp-host-prohibited

意思是:

①:如果报文是途径em2网卡,访问任意其他网卡。则全部放行。(这就是为什么192段的访问全部放行)

②:如果报文是tcp,不管报文从哪个网卡出来,去往哪个网卡,只要目的端口是333,就放行。(这就是为什么10段的访问,只能访问333)

我们容器发出的报文,网卡是 cal 网卡(calico的网卡名称),所以,容器只能访问333。

错误操作:

要把9999端口放开,意味着,我要添加开放9999端口到INPUT链路中,为了让iptables再重启后依然生效,我将规则,添加到

/etc/sysconfig/iptables

在添加完成后其实并未生效,然后,有2种方式,用于让iptables生效:

①:手动添加规则,比如 iptables -t filter -I INPUT 9 -s 172.20.0.0/14 -p tcp -m tcp --dport 9999 -j ACCEPT

②:重启iptables(会自动加载 /etc/sysconfig/iptables内容 )

我选择了后者,之所以选择后者,其实是因为,即便重启了iptables,加载了刚刚的规则,原来的k8s和calico的iptables会丢失,但是,k8s会重建自己的整套iptables规则的。

事实上,k8s确实也在我重启iptables后,重建了iptables,但问题来了。

引发的2个网络问题:

1、我们线上的CI系统,是基于drone,做的二次开发,改动了很多的东西,添加了很多特性,结果上面一系列操作之后,我发现,我们的CI系统中,个别镜像的构建(Dockerfile中的RUN操作,有网络相关操作时,比如yum)会失败。

2、线上的机器,执行 docker run,起来的容器,无法访问外网了。然而,k8s起来的pod里的容器,却可以访问外网。

镜像的构建,其实本质上,也是起容器来做事情,而且,你无法定制docker build操作时,使用的网络模式,只能是bridge模式。而 docker run 起来的容器,默认也是 bridge 模式。结合上面2个内容,基本上可以确定,此问题,和k8s无关,而是纯粹的docker的问题了。

排查:

①:一开始以为是k8s的iptables重建不完整,所以,多次用线上的机器的机器 nodeA(无人访问的一台),不断尝试清空iptables,等待k8s重建iptables,多次尝试无效。

②:stop docker -> stop kubelet -> clean iptables -> start docker -> start kubelet。这个操作的意义是,以为重启docker,重启k8s,docker 和 k8s 都会重建自己的 iptables。多次尝试无效。

③:使用现在的k8s安装工具:kubespray,重新安装 nodeA,并添加到k8s集群内。寄希望于安装工具重装docker和k8s,结果依然无效。

④:回归问题本身,问题一定出在iptables上。也是因为一开始重启了iptables导致此一系列问题。

解决过程:

既然问题出在iptables上,而我们要访问外网,那么,就得重iptables 报文转出入手。好在线上的机器,并没有都为了适配9999端口重启iptables,有3台 k8s 的 master 节点,并没有重启 iptables。

然后,对比有问题机器、没有问题机器的 FORWARD、POSTROUTING 的规则。发现,缺少DOCKER相关的规则,这些规则,本来是安装docker之后,由docker创建的。那么,解决此问题,就需要重建docker的iptables。

①:找一台干净的机器(只安装了docker,未启动容器,为安装k8s),然后从中提取docker相关的规则

②:将提取的规则,与出问题的机器的iptables默认规则融合。

③:执行 iptables-restore 恢复规则。

后续验证:

在问题机器上,docker run centos 容器,然后ping qq.com,链路畅通。有一个小问题,就是如果你先启动的容器执行 ping 外网操作。然后才再目的机器上执行 iptables-restore 的话,会发现,容器的 ping,有一个短暂的耗时,然后才会畅通,这是因为 iptables-restore 恢复规则后,有一个过程。

最后:

我整理一个相对标准的docker iptables规则备份,如果你也遇到了启动的docker容器,无法访问外网的问题,可以通过下面的内容,恢复规则

将下面的规则,保存到一个文件,比如 docker-iptables-backup

# Generated by iptables-save v1.4.21 on Thu Apr 30 20:48:42 2015
*nat
:PREROUTING ACCEPT [18:1080]
:INPUT ACCEPT [18:1080]
:OUTPUT ACCEPT [22:1550]
:POSTROUTING ACCEPT [22:1550]
:DOCKER - [0:0]
-A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
-A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER
-A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE
-A POSTROUTING -s 172.17.0.1/32 -d 172.17.0.1/32 -p tcp -m tcp --dport 80 -j MASQUERADE
-A DOCKER ! -i docker0 -p tcp -m tcp --dport 3001 -j DNAT --to-destination 172.17.0.1:80
COMMIT
# Completed on Thu Apr 30 20:48:42 2015
# Generated by iptables-save v1.4.21 on Thu Apr 30 20:48:42 2015
*filter
:INPUT ACCEPT [495:53218]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [480:89217]
:DOCKER - [0:0]
-A FORWARD -o docker0 -j DOCKER
-A FORWARD -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -i docker0 ! -o docker0 -j ACCEPT
-A FORWARD -i docker0 -o docker0 -j ACCEPT
-A DOCKER -d 172.17.0.1/32 ! -i docker0 -o docker0 -p tcp -m tcp --dport 80 -j ACCEPT
COMMIT
# Completed on Thu Apr 30 20:48:42 2015

然后,执行恢复 iptables-restore docker-iptables-backup

注意:

①:如果你的docker在k8s集群内部,理论上来说,上面的操作会有清空iptables的能力,但是你不需要担心,因为k8s会自行修复本身的iptables,也就是说,k8s会重建自己的iptables。但是假如你的k8s没能完整重建,就需要手动恢复k8s的iptables。如果是calico网络,只需要删除当前节点的calico pod即可,删除之后,k8s会重启这个pod,自然也就会重建iptables了。同理,flannel网络也是一样的。

②:上面的规则,有一个关键,是 172.17.0.0 和 172.17.0.1,这是docker默认安装后的网段和docker0网卡的IP。如果你是默认安装的docker,上面的规则不需要改动,但如果你定制了docker0网卡的IP,记得修改一下上面的规则,适配你的环境。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,165评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,720评论 1 298
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,849评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,245评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,596评论 3 288
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,747评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,977评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,708评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,448评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,657评论 2 249
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,141评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,493评论 3 258
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,153评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,108评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,890评论 0 198
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,799评论 2 277
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,685评论 2 272