运维烂笔头

一个 SA 老兵的工作日志

缘起

我们的 ECS 集群都是 EC2 启动类型,任务一律用 awsvpc 网络模式。

刚开始搭 dev 环境的时候就撞过一次墙:机器的 CPU、内存都还有富余,新任务却起不来,原因是 ENI 不够用了。当时的解法是打开 ECS 的 awsvpcTrunking(俗称 VPC trunk / ENI trunking),让一台 EC2 能挂更多的网卡。代价是:这个方案不是每种机型都支持。

半年多过去,环境从 dev 一路扩到 qa、preprod、prod,机型换了好几轮。某天下午我突然想起这件事:现在各个环境的 ECS 集群,还有没有 ENI 不够的隐患?换过的机型,还都支持 trunking 吗?

巧的是,同一天下午 prod 正好有个任务卡在 PROVISIONING 起不来,ENI 也一度被列为头号嫌疑。这篇就把 trunking 的原理、我们怎么落地的、怎么巡检,以及那次”差点冤枉了 ENI”的排查,一起记下来。

阅读全文 »

缘起

上一篇写 GitHub Actions 构建优化的时候,贴过一段服务仓库的 pipeline.yml,里面的 run-name 会把运行分成三类:[PR gate]、[Path-A · dev/qa] 和 [Path-B · prod train]。当时没有展开讲,这篇专门说说这套发布模型。

背景是这样的:我们有十几个 Java 微服务,跑在 ECS 上,环境有 dev、qa、preprod、prod 四个。早期的流程是合并到 main 之后,一路 dev、qa、preprod、prod 串行部署下去。这样做的问题是,任何一次合并都可能一路滚到 prod 门口,”什么时候发版”和”什么时候合代码”绑在了一起。

后来我们用 Release Please 把这两件事拆开:合代码只到 qa,发版是一次单独的、有版本号的动作。

下面以 gateway 服务为例,按 workflow 源码把这套流程过一遍。

阅读全文 »

缘起

我们 prod 的 ECS 集群是 EC2 启动类型,四台节点,跑着十几个 Java 微服务。

某天发现有两个 task 一直起不来,原因是四台机器的 CPU 都被预留满了。为此提了一个 PR,把 prod 所有服务 task definition 里容器的 cpu 减半,已经合进了 DevOps 仓库的 main。

问题是,按我们的流程,task definition 的改动要走 CD 才能生效。而 CD 是从 dev 开始,经过 qa、preprod,最后才到 prod。这次又涉及所有服务,一个个从 dev 推到 prod,太慢了。

于是我的第一反应是:能不能直接用命令行,对 prod 的服务来一次 force-new-deployment?

答案是:命令行可以,但 force-new-deployment 不行。

阅读全文 »

缘起

我们的 Spring Boot 服务都跑在 ECS 上,CI/CD 用的是 GitHub Actions。

最早每个服务仓库里都有一份自己的 pipeline.yml,里面依次调用公共的 reusable-ci.yml(构建、扫描、签名、推送镜像)和 reusable-cd.yml(部署)。前段时间,我们集中对这套流水线做了一轮优化。

这篇文章以一个单模块的 Spring Cloud Gateway 服务(下文简称 gateway)为例,把这轮已经落地的优化点逐个过一遍,并且用 gateway 仓库真实的运行记录说明:哪些优化有明确收益,哪些优化的收益在数据里其实看不出来。

阅读全文 »

背景

我厂在 AWS 上有 tooling、dev、qa、preprod 四个环境,VPC 之间通过 peering 互通。日常运维需要从办公网络访问这些 VPC 内的资源,走的是 AWS Client VPN。

Client VPN 的认证方式我们选了证书双向认证(mutual TLS)。AWS 也支持 Active Directory 或 SAML SSO 认证,但我们的场景比较简单——十来个人用,不想为此多维护一套认证基础设施。证书认证的好处是纯客户端侧,不依赖额外的认证服务,配好 .ovpn 文件就能连。

阅读全文 »

缘起

