python版本
import requests
from requests.auth import HTTPBasicAuth
import urllib3
from typing import Optional, Dict, List
import json
# 禁用 SSL 警告
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
class DockerRegistryClient:
def __init__(self, registry_url: str, username: str, password: str):
self.registry_url = registry_url.rstrip('/')
self.auth = HTTPBasicAuth(username, password)
self.session = requests.Session()
self.session.auth = self.auth
self.session.verify = False
def get_catalog(self) -> Optional[List[str]]:
"""获取所有仓库列表"""
url = f"{self.registry_url}/v2/_catalog"
try:
response = self.session.get(url, timeout=30)
response.raise_for_status()
return response.json().get('repositories', [])
except Exception as e:
print(f"获取 catalog 失败: {e}")
return None
def get_tags(self, repository: str) -> Optional[List[str]]:
"""获取指定仓库的所有标签"""
url = f"{self.registry_url}/v2/{repository}/tags/list"
try:
response = self.session.get(url, timeout=30)
response.raise_for_status()
return response.json().get('tags', [])
except Exception as e:
print(f"获取 {repository} 的标签失败: {e}")
return None
def get_all_images_with_tags(self) -> Dict[str, List[str]]:
"""获取所有仓库及其对应的标签"""
result = {}
repositories = self.get_catalog()
if not repositories:
return result
print(f"找到 {len(repositories)} 个仓库,正在获取标签...")
for idx, repo in enumerate(repositories, 1):
print(f"[{idx}/{len(repositories)}] 正在获取: {repo}")
tags = self.get_tags(repo)
if tags:
result[repo] = tags
print(f" └─ 标签数量: {len(tags)}, 标签: {tags[:3]}{'...' if len(tags) > 3 else ''}")
else:
result[repo] = []
print(f" └─ 无标签")
return result
def get_image_manifest(self, repository: str, tag: str) -> Optional[Dict]:
"""获取指定镜像 tag 的 manifest 信息"""
url = f"{self.registry_url}/v2/{repository}/manifests/{tag}"
headers = {
'Accept': 'application/vnd.docker.distribution.manifest.v2+json'
}
try:
response = self.session.get(url, headers=headers, timeout=30)
response.raise_for_status()
return response.json()
except Exception as e:
print(f"获取 {repository}:{tag} 的 manifest 失败: {e}")
return None
def main():
# 配置信息(已修改)
registry_url = "https://hub.docker.io"
username = "qiaoning"
password = "YOUR_PASSWORD_HERE" # 请替换为实际密码
client = DockerRegistryClient(registry_url, username, password)
# 1. 获取所有镜像及其标签
print("=" * 60)
print("获取所有镜像及标签")
print("=" * 60)
images_with_tags = client.get_all_images_with_tags()
# 2. 保存结果到文件
with open('registry_images.json', 'w', encoding='utf-8') as f:
json.dump(images_with_tags, f, indent=2, ensure_ascii=False)
print(f"\n结果已保存到 registry_images.json")
# 3. 展示部分结果
print("\n" + "=" * 60)
print("镜像及标签汇总")
print("=" * 60)
total_tags = 0
for repo, tags in images_with_tags.items():
print(f"\n{repo}:")
if tags:
for tag in tags:
print(f" - {tag}")
total_tags += 1
else:
print(" (无标签)")
print(f"\n总计: {len(images_with_tags)} 个仓库, {total_tags} 个标签")
# 4. 示例:获取特定镜像的详细信息
print("\n" + "=" * 60)
print("获取特定镜像的详细信息")
print("=" * 60)
# 获取第一个有标签的镜像的 manifest
for repo, tags in images_with_tags.items():
if tags:
target_repo = repo
target_tag = tags[0]
print(f"获取 {target_repo}:{target_tag} 的详细信息...")
manifest = client.get_image_manifest(target_repo, target_tag)
if manifest:
print(f" Schema 版本: {manifest.get('schemaVersion')}")
print(f" Media Type: {manifest.get('mediaType')}")
print(f" Config Digest: {manifest.get('config', {}).get('digest')}")
print(f" Layers 数量: {len(manifest.get('layers', []))}")
break
if __name__ == "__main__":
main()
shell版本
#!/bin/bash
REGISTRY="https://hub.docker.io"
USERNAME="qiaoning"
PASSWORD="YOUR_PASSWORD_HERE" # 请替换为实际密码
# 获取所有仓库列表
REPOS=$(curl -s --fail -u "${USERNAME}:${PASSWORD}" \
"${REGISTRY}/v2/_catalog" | jq -r '.repositories[]')
# 遍历每个仓库获取标签
echo "$REPOS" | while read -r repo; do
echo "========================================="
echo "仓库: $repo"
# 获取该仓库的标签
TAGS=$(curl -s --fail -u "${USERNAME}:${PASSWORD}" \
"${REGISTRY}/v2/${repo}/tags/list" | jq -r '.tags[]?')
if [ -n "$TAGS" ]; then
echo "标签:"
echo "$TAGS" | while read -r tag; do
echo " - $tag"
done
else
echo " (无标签)"
fi
echo ""
done
最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。