BR 无法备份到阿里云OSS

【 TiDB 使用环境】生产环境 /测试/ Poc
【 TiDB 版本】 7.5.0
【BR 版本】7.5.0,7.5.1 ,甚至8.0 都是一样的错误
【复现路径】
1、创建一个阿里云ECS 实例(能连接到TiDB集群),安装BR 命令;
2、在阿里云控制台创建一个RAM 角色(比如:ops-backup-runner),并且为该角色授予:AliyunOSSFullAccess 和 AliyunSTSAssumeRoleAccess 权限。
3、将上述角色(ops-backup-runner) 赋给 第一步创建的ECS 实例。
4、在阿里云控制台创建一个 OSS bucket;
5、执行如下命令来备份数据到该OSS 桶:

br backup full \
  --pd "192.168.6.15:2379,192.168.6.16:2379,192.168.6.12:2379" \
  --s3.endpoint "https://oss-cn-hangzhu.aliyuncs.com" \
  --s3.provider "alibaba" \
  --s3.region "oss-cn-hangzhu" \
  --log-level debug \
  --storage "s3://${you-bucket-name}/tidb/test"

【遇到的问题:问题现象及影响】
BR 无法完成备份,从报错来看,阿里云反馈一个错误页面: **https://api.aliyun.com/troubleshoot?q=0002-00000003**,该页面显示:
您使用了STS类型的AccessKey ID,但是未采用STS的认证方式发起请求。
使用了STS类型的AccessKey ID,但是未在请求中附上SecurityToken字段表明使用了STS的认证方式。

详细错误日志如下:

[2024/04/04 18:05:18.071 +08:00] [ERROR] [main.go:60] ["br failed"] [error="error happen in store 2 at 192.168.6.18:20160: Io(Custom { kind: Other, error: \"failed to put object rusoto error Request ID: None Body: <?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\\n<Error>\\n  <Code>InvalidAccessKeyId</Code>\\n  <Message>The OSS Access Key Id you provided does not exist in our records. The Security Token may be lost to specify that it is a STS Access Id.</Message>\\n  <RequestId>660E7B5CF947FB36323C0335</RequestId>\\n  <HostId>17study-ops-backup.oss-cn-hangzhou.aliyuncs.com</HostId>\\n  <AWSAccessKeyId>STS.NUqcKhq7qeE7i4nKLu9KeaJbx</AWSAccessKeyId>\\n  <EC>0002-00000003</EC>\\n  <RecommendDoc>https://api.aliyun.com/troubleshoot?q=0002-00000003</RecommendDoc>\\n</Error>\\n\" }): [BR:KV:ErrKVStorage]tikv storage occur I/O error"] [errorVerbose="[BR:KV:ErrKVStorage]tikv storage occur I/O error\nerror happen in store 2 at 192.168.6.18:20160: Io(Custom { kind: Other, error: \"failed to put object rusoto error Request ID: None Body: <?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\\n<Error>\\n  <Code>InvalidAccessKeyId</Code>\\n  <Message>The OSS Access Key Id you provided does not exist in our records. The Security Token may be lost to specify that it is a STS Access Id.</Message>\\n  <RequestId>660E7B5CF947FB36323C0335</RequestId>\\n  <HostId>17study-ops-backup.oss-cn-hangzhou.aliyuncs.com</HostId>\\n  <AWSAccessKeyId>STS.NUqcKhq7qeE7i4nKLu9KeaJbx</AWSAccessKeyId>\\n  <EC>0002-00000003</EC>\\n  <RecommendDoc>https://api.aliyun.com/troubleshoot?q=0002-00000003</RecommendDoc>\\n</Error>\\n\" })\ngithub.com/pingcap/tidb/br/pkg/backup.(*pushDown).pushBackup\n\t/home/jenkins/agent/workspace/build-common/go/src/github.com/pingcap/br/br/pkg/backup/push.go:218\ngithub.com/pingcap/tidb/br/pkg/backup.(*Client).BackupRange\n\t/home/jenkins/agent/workspace/build-common/go/src/github.com/pingcap/br/br/pkg/backup/client.go:962\ngithub.com/pingcap/tidb/br/pkg/backup.(*Client).BackupRanges.func2\n\t/home/jenkins/agent/workspace/build-common/go/src/github.com/pingcap/br/br/pkg/backup/client.go:876\ngithub.com/pingcap/tidb/br/pkg/utils.(*WorkerPool).ApplyOnErrorGroup.func1\n\t/home/jenkins/agent/workspace/build-common/go/src/github.com/pingcap/br/br/pkg/utils/worker.go:76\ngolang.org/x/sync/errgroup.(*Group).Go.func1\n\t/go/pkg/mod/golang.org/x/sync@v0.3.0/errgroup/errgroup.go:75\nruntime.goexit\n\t/usr/local/go/src/runtime/asm_amd64.s:1650"] [stack="main.main\n\t/home/jenkins/agent/workspace/build-common/go/src/github.com/pingcap/br/br/cmd/br/main.go:60\nruntime.main\n\t/usr/local/go/src/runtime/proc.go:267"

【资源配置】进入到 TiDB Dashboard -集群信息 (Cluster Info) -主机(Hosts) 截图此页面

【附件:截图/日志/监控】

没有添加访问密钥,

aws好像也是这样的,你直接用 br 携带ak sk去请求

要写认证秘钥,参考如下格式:

tiup br backup full \
    --pd ${PD} \
    --storage "${S3PREFIX}?access-key=${ACCESSKEY}&secret-access-key=${SECRETKEY}" \
    --s3.endpoint ${S3ENDPOINT} \
    --send-credentials-to-tikv=true

The OSS Access Key Id you provided does not exist in our records. The Security Token may be lost to specify that it is a STS Access Id

看起来像是认证没过没添加访问密钥

阿里云OSS 只支持STS 模式,BR 源代码里是引用了阿里云的SDK 通过RAM role 去获取临时凭证的,我们手动设置更是无法使用

BR 源码里,判断endpoint 包含 aliyuncs.com 的话,就不会使用 外部提供的AK/SK 了,转而调用阿里云SDK 通过RAM rule 获取STS 凭证。这个没问题,但是在put 文件到OSS 时,他使用的认证方式没有传递 STS token ,我认为这个是BUG

我修改源码,加入调试信息,发现BR 调用阿里云sdk 确实完成了 sts token 的获取,但是在上传文件的时候就是没有传递STS token。但是这个是阿里云要求的,所以一直上传不了。

2 个赞

还有一个现象,就是BR 能去OSS 中创建备份目录,以及backup lock 文件,但是就是无法推送备份文件,我怀疑这里面存在2中不同的接口调用方式。

普通的ak/sk 行不通,尤其是在K8S 里通过BackupSchedule 来备份时,直接提供AK/SK 会报错没权限,因为BR 底层通过访问阿里云的一个IP 地址获取RAM rule,并且用该RAM rule 去访问OSS。

好吧 这样子的。 之前用的腾讯云的COS没出现过这个问题。 :sweat_smile:

遇到同样的问题,感谢分享

我在github 也提了issue,目前没人回复 :sob:

没写访问秘钥吧

BR 访问阿里云OSS 时不使用AKSK,二十通过阿里云SDK 自动获取STS token。

需要添加ak sk

哦,那就不知道了 我们存到了自建的minio中了

看着像是连接配置的问题啊

br 目前还不支持直接上传到阿里云的oss吧