前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >没能躲开的云服务容器网络问题

没能躲开的云服务容器网络问题

作者头像
soulteary
发布2020-12-16 11:46:20
9340
发布2020-12-16 11:46:20
举报

没能躲开的云服务容器网络问题

遇到一个诡异的问题,在固定的 VPC 环境里运行了一年的 ECS 机器,突然连不上 RDS 数据库,而这个问题在早些时候,也曾在另外一台机器上出现过。

为了避免后续在业务日常运行和重大活动过程中出现类似问题,我们和阿里云进行了反馈,并进行的排查。

写在前面

由于同一业务分组的几台机器中,有两台(暂命名为 host-prehost-01)都出现了这个问题,所以我们将同一业务分组的几台机器同时作为样本进行问题排查。

在解决问题过程的时候,我们首先收集了基础环境的相关线索:

  • 机器运行应用均为无状态容器,没有持久化内容存在。
  • 被测试的机器均处于相同 VPC 环境内,为避免容器网络问题,2019 年初始化 VPC 时使用了比较不容易撞车的 192.168.73.x 网段。。
  • 机器、数据库都没有关闭 ICMP。
  • 机器的安全策略组允许访问 RDS。
  • 机器在数据库白名单之内。
  • 这几台机器都是于去年购买,在一个月前执行过系统版本和软件升级。
  • 这几台机器在半年前执行过硬件配置升降级。

问题状况:连不通的数据库

分别使用服务器对数据库进行 ping

代码语言:javascript
复制
ssh host-pre ping rm-intra.mysql.rds.aliyuncs.com
PING rm-intra.mysql.rds.aliyuncs.com (192.168.0.166) 56(84) bytes of data.
From host-pre (192.168.0.1) icmp_seq=1 Destination Host Unreachable
From host-pre (192.168.0.1) icmp_seq=2 Destination Host Unreachable
From host-pre (192.168.0.1) icmp_seq=3 Destination Host Unreachable

ssh host-01 ping rm-intra.mysql.rds.aliyuncs.com
PING rm-intra.mysql.rds.aliyuncs.com (192.168.0.166) 56(84) bytes of data.
64 bytes from 192.168.0.166 (192.168.0.166): icmp_seq=1 ttl=102 time=1.11 ms
64 bytes from 192.168.0.166 (192.168.0.166): icmp_seq=2 ttl=102 time=1.09 ms
64 bytes from 192.168.0.166 (192.168.0.166): icmp_seq=3 ttl=102 time=1.12 ms

ssh host-02 ping rm-intra.mysql.rds.aliyuncs.com
PING rm-intra.mysql.rds.aliyuncs.com (192.168.0.166) 56(84) bytes of data.
64 bytes from 192.168.0.166 (192.168.0.166): icmp_seq=1 ttl=102 time=0.992 ms
64 bytes from 192.168.0.166 (192.168.0.166): icmp_seq=2 ttl=102 time=0.994 ms
64 bytes from 192.168.0.166 (192.168.0.166): icmp_seq=3 ttl=102 time=0.977 ms

ssh host-03 ping rm-intra.mysql.rds.aliyuncs.com
PING rm-intra.mysql.rds.aliyuncs.com (192.168.0.166) 56(84) bytes of data.
64 bytes from 192.168.0.166 (192.168.0.166): icmp_seq=1 ttl=102 time=1.07 ms
64 bytes from 192.168.0.166 (192.168.0.166): icmp_seq=2 ttl=102 time=1.07 ms
64 bytes from 192.168.0.166 (192.168.0.166): icmp_seq=3 ttl=102 time=1.04 ms

发现只有第一台 host-pre 出现了 Destination Host Unreachable,其余几台均正常。host-01 在早些时候也出现过相同的问题。

登录服务器:进一步探查问题

既然 host-pre 出现问题,我们就先来排查下它的容器运行状况是否出现问题。登录机器 ,忽略掉最近更新变动的应用,可以看到机器上目前运行最久的应用的启动时间是七个月前,分别使用 exec ,以及 curl 请求本地服务,都有正常的反馈,所以首先可以排除是容器应用自身的问题。

代码语言:javascript
复制
docker ps -a

...
c092f8c5f41e        docker.dev.baai.ac.cn/nesletter-api:0.9.1         "docker-php-entrypoi…"   4 months ago        Up 4 months (healthy)   9000/tcp             newsletter-api
ed0c7fb1945f        docker.dev.baai.ac.cn/hub-node-gate:14            "docker-entrypoint.s…"   4 months ago        Up 4 months             3000/tcp             xxxxx_1
7aba2cbc2e21        traefik:v2.2.0                                    "/entrypoint.sh trae…"   5 months ago        Up 5 months (healthy)   0.0.0.0:80->80/tcp   traefik
1a9e0a150133        xxx:4.7.6-xxx                          "entrypoint.sh docke…"   7 months ago        Up 7 months             8080/tcp             xxx_1

