阿里云 ACM/RAM 踩坑

 阅读约 8 分钟

免责声明:

  1. 不要问我为什么用阿里云,我刚买的时候只有阿里云的国内备案服务做得比较靠谱
  2. 摸着良心讲,国内的其它云更不靠谱

什么是 ACM

应用配置管理 ACM(Application Configuration Management)前身为淘宝内部配置中心 Diamond,可简化微服务、DevOps 等场景下的配置管理,并帮助您确保配置安全合规。

简单来说就是你可以把配置项放在 ACM 里,比如密码、密钥等,形如:

mysql.address.alice=192.168.0.123:3306
mysql.username.alice=alice
mysql.password.alice=h0s7nt5720g # 不是真的

应用配置管理 ACM > 用户指南 > 创建配置

创建后怎么找到这个配置呢,你需要找到形如这样的几个参数:

dataId: alice
group: DEFULAT_GROUP # 没看出来不用默认组的意义
tenent: efa47c66-a01b-454e-9032-1561c493c441 # 不是真的

注意,这个 tenant 实际上在其它各种文档里也有可能被叫做 namespace

应用怎么拿到配在 ACM 里的值

首先当然是有各种 官方 SDK,然而本文需要讨论的是 SDK 背后的实际工作原理。

首先你需要阅读官方文档 应用配置管理 ACM > API 参考 > 调用方式,当然基本上是读不懂的,于是就需要一个阅读理解了。

第一步:找到提供 API 服务的 IP,然后后续的操作都应该使用 IP 而不是域名

$ curl http://${地址服务器域名}:8080/diamond-server/diamond

如果你是杭州,那么就是

$ curl http://addr-hz-internal.edas.aliyun.com:8080/diamond-server/diamond
100.100.17.7
100.100.19.18
100.100.45.175
100.100.45.174

第二步:拿到 AK

ACM_KEY=div8rspt6fmk0kv174kpopfju9sc2k88 # 不是真的
ACM_SECRET=M/r9o5MSBvCU1KT9745as92DQ7jNGIda5F= # 不是真的

官方的文档上写着不推荐使用,马上就要废弃,然而以他们 RAM 文档的难用程度以及客服工程师都不懂我在说什么的现状来看,估计废弃不了。

第三步:签名,以下都是伪代码,因为官方给的真代码太难看懂了;所以你需要找到的是伪代码在你用的语言里的实际实现,不要问这个库或者那个方法为什么没有,你要去找呀

const dataId = 'alice'; // 还记得这 3 个值哪里来的吗,往上翻
const group= 'DEFULAT_GROUP';
const tenent = 'efa47c66-a01b-454e-9032-1561c493c441';

const diamond = 'http://100.100.17.7:8080/diamond-server/config.co'
              + '?dataId=' + dataId
              + '&group=' + group
              + '&tenant=' + tenant;

const timestamp = Date.now() + ''; // 形如 '1535275961000'
const message = tenant + '+' + group + '+' + timestamp; // 注意到这两个加号了吗,困在官方文档里的你是不是内心崩溃的

const key = 'div8rspt6fmk0kv174kpopfju9sc2k88';
const secret = 'M/r9o5MSBvCU1KT9745as92DQ7jNGIda5F=';
const digest = hmac('sha1', secret, message); // 注意这里是 hmac-sha1,不是 sha1
const signature = base64.encode(digest); // digest 是个 byte[],具体可能取决于你使用的的加解密库

const props = curl.get(api, { headers: {
  'Spas-AccessKey': key,
  'timeStamp': timestamp,
  'Spas-Signature': signature,
}});

得到的 props 是一个文本。当然,这好像取决于你在 ACM 后台的配置,不过我觉得正常来说这里都应该配置成文本,应用自己如果要用 json 或者 xml 之类的,让它们自己去转。

因此得到的 props 形如:

mysql.address.alice=192.168.0.123:3306
mysql.username.alice=alice
mysql.password.alice=h0s7nt5720g

至此结束,等阿里的客服工程师学会了怎么用 RAM,我再来教大家。

更新 RAM 的部分

给阿里云提了一个工单,辗转了 4 个客服,历时两天,估计是终于找到写代码的那位小哥哥了,他说:

图片描述

我觉得这个工单值一张代金券。

通过 ECS 实例 RAM 角色访问 ACM借助于实例 RAM 角色访问其他云产品

RAM 的原理就是开发不接触敏感信息,运维也不接触敏感信息,由于云内网机器之间的某种物理信任,机器和机器之间通过一些临时的授权以及加解密关系传递敏感信息。

以下还是伪代码,同时由于是在做一个和传统铭文配置文件兼容的功能你所有没有开加解密了,原则上你应该使用 SDK

const meta = 'http://100.100.100.200/latest/meta-data/ram/security-credentials/acm'; // 这个 acm 是你自己起的角色名字,具体见文档
const credentials = request.get(meta);
const { SecurityToken, AccessKeyId, AccessKeySecret } = credentials;

// 签名方法和上面一样,略
const props = curl.get(api, { SecurityToken: {
  'Spas-SecurityToken': token, // 注意!!!这就是文档上本来没写,后来加上,但仍然标着非必填参数,值一张优惠券的坑
  'Spas-AccessKey': AccessKeyId,
  'timeStamp': timestamp,
  'Spas-Signature': signature,
}});

好,这次真的全部结束了,一个在 openresty 上实现的完整的实战代码参考 https://github.com/liz-ai/prop出于架构的设计,这个项目被我设为私有了仓库了,有需要的投条私聊。

欢迎打赏:

图片描述

也欢迎关注我的知乎专栏:一地鸡毛总冠军,过几天可能有惊喜哦。

最后一次更新,客服给了我一张除了云市场的 100 块优惠券,哪位大哥知道能买啥吗?

阅读 1.8k更新于 2018-12-12
推荐阅读
目录