Files
ljwx-harbor/harbor/harbor-k8s-images.sh
gaoandClaude fc9371e443 feat: 完成企业级 DevOps 基础设施部署
## 🏗️ 新增功能
- **shared/**: 完整的基础组件部署方案
  - docker-compose.yml: 统一编排所有基础服务
  - .env.example: 标准化环境变量配置
  - prometheus/prometheus.yml: 监控配置
  - bin/up.sh & down.sh: 一键部署脚本
  - README.md: 完整的使用文档

## 🛠️ 核心服务
- **数据库层**: PostgreSQL 16 + MySQL 8 (统一密码: 123456)
- **缓存层**: Redis 7 (密码: 123456)
- **代码管理**: GitLab CE + Gitea (双代码仓库)
- **镜像仓库**: Harbor (Docker Registry)
- **监控层**: Prometheus + Grafana + cAdvisor
- **网关反代**: Traefik v3.1

## 🔧 技术优化
- 所有端口统一使用 2xx80 系列,避免端口冲突
- 统一网络架构 (core network),支持多项目接入
- 完善的健康检查和服务依赖配置
- 支持 ARM64 架构 (MySQL 8 兼容性修复)

## 📚 文档更新
- SYSTEM-CONFIG.md: 系统配置文档完善
- harbor/README.md: Harbor 模块使用说明
- docs/: 完整的部署和运维文档

## 🚀 部署说明
所有服务已成功启动并通过验证:
- GitLab: http://localhost:28082 (root/SecurePass2024!)
- Gitea: http://localhost:23000
- Harbor: http://localhost:28081
- Grafana: http://localhost:23001 (admin/123456)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-22 00:19:41 +08:00

698 lines
22 KiB
Bash
Executable File

#!/bin/bash
# Harbor Kubernetes 镜像预下载和推送脚本
# 自动下载常用的 Kubernetes 相关镜像并推送到 Harbor 仓库
set -euo pipefail
# 配置变量
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
HARBOR_DOMAIN="${HARBOR_DOMAIN:-192.168.1.83}"
HARBOR_PORT="${HARBOR_PORT:-8080}"
HARBOR_HTTPS_PORT="${HARBOR_HTTPS_PORT:-8443}"
HARBOR_USER="${HARBOR_USER:-admin}"
HARBOR_PASSWORD="${HARBOR_PASSWORD:-admin}"
HARBOR_PROJECT="${HARBOR_PROJECT:-kubernetes}"
HARBOR_USE_HTTPS="${HARBOR_USE_HTTPS:-true}"
LOG_FILE="${LOG_FILE:-~/ops/logs/harbor-k8s-images.log}"
IMAGES_CONFIG_FILE="${IMAGES_CONFIG_FILE:-${SCRIPT_DIR}/k8s-images.list}"
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
PURPLE='\033[0;35m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color
# 日志函数
log() {
echo -e "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "${LOG_FILE}"
}
info() {
log "${BLUE}[INFO]${NC} $1"
}
success() {
log "${GREEN}[SUCCESS]${NC} $1"
}
warning() {
log "${YELLOW}[WARNING]${NC} $1"
}
error() {
log "${RED}[ERROR]${NC} $1"
}
progress() {
log "${PURPLE}[PROGRESS]${NC} $1"
}
# 检查必要的依赖
check_dependencies() {
local deps=("docker" "curl" "jq")
for dep in "${deps[@]}"; do
if ! command -v "$dep" &> /dev/null; then
error "$dep 未安装,请先安装 $dep"
exit 1
fi
done
# 检查 Docker 是否运行
if ! docker info &> /dev/null; then
error "Docker 未运行,请启动 Docker Desktop"
exit 1
fi
}
# 创建必要的目录
ensure_directories() {
mkdir -p "$(dirname "${LOG_FILE}")"
mkdir -p "$(dirname "${IMAGES_CONFIG_FILE}")"
}
# 检查 Harbor 连接
check_harbor_connection() {
info "检查 Harbor 连接..."
local harbor_url
local curl_opts=""
if [[ "$HARBOR_USE_HTTPS" == "true" ]]; then
harbor_url="https://${HARBOR_DOMAIN}:${HARBOR_HTTPS_PORT}"
curl_opts="-k" # 忽略证书验证
else
harbor_url="http://${HARBOR_DOMAIN}:${HARBOR_PORT}"
fi
# 检查 Harbor 服务是否可用
if ! curl -s -f $curl_opts "${harbor_url}/api/v2.0/health" > /dev/null 2>&1; then
error "无法连接到 Harbor 服务: ${harbor_url}"
error "请确保 Harbor 服务正在运行"
return 1
fi
success "Harbor 连接正常: ${harbor_url}"
return 0
}
# Harbor 登录
harbor_login() {
info "登录 Harbor 仓库..."
local harbor_port
if [[ "$HARBOR_USE_HTTPS" == "true" ]]; then
harbor_port="${HARBOR_HTTPS_PORT}"
else
harbor_port="${HARBOR_PORT}"
fi
# 尝试登录 Harbor
if echo "${HARBOR_PASSWORD}" | docker login "${HARBOR_DOMAIN}:${harbor_port}" -u "${HARBOR_USER}" --password-stdin 2>/dev/null; then
success "Harbor 登录成功"
return 0
else
# 如果直接登录失败,提供解决方案
error "Harbor 登录失败"
info "可能的解决方案:"
info "1. 对于 HTTPS + 自签名证书,尝试以下命令:"
info " mkdir -p ~/.docker && echo '{\"insecure-registries\":[\"${HARBOR_DOMAIN}:${harbor_port}\"]}' > ~/.docker/daemon.json"
info " 然后重启 OrbStack"
info ""
info "2. 或者使用 HTTP 方式(如果 Harbor 支持):"
info " HARBOR_USE_HTTPS=false ./harbor-k8s-images.sh sync"
info ""
info "3. 检查 Harbor Web 界面确认用户名和密码是否正确"
return 1
fi
}
# 创建 Harbor 项目(如果不存在)
ensure_harbor_project() {
info "确保 Harbor 项目 '${HARBOR_PROJECT}' 存在..."
local harbor_url
local curl_opts=""
if [[ "$HARBOR_USE_HTTPS" == "true" ]]; then
harbor_url="https://${HARBOR_DOMAIN}:${HARBOR_HTTPS_PORT}"
curl_opts="-k"
else
harbor_url="http://${HARBOR_DOMAIN}:${HARBOR_PORT}"
fi
local project_url="${harbor_url}/api/v2.0/projects"
# 检查项目是否存在
if curl -s $curl_opts -u "${HARBOR_USER}:${HARBOR_PASSWORD}" "${project_url}?name=${HARBOR_PROJECT}" | jq -e '.[] | select(.name == "'"${HARBOR_PROJECT}"'")' > /dev/null 2>&1; then
success "项目 '${HARBOR_PROJECT}' 已存在"
return 0
fi
# 创建项目
info "创建项目 '${HARBOR_PROJECT}'..."
local create_data="{\"project_name\":\"${HARBOR_PROJECT}\",\"public\":true}"
if curl -s $curl_opts -u "${HARBOR_USER}:${HARBOR_PASSWORD}" \
-H "Content-Type: application/json" \
-d "${create_data}" \
"${project_url}" > /dev/null 2>&1; then
success "项目 '${HARBOR_PROJECT}' 创建成功"
return 0
else
error "项目 '${HARBOR_PROJECT}' 创建失败"
return 1
fi
}
# 创建默认镜像配置文件
create_default_images_config() {
if [[ -f "${IMAGES_CONFIG_FILE}" ]]; then
return 0
fi
info "创建默认镜像配置文件: ${IMAGES_CONFIG_FILE}"
cat > "${IMAGES_CONFIG_FILE}" << 'EOF'
# Kubernetes 镜像列表配置
# 格式: <镜像名称>:<标签> <目标仓库别名> <描述>
# 别名用于在 Harbor 中组织镜像,可以使用 / 分层
# 核心组件
k8s.gcr.io/kube-apiserver:v1.28.0 kube-apiserver Kubernetes API Server
k8s.gcr.io/kube-controller-manager:v1.28.0 kube-controller-manager Kubernetes Controller Manager
k8s.gcr.io/kube-scheduler:v1.28.0 kube-scheduler Kubernetes Scheduler
k8s.gcr.io/kube-proxy:v1.28.0 kube-proxy Kubernetes Proxy
k8s.gcr.io/etcd:3.5.9-0 etcd etcd Key-Value Store
k8s.gcr.io/coredns/coredns:v1.10.1 coredns CoreDNS Service Discovery
k8s.gcr.io/pause:3.9 pause Kubernetes Pause Container
# 网络组件
quay.io/calico/cni:v3.26.0 calico/cni Calico CNI Plugin
quay.io/calico/node:v3.26.0 calico/node Calico Node Agent
quay.io/calico/kube-controllers:v3.26.0 calico/kube-controllers Calico Kubernetes Controllers
quay.io/calico/typha:v3.26.0 calico/typha Calico Typha Daemon
flannelcni/flannel:v0.22.0 flannel Flannel CNI Plugin
flannel/flannel-cni-plugin:v1.2.0 flannel-cni-plugin Flannel CNI Plugin
# Ingress 控制器
registry.k8s.io/ingress-nginx/controller:v1.9.4 ingress-nginx/controller NGINX Ingress Controller
registry.k8s.io/ingress-nginx/kube-webhook-certgen:v1.4.0 ingress-nginx/kube-webhook-certgen NGINX Webhook Cert Generator
# 存储组件
quay.io/external_storage/rbd-provisioner:v2.1.1-k8s1.11 rbd-provisioner Ceph RBD Provisioner
quay.io/ceph/ceph:v15.2.17 ceph Ceph Container
quay.io/cephcsi/cephcsi:v3.7.0 cephcsi Ceph CSI Driver
# 监控组件
prom/prometheus:v2.45.0 prometheus Prometheus Monitoring
prom/alertmanager:v0.25.0 alertmanager AlertManager
grafana/grafana:10.1.0 grafana Grafana Visualization
quay.io/prometheus-operator/prometheus-operator:v0.68.0 prometheus-operator Prometheus Operator
quay.io/prometheus-operator/prometheus-config-reloader:v0.68.0 prometheus-config-reloader Prometheus Config Reloader
# 日志组件
fluent/fluent-bit:2.2.0 fluent-bit Fluent Bit Log Processor
elastic/elasticsearch:8.8.0 elasticsearch Elasticsearch
elastic/kibana:8.8.0 kibana Kibana Visualization
# 安全组件
quay.io/coreos/oidc-discovery-provider:v1.0 oidc-discovery-provider OIDC Discovery Provider
quay.io/jetstack/cert-manager-controller:v1.13.0 cert-manager/cert-manager-cert-manager Cert Manager Controller
quay.io/jetstack/cert-manager-webhook:v1.13.0 cert-manager/cert-manager-webhook Cert Manager Webhook
quay.io/jetstack/cert-manager-cainjector:v1.13.0 cert-manager/cert-manager-cainjector Cert Manager CA Injector
# CI/CD 组件
gcr.io/kaniko-project/executor:v1.9.1 kaniko Kaniko Image Builder
argoproj/argo-cd:v2.7.3 argo-cd ArgoCD GitOps
argoproj/argo-workflows:v3.4.8 argo-workflows Argo Workflows
gcr.io/jenkinsx/inigo:0.1.73 inigo Jenkins X Build Controller
# 服务网格
istio/proxyv2:1.19.0 istio/proxyv2 Istio Envoy Proxy
istio/pilot:1.19.0 istio/pilot Istio Pilot
docker.io/istio/citadel:1.19.0 istio/citadel Istio Citadel
# 数据库
postgres:15.3 postgres PostgreSQL Database
mysql:8.1.0 mysql MySQL Database
redis:7.0.11 redis Redis Cache
mongo:6.0.13 mongo MongoDB
# 应用镜像
nginx:1.24.0 nginx Nginx Web Server
httpd:2.4.57 httpd Apache HTTP Server
tomcat:10.1.13-jdk11-temurin tomcat Apache Tomcat
openjdk:17-jdk-slim openjdk OpenJDK 17
python:3.11.4-slim python Python 3.11
node:18.16.1-slim node Node.js 18
# 工具镜像
busybox:1.36.1 busybox BusyBox Utilities
alpine:3.18.3 alpine Alpine Linux
ubuntu:22.04 ubuntu Ubuntu 22.04
# 多架构支持
--multi-arch k8s.gcr.io/kube-apiserver:v1.28.0 kube-apiserver-multi Kubernetes API Server (Multi-arch)
--multi-arch k8s.gcr.io/kube-controller-manager:v1.28.0 kube-controller-manager-multi Kubernetes Controller Manager (Multi-arch)
--multi-arch k8s.gcr.io/kube-scheduler:v1.28.0 kube-scheduler-multi Kubernetes Scheduler (Multi-arch)
EOF
success "默认镜像配置文件已创建"
info "您可以编辑 ${IMAGES_CONFIG_FILE} 来自定义镜像列表"
}
# 解析镜像配置
parse_images_config() {
local images=()
if [[ ! -f "${IMAGES_CONFIG_FILE}" ]]; then
error "镜像配置文件不存在: ${IMAGES_CONFIG_FILE}"
return 1
fi
while IFS= read -r line; do
# 跳过空行和注释
[[ -z "$line" || "$line" =~ ^[[:space:]]*# ]] && continue
# 解析多架构标记
local multi_arch=false
if [[ "$line" =~ ^--multi-arch[[:space:]]+(.+)$ ]]; then
multi_arch=true
line="${BASH_REMATCH[1]}"
fi
# 解析镜像信息
if [[ "$line" =~ ^([a-zA-Z0-9.-_/]+:[^[:space:]]+)[[:space:]]+([^[:space:]]+)[[:space:]]*(.*)$ ]]; then
local source_image="${BASH_REMATCH[1]}"
local target_alias="${BASH_REMATCH[2]}"
local description="${BASH_REMATCH[3]}"
images+=("$source_image|$target_alias|$description|$multi_arch")
fi
done < "${IMAGES_CONFIG_FILE}"
if [[ ${#images[@]} -eq 0 ]]; then
error "镜像配置文件中没有找到有效的镜像配置"
return 1
fi
printf '%s\n' "${images[@]}"
return 0
}
# 获取镜像架构信息
get_image_architectures() {
local image="$1"
local arch_info
# 使用 docker manifest inspect 获取架构信息
if arch_info=$(docker manifest inspect "$image" 2>/dev/null); then
echo "$arch_info" | jq -r '.manifests[].platform.architecture' | sort -u | tr '\n' ',' | sed 's/,$//'
else
# 如果没有 manifest 信息,尝试获取本地镜像的架构
if docker image inspect "$image" &>/dev/null; then
docker image inspect "$image" --format='{{.Architecture}}' 2>/dev/null || echo "amd64"
else
echo "amd64" # 默认架构
fi
fi
}
# 拉取镜像
pull_image() {
local source_image="$1"
local multi_arch="${2:-false}"
info "拉取镜像: $source_image"
if [[ "$multi_arch" == "true" ]]; then
# 拉取多架构镜像
if docker manifest create "$source_image" >/dev/null 2>&1 || true; then
docker manifest rm "$source_image" >/dev/null 2>&1 || true
fi
if docker pull "$source_image" --platform linux/amd64,linux/arm64; then
success "多架构镜像拉取成功: $source_image"
return 0
else
warning "多架构镜像拉取失败,尝试单架构拉取"
if docker pull "$source_image"; then
success "镜像拉取成功: $source_image"
return 0
else
error "镜像拉取失败: $source_image"
return 1
fi
fi
else
# 拉取单架构镜像
if docker pull "$source_image"; then
success "镜像拉取成功: $source_image"
return 0
else
error "镜像拉取失败: $source_image"
return 1
fi
fi
}
# 推送镜像到 Harbor
push_image_to_harbor() {
local source_image="$1"
local target_alias="$2"
local multi_arch="${3:-false}"
local harbor_port
if [[ "$HARBOR_USE_HTTPS" == "true" ]]; then
harbor_port="${HARBOR_HTTPS_PORT}"
else
harbor_port="${HARBOR_PORT}"
fi
local harbor_image="${HARBOR_DOMAIN}:${harbor_port}/${HARBOR_PROJECT}/${target_alias}"
info "推送镜像到 Harbor: $source_image -> $harbor_image"
# 标记镜像
if docker tag "$source_image" "$harbor_image"; then
success "镜像标记成功: $harbor_image"
else
error "镜像标记失败: $source_image -> $harbor_image"
return 1
fi
# 推送镜像
if [[ "$multi_arch" == "true" ]]; then
# 推送多架构镜像
if docker push "$harbor_image"; then
success "多架构镜像推送成功: $harbor_image"
return 0
else
error "多架构镜像推送失败: $harbor_image"
return 1
fi
else
# 推送单架构镜像
if docker push "$harbor_image"; then
success "镜像推送成功: $harbor_image"
return 0
else
error "镜像推送失败: $harbor_image"
return 1
fi
fi
}
# 清理本地镜像
cleanup_local_image() {
local source_image="$1"
local harbor_image="$2"
# 可选:清理本地临时镜像
if [[ "${CLEANUP_LOCAL_IMAGES:-false}" == "true" ]]; then
info "清理本地镜像: $source_image"
docker rmi "$source_image" 2>/dev/null || true
docker rmi "$harbor_image" 2>/dev/null || true
fi
}
# 处理单个镜像
process_image() {
local image_info="$1"
IFS='|' read -r source_image target_alias description multi_arch <<< "$image_info"
progress "处理镜像: $source_image -> $target_alias ($description)"
# 拉取镜像
if ! pull_image "$source_image" "$multi_arch"; then
error "跳过镜像: $source_image (拉取失败)"
return 1
fi
# 推送到 Harbor
local harbor_port
if [[ "$HARBOR_USE_HTTPS" == "true" ]]; then
harbor_port="${HARBOR_HTTPS_PORT}"
else
harbor_port="${HARBOR_PORT}"
fi
local harbor_image="${HARBOR_DOMAIN}:${harbor_port}/${HARBOR_PROJECT}/${target_alias}"
if ! push_image_to_harbor "$source_image" "$target_alias" "$multi_arch"; then
error "跳过镜像: $source_image (推送失败)"
return 1
fi
# 清理本地镜像(可选)
cleanup_local_image "$source_image" "$harbor_image"
success "镜像处理完成: $target_alias"
return 0
}
# 同步所有镜像
sync_all_images() {
info "开始同步 Kubernetes 镜像到 Harbor..."
# 解析镜像配置
local images
if ! images=($(parse_images_config)); then
error "无法解析镜像配置"
return 1
fi
local total_images=${#images[@]}
local success_count=0
local failed_count=0
info "总共需要处理 ${total_images} 个镜像"
# 处理每个镜像
for i in "${!images[@]}"; do
local image_info="${images[$i]}"
local current_num=$((i + 1))
progress "[$current_num/$total_images] 处理镜像..."
if process_image "$image_info"; then
((success_count++))
else
((failed_count++))
fi
# 显示进度
local progress_percent=$((current_num * 100 / total_images))
echo -e "\r${CYAN}进度: ${progress_percent}% (${success_count} 成功, ${failed_count} 失败)${NC}"
done
echo "" # 换行
# 显示结果统计
info "镜像同步完成!"
success "成功: ${success_count} 个镜像"
if [[ $failed_count -gt 0 ]]; then
error "失败: ${failed_count} 个镜像"
return 1
fi
return 0
}
# 显示 Harbor 项目中的镜像
list_harbor_images() {
info "列出 Harbor 项目 '${HARBOR_PROJECT}' 中的镜像..."
local harbor_url="http://${HARBOR_DOMAIN}:${HARBOR_PORT}"
local project_id
# 获取项目 ID
project_id=$(curl -s -u "${HARBOR_USER}:${HARBOR_PASSWORD}" \
"${harbor_url}/api/v2.0/projects?name=${HARBOR_PROJECT}" | \
jq -r '.[] | select(.name == "'"${HARBOR_PROJECT}"'") | .project_id')
if [[ -z "$project_id" ]]; then
error "项目 '${HARBOR_PROJECT}' 不存在"
return 1
fi
# 获取仓库列表
local repositories
repositories=$(curl -s -u "${HARBOR_USER}:${HARBOR_PASSWORD}" \
"${harbor_url}/api/v2.0/projects/${project_id}/repositories" | \
jq -r '.[].name' | sed "s|^${HARBOR_PROJECT}/||" | sort)
if [[ -z "$repositories" ]]; then
warning "项目 '${HARBOR_PROJECT}' 中没有镜像"
return 0
fi
echo ""
echo -e "${BLUE}Harbor 项目 '${HARBOR_PROJECT}' 中的镜像:${NC}"
echo "--------------------------------------------------"
for repo in $repositories; do
# 获取标签信息
local tags
tags=$(curl -s -u "${HARBOR_USER}:${HARBOR_PASSWORD}" \
"${harbor_url}/api/v2.0/projects/${project_id}/repositories/${HARBOR_PROJECT}%2F${repo}/artifacts" | \
jq -r '.[].tags[0].name' | sort -u | tr '\n' ', ' | sed 's/,$//')
printf "%-40s %s\n" "$repo" "${tags:-N/A}"
done
echo "--------------------------------------------------"
}
# 清理 Harbor 项目中的镜像
cleanup_harbor_images() {
local keep_count="${1:-5}"
warning "清理 Harbor 项目 '${HARBOR_PROJECT}' 中的旧镜像 (保留最近 ${keep_count} 个版本)"
read -p "确定要继续吗? (y/N): " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
info "清理操作已取消"
return 0
fi
local harbor_url="http://${HARBOR_DOMAIN}:${HARBOR_PORT}"
local project_id
# 获取项目 ID
project_id=$(curl -s -u "${HARBOR_USER}:${HARBOR_PASSWORD}" \
"${harbor_url}/api/v2.0/projects?name=${HARBOR_PROJECT}" | \
jq -r '.[] | select(.name == "'"${HARBOR_PROJECT}"'") | .project_id')
if [[ -z "$project_id" ]]; then
error "项目 '${HARBOR_PROJECT}' 不存在"
return 1
fi
# 获取仓库列表并清理
local repositories
repositories=$(curl -s -u "${HARBOR_USER}:${HARBOR_PASSWORD}" \
"${harbor_url}/api/v2.0/projects/${project_id}/repositories" | \
jq -r '.[].name')
for repo_full in $repositories; do
local repo_name=$(echo "$repo_full" | sed "s|^${HARBOR_PROJECT}/||")
# 获取标签列表
local artifacts
artifacts=$(curl -s -u "${HARBOR_USER}:${HARBOR_PASSWORD}" \
"${harbor_url}/api/v2.0/projects/${project_id}/repositories/${repo_full}/artifacts" | \
jq -r '.[] | select(.tags != null) | "\(.tags[0].name)|\(.created)"')
if [[ -n "$artifacts" ]]; then
# 按创建时间排序,保留最新的 N 个
local old_tags
old_tags=$(echo "$artifacts" | sort -r | tail -n +$((keep_count + 1)) | cut -d'|' -f1)
for tag in $old_tags; do
info "删除旧镜像: ${repo_name}:${tag}"
curl -s -X DELETE -u "${HARBOR_USER}:${HARBOR_PASSWORD}" \
"${harbor_url}/api/v2.0/projects/${project_id}/repositories/${repo_full}/artifacts/${tag}" > /dev/null || true
done
fi
done
success "旧镜像清理完成"
}
# 显示帮助信息
show_help() {
cat << EOF
Harbor Kubernetes 镜像预下载和推送脚本
用法: $0 [命令] [参数]
命令:
sync 同步所有镜像到 Harbor
list 列出 Harbor 项目中的镜像
cleanup [数量] 清理 Harbor 项目中的旧镜像 (默认保留 5 个)
config 显示镜像配置文件路径
help 显示帮助信息
环境变量:
HARBOR_DOMAIN Harbor 域名 (默认: 192.168.1.83)
HARBOR_PORT Harbor 端口 (默认: 8080)
HARBOR_USER Harbor 用户名 (默认: admin)
HARBOR_PASSWORD Harbor 密码 (默认: admin)
HARBOR_PROJECT Harbor 项目名 (默认: kubernetes)
CLEANUP_LOCAL_IMAGES 是否清理本地镜像 (默认: false)
LOG_FILE 日志文件路径
IMAGES_CONFIG_FILE 镜像配置文件路径
镜像配置文件格式:
<源镜像>:<标签> <目标别名> <描述>
--multi-arch <源镜像>:<标签> <目标别名> <描述> # 多架构镜像
示例:
$0 sync # 同步所有镜像
$0 list # 列出 Harbor 中的镜像
$0 cleanup 10 # 保留最近 10 个版本
$0 config # 显示配置文件路径
配置文件编辑:
${IMAGES_CONFIG_FILE}
EOF
}
# 主函数
main() {
local command="${1:-help}"
# 设置环境变量
export PATH="/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:$PATH"
case "$command" in
"sync")
check_dependencies
ensure_directories
create_default_images_config
check_harbor_connection
harbor_login
ensure_harbor_project
sync_all_images
;;
"list")
check_dependencies
ensure_directories
check_harbor_connection
list_harbor_images
;;
"cleanup")
check_dependencies
ensure_directories
check_harbor_connection
harbor_login
cleanup_harbor_images "${2:-5}"
;;
"config")
check_dependencies
ensure_directories
create_default_images_config
echo "镜像配置文件: ${IMAGES_CONFIG_FILE}"
;;
"help"|"-h"|"--help")
show_help
;;
*)
error "未知命令: $command"
show_help
exit 1
;;
esac
}
# 如果脚本被直接执行,调用主函数
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
main "$@"
fi