Shell脚本如何进入容器调试问题

wen 实用脚本 3

本文目录导读:

Shell脚本如何进入容器调试问题

  1. 使用
  2. 只读模式挂载

在Shell脚本中进入容器调试问题,主要有以下几种方法:

直接使用 docker exec 进入容器

基础用法

# 进入容器的交互式shell
docker exec -it 容器名称或ID /bin/bash
# 或者使用 sh(如果容器没有bash)
docker exec -it 容器名称或ID /bin/sh

在脚本中使用

#!/bin/bash
CONTAINER_NAME="myapp"
# 检查容器是否运行
if docker ps --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then
    echo "进入容器 $CONTAINER_NAME..."
    docker exec -it $CONTAINER_NAME /bin/bash
else
    echo "容器 $CONTAINER_NAME 未运行"
fi

调试特定服务或进程

查看容器内进程

#!/bin/bash
CONTAINER="webapp"
# 查看容器内的进程
docker exec $CONTAINER ps aux
# 查看特定服务状态
docker exec $CONTAINER systemctl status nginx
# 查看日志
docker exec $CONTAINER tail -f /var/log/app.log

复制文件进行调试

将脚本或工具复制到容器

#!/bin/bash
CONTAINER="myapp"
# 复制调试脚本到容器
docker cp debug.sh $CONTAINER:/tmp/
docker exec $CONTAINER chmod +x /tmp/debug.sh
docker exec $CONTAINER /tmp/debug.sh
# 从容器复制文件出来
docker cp $CONTAINER:/app/logs/error.log ./error.log

执行一次性调试命令

#!/bin/bash
CONTAINER="database"
# 检查网络连接
docker exec $CONTAINER ping -c 3 google.com
# 检查端口监听
docker exec $CONTAINER netstat -tlnp
# 检查磁盘使用
docker exec $CONTAINER df -h
# 检查内存使用
docker exec $CONTAINER free -m

完整的调试脚本示例

#!/bin/bash
# 调试脚本 - docker_debug.sh
CONTAINER_NAME=$1
DEBUG_MODE=${2:-"interactive"}
usage() {
    echo "用法: $0 <容器名称> [interactive|diagnostic]"
    exit 1
}
if [ -z "$CONTAINER_NAME" ]; then
    usage
fi
# 检查容器是否存在
if ! docker ps --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then
    echo "错误: 容器 $CONTAINER_NAME 未运行"
    exit 1
fi
case $DEBUG_MODE in
    "interactive")
        echo "进入交互式调试模式..."
        docker exec -it $CONTAINER_NAME /bin/bash
        ;;
    "diagnostic")
        echo "运行诊断检查..."
        # 系统信息
        echo "=== 系统信息 ==="
        docker exec $CONTAINER_NAME uname -a
        # 进程列表
        echo "=== 运行进程 ==="
        docker exec $CONTAINER_NAME ps aux
        # 磁盘使用
        echo "=== 磁盘使用 ==="
        docker exec $CONTAINER_NAME df -h
        # 内存使用
        echo "=== 内存使用 ==="
        docker exec $CONTAINER_NAME free -m
        # 网络连接
        echo "=== 网络连接 ==="
        docker exec $CONTAINER_NAME netstat -tlnp 2>/dev/null || \
        docker exec $CONTAINER_NAME ss -tlnp
        ;;
    *)
        usage
        ;;
esac

处理特殊情况

容器没有bash/shell

#!/bin/bash
CONTAINER="minimal-container"
# 尝试不同的shell
for shell in /bin/bash /bin/sh /bin/ash /bin/zsh; do
    if docker exec $CONTAINER test -f $shell 2>/dev/null; then
        docker exec -it $CONTAINER $shell
        break
    fi
done

使用nsenter进入容器命名空间

#!/bin/bash
CONTAINER="myapp"
# 获取容器PID
PID=$(docker inspect -f '{{.State.Pid}}' $CONTAINER)
# 使用nsenter进入容器
if [ -n "$PID" ]; then
    nsenter -t $PID -m -u -i -n -p
fi

调试Web应用程序

#!/bin/bash
CONTAINER="webapp"
# 检查Web服务器
echo "测试HTTP响应..."
docker exec $CONTAINER curl -s -o /dev/null -w "%{http_code}" http://localhost:80/
# 检查应用日志
echo "查看最近10行日志..."
docker exec $CONTAINER tail -10 /var/log/app.log
# 检查环境变量
echo "环境变量..."
docker exec $CONTAINER env | grep -E "APP_|DB_"

实用技巧

  1. 别名简化命令
    alias dexec='docker exec -it'

使用

dexec myapp /bin/bash


2. **批量调试多个容器**
```bash
#!/bin/bash
# 调试所有运行中的容器
for container in $(docker ps --format '{{.Names}}'); do
    echo "=== 调试 $container ==="
    docker exec $container hostname
    docker exec $container df -h /data
done
  1. 安全考虑
    # 以非root用户进入容器
    docker exec -u www-data -it myapp /bin/bash

只读模式挂载

docker exec -it --read-only myapp /bin/bash


选择哪种方式取决于你的调试需求:
- **交互式调试**:使用 `docker exec -it`
- **批量检查**:使用一次性命令
- **文件传输**:使用 `docker cp`
- **高级调试**:使用 `nsenter` 或 `docker inspect`

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