自动化脚本如何清理未使用标签

wen 实用脚本 21

本文目录导读:

自动化脚本如何清理未使用标签

  1. 清理 Docker 未使用标签(Dangling / Untagged Images)
  2. 清理 Git 仓库中的未使用标签(Git Tag Cleanup)
  3. 清理 AWS 未使用的资源标签(EC2 Tag Cleanup)
  4. 清理 Kubernetes 未使用的 Helm Release 标签
  5. 清理数据库中的未使用标签(如 PostgreSQL / MySQL)
  6. ⚠️ 安全与最佳实践

针对自动化清理未使用标签的需求,具体实现方式取决于你使用的平台(如 GitHub、GitLab、AWS、Kubernetes)或技术栈(如 Docker、数据库),以下是几种常见场景的自动化脚本方案及代码示例:


清理 Docker 未使用标签(Dangling / Untagged Images)

Docker 中未使用的标签通常指 <none>:<none> 镜像(dangling images)。

脚本(Bash):

#!/bin/bash
# 清理所有未使用的镜像(包括无标签和未被容器引用的)
echo "Start cleaning unused Docker images..."
# 清理 dangling 镜像(无标签)
docker image prune -a -f
# 或更彻底的清理:删除所有未被使用的镜像(注意:会删除未被任何容器引用的镜像)
# docker system prune -a -f
echo "Cleanup completed."

定时执行(cron):

# 每天凌晨2点执行
0 2 * * * /path/to/clean_docker.sh

清理 Git 仓库中的未使用标签(Git Tag Cleanup)

在 CI/CD 或长期项目中,Git 标签常因分支删除、版本迭代而失效。

预期行为: 删除所有不在远程某分支上的标签(或按模式筛选)。

脚本(Bash):

#!/bin/bash
# 定义远程名称(通常为 origin)
REMOTE="origin"
echo "Fetching latest remote refs..."
git fetch --prune $REMOTE
# 获取远程存在的所有标签(按需过滤)
echo "Listing remote tags..."
git tag -l | while read tag; do
    # 检查该标签是否指向有效的远程提交(如果标签已被删除,此处会失败)
    if ! git rev-parse --verify "$tag^{commit}" &>/dev/null; then
        echo "Deleting invalid tag: $tag"
        git push $REMOTE --delete "$tag"
        git tag -d "$tag"
    fi
done
# 另一种策略:删除所有本地已有但远程不存在的标签
echo "Pruning local tags not on remote..."
git tag -l | while read tag; do
    if [ -z "$(git ls-remote --tags $REMOTE | grep "refs/tags/$tag")" ]; then
        echo "Deleting local-only tag: $tag"
        git tag -d "$tag"
    fi
done

清理 AWS 未使用的资源标签(EC2 Tag Cleanup)

AWS 资源标签用于成本分配,未使用的旧标签会混乱管理。

前提: 需配置 AWS CLI 及适当权限。

脚本(Python + boto3):

import boto3
import sys
from datetime import datetime, timedelta
def cleanup_unused_ec2_tags(days_threshold=30):
    ec2 = boto3.client('ec2')
    # 获取所有已存在的标签(不局限于特定资源)
    tags = ec2.describe_tags()['Tags']
    # 找出最近30天未使用过的标签
    cutoff_time = datetime.utcnow() - timedelta(days=days_threshold)
    unused_tags = [tag for tag in tags 
                   if tag['ResourceType'] in ['instance', 'volume']  # 只关注实例和卷
                   and tag['LastUpdateTime'] < cutoff_time]
    if not unused_tags:
        print("No unused tags found.")
        return
    print(f"Will delete {len(unused_tags)} unused tags...")
    # 逐个删除(实际生产环境建议先review)
    for tag in unused_tags:
        ec2.delete_tags(
            Resources=[tag['ResourceId']],
            Tags=[{'Key': tag['Key']}]
        )
        print(f"Deleted tag {tag['Key']} from resource {tag['ResourceId']}")
if __name__ == '__main__':
    cleanup_unused_ec2_tags(days_threshold=60)  # 60天未更新视为未使用

清理 Kubernetes 未使用的 Helm Release 标签

Helm 部署后,可能残留旧的 Release 标签(如 releaseapp.kubernetes.io/managed-by)。

脚本(Bash + kubectl):

#!/bin/bash
# 清理所有没有对应 pod 的 Helm Release 标签(需要谨慎)
NAMESPACES=("default" "production")
for ns in "${NAMESPACES[@]}"; do
    echo "Checking namespace: $ns"
    # 列出所有 Helm Release 标签
    kubectl get pods -n "$ns" -o jsonpath='{range .items[*]}{.metadata.labels.release}{"\n"}{end}' | \
    sort | uniq | while read release; do
        if [ -z "$release" ]; then continue; fi
        # 检查该 release 是否还有其他 pod
        count=$(kubectl get pods -n "$ns" -l "release=$release" --no-headers 2>/dev/null | wc -l)
        if [ "$count" -eq 0 ]; then
            # 确认该 release 已被完全删除(或异常残留)
            echo "Found unused release label: $release in namespace $ns"
            # 可执行清理(注释掉以防误操作)
            # kubectl label pod --all -n "$ns" "release-$release-"  # 删除特定标签
        fi
    done
done

清理数据库中的未使用标签(如 PostgreSQL / MySQL)

应用层常维护 tags 表,需删除未被任何资源引用的标签行。

确保参考完整性: 假设存在 post_tags 关联表。

SQL脚本(适用于定时任务):

-- 清理 Postgres 中的未使用标签
DELETE FROM tags
WHERE id NOT IN (
    SELECT DISTINCT tag_id FROM post_tags
);
-- 或删除所有在最近90天内未使用的标签(需有最后使用时间字段)
DELETE FROM tags
WHERE last_used_at < NOW() - INTERVAL '90 days';

自动化任务(cron + psql):

0 3 * * 0 psql -U app_user -d mydb -c "DELETE FROM tags WHERE id NOT IN (SELECT DISTINCT tag_id FROM post_tags);"

⚠️ 安全与最佳实践

  1. 先模拟再执行: 使用 --dry-run--what-if 参数验证。
  2. 保留审计日志: 记录删除的标签、资源ID、时间。
  3. 版本控制: 将脚本放入 Git 仓库,确保可追溯。
  4. 分批次执行: 对大量资源(如 AWS 标签),每次处理100个,避免限速。
  5. 通知机制: 成功/失败时发送通知(Slack、邮件)。

需要针对具体平台(如 GitLab、Azure、Harbor)的定制方案,请补充说明。

抱歉,评论功能暂时关闭!