容器不健康时,自动重启(进阶方案)

进阶方案:Docker Compose 配置(多容器场景)

若用 Docker Compose 管理容器,可在 docker-compose.yml 中统一配置健康检查和重启策略,更易维护。

示例 docker-compose.yml

yaml

version: '3.8'
services:
  nginx:
    image: nginx
    container_name: nginx-health
    restart: on-failure:5  # 重启策略:非0退出码时重启,最多5次
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:80"]  # 健康检查命令
      interval: 10s         # 检查间隔
      timeout: 5s           # 超时时间
      retries: 3            # 连续失败3次标记为不健康
      start_period: 30s     # 启动后延迟检查
启动命令

bash

运行

docker-compose up -d
<think>我们使用shell脚本来实现容器健康检查,通常可以通过以下步骤:1.使用`dockerinspect`命令获取容器健康状态。 2.解析输出,判断状态是否为"healthy"。 3.根据状态进行后续操作(如告警、重启容器等)。由于之前提到过几种解析方法,这里我们使用依赖jq的纯shell方法,以及使用jq的方法分别示例。 ###方法1:使用纯Shell解析(无jq依赖)```bash#!/bin/bash#定义容器名称CONTAINER_NAME="compose-web1-1" #获取健康状态health_status=$(sudo dockerinspect $CONTAINER_NAME| grep-A10'"Health":'| grep'"Status":'| cut-d'"'-f4) #判断状态if ["$health_status"= "healthy"]; thenecho "容器 $CONTAINER_NAME状态健康"#执行健康的操作elif ["$health_status"= "unhealthy" ];thenecho"容器$CONTAINER_NAME状态健康"#执行健康的操作,例如重启容器或者发送告警elif ["$health_status"= "starting"]; thenecho "容器 $CONTAINER_NAME正在启动中" elseecho "容器 $CONTAINER_NAME未配置健康检查或状态未知" fi```###方法2:使用jq工具(推荐,更可靠) ```bash#!/bin/bash#定义容器名称CONTAINER_NAME="compose-web1-1" #使用jq获取健康状态health_status=$(sudodocker inspect$CONTAINER_NAME |jq-r'.[0].State.Health.Status') #判断状态case $health_statusin"healthy")echo"容器$CONTAINER_NAME状态健康";;"unhealthy")echo"容器$CONTAINER_NAME状态健康"#执行健康的操作;;"starting")echo "容器 $CONTAINER_NAME正在启动中";;*)echo "容器 $CONTAINER_NAME未配置健康检查或状态未知: $health_status";; esac``` ###方法3:结合docker命令和shell直接获取如果容器是通过dockercompose管理的,还可以使用`docker-compose ps`命令,但输出格式可能直接包含健康状态。因此,我们主要使用`docker inspect`。###注意事项-确保执行脚本的用户有足够的权限(通常需要sudo)。-如果容器数量多,建议使用循环处理多个容器。 -在生产环境中,建议将健康检查脚本加入定任务(如cron)进行定期检查。###示例:定检查并重启健康容器```bash#!/bin/bashCONTAINER_NAME="compose-web1-1" health_status=$(sudo dockerinspect $CONTAINER_NAME| jq -r '.[0].State.Health.Status')if ["$health_status"= "unhealthy" ];thenecho"$(date)-容器 $CONTAINER_NAME状态健康,尝试重启..."sudodocker restart$CONTAINER_NAME#记录日志echo "$(date) -已重启容器$CONTAINER_NAME">> /var/log/container_monitor.logfi```将上述脚本保存为`check_container.sh`,然后加入crontab,例如每分钟检查一次: ```bash* ** ** /path/to/check_container.sh```§§相关问题§§1.如何用Shell脚本同监控多个容器健康状态? 2.在Docker Swarm或Kubernetes环境中,容器健康检查的方法有何同? 3.如何为没有配置健康检查的容器添加健康检查? 4.使用Shell脚本监控容器,如何避免因容器短暂停止而误判? 5.除了重启容器,还有哪些常见的容器健康处理措施?</think>### 使用 Shell 脚本实现容器健康检查 以下是几种实用的 Shell 脚本方案,用于监控 Docker 容器健康状态并执行自动化操作: #### 方案 1:基础状态检查脚本 ```bash #!/bin/bash # 配置参数 CONTAINER_NAME="compose-web1-1" MAX_RETRIES=3 RETRY_DELAY=5 # 获取健康状态函数 get_health_status() { docker inspect --format '{{.State.Health.Status}}' $CONTAINER_NAME 2>/dev/null } # 状态检查逻辑 status=$(get_health_status) case $status in "healthy") echo "[SUCCESS] $CONTAINER_NAME 状态健康" ;; "unhealthy") echo "[CRITICAL] $CONTAINER_NAME 状态异常!" # 添加告警或重启操作 ;; "starting") echo "[WARNING] $CONTAINER_NAME 正在启动..." ;; *) echo "[ERROR] 无法获取状态: $status" ;; esac ``` #### 方案 2:带重试机制的监控脚本 ```bash #!/bin/bash # 配置参数 CONTAINER_NAME="your_container" TIMEOUT=60 # 总超() INTERVAL=5 # 检查间隔 # 等待健康状态 start_time=$(date +%s) while : ; do status=$(docker inspect -f '{{.State.Health.Status}}' $CONTAINER_NAME) # 状态判断 [[ $status == "healthy" ]] && break # 超判断 current_time=$(date +%s) elapsed=$((current_time - start_time)) [[ $elapsed -ge $TIMEOUT ]] && { echo "启动超"; exit 1; } echo "等待健康状态... ($elapsed/$TIMEOUT 秒)" sleep $INTERVAL done echo "容器已就绪" ``` #### 方案 3:自动化修复脚本 ```bash #!/bin/bash CONTAINER_NAME="web_service" LOG_FILE="/var/log/container_monitor.log" # 监控循环 while true; do status=$(docker inspect -f '{{.State.Health.Status}}' $CONTAINER_NAME) timestamp=$(date "+%Y-%m-%d %H:%M:%S") if [ "$status" == "unhealthy" ]; then echo "$timestamp - 检测到异常状态,尝试重启容器..." | tee -a $LOG_FILE docker restart $CONTAINER_NAME >> $LOG_FILE 2>&1 # 等待重启完成 sleep 30 new_status=$(docker inspect -f '{{.State.Health.Status}}' $CONTAINER_NAME) [ "$new_status" == "healthy" ] && echo "重启成功" || echo "重启失败" fi sleep 60 # 每分钟检查一次 done ``` ### 关键功能说明 1. **核心命令** `docker inspect --format '{{.State.Health.Status}}'` 始终是获取状态的最直接方式 2. **进阶技巧** - 使用 `docker events` 实监听状态变化: ```bash docker events --filter 'event=health_status' --format '{{.Actor.Attributes.name}} 状态: {{.status}}' ``` - 结合 `curl` 检查服务端口: ```bash container_ip=$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $CONTAINER) curl -sSf http://$container_ip:8080/health > /dev/null && echo "服务响应正常" ``` 3. **部署建议** - 通过 crontab 定运行:`*/5 * * * * /opt/scripts/container_healthcheck.sh` - 使用 systemd 服务实现持久监控 - 集成到 Prometheus 监控系统: ```yaml # Docker exporter 配置示例 - job_name: 'docker' static_configs: - targets: ['docker-host:9323'] ``` > **最佳实践**:生产环境应结合日志记录(tee)、错误重试(retry logic)和通知机制(mail/mattermost)
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值