AWS EC2 的入向流量完全免费,出向有一个每月免费 100 GB 的额度,包括 “data transfer out under the monthly global free tier” 和 “regional data transfer under the monthly global free tier” 两种收费项都可以用,后者应该是包含了同 region 的跨 AZ 流量费。

这样看似乎只要不用超这 100 GB 正常的单 AZ、只访问互联网的话使用是不会收费的。但我还是在 Free Tier 没有用完之前就收到了配置的 0% 预算报警邮件。

从 Cost Explorer 按 Usage Type 分组后下载 csv 可以看出收费项是 <使用的region>-<某个未使用的region>-AWS-Out-Bytes。参考 S3 文档可以发现这是从我使用的 region 到一个我没有使用的 region 的数据传输费用。

Figure-2.-Accessing-AWS-services-in-different-Region-1.jpg

[^] 上图来自 https://aws.amazon.com/blogs/architecture/overview-of-data-transfer-costs-for-common-architectures/

从上图可以看出,即使流量通过了 Internet Gateway,到其他 AWS region 的流量还是会按跨 region 流量收费,而这部分是不在 Free Tier 范围内的。这甚至包含了非自己账号下的资源,例如被其他部署在 AWS 上的爬虫扫描和主动调用构建在 AWS 上的第三方服务产生的出向流量。

开启 Cost Allocation Tags 尝试分析流量来源发现确实是 EC2 实例调用某 SaaS 服务时产生的费用,只能避免使用该服务了。使用量很小的前几天还没有出现在账单里,但是预算报警已经提前触发了,此时可以从 Cost Explorer 分析来源及时止损。

其实 AWS 的本意应该是对于跨 region 的流量按比到互联网更低的 $0.01-0.02/GB 价格收费,但由于这部分没有计入 Free Tier 反而增加了成本。想要完全免费使用 Free Tier 就必须避开构建在 AWS 其他 region 上的服务并且用安全组限制只开放服务给特定网段,例如 https://aws.amazon.com/blogs/security/automatically-update-security-groups-for-amazon-cloudfront-ip-ranges-using-aws-lambda/ 这种使用 Lambda 定时更新安全组的方案。

不过话说回来这个价格已经很低了,如果嫌麻烦直接付了也没问题。

虽然时序数据很好压缩导致占用的存储量不多,但公有云上的托管 Prometheus 是按摄入采样数计费的,对于 15s 间隔的采样来说用量很容易超标。

为了控制成本,我们先禁用掉大部分默认导出的指标,然后明确启用需要的采集器。

--collector.disable-defaults --web.disable-exporter-metrics

Uptime

--collector.stat --collector.time (Linux)
--collector.boottime --collector.time (FreeBSD)

CPU

--collector.cpu

MEM

--collector.meminfo

Disk

--collector.diskstats --collector.filesystem (Linux)
--collector.devstat --collector.filesystem (FreeBSD)

Network

--collector.netdev --collector.netstat (Linux)
--collector.netdev --collector.devstat (FreeBSD)

OS

--collector.os

DigitalOcean 新推出了一款只有 512 MB 内存的 droplet,然而跑个 dnf upgrade 都能触发 Out of memory: Killed process 10365 (semodule)

ps avxf 可以查看进程的内存占用(RSS)。在搜索资料后我发现以下服务可以优化掉,不过要避免 out of memory 还是建议配置 swap,或者换个包管理器更轻量的发行版,例如 Debian。

droplet-agent

即 The DigitalOcean Droplet Agent,可通过 systemctl 关闭,或用 dnf 完全卸载。

dnf remove droplet-agent

sssd

参考 https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html-single/configuring_authentication_and_authorization_in_rhel/index 使用以下命令可切换到最小化认证并关闭 sssd 服务。

authselect select minimal
systemctl stop sssd.service
systemctl disable sssd.service

tuned

参考 https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/monitoring_and_managing_system_status_and_performance/getting-started-with-tuned_monitoring-and-managing-system-status-and-performance 修改 /etc/tuned/tuned-main.conf 配置即可。

daemon = 0

gssproxy

不需要 Kerberos 的话直接卸载也不会有什么问题。 https://github.com/gssapi/gssproxy/blob/main/docs/README.md

dnf remove gssproxy

dnf-makecache

dnf 缓存会定期自动更新,为了保证稳定的内存占用需要禁用掉 dnf-makecache.timer.

systemctl stop dnf-makecache.timer
systemctl disable dnf-makecache.timer

最终效果

# free -h
              total        used        free      shared  buff/cache   available
Mem:          460Mi       103Mi       227Mi       6.0Mi       130Mi       339Mi
Swap:            0B          0B          0B

首先由于 IPv6 VPN 服务器会转发 IPv6 包,需要用 sysctl 开启内核的 IPv6 转发。将以下内容配置到 /etc/sysctl.d 目录下一个 .conf 文件中,并用 sysctl -p xxx.conf 加载或重启服务器。

net.ipv6.conf.all.forwarding = 1

然后我们来安装 strongSwan。 dnf install epel-release 安装上 EPEL 源,然后 dnf install strongswan 就 OK 了。

strongSwan 现已支持 swanctl.conf 新格式的配置文件,文件路径在 /etc/strongswan/swanctl/swanctl.conf,密钥放在 /etc/strongswan/swanctl 对应目录下。下面给出一个示例配置,配置完成后可以通过 systemctl start strongswan.service 启动。

connections {
    ikev2-vpn {
        version=2
        remote_addrs=%any
        local_addrs=%any
        send_cert=always
        pools=pool-subnet-ipv6
        dpd_delay=300s
        children {
            ikev2-vpn {
                local_ts=::/0
                dpd_action=clear
            }

        }
        local-0 {
            certs = cert.pem
            id = @<domain>
        }
        remote-0 {
            auth = eap-mschapv2
            id = %any
        }
    }
}

pools {
    pool-subnet-ipv6 {
        addrs=xxx:8/125
        dns=2001:4860:4860::8888,2001:4860:4860::8844
    }
}

secrets {
    eap-user1 {
        id=user1
        secret="password"
    }
}

authorities {
}

P.S. 带有中间证书的证书文件需要拆分,strongSwan 只会读取证书文件里的第一个 PEM 证书。