我之前帮一位初学后端的朋友排查过一次服务异常问题,他把本地跑通的web服务搬到了谷歌云上,结果启动之后始终无法正常访问,翻了好几份中文教程都没找到问题,折腾了快三个小时才来找我。我登上去看了不到十分钟就找到了原因,其实就是一个非常基础的配置漏项,很多第一次接触的人都会在这里踩坑。
资源配置的核心注意点
很多人创建第一个谷歌云资源的时候,第一个操作就是随便选一个名称看起来接近的区域,不会去查区域的实际网络情况。谷歌云的每个区域由至少两个可用区组成,同一个区域内的可用区之间,底层是低延迟的专有网络互联,可用性承诺也和跨区域部署不一样。如果是做高可用架构,至少要把实例分布在同一个区域的两个可用区,如果是做容灾,才需要跨区域部署。很多入门开发者搞反了,把实例都放同一个可用区,一旦可用区出现维护,整个服务就断了,或者为了省事儿跨区域部署多实例,平白增加了很多延迟,这些都是一开始不注意概念导致的问题。选区域的时候,不要光看名称判断,谷歌云提供了公开的网络测试方式,能直接测从客户端到不同区域的延迟,选延迟符合需求的区域就好。
我那个朋友碰到的问题,就是防火墙规则配错了。很多做过自建服务器的开发者,习惯了只配置操作系统内部的防火墙,觉得只要系统里放通了端口就没问题。但是谷歌云的网络安全是分层设计的,最外层是租户级的防火墙,所有进入实例的流量都要先过这一层,默认情况下,新项目的防火墙只放通了远程管理的端口,其他所有入站流量都是默认拒绝的。
我那个朋友在系统里放通了服务端口,但是忘了在谷歌云的控制台加对应规则,所以流量根本到不了实例内部。还有一种常见情况,就是很多人配了规则,但是错绑了网络或者错选了实例标签,规则实际没生效,配完之后一定要检查规则的作用范围,是不是覆盖了需要的实例。这类问题排查起来特别容易绕弯路,因为很多人不会想到平台层面还有一层过滤,会一直盯着实例内部的配置改,浪费很多时间。
还有一个小细节,新建谷歌云项目的时候,平台会自动生成一个默认的VPC网络,这个默认配置已经适配了大多数普通场景,要是没有特殊的网络隔离需求,直接用默认的就好,不用自己重新建VPC改路由配置。我见过有人为了"优化网络",自己改了VPC的路由表,结果把很多内部服务的连通性改坏了,最后排了好久才改回默认配置,平白做了很多无用功。当然要是有明确的网络隔离需求,那另说,大多数普通开发者真的不需要动默认的VPC配置。
权限体系的常见误区
谷歌云的权限管理全部走IAM体系,从项目访问到具体资源的读写,都通过IAM角色控制,这个设计本身很清晰,但是刚接触的人很容易踩过度授权的坑。我之前见过一个做个人项目的开发者,为了让自己的服务器能拉取对象存储里的资源,直接给服务器对应的服务账号开了项目所有者的权限,理由是"反正自己用,开大点省得配权限麻烦"。
这种操作其实有很大的安全隐患,一旦服务账号的密钥泄露,整个项目的所有资源都会被完全控制。而且谷歌云的IAM权限是默认继承的,项目级别的权限会自动透传到下面所有资源,没法单独撤销某个资源的权限,所以一开始配错了,后面改起来特别麻烦。
正确的做法是,给每个服务账号开刚好够用的最小权限,比如只需要读对象存储的某个桶,就只给这个桶的只读权限,不要开项目级的权限。哪怕是个人开发,也尽量按照最小权限原则配置,习惯养好了,做团队项目的时候不会出大问题。如果是团队多人共用同一个谷歌云项目,一定要给每个人分配独立的账号,按工作需要给对应权限,不要所有人共用一个项目所有者主账号,密钥到处转发。很多小团队图方便共用账号,等到有人离职或者换岗位,想要收回权限都做不到,还容易出现账号控制权丢失的问题,这一点也是比较需要注意的。
日常运维的实用经验
除了配置和权限,资源配额是另一个容易被忽略的点。谷歌云对每个项目的各类资源,都有默认的配额限制,比如某个区域能创建的CPU核心总数、对象存储的总容量、每秒的请求数这些,都是有上限的。很多开发者一开始做项目,资源用得少,配额够,就从来不会关注这件事,等到业务增长,要扩容加机器的时候,才发现创建新实例一直失败,报错提示是配额不足,这个时候再去申请调整配额,还要走流程,少则几十分钟多则几个小时,业务已经受到影响了。
我自己的习惯是,每次项目版本大更新之前,都会去看一眼谷歌云的配额使用情况,给核心资源留出至少一倍的冗余,要是快到阈值了,提前申请调整,不会等出问题了再动手。
很多开发者习惯了在实例内部自己搭监控,觉得云平台自带的监控没用,就一直关掉不用,其实谷歌云自带的监控能拿到很多实例内部拿不到的指标,很多疑难问题最后都要靠这个定位。我之前帮一家小团队排查过一个奇怪的问题,他们的服务每隔几天就会出现十几分钟的随机超时,实例内部看CPU、内存、磁盘IO都正常,应用日志也没报错,折腾了快一个月都没找到原因。
最后我让他们打开谷歌云自带的监控,看了一周的数据,发现每次超时之前,节点所在物理机都会有底层存储的性能异常预警,是物理硬件的小问题,他们自己的监控根本拿不到这个信息。后来把实例迁到另一个可用区,问题就再也没出现过。
从这个案例能看出来,云平台的监控不是多余的,它能帮你定位那些底层基础设施的问题,这是用户自己在实例内部做不到的。我现在做部署,不管搭不搭自己的监控,都会把谷歌云自带的监控和告警打开,核心指标都配好告警规则,万一出问题能提前拿到信息,不会等到用户投诉了才发现异常。
还有一个很多人不在意的点,就是数据备份。不少开发者觉得,既然把数据放在云平台上,云平台肯定会帮我做好备份,不用自己管。实际上不管哪个云厂商,包括谷歌云,默认都不会帮用户做自动备份,所有的快照、备份策略都需要用户自己配置。
我之前听过一个案例,有个开发者的谷歌云实例系统盘因为底层硬件故障损坏,因为没有做过任何快照备份,上面的代码和数据库全都找不回来,项目做了快一年,相当于从头再来。这个问题其实真的不难避免,谷歌云提供了自动快照的功能,只要花十分钟配置一下定期策略,把快照存到对象存储里,甚至可以跨区域存储,就算出问题,十几分钟就能恢复。哪怕是个人项目,也花点时间把备份配上,总比出了问题后悔强。
某种意义上说,谷歌云的整个产品设计,是从谷歌自身处理超大规模服务的经验提炼出来的,所以很多设计思路偏向于给用户足够多的控制权限,默认配置会比较保守,需要用户根据自己的需求去调整,不会默认给你开很多方便但是有安全隐患的配置。
这个设计思路本身没问题,但是对于习惯了"开箱即用"的开发者来说,就容易碰到各种默认配置下用不了的问题,很多坑其实都是因为不适应这个设计思路带来的。只要一开始多花点时间把基础概念理清楚,知道哪些地方是平台多做了一层控制,哪些地方需要自己手动配置,踩坑的概率会低很多。
很多普通开发者刚开始接触谷歌云,不知道怎么选产品,其实不用选太复杂的架构。如果是个人小项目,用虚拟机实例就够了,不用硬上容器集群,配置简单,维护成本低。如果需要存静态资源,用自带的对象存储就够,稳定性很好,不用自己搭文件服务器。要是团队做规模大一点的项目,再考虑用容器编排和托管服务,这样能省不少运维的精力,这个选择思路对大多数普通开发者都是适用的。