最近一直在啃 WIZ 扫出来的漏洞,修了有一两个月。今天打开一看:某两台 Amazon Linux 2023 的 EC2,操作系统软件包漏洞突然多了大几十个、上百个。

第一反应不是「又有新 CVE 发布了」,而是:你们不是开了每天自动更新吗?

上去一查,更气。dnf-automatic-install.timer 天天在跑,journal 里全是 Success;再对比同环境另一台机器,那边包版本已经新一截了,这两台还停在旧的。不是 timer 挂了,不是没装 dnf-automatic,也不是没写 releasever=latest——配置「看起来全都对」,预期作用却等于零。

气从何来?因为这不是偶发运维疏忽,而是 默认行为在逻辑上就不该和「每天更新」摆在一起。你以为自己买了份日更保险,其实保单条款里写着:索引最多可以旧两天。

阅读全文 »

缘起

preprod 里有个维护窗口:nusa-preprod-windows-patch,每天凌晨 03:17(Asia/Singapore)跑 AWS-RunPatchBaseline,目标是两台带 PatchGroup=preprod-windows 的 PowerBI Gateway。

某天随手翻了一下执行历史,发现一件不太妙的事:

从 6 月 25 号到 7 月 24 号,最近三十来次执行,全部 Failed。

不是偶发超时,不是某一台掉线,是窗口级天天红。SSM Agent 在线,机器也跑着,任务确实打上去了——然后挂在 Windows 补丁搜索这一步。

现象

错误信息不长,但很「经典」:

1
2
An error occurred when attempting to search Windows Update.
Exception from HRESULT: 0x80072F8F
阅读全文 »

缘起

前段时间升级了一下公司的 SonarQube,版本升到了 2026 年 7 月版。

这个 SonarQube 是通过 AWS 的公网 ALB 对外提供服务的。既然放在公网,虽然不是谁都能登录,但让它就这么裸奔着总觉得不太合适,于是我在 ALB 前面加了一层 AWS WAF。

WAF 里启用了几组 AWS Managed Rules,包括:

  • AWSManagedRulesCommonRuleSet
  • AWSManagedRulesKnownBadInputsRuleSet
  • AWSManagedRulesSQLiRuleSet
  • AWSManagedRulesAmazonIpReputationList

另外还加了一个按 IP 限速的规则。

SonarScanner 上传的数据比较大,所以当时还专门对 SizeRestrictions_BODY、CrossSiteScripting_BODY 和 SQLi_BODY 做了放行或者只计数处理。

过了几天,我又给 SonarQube 加了一层 IP 白名单:只有办公室出口 IP 和 GitHub Actions 的公网 IP 才能访问。

为了不影响同一个 ALB 后面将来可能挂的其他服务,这个白名单不是直接加在 ALB 的 Security Group 上,而是在 WAF 里根据 HTTP Host 匹配,只限制 SonarQube 的域名。

看起来考虑得还挺周全。

然后,坑就挖好了。

阅读全文 »

我在 xxxxx 的工作总结(AI 生成)

从 xxxx 年 xx 月到 xxxx 年 xx 月,我在 xxxxxx 担任 DevOps 工程师。这是一段充满挑战与成长的旅程。在这篇文章里,我将回顾并总结我在这期间负责的主要工作、技术实践以及个人收获,希望能为同样走在 DevOps 路上的朋友们提供一些参考。

阅读全文 »

背景介绍

之前用 rsyslogd 做过一个集中的 log server,主要是收集服务器系统和审计日志。最近要做的这个集中的 log server,则是专注于收集、展示应用日志的。我现在的服务器,操作系统有两种:Debian 12(bookworm) 和 Ubuntu 24.04,准确的说:应用服务器都是 Ubuntu 24.04,只有运维专用的两台(含要做的这个 log server)是 Debian 12。

因为是小厂,所以就摒弃掉大而重的 elasicsearch 系的方案,直接用 grafana 同源的 loki 来做服务端,客户端收集日志也是 grafana 同源的 promtail,技术方案选型就这么愉快得决定了。

阅读全文 »
0%