From 1103cc224b82714a6ed7a3e3132336c5683bfb4b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 10 Jan 2026 07:52:50 +0000 Subject: [PATCH 1/3] Initial plan From 47e7663a69e9eb9e620b9e305b227c5b1d6d4e21 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 10 Jan 2026 07:55:56 +0000 Subject: [PATCH 2/3] Add comprehensive Chinese FAQ document Co-authored-by: CodeSpaceiiii <129646304+CodeSpaceiiii@users.noreply.github.com> --- FAQ-CN.md | 684 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 684 insertions(+) create mode 100644 FAQ-CN.md diff --git a/FAQ-CN.md b/FAQ-CN.md new file mode 100644 index 0000000..5544dc8 --- /dev/null +++ b/FAQ-CN.md @@ -0,0 +1,684 @@ +# Alibaba Cloud Credentials Python SDK 常见问题 + +本文档整理了使用阿里云凭证 Python SDK 时可能遇到的常见问题及解决方案。 + +## 目录 + +- [环境变量相关问题](#环境变量相关问题) +- [配置文件相关问题](#配置文件相关问题) +- [ECS RAM 角色相关问题](#ecs-ram-角色相关问题) +- [OIDC 角色相关问题](#oidc-角色相关问题) +- [多线程/异步相关问题](#多线程异步相关问题) +- [日志和调试相关问题](#日志和调试相关问题) +- [凭证刷新和缓存问题](#凭证刷新和缓存问题) +- [Credentials URI 相关问题](#credentials-uri-相关问题) +- [其他常见问题](#其他常见问题) + +--- + +## 环境变量相关问题 + +### 1. 环境变量 accessKeyId 不能为空 + +**问题描述:** +``` +CredentialException: Environment variable accessKeyId cannot be empty +``` + +**原因:** +使用默认凭证链时,SDK 首先尝试从环境变量中获取凭证。如果设置了 `ALIBABA_CLOUD_ACCESS_KEY_ID` 但值为空,会导致此错误。 + +**解决方案:** +- 确保环境变量 `ALIBABA_CLOUD_ACCESS_KEY_ID` 和 `ALIBABA_CLOUD_ACCESS_KEY_SECRET` 已正确设置且不为空 +- 或者取消这两个环境变量的设置,让 SDK 使用默认凭证链的其他方式获取凭证 +- 或者显式指定凭证类型,避免使用默认凭证链 + +```python +import os +from alibabacloud_credentials.client import Client +from alibabacloud_credentials.models import Config + +# 方案1: 确保环境变量设置正确 +os.environ['ALIBABA_CLOUD_ACCESS_KEY_ID'] = 'your_access_key_id' +os.environ['ALIBABA_CLOUD_ACCESS_KEY_SECRET'] = 'your_access_key_secret' + +# 方案2: 显式指定凭证类型 +config = Config( + type='access_key', + access_key_id='your_access_key_id', + access_key_secret='your_access_key_secret' +) +cred = Client(config) +``` + +### 2. 环境变量 accessKeySecret 不能为空 + +**问题描述:** +``` +CredentialException: Environment variable accessKeySecret cannot be empty +``` + +**原因:** +`ALIBABA_CLOUD_ACCESS_KEY_SECRET` 环境变量未设置或为空。 + +**解决方案:** +参考上一问题的解决方案,确保 AccessKey Secret 环境变量正确设置。 + +--- + +## 配置文件相关问题 + +### 3. 无法打开凭证配置文件 + +**问题描述:** +``` +CredentialException: unable to open credentials file: /path/to/config.json +``` + +**原因:** +- 配置文件不存在 +- 文件路径错误 +- 文件权限不足 + +**解决方案:** +- 检查配置文件是否存在于正确位置: + - Linux/Mac: `~/.aliyun/config.json` + - Windows: `C:\Users\USER_NAME\.aliyun\config.json` +- 确保文件具有读取权限 +- 创建配置文件目录和文件: + +```bash +# Linux/Mac +mkdir -p ~/.aliyun +touch ~/.aliyun/config.json + +# 编辑配置文件,添加凭证信息 +``` + +### 4. 配置文件解析失败 + +**问题描述:** +``` +CredentialException: failed to parse credential form cli credentials file: /path/to/config.json +``` + +**原因:** +- 配置文件不是有效的 JSON 格式 +- 配置文件编码问题 + +**解决方案:** +- 使用 JSON 验证工具检查配置文件格式 +- 确保配置文件使用 UTF-8 编码 +- 参考正确的配置文件格式: + +```json +{ + "current": "default", + "profiles": [ + { + "name": "default", + "mode": "AK", + "access_key_id": "", + "access_key_secret": "" + } + ] +} +``` + +### 5. 不支持的 profile 模式 + +**问题描述:** +``` +CredentialException: unsupported profile mode 'CloudSSO' form cli credentials file +``` + +**原因:** +当前版本的 SDK 不支持 CloudSSO 模式(参见 [Issue #64](https://github.com/aliyun/credentials-python/issues/64))。 + +**解决方案:** +- 使用其他支持的凭证模式,如 AK、StsToken、RamRoleArn、EcsRamRole、OIDC 等 +- 等待官方支持 CloudSSO 模式 +- 临时方案:使用 `process_command` 执行 `aliyun` CLI 获取凭证 + +--- + +## ECS RAM 角色相关问题 + +### 6. Signal 只能在主线程中使用 + +**问题描述:** +``` +ValueError: signal only works in main thread of the main interpreter +``` + +**原因:** +使用默认凭证链时,SDK 会初始化 ECS RAM Role 凭证提供者,该提供者在子线程中注册了 signal 处理器(参见 [Issue #63](https://github.com/aliyun/credentials-python/issues/63) 和 [Issue #67](https://github.com/aliyun/credentials-python/issues/67))。 + +**解决方案:** +- 方案1:禁用 ECS 元数据服务访问 + +```python +import os +os.environ['ALIBABA_CLOUD_ECS_METADATA_DISABLED'] = 'true' + +from alibabacloud_credentials.client import Client +cred = Client() +``` + +- 方案2:显式指定凭证类型,避免使用默认凭证链 + +```python +from alibabacloud_credentials.client import Client +from alibabacloud_credentials.models import Config + +config = Config( + type='access_key', + access_key_id='your_access_key_id', + access_key_secret='your_access_key_secret' +) +cred = Client(config) +``` + +### 7. 从 ECS 元数据服务获取 RAM 凭证失败 + +**问题描述:** +``` +CredentialException: Failed to get RAM session credentials from ECS metadata service. HttpCode=404 +``` + +**原因:** +- 当前环境不是 ECS 实例 +- ECS 实例未绑定 RAM 角色 +- 元数据服务不可访问 + +**解决方案:** +- 确认代码运行在 ECS 实例上 +- 在 ECS 控制台为实例绑定 RAM 角色 +- 检查安全组规则,确保可以访问元数据服务(100.100.100.200) +- 如果不在 ECS 环境,设置环境变量禁用 ECS 元数据: + +```bash +export ALIBABA_CLOUD_ECS_METADATA_DISABLED=true +``` + +### 8. Scheduler 未运行错误 + +**问题描述:** +``` +apscheduler.schedulers.SchedulerNotRunningError: Scheduler is not running +``` + +**原因:** +ECS RAM Role 凭证提供者在 shutdown 时未检查 scheduler 状态就调用了 shutdown 方法(参见 [Issue #71](https://github.com/aliyun/credentials-python/issues/71))。 + +**解决方案:** +- 这是 SDK 内部问题,建议升级到最新版本 +- 临时方案:捕获该异常并忽略 + +```python +try: + # 你的代码 + pass +except Exception as e: + if 'SchedulerNotRunningError' not in str(type(e)): + raise +``` + +--- + +## OIDC 角色相关问题 + +### 9. OIDC 必需参数为空 + +**问题描述:** +``` +ValueError: role_arn or environment variable ALIBABA_CLOUD_ROLE_ARN cannot be empty +ValueError: oidc_provider_arn or environment variable ALIBABA_CLOUD_OIDC_PROVIDER_ARN cannot be empty +ValueError: oidc_token_file_path or environment variable ALIBABA_CLOUD_OIDC_TOKEN_FILE cannot be empty +``` + +**原因:** +使用 OIDC 凭证时,必须提供以下三个参数之一(配置参数或环境变量): +- `role_arn` / `ALIBABA_CLOUD_ROLE_ARN` +- `oidc_provider_arn` / `ALIBABA_CLOUD_OIDC_PROVIDER_ARN` +- `oidc_token_file_path` / `ALIBABA_CLOUD_OIDC_TOKEN_FILE` + +**解决方案:** +- 方案1:通过配置参数指定 + +```python +from alibabacloud_credentials.client import Client +from alibabacloud_credentials.models import Config + +config = Config( + type='oidc_role_arn', + role_arn='acs:ram::123456789:role/role-name', + oidc_provider_arn='acs:ram::123456789:oidc-provider/provider-name', + oidc_token_file_path='/var/run/secrets/token', + role_session_name='session-name' +) +cred = Client(config) +``` + +- 方案2:通过环境变量指定 + +```bash +export ALIBABA_CLOUD_ROLE_ARN='acs:ram::123456789:role/role-name' +export ALIBABA_CLOUD_OIDC_PROVIDER_ARN='acs:ram::123456789:oidc-provider/provider-name' +export ALIBABA_CLOUD_OIDC_TOKEN_FILE='/var/run/secrets/token' +``` + +### 10. Session 过期时间设置错误 + +**问题描述:** +``` +ValueError: session duration should be in the range of 900s - max session duration +``` + +**原因:** +`duration_seconds` 参数小于 900 秒(15分钟)。 + +**解决方案:** +设置 `role_session_expiration` 或 `duration_seconds` 参数为 900 到 43200(12小时)之间的值: + +```python +config = Config( + type='oidc_role_arn', + role_arn='your_role_arn', + oidc_provider_arn='your_oidc_provider_arn', + oidc_token_file_path='/path/to/token', + role_session_expiration=3600 # 1小时 +) +``` + +--- + +## 多线程/异步相关问题 + +### 11. 没有当前事件循环 + +**问题描述:** +``` +RuntimeError: There is no current event loop in thread 'MainThread' +``` + +**原因:** +在 Python 3.10+ 中,`asyncio.get_event_loop()` 在没有运行中的事件循环时会抛出异常(参见 [Issue #57](https://github.com/aliyun/credentials-python/issues/57))。 + +**解决方案:** +- 升级到最新版本的 SDK(已在 1.0.1+ 版本修复) +- 如果无法升级,确保在异步上下文中使用凭证: + +```python +import asyncio +from alibabacloud_credentials.client import Client + +async def main(): + cred = Client() + credential = await cred.get_credential_async() + # 使用凭证 + +asyncio.run(main()) +``` + +### 12. Job 无法序列化 + +**问题描述:** +``` +ValueError: This Job cannot be serialized since the reference to its callable (.refresh_task at 0x7f96cc373ba0>) could not be determined +``` + +**原因:** +使用多进程和 ECS RAM Role 自动刷新功能时,内部的刷新任务无法被序列化(参见 [Issue #66](https://github.com/aliyun/credentials-python/issues/66))。 + +**解决方案:** +- 在多进程环境中禁用异步更新: + +```python +from alibabacloud_credentials.provider import EcsRamRoleCredentialsProvider + +provider = EcsRamRoleCredentialsProvider( + async_update_enabled=False # 禁用异步刷新 +) +``` + +- 或使用静态凭证类型 + +--- + +## 日志和调试相关问题 + +### 13. SDK 强制设置全局日志级别为 DEBUG + +**问题描述:** +SDK 将全局日志级别强制设置为 DEBUG,导致过多日志输出(参见 [Issue #58](https://github.com/aliyun/credentials-python/issues/58))。 + +**原因:** +1.0.0 版本中存在 `logging.basicConfig(level=logging.DEBUG)` 调用。 + +**解决方案:** +- 升级到 1.0.1 或更高版本(已修复) +- 在程序中重新设置日志级别: + +```python +import logging + +# 在导入 SDK 后重置日志级别 +logging.getLogger().setLevel(logging.WARNING) +``` + +### 14. 模块级日志配置忽略根日志配置 + +**问题描述:** +某些模块显式设置了 DEBUG 日志级别,忽略了根日志配置(参见 [Issue #65](https://github.com/aliyun/credentials-python/issues/65))。 + +**原因:** +SDK 代码中使用了 `setLevel(logging.DEBUG)`。 + +**解决方案:** +- 显式配置 SDK 的日志记录器: + +```python +import logging + +# 禁用或调整 credentials 模块的日志级别 +logging.getLogger('credentials').setLevel(logging.WARNING) +logging.getLogger('alibabacloud_credentials').setLevel(logging.WARNING) +``` + +--- + +## 凭证刷新和缓存问题 + +### 15. 获取不一致的 STS Token + +**问题描述:** +在 Token 即将过期时,可能获取到不匹配的 AccessKey/Secret/Token 组合(参见 [Issue #55](https://github.com/aliyun/credentials-python/issues/55))。 + +**原因:** +SDK 分别返回 AccessKey ID、AccessKey Secret 和 Security Token,在过期边界可能导致不一致。 + +**解决方案:** +- 使用 `get_credential()` 方法一次性获取完整凭证: + +```python +from alibabacloud_credentials.client import Client + +cred = Client() +# 推荐:一次性获取完整凭证 +credential = cred.get_credential() +access_key_id = credential.access_key_id +access_key_secret = credential.access_key_secret +security_token = credential.security_token + +# 不推荐:分别获取(可能不一致) +# access_key_id = cred.get_access_key_id() +# access_key_secret = cred.get_access_key_secret() +# security_token = cred.get_security_token() +``` + +### 16. 默认凭证链无法加载任何凭证 + +**问题描述:** +``` +CredentialException: unable to load credentials from any of the providers in the chain: [...] +``` + +**原因:** +默认凭证链尝试了所有凭证提供者,但都失败了。 + +**解决方案:** +- 检查错误消息中的详细信息,了解每个提供者失败的原因 +- 确保至少配置了一种凭证方式: + - 环境变量 + - OIDC(如果在 K8s 环境) + - 配置文件 `~/.aliyun/config.json` + - ECS RAM 角色(如果在 ECS 上) + - Credentials URI + +示例: + +```python +# 显式配置凭证,避免依赖默认凭证链 +from alibabacloud_credentials.client import Client +from alibabacloud_credentials.models import Config + +config = Config( + type='access_key', + access_key_id='your_access_key_id', + access_key_secret='your_access_key_secret' +) +cred = Client(config) +``` + +--- + +## Credentials URI 相关问题 + +### 17. Credentials URI 不支持 HTTPS + +**问题描述:** +Credentials URI 方式不支持 HTTPS 端点(参见 [Issue #49](https://github.com/aliyun/credentials-python/issues/49))。 + +**原因:** +旧版本只支持 HTTP 协议。 + +**解决方案:** +- 升级到最新版本(已支持 HTTPS) +- 确保 URI 格式正确: + +```python +from alibabacloud_credentials.client import Client +from alibabacloud_credentials.models import Config + +config = Config( + type='credentials_uri', + credentials_uri='https://your-service.com/credentials' # 支持 HTTPS +) +cred = Client(config) +``` + +### 18. Credentials URI 响应格式错误 + +**问题描述:** +``` +CredentialException: Failed to get credentials from the URL +``` + +**原因:** +- URI 返回的 HTTP 状态码不是 200 +- 响应体格式不正确 + +**解决方案:** +确保 Credentials URI 服务返回正确的响应格式: + +```json +{ + "Code": "Success", + "AccessKeyId": "your_access_key_id", + "AccessKeySecret": "your_access_key_secret", + "SecurityToken": "your_security_token", + "Expiration": "2021-09-26T03:46:38Z" +} +``` + +要求: +- HTTP 状态码必须是 200 +- `Content-Type` 应为 `application/json` +- `Code` 字段必须为 `"Success"` + +--- + +## 其他常见问题 + +### 19. RAM Role ARN 缺少必需参数 + +**问题描述:** +``` +CredentialException: {"Code":"MissingTimestamp","Message":"Timestamp is mandatory for this action."} +``` + +**原因:** +旧版本可能缺少必需的 API 参数(参见 [Issue #27](https://github.com/aliyun/credentials-python/issues/27))。 + +**解决方案:** +- 升级到最新版本的 SDK +- 确保系统时间正确 + +### 20. 如何使用单例模式初始化凭证客户端 + +**问题描述:** +多次创建凭证客户端导致性能问题和流量控制。 + +**解决方案:** +使用单例模式初始化凭证客户端: + +```python +from alibabacloud_credentials.client import Client + +class CredentialsManager: + _instance = None + _client = None + + def __new__(cls): + if cls._instance is None: + cls._instance = super().__new__(cls) + cls._client = Client() # 或传入配置 + return cls._instance + + def get_client(self): + return self._client + +# 使用 +manager = CredentialsManager() +cred = manager.get_client() +``` + +### 21. 如何安全地管理 AccessKey + +**问题描述:** +在代码中硬编码 AccessKey 存在安全风险。 + +**解决方案:** +- **推荐方式 1**:使用环境变量 + +```bash +export ALIBABA_CLOUD_ACCESS_KEY_ID='your_access_key_id' +export ALIBABA_CLOUD_ACCESS_KEY_SECRET='your_access_key_secret' +``` + +```python +from alibabacloud_credentials.client import Client +cred = Client() # 自动从环境变量读取 +``` + +- **推荐方式 2**:使用配置文件 + +创建 `~/.aliyun/config.json`,设置严格的文件权限(仅所有者可读): + +```bash +chmod 600 ~/.aliyun/config.json +``` + +- **推荐方式 3**:在 ECS/ECI 上使用 RAM 角色 + +为实例绑定 RAM 角色,无需管理 AccessKey: + +```python +from alibabacloud_credentials.client import Client +from alibabacloud_credentials.models import Config + +config = Config(type='ecs_ram_role') +cred = Client(config) +``` + +- **推荐方式 4**:在 Kubernetes 上使用 OIDC + +使用 RRSA(RAM Roles for Service Account)功能。 + +### 22. 如何查看 SDK 版本 + +**问题描述:** +需要确认当前使用的 SDK 版本。 + +**解决方案:** + +```python +import alibabacloud_credentials +print(alibabacloud_credentials.__version__) +``` + +或通过 pip: + +```bash +pip show alibabacloud-credentials +``` + +### 23. SDK 支持哪些 Python 版本 + +**问题描述:** +不确定 SDK 的 Python 版本兼容性。 + +**解决方案:** +- `alibabacloud-credentials` 1.0rc1 及以上版本仅支持 Python 3.7+ +- 如果使用 Python 3.6 或更早版本,需要使用旧版本 SDK + +### 24. 如何禁用特定的凭证提供者 + +**问题描述:** +希望禁用默认凭证链中的某些提供者。 + +**解决方案:** +- 禁用 ECS 元数据: + +```bash +export ALIBABA_CLOUD_ECS_METADATA_DISABLED=true +``` + +- 禁用 CLI 配置文件: + +```bash +export ALIBABA_CLOUD_CLI_PROFILE_DISABLED=true +``` + +- 禁用 IMDSv1(仅使用 IMDSv2): + +```bash +export ALIBABA_CLOUD_IMDSV1_DISABLED=true +``` + +--- + +## 获取帮助 + +如果以上 FAQ 无法解决您的问题,可以通过以下方式获取帮助: + +1. **查看官方文档**:[README-CN.md](./README-CN.md) +2. **提交 Issue**:[GitHub Issues](https://github.com/aliyun/credentials-python/issues) +3. **查看更新日志**:[ChangeLog.md](./ChangeLog.md) + +提交 Issue 时,请提供: +- SDK 版本 +- Python 版本 +- 完整的错误堆栈 +- 最小可复现代码示例(不要包含真实的 AccessKey) +- 运行环境(本地开发、ECS、容器、Kubernetes 等) + +--- + +## 最佳实践总结 + +1. **使用单例模式**初始化凭证客户端,启用 SDK 缓存功能 +2. **避免硬编码** AccessKey,使用环境变量、配置文件或 RAM 角色 +3. **使用 `get_credential()` 方法**一次性获取完整凭证,避免不一致 +4. **升级到最新版本**以获得 bug 修复和新特性 +5. **在生产环境使用 RAM 角色**(ECS RAM Role、OIDC)替代 AccessKey +6. **正确配置日志级别**,避免过多日志输出影响性能 +7. **在多线程/多进程环境中**注意凭证客户端的线程安全性 +8. **设置合理的超时时间**,避免网络问题导致长时间阻塞 + +--- + +**文档更新时间**:2026-01 + +**适用 SDK 版本**:alibabacloud-credentials >= 1.0.0 From 8e87735415b1e9b31a993f451e9fb6e99f84c04e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 10 Jan 2026 07:56:35 +0000 Subject: [PATCH 3/3] Update README files to link to FAQ document Co-authored-by: CodeSpaceiiii <129646304+CodeSpaceiiii@users.noreply.github.com> --- README-CN.md | 6 ++++-- README.md | 4 +++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/README-CN.md b/README-CN.md index a8f85c6..5a46e7e 100644 --- a/README-CN.md +++ b/README-CN.md @@ -426,9 +426,11 @@ cred_type = credential.get_type() 如果上述方式均未找到有效的凭据信息,Credentials工具会检查环境变量 ***ALIBABA_CLOUD_CREDENTIALS_URI*** ,如果该变量存在且指向一个有效的URI地址,Credentials会向该URI发起HTTP请求,获取临时安全凭证作为默认凭据。 -## 问题 +## 常见问题 -[提交 Issue](https://github.com/aliyun/credentials-python/issues/new),不符合指南的问题可能会立即关闭。 +遇到问题时,请先查看[常见问题文档(FAQ)](./FAQ-CN.md),其中包含了常见错误及解决方案。 + +如果 FAQ 无法解决您的问题,欢迎[提交 Issue](https://github.com/aliyun/credentials-python/issues/new),不符合指南的问题可能会立即关闭。 ## 发行说明 diff --git a/README.md b/README.md index fdd7507..ee3b165 100644 --- a/README.md +++ b/README.md @@ -425,7 +425,9 @@ If you want to use different types of credentials in the development and product ## Issues -[Opening an Issue](https://github.com/aliyun/credentials-python/issues/new), Issues not conforming to the guidelines may be closed immediately. +If you encounter any issues, please check the [FAQ document (Chinese)](./FAQ-CN.md) first for common problems and solutions. + +If the FAQ doesn't solve your problem, feel free to [open an issue](https://github.com/aliyun/credentials-python/issues/new). Issues not conforming to the guidelines may be closed immediately. ## Changelog