You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过API列举GCP项目内所有镜像URL以配合Go实现容器漏洞扫描

实现方案

核心原理

你执行的gcloud container images list命令底层对应两套API,根据你使用的镜像托管服务选择即可:

  • 旧版Container Registry(gcr.io、us.gcr.io等域名):兼容Docker Registry V2 API,也可以直接调用GCP官方提供的Container Registry专用接口
  • 新版Artifact Registry(<区域>-docker.pkg.dev域名):使用Artifact Registry官方Go SDK调用列表接口

注意事项

  • 运行代码的身份(服务账号/个人账号)需要对应镜像仓库的读取权限,和调用Container Analysis API所需权限兼容,无需额外配置特殊权限
  • 如果你的项目只使用其中一种镜像托管服务,只需要调用对应列表函数即可

Go代码实现示例

前置依赖

先安装所需依赖:

go get google.golang.org/api/containerregistry/v1
go get google.golang.org/api/artifactregistry/v1
go get golang.org/x/oauth2/google

1. 拉取Container Registry下所有镜像URL

package main

import (
	"context"
	"fmt"
	"golang.org/x/oauth2/google"
	"google.golang.org/api/containerregistry/v1"
)

func listGCRImages(projectID string) ([]string, error) {
	ctx := context.Background()
	// 复用GCP默认认证,和Container Analysis SDK认证逻辑一致
	client, err := google.DefaultClient(ctx, containerregistry.CloudPlatformScope)
	if err != nil {
		return nil, err
	}

	regService, err := containerregistry.New(client)
	if err != nil {
		return nil, err
	}

	var imageUrls []string
	// GCR支持的多区域域名,按需增删
	domains := []string{"gcr.io", "us.gcr.io", "eu.gcr.io", "asia.gcr.io"}
	for _, domain := range domains {
		parent := fmt.Sprintf("projects/%s", projectID)
		res, err := regService.Projects.Tags.List(domain, parent).Do()
		if err != nil {
			// 对应区域没有镜像时跳过
			continue
		}
		for _, img := range res.Child {
			// 拼接成符合要求的resourceURL格式
			imageUrls = append(imageUrls, fmt.Sprintf("https://%s/%s/%s", domain, projectID, img))
		}
	}
	return imageUrls, nil
}

2. 拉取Artifact Registry下所有镜像URL

import "strings"
import "google.golang.org/api/artifactregistry/v1"

func listARImages(projectID string) ([]string, error) {
	ctx := context.Background()
	client, err := google.DefaultClient(ctx, artifactregistry.CloudPlatformScope)
	if err != nil {
		return nil, err
	}

	arService, err := artifactregistry.New(client)
	if err != nil {
		return nil, err
	}

	var imageUrls []string
	// 先拉取项目下所有Docker格式的仓库
	parent := fmt.Sprintf("projects/%s/locations/-", projectID) // 用-代表查询所有区域
	res, err := arService.Projects.Locations.Repositories.List(parent).Filter("format:DOCKER").Do()
	if err != nil {
		return nil, err
	}

	for _, repo := range res.Repositories {
		// 拉取单个仓库下所有镜像
		pkgRes, err := arService.Projects.Locations.Repositories.Packages.List(repo.Name).Do()
		if err != nil {
			continue
		}
		for _, pkg := range pkgRes.Packages {
			// 解析出镜像URL
			parts := strings.Split(repo.Name, "/")
			location := parts[3]
			repoName := parts[5]
			imageName := strings.Split(pkg.Name, "/")[7]
			imageUrl := fmt.Sprintf("https://%s-docker.pkg.dev/%s/%s/%s", location, projectID, repoName, imageName)
			imageUrls = append(imageUrls, imageUrl)
		}
	}
	return imageUrls, nil
}

后续使用

把两个函数返回的镜像URL列表合并后,循环调用findVulnerabilityOccurrencesForImage()即可获取全量镜像漏洞信息。

内容的提问来源于stack exchange,提问作者Emre Chomko

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 00:24:04