接着我们试着在 host-pre 上 ping 其他的服务器,发现也是正常的,所以 VPC 网络内的连通性也是没有问题的,那么问题应该是出现在了 “ECS 或 VPC 到 RDS” 的网络被“阻塞”了。

排查路由表:定位问题

随后,阿里云 ECS 的工程师建议我们进行路由表的排查,于是我们分别在几台机器上查看了路由规则状况:

代码语言:javascript
复制
ssh host-pre route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.73.253  0.0.0.0         UG    100    0        0 eth0
172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 docker0
172.18.0.0      0.0.0.0         255.255.0.0     U     0      0        0 br-df03b027a5e8
192.168.0.0     0.0.0.0         255.255.240.0   U     0      0        0 br-c3c094fc6759
192.168.73.0    0.0.0.0         255.255.255.0   U     0      0        0 eth0
192.168.73.253  0.0.0.0         255.255.255.255 UH    100    0        0 eth0

ssh host-01 route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.73.253  0.0.0.0         UG    100    0        0 eth0
172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 docker0
172.18.0.0      0.0.0.0         255.255.0.0     U     0      0        0 br-0cb13ae8df3c
192.168.32.0    0.0.0.0         255.255.240.0   U     0      0        0 br-bb02c47906ee
192.168.73.0    0.0.0.0         255.255.255.0   U     0      0        0 eth0
192.168.73.253  0.0.0.0         255.255.255.255 UH    100    0        0 eth0

ssh host-02 route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.73.253  0.0.0.0         UG    100    0        0 eth0
172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 docker0
172.18.0.0      0.0.0.0         255.255.0.0     U     0      0        0 br-405544233f47
172.28.0.0      0.0.0.0         255.255.0.0     U     0      0        0 br-f11216ce202f
192.168.73.0    0.0.0.0         255.255.255.0   U     0      0        0 eth0
192.168.73.253  0.0.0.0         255.255.255.255 UH    100    0        0 eth0

ssh host-03 route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.73.253  0.0.0.0         UG    100    0        0 eth0
172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 docker0
172.18.0.0      0.0.0.0         255.255.0.0     U     0      0        0 br-df03b027a5e8
172.19.0.0      0.0.0.0         255.255.255.0   U     0      0        0 br-5089b1504e22
192.168.73.0    0.0.0.0         255.255.255.0   U     0      0        0 eth0
192.168.73.253  0.0.0.0         255.255.255.255 UH    100    0        0 eth0

可以看到机器基础 VPC 网络都在 192.168.73.1/24 段内,唯一有差别的是 docker 创建的桥接网卡。

host-02host-03 的网卡指定网段都在 172.27~30.1.1/8 内,而 host-01host-pre 的网卡则出现了两张在 192.168.x.x 的网卡:

代码语言:javascript
复制
host-pre
192.168.0.0     0.0.0.0         255.255.240.0   U     0      0        0 br-c3c094fc6759

host-01
192.168.32.0    0.0.0.0         255.255.240.0   U     0      0        0 br-bb02c47906ee

看到路由表之后,阿里云工程师反馈网络冲突了,第一反应确实如此,因为在排查连通性的时候,我们确实看到了当前连接 RDS 的地址是 192.168.0.xxx 的远程地址。但是随后我们又想到了一个问题,为什么这个问题现在才出现,或者说,为什么之前的业务运行没有受到影响呢?

此时阿里云工程师提示我们“RDS 实例IP地址可能发生变化,连接串则始终不变,请使用以上连接串进行实例连接。”

到了这个时候,答案呼之欲出:容器创建应用内部桥接网卡的网段和阿里云 RDS 网络撞车了。 虽然概率很小,但是它确实出现了,因为 CI/CD 过程中容器会随机创建新的应用内部网卡,赶巧和 RDS 网络切换后的地址撞在了一起,就会出现这个问题。

和阿里云工程师沟通确认 “ 192.168.0.0/16 是 RDS 所在 VPC 的网段”后,就可以放心动手解决问题了。

解决问题:修改容器网卡地址分配规则

登录 host-pre ,先再次打印路由表,以及查看容器创建的网卡列表:

代码语言:javascript
复制
host-pre:~# route -n 
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.73.253  0.0.0.0         UG    100    0        0 eth0
172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 docker0
172.18.0.0      0.0.0.0         255.255.0.0     U     0      0        0 br-df03b027a5e8
192.168.0.0     0.0.0.0         255.255.240.0   U     0      0        0 br-c3c094fc6759
192.168.73.0    0.0.0.0         255.255.255.0   U     0      0        0 eth0
192.168.73.253  0.0.0.0         255.255.255.255 UH    100    0        0 eth0

host-pre:~# docker network ls
NETWORK ID          NAME                            DRIVER              SCOPE
0fba8dbbbff8        bridge                          bridge              local
8b92ba96f640        host                            host                local
c3c094fc6759        project-grpup_project-name      bridge              local
123b8780367b        none                            null                local
df03b027a5e8        traefik                         bridge              local

可以看到 br-c3c094fc6759 这个网卡在 docker 中命名为 c3c094fc6759,是由 project-grpup_project-name 这个项目创建,使用的网络段确实是和 RDS 发生了冲突。

通过查看 docker 官方文档,我们可以找到我们需要的 daemon 配置项 default-address-pools,来主动规避掉和阿里云 RDS 网络冲突的问题。

修改 /etc/docker/daemon.json ,声明和 192.168.0.0/16 不冲突的地址:

代码语言:javascript
复制
{
 ...
    "default-address-pools": [
        {
            "base": "172.18.0.0/16",
            "size": 24
        },
        {
            "base": "172.19.0.0/16",
            "size": 24
        },
        {
            "base": "172.20.0.0/16",
            "size": 24
        },
        {
            "base": "172.21.0.0/16",
            "size": 24
        },
        {
            "base": "172.22.0.0/16",
            "size": 24
        },
  ...
    ]
}

在修改配置后,执行 service docker restart,接着重新启动应用,触发重新创建内部网卡逻辑,然后再次查看容器网卡列表:

代码语言:javascript
复制
docker network ls
NETWORK ID          NAME                            DRIVER              SCOPE
52a7bbc2b5fe        bridge                          bridge              local
8b92ba96f640        host                            host                local
5089b1504e22        project-grpup_project-name      bridge              local
123b8780367b        none                            null                local
df03b027a5e8        traefik                         bridge              local

看到创建的新网卡为 5089b1504e22,我们使用 inspect 检查网卡分配网络:

代码语言:javascript
复制
docker inspect 5089b1504e22 --format='{{json .IPAM.Config}}'
[{"Subnet":"172.19.0.0/24","Gateway":"172.19.0.1"}]

可以看到分配网络与我们预期一致,规避了 192.168.0.0/16 ,至此问题解决。

最后

如同“墨菲定律”所言,凡是可能出错的事情就一定会出错。

为了避免出错,靠谱的方案是:彻底查出可能出现事故的问题所在和根本原因,对其进行标本兼治的方案,才能防患于未然。

--EOF


我现在有一个小小的折腾群,里面聚集了一些喜欢折腾的小伙伴。

在不发广告的情况下,我们在里面会一起聊聊软件、HomeLab、编程上的一些问题,也会在群里不定期的分享一些技术沙龙的资料。

喜欢折腾的小伙伴欢迎扫码添加好友。(请注明来源和目的,否则不会通过审核)

关于折腾群入群的那些事


本文使用「署名 4.0 国际 (CC BY 4.0)」许可协议,欢迎转载、或重新修改使用,但需要注明来源。署名 4.0 国际 (CC BY 4.0)

本文作者: 苏洋

创建时间: 2020年12月04日 统计字数: 6281字 阅读时间: 13分钟阅读 本文链接: https://soulteary.com/2020/12/04/cloud-service-container-network-problems-that-could-not-be-avoided.html

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-12-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 折腾技术 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 没能躲开的云服务容器网络问题
    • 写在前面
      • 问题状况:连不通的数据库
        • 登录服务器:进一步探查问题
          • 排查路由表:定位问题
            • 解决问题:修改容器网卡地址分配规则
              • 最后
              相关产品与服务
              私有网络
              私有网络(Virtual Private Cloud,VPC)是基于腾讯云构建的专属云上网络空间,为您在腾讯云上的资源提供网络服务,不同私有网络间完全逻辑隔离。作为您在云上的专属网络空间,您可以通过软件定义网络的方式管理您的私有网络 VPC,实现 IP 地址、子网、路由表、网络 ACL 、流日志等功能的配置管理。私有网络还支持多种方式连接 Internet,如弹性 IP 、NAT 网关等。同时,您也可以通过 VPN 连接或专线接入连通腾讯云与您本地的数据中心,灵活构建混合云。
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档