如何使用 python / 列出 docker 图像获取 GCR 访问令牌

how to obtain GCR access token with python / listing docker images

我通过 gcloud auth print-access-token 获得的访问令牌显然与我通过一些基本 python 代码获得的访问令牌不同:

export GOOGLE_APPLICATION_CREDENTIALS=/the-credentials.json
from oauth2client.client import GoogleCredentials
credentials = GoogleCredentials.get_application_default()
credentials.get_access_token()

我想做的是获得一个可以使用的令牌:

curl -u _token:<mytoken> https://eu.gcr.io/v2/my-project/my-docker-image/tags/list

我不想安装 gcloud 实用程序作为我的应用程序的依赖项,因此我尝试通过 oath google 凭据

以编程方式获取访问令牌

所以我觉得有几个问题:

gcloud auth print-access-token 对比 GoogleCredentials.get_application_default()

gcloud 在执行 gcloud auth login 时不再默认设置应用程序默认凭据,因此您从 gcloud auth print-access-token 获得的 access_token 将是与您用于登录的用户对应的那个。

只要您遵循 instructions to create ADC's for a service account, that account has the necessary permissions,并且您执行脚本的环境可以访问 ENV var 和 adc.json 文件,您应该没问题。

如何使 curl 工作

Docker 注册表 API 指定应该进行令牌交换,将您的基本身份验证(即 Authorization: Basic base64(_token:<gcloud_access_token>))交换为短期 Bearer 令牌。此过程可能有点复杂,但已记录在案 here under "How to authenticate" and "Requesting a Token"。将 auth.docker.io/token 替换为 eu.gcr.io/v2/token,将 service=registry.docker.io 替换为 service=eu.gcr.io,等等。在此使用 curl -u oauth2accesstoken:<mytoken>

另请参阅:

完全回避这个问题

我们有一个 python 库可能与您的需求相关: https://github.com/google/containerregistry

我知道这是一个很老的问题,但我刚刚遇到 ,并设法让它工作。

您需要做的是使用变量 credentials.token,除非您第一次创建凭据对象后它不存在,返回 None。为了生成令牌,凭据必须由 google.cloud 库使用,在我的例子中,这是通过使用 googleapiclient.discovery.build 方法完成的:

sqladmin = googleapiclient.discovery.build('sqladmin', 'v1beta4', credentials=credentials)
response = sqladmin.instances().get(project=PROJECT_ID, instance=INSTANCE_ID).execute()
print(json.dumps(response))

之后 ACCESS_TOKEN 可以使用

正确生成
access_token = credentials.token

我还使用 google.cloud storage 测试了它作为测试凭据的方法,它也有效,只是尝试通过适当的 Python 库访问 GCS 中的存储桶:

from google.oauth2 import service_account
from google.cloud import storage
PROJECT_ID = your_project_id_here
SCOPES = ['https://www.googleapis.com/auth/sqlservice.admin']
SERVICE_ACCOUNT_FILE = '/path/to/service.json'
credentials = service_account.Credentials.from_service_account_file(
        SERVICE_ACCOUNT_FILE, scopes=SCOPES)
try:
    list(storage.Client(project=PROJECT_ID, credentials=credentials).bucket('random_bucket').list_blobs())
except:
    print("Failed because no bucket exists named 'random_bucket' in your project... but that doesn't matter, what matters is that the library tried to use the credentials and in doing so generated an access_token, which is what we're interested in right now")

access_token = credentials.token
print(access_token)