今天,咱们来聊一个对于许多刚接触AWS的运维同学来说,既常见又有点头疼的话题:如何优雅地排查和解决AWS上ALB(Application Load Balancer)暴露EC2服务时遇到的种种疑难杂症。
最近,我刚帮一个朋友解决了类似的问题,他遇到的坑,我相信许多aws韵味朋友可能也踩过。结合他的案例和我的经验,我整理出了一套清晰的故障定位思路和关键检查点。希望这篇文章能成为大家云上运维工具箱里的一件利器。
从宏观到微观:理解ALB的工作流
在深入细节之前,我们先来建立一个全局视野。当一个用户通过互联网访问我们的服务时,请求的旅程是怎样的?下图清晰地展示了从用户到EC2服务的完整路径,以及我们接下来要讨论的关键检查点。
这个流程图就像一张地图,当我们遇到“服务访问不了”这类问题时,按图索骥,逐一排查,就能快速定位问题所在。
故障排查实战:七个关键检查点
下面,我们来详细拆解朋友总结的七个关键点,这也是一套行之有效的故障排查清单。
1. EC2安全组:为服务敞开对内的大门
很多新手或懒鬼会下意识地把EC2安全组的入站规则设置为对所有IP(0.0.0.0/0)开放,这虽然能让服务跑起来,但存在巨大的安全隐患。
正确的做法是,EC2实例的安全组(Security Group)应该只允许来自ALB所在安全组的流量。这是一个最小权限原则的最佳实践。
如何配置:
- 找到我们的ALB,记下它的安全组ID(例如
sg-alb12345
)。 - 进入我们的EC2实例的安全组配置页面。
- 添加入站规则:
- 类型/协议: 选择我们的服务使用的协议和端口(例如,HTTP/80端口,或我们自定义的8080端口)。
- 源: 选择“自定义”,然后输入ALB的安全组ID
sg-alb12345
。
- 找到我们的ALB,记下它的安全组ID(例如
常见错误: 源地址错误地配置为ALB的公网IP。请记住,ALB与EC2之间是通过私有IP通信的,并且ALB节点的IP可能会变化,因此引用安全组是最稳定可靠的方式。
2. ALB安全组:对外开放服务的窗口
与EC2安全组的“对内”不同,ALB的安全组需要“对外”,即允许来自最终用户的访问。
如何配置:
- 入站规则:
- 类型/协议: 通常是HTTP(80端口)和/或HTTPS(443端口)。
- 源: 一般设置为
0.0.0.0/0
,表示允许来自任何互联网用户的访问。如果我们的服务只对特定IP开放,可以在这里做限制。
- 出站规则: 默认情况下,出站规则是允许所有流量,这通常不需要修改。
- 入站规则:
实用建议: 将ALB的安全组和EC2的安全组分开管理,职责清晰,一个负责对外,一个负责对内,能有效降低配置错误的风险。
3. 健康检查:ALB的“听诊器”
ALB通过健康检查来判断后端的EC2实例是否“活蹦乱跳”且能正常处理请求。如果健康检查失败,ALB会认为该实例“不健康”(Unhealthy),并停止向其转发流量。
关键配置项:
- 协议(Protocol): 应与我们的目标组协议一致。
- 端口(Port): 应该是我们EC2上服务真正在监听的端口。
- 路径(Path): ALB会向这个路径发送GET请求。我们需要确保这个URL能返回HTTP 200状态码。很多Web框架默认的
/
路径可能包含复杂的业务逻辑或重定向,建议专门为健康检查创建一个简单的路径,如/health
或/ping
,它只需直接返回一个200 OK即可。 - 成功代码(Success codes): 默认是
200
。如果我们的健康检查接口返回其他成功码(如200-299),需要在这里修改。
排查技巧: 如果目标组中的实例持续处于
unhealthy
状态,可以直接从一台能访问该EC2的机器上(比如同一VPC下的另一台EC2),使用curl -v http://<EC2-私有IP>:<端口>/<健康检查路径>
命令来模拟健康检查,查看返回的状态码和内容是否符合预期。
4. 健康检查的耐心:了解初始化时间
“为什么我的实例明明启动了,却一直是unhealthy?” 这是一个非常常见的问题。ALB将一个新注册的实例判定为“健康”需要一个过程。
- 相关配置:
- 检查间隔(Interval): 两次健康检查之间的间隔时间(默认30秒)。
- 超时(Timeout): 每次检查等待响应的最长时间(默认5秒)。
- 健康阈值(Healthy threshold): 实例从不健康变为健康,需要连续成功的检查次数(默认5次)。
计算一下:Interval * Healthy threshold
= 30s * 5 = 150s
。也就是说,在理想情况下,一个新实例至少需要2.5分钟才能被标记为健康。如果中间有一次失败,时间会更长。
- 实用建议: 在服务部署或变更后,请保持耐心。先去喝杯咖啡,再回来看状态。如果几分钟后依然不健康,再根据上一条的技巧进行排查。对于需要快速启动的应用,可以适当调低这些参数,但要小心过于频繁的检查给应用带来压力。
5. 目标组协议:与后端服务的“暗号”
ALB的目标组(Target Group)定义了流量将如何被转发到后端EC2。这里的协议和端口必须与我们EC2上实际运行的服务监听的协议和端口完全匹配。
常见场景:
- 用户通过HTTPS访问ALB,ALB终止SSL,然后通过HTTP将请求转发给后端EC2。这时,ALB监听器是
HTTPS:443
,而目标组协议是HTTP:80
(或8080等)。 - 端到端加密,ALB和EC2之间也使用HTTPS。这时,目标组协议需要配置为
HTTPS
,并且EC2上需要配置好证书。
- 用户通过HTTPS访问ALB,ALB终止SSL,然后通过HTTP将请求转发给后端EC2。这时,ALB监听器是
错误案例: 后端服务监听的是8080端口,但目标组里填写的端口是80。后端服务监听的是http端口,但目标组里填写的协议是https。这种“暗号”对不上的情况,流量自然无法送达。
6. 证书与域名:HTTPS的“身份证”
如果我们使用HTTPS监听器,ALB需要绑定一个SSL/TLS证书。这个证书必须与用户访问的域名完全匹配,否则浏览器会报“NET::ERR_CERT_COMMON_NAME_INVALID”之类的安全警告。
- 最佳实践:
- 使用AWS Certificate Manager (ACM) 来免费申请和管理我们的SSL证书。
- 确保证书覆盖了我们的主域名(
example.com
)和需要的子域名(如www.example.com
)。使用通配符证书(*.example.com
)可以简化管理。 - 当证书即将过期时,如果使用的是ACM管理的公有证书,ACM会自动续订,非常省心。
7. 域名解析与Host头:测试的捷径
在服务部署的最后一步,我们需要将我们的域名通过DNS解析到ALB的DNS名称上(通常是CNAME记录)。
快速测试技巧: DNS解析在全球生效需要一些时间。如果想立即测试,有两种方法:
- 修改本地hosts文件: 在我们的电脑上,将ALB的IP地址和我们想要测试的域名绑定。
- 使用
curl
的--resolve
或Host
头: 这是一种更优雅的方式,无需修改系统文件。我们可以直接指定域名与IP的解析关系,或者通过Host
头来模拟特定域名的访问。
# 使用Host头,<ALB_DNS_NAME>是ALB的地址 curl -H "Host: your-domain.com" http://<ALB_DNS_NAME>/path # 或者,如果知道ALB的某个IP curl --resolve "your-domain.com:80:123.45.67.89" http://your-domain.com/path
这个技巧在排查基于域名的路由规则时尤其有用。
总结
排查ALB与EC2的通信问题,本质上是一个抽丝剥茧、由外及里的过程。从用户DNS查询开始,到ALB的监听器和安全组,再到目标组的健康检查和协议配置,最后落到EC2实例自身的安全组和应用服务。
记住这七个关键检查点,下次再遇到“网站打不开”的紧急工单时,相信大家一定能更有条理,从容不迫地定位并解决问题。
希望这篇文章对大家有帮助!如果大家有其他问题或者独到的经验,欢迎在评论区分享交流!