diff --git a/Docker容器管理面板 b/Docker容器管理面板 new file mode 100644 index 0000000..4fe7533 --- /dev/null +++ b/Docker容器管理面板 @@ -0,0 +1,449 @@ +#!/bin/bash + +# Docker 管理脚本 +# 功能:容器管理、端口监控、镜像管理、源配置 + +CONFIG_FILE="/etc/docker-manager.conf" +DOCKER_DAEMON_FILE="/etc/docker/daemon.json" +BACKUP_DIR="/opt/docker-backup" + +# 颜色定义 +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +# 日志函数 +log() { + echo -e "${GREEN}[$(date '+%Y-%m-%d %H:%M:%S')]${NC} $1" +} + +error() { + echo -e "${RED}[ERROR]${NC} $1" +} + +warning() { + echo -e "${YELLOW}[WARNING]${NC} $1" +} + +# 检查 Docker 是否安装 +check_docker() { + if ! command -v docker &> /dev/null; then + error "Docker 未安装,请先安装 Docker" + exit 1 + fi +} + +# 初始化配置 +init_config() { + if [ ! -f "$CONFIG_FILE" ]; then + mkdir -p $(dirname "$CONFIG_FILE") + cat > "$CONFIG_FILE" << EOF +# Docker 管理器配置文件 +DEFAULT_REGISTRY_MIRROR="https://docker.mirrors.ustc.edu.cn" +BACKUP_ENABLED=true +AUTO_CLEAN=false +LOG_RETENTION_DAYS=7 +EOF + log "配置文件已创建: $CONFIG_FILE" + fi + + if [ ! -d "$BACKUP_DIR" ]; then + mkdir -p "$BACKUP_DIR" + fi +} + +# 加载配置 +load_config() { + if [ -f "$CONFIG_FILE" ]; then + source "$CONFIG_FILE" + fi +} + +# 显示菜单 +show_menu() { + clear + echo "======================================" + echo " Docker 容器管理面板" + echo "======================================" + echo "1. 查看所有容器状态和端口" + echo "2. 查看容器详细信息" + echo "3. 启动/停止/重启容器" + echo "4. 删除容器" + echo "5. 查看镜像列表" + echo "6. 删除镜像" + echo "7. 清理无用镜像和容器" + echo "8. 设置 Docker 镜像源" + echo "9. 备份容器配置" + echo "10. 恢复容器配置" + echo "11. 查看资源使用情况" + echo "12. 退出" + echo "======================================" +} + +# 功能1: 查看所有容器状态和端口 +list_containers() { + log "正在获取容器信息..." + echo + echo -e "${BLUE}容器名称\t状态\t端口映射${NC}" + echo "--------------------------------------" + + docker ps -a --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" | tail -n +2 | while read line; do + name=$(echo "$line" | awk '{print $1}') + status=$(echo "$line" | awk '{print $2}') + ports=$(echo "$line" | awk '{$1=$2=""; print $0}' | sed 's/^ *//') + + if [[ "$status" == "Up" ]]; then + echo -e "${GREEN}$name\t$status\t$ports${NC}" + else + echo -e "${RED}$name\t$status\t$ports${NC}" + fi + done +} + +# 功能2: 查看容器详细信息 +inspect_container() { + list_containers + echo + read -p "请输入容器名称: " container_name + + if docker inspect "$container_name" &> /dev/null; then + echo + log "容器 $container_name 的详细信息:" + echo "--------------------------------------" + docker inspect "$container_name" | jq '.[0] | { + Name: .Name, + State: .State.Status, + Running: .State.Running, + IPAddress: .NetworkSettings.IPAddress, + Ports: .NetworkSettings.Ports, + Image: .Config.Image, + Created: .Created, + Mounts: .Mounts + }' + else + error "容器 $container_name 不存在" + fi +} + +# 功能3: 启动/停止/重启容器 +manage_container() { + list_containers + echo + read -p "请输入容器名称: " container_name + + if docker inspect "$container_name" &> /dev/null; then + echo + echo "1. 启动容器" + echo "2. 停止容器" + echo "3. 重启容器" + echo "4. 查看容器日志" + read -p "请选择操作: " action + + case $action in + 1) + docker start "$container_name" + log "容器 $container_name 已启动" + ;; + 2) + docker stop "$container_name" + log "容器 $container_name 已停止" + ;; + 3) + docker restart "$container_name" + log "容器 $container_name 已重启" + ;; + 4) + docker logs -f "$container_name" + ;; + *) + error "无效选择" + ;; + esac + else + error "容器 $container_name 不存在" + fi +} + +# 功能4: 删除容器 +delete_container() { + list_containers + echo + read -p "请输入要删除的容器名称: " container_name + + if docker inspect "$container_name" &> /dev/null; then + read -p "确定要删除容器 $container_name 吗?(y/N): " confirm + if [[ $confirm == "y" || $confirm == "Y" ]]; then + docker rm -f "$container_name" + log "容器 $container_name 已删除" + else + log "操作已取消" + fi + else + error "容器 $container_name 不存在" + fi +} + +# 功能5: 查看镜像列表 +list_images() { + log "镜像列表:" + echo + docker images --format "table {{.Repository}}\t{{.Tag}}\t{{.ID}}\t{{.Size}}" +} + +# 功能6: 删除镜像 +delete_image() { + list_images + echo + read -p "请输入要删除的镜像ID: " image_id + + if docker images --no-trunc | grep -q "$image_id"; then + read -p "确定要删除镜像 $image_id 吗?(y/N): " confirm + if [[ $confirm == "y" || $confirm == "Y" ]]; then + # 检查是否有容器使用此镜像 + if docker ps -a --filter ancestor="$image_id" | grep -q "$image_id"; then + error "有容器正在使用此镜像,请先删除相关容器" + return + fi + docker rmi "$image_id" + log "镜像 $image_id 已删除" + else + log "操作已取消" + fi + else + error "镜像 $image_id 不存在" + fi +} + +# 功能7: 清理无用资源 +cleanup() { + log "正在清理无用资源..." + + echo + read -p "是否清理已停止的容器?(y/N): " clean_containers + if [[ $clean_containers == "y" || $clean_containers == "Y" ]]; then + stopped_containers=$(docker ps -aq -f status=exited) + if [ -n "$stopped_containers" ]; then + docker rm $stopped_containers + log "已清理已停止的容器" + else + log "没有已停止的容器需要清理" + fi + fi + + echo + read -p "是否清理悬空镜像?(y/N): " clean_images + if [[ $clean_images == "y" || $clean_images == "Y" ]]; then + dangling_images=$(docker images -q -f dangling=true) + if [ -n "$dangling_images" ]; then + docker rmi $dangling_images + log "已清理悬空镜像" + else + log "没有悬空镜像需要清理" + fi + fi + + echo + read -p "是否清理无用网络?(y/N): " clean_networks + if [[ $clean_networks == "y" || $clean_networks == "Y" ]]; then + docker network prune -f + log "已清理无用网络" + fi + + echo + read -p "是否清理构建缓存?(y/N): " clean_build_cache + if [[ $clean_build_cache == "y" || $clean_build_cache == "Y" ]]; then + docker system prune -f + log "已清理构建缓存" + fi +} + +# 功能8: 设置 Docker 镜像源 +set_registry_mirror() { + echo + echo "可用的镜像源:" + echo "1. 中科大镜像源 (https://docker.mirrors.ustc.edu.cn)" + echo "2. 阿里云镜像源 (需要自行配置)" + echo "3. 网易镜像源 (https://hub-mirror.c.163.com)" + echo "4. 自定义镜像源" + echo "5. 恢复默认配置" + read -p "请选择镜像源: " mirror_choice + + case $mirror_choice in + 1) + registry_mirror="https://docker.mirrors.ustc.edu.cn" + ;; + 2) + read -p "请输入阿里云镜像源地址: " custom_mirror + registry_mirror="$custom_mirror" + ;; + 3) + registry_mirror="https://hub-mirror.c.163.com" + ;; + 4) + read -p "请输入自定义镜像源地址: " custom_mirror + registry_mirror="$custom_mirror" + ;; + 5) + registry_mirror="" + ;; + *) + error "无效选择" + return + ;; + esac + + # 备份原有配置 + if [ -f "$DOCKER_DAEMON_FILE" ]; then + cp "$DOCKER_DAEMON_FILE" "$DOCKER_DAEMON_FILE.bak" + log "原配置已备份到 $DOCKER_DAEMON_FILE.bak" + fi + + # 创建新的配置 + if [ -n "$registry_mirror" ]; then + cat > "$DOCKER_DAEMON_FILE" << EOF +{ + "registry-mirrors": ["$registry_mirror"] +} +EOF + log "已设置镜像源: $registry_mirror" + else + # 恢复默认配置 + if [ -f "$DOCKER_DAEMON_FILE" ]; then + rm "$DOCKER_DAEMON_FILE" + fi + log "已恢复默认配置" + fi + + # 重启 Docker 服务 + echo + read -p "需要重启 Docker 服务使配置生效,是否继续?(y/N): " restart_docker + if [[ $restart_docker == "y" || $restart_docker == "Y" ]]; then + systemctl restart docker + log "Docker 服务已重启,镜像源设置完成" + else + warning "请手动重启 Docker 服务以使配置生效" + fi +} + +# 功能9: 备份容器配置 +backup_containers() { + log "正在备份容器配置..." + + timestamp=$(date +%Y%m%d_%H%M%S) + backup_file="$BACKUP_DIR/backup_$timestamp.tar.gz" + + # 获取所有容器 + containers=$(docker ps -a --format "{{.Names}}") + + if [ -z "$containers" ]; then + error "没有找到任何容器" + return + fi + + temp_dir=$(mktemp -d) + + for container in $containers; do + log "备份容器: $container" + + # 导出容器配置 + docker inspect "$container" > "$temp_dir/${container}_inspect.json" + + # 如果容器正在运行,创建提交点 + if docker ps | grep -q "$container"; then + docker commit -p "$container" "backup_${container}:$timestamp" > /dev/null 2>&1 + fi + done + + # 打包备份文件 + tar -czf "$backup_file" -C "$temp_dir" . + rm -rf "$temp_dir" + + log "备份完成: $backup_file" +} + +# 功能10: 恢复容器配置 +restore_containers() { + log "可用的备份文件:" + ls -1 "$BACKUP_DIR"/*.tar.gz 2>/dev/null || echo "没有找到备份文件" + + read -p "请输入备份文件名: " backup_file + full_path="$BACKUP_DIR/$backup_file" + + if [ ! -f "$full_path" ]; then + error "备份文件不存在: $full_path" + return + fi + + temp_dir=$(mktemp -d) + tar -xzf "$full_path" -C "$temp_dir" + + for inspect_file in "$temp_dir"/*_inspect.json; do + if [ -f "$inspect_file" ]; then + container_name=$(basename "$inspect_file" | sed 's/_inspect.json//') + log "恢复容器配置: $container_name" + # 这里可以实现更复杂的恢复逻辑 + cat "$inspect_file" | docker config create "${container_name}_config" - > /dev/null 2>&1 + fi + done + + rm -rf "$temp_dir" + log "恢复完成" +} + +# 功能11: 查看资源使用情况 +show_resources() { + log "Docker 资源使用情况:" + echo + docker system df + + echo + log "容器资源使用情况:" + echo + docker stats --no-stream --format "table {{.Container}}\t{{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.NetIO}}\t{{.BlockIO}}" +} + +# 主循环 +main() { + check_docker + init_config + load_config + + while true; do + show_menu + read -p "请选择功能 (1-12): " choice + + case $choice in + 1) list_containers ;; + 2) inspect_container ;; + 3) manage_container ;; + 4) delete_container ;; + 5) list_images ;; + 6) delete_image ;; + 7) cleanup ;; + 8) set_registry_mirror ;; + 9) backup_containers ;; + 10) restore_containers ;; + 11) show_resources ;; + 12) + log "再见!" + exit 0 + ;; + *) + error "无效选择,请重新输入" + ;; + esac + + echo + read -p "按回车键继续..." + done +} + +# 脚本入口 +if [ "$(id -u)" -ne 0 ]; then + error "请使用 root 用户运行此脚本" + exit 1 +fi + +main