设置自启动程序的方式有很多,从最简单的"启动文件夹",到进阶的"任务计划程序""注册表"和"企业环境组策略"等等。相较于其它方式,使用"任务计划程序"可以避免 UAC(用户账户控制)弹窗,并且支持更灵活的启动条件,包括用户登录时、系统启动时、延迟 X 秒 / X 分钟启动、仅在某个用户登录时启动、仅在接通电源 / 网络可用时启动、失败后自动重试等等。
Docker常见问题与解决 - 教程
一、安装与启动问题
1.1 Docker服务启动失败
1.1.1 问题现象
|---------------------------------------------------------------------------------------------|
| # 启动Docker服务失败 |
| sudo systemctl start docker |
| Job for docker.service failed because the control process exited with error code. |
| See "systemctl status docker.service" and "journalctl -xe" for details. |
| # 查看服务状态 |
| sudo systemctl status docker.service |
| ● docker.service - Docker Application Container Engine |
| Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; vendor preset: disabled) |
| Active: failed (Result: exit-code) since Tue 2024-01-15 10:30:45 CST; 5min ago |
| Docs: https://docs.docker.com |
| Process: 1234 ExecStart=/usr/bin/dockerd (code=exited, status=1/FAILURE) |
| Main PID: 1235 (code=exited, status=1/FAILURE) |
1.1.2 常见原因及解决方案
原因1:存储驱动不兼容
|---------------------------------------------|
| # 检查系统支持的存储驱动 |
| lsmod | grep overlay |
| # 如果没有overlay模块,尝试加载 |
| sudo modprobe overlay |
| # 检查内核版本是否支持 |
| uname -r |
| # 需要内核版本3.18以上支持overlay |
| # 修改Docker配置文件 |
| sudo tee /etc/docker/daemon.json <<-'EOF' |
| { |
| "storage-driver": "devicemapper" |
| } |
| EOF |
| # 重启Docker服务 |
| sudo systemctl restart docker |
原因2:SELinux冲突
|----------------------------------------------------------------------------|
| # 临时关闭SELinux |
| sudo setenforce 0 |
| # 永久关闭SELinux(不推荐生产环境) |
| sudo sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config |
| # 或者配置Docker与SELinux兼容 |
| sudo tee /etc/docker/daemon.json <<-'EOF' |
| { |
| "selinux-enabled": false |
| } |
| EOF |
| # 重启Docker服务 |
| sudo systemctl restart docker |
原因3:端口冲突
|------------------------------------------------------------------|
| # 检查端口占用 |
| sudo netstat -tlnp | grep :2375 |
| sudo netstat -tlnp | grep :2376 |
| # 修改Docker守护进程端口 |
| sudo tee /etc/docker/daemon.json <<-'EOF' |
| { |
| "hosts": ["unix:///var/run/docker.sock", "tcp://0.0.0.0:2376"] |
| } |
| EOF |
| # 重启Docker服务 |
| sudo systemctl restart docker |
1.1.3 诊断步骤
|--------------------------------------------------------------|
| # 1. 查看详细错误日志 |
| sudo journalctl -u docker.service -n 50 |
| # 2. 检查Docker配置文件语法 |
| sudo dockerd --config-file /etc/docker/daemon.json --debug |
| # 3. 手动启动Docker守护进程查看错误 |
| sudo dockerd --debug |
| # 4. 检查系统资源 |
| df -h |
| free -h |
1.2 安装后无法使用Docker命令
1.2.1 问题现象
|-------------------------------------------------------------------------------------------------------------|
| # 普通用户执行Docker命令报错 |
| docker ps |
| Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: |
| Get "http://%2Fvar%2Frun%2Fdocker.sock/v1.24/containers/json": |
| dial unix /var/run/docker.sock: connect: permission denied |
1.2.2 解决方案
方案1:将用户添加到docker组
|---------------------------------|
| # 创建docker用户组(如果不存在) |
| sudo groupadd docker |
| # 将当前用户添加到docker组 |
| sudo usermod -aG docker $USER |
| # 激活用户组(需要重新登录或执行以下命令) |
| newgrp docker |
| # 验证权限设置 |
| docker ps |
方案2:配置sudo权限(临时解决方案)
|------------------------------------------------|
| # 编辑sudoers文件 |
| sudo visudo |
| # 添加以下行(将username替换为实际用户名) |
| username ALL=(ALL) NOPASSWD: /usr/bin/docker |
| # 保存后测试 |
| sudo docker ps |
方案3:修改Docker socket权限
|-----------------------------------------------|
| # 修改socket文件权限 |
| sudo chmod 666 /var/run/docker.sock |
| # 或者修改socket文件所属组 |
| sudo chown root:docker /var/run/docker.sock |
| sudo chmod 660 /var/run/docker.sock |
1.3 内核版本不兼容
1.3.1 问题现象
|---------------------------------------------------------------------|
| # 安装Docker时提示内核版本过低 |
| Error: Package: docker-ce-20.10.7-3.el7.x86_64 (docker-ce-stable) |
| Requires: container-selinux >= 2:2.74 |
| Available: container-selinux-2:2.74-1.el7.noarch (extras) |
| container-selinux = 2:2.74-1.el7 |
| Error: Package: docker-ce-20.10.7-3.el7.x86_64 (docker-ce-stable) |
| Requires: kernel >= 3.10 |
1.3.2 解决方案
方案1:升级内核版本
|-------------------------------------------------------------------------------|
| # 对于CentOS/RHEL系统 |
| # 导入ELRepo仓库 |
| sudo rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org |
| sudo rpm -Uvh https://www.elrepo.org/elrepo-release-7.el7.elrepo.noarch.rpm |
| # 安装最新内核 |
| sudo yum --enablerepo=elrepo-kernel install kernel-ml |
| # 更新GRUB配置 |
| sudo grub2-set-default 0 |
| sudo grub2-mkconfig -o /boot/grub2/grub.cfg |
| # 重启系统 |
| sudo reboot |
| # 验证内核版本 |
| uname -r |
方案2:安装兼容的Docker版本
|-----------------------------------------------------------------------------|
| # 查看可用的Docker版本 |
| yum list docker-ce --showduplicates | sort -r |
| # 安装较旧的兼容版本 |
| sudo yum install -y docker-ce-18.09.1 docker-ce-cli-18.09.1 containerd.io |
| # 启动Docker服务 |
| sudo systemctl start docker |
| sudo systemctl enable docker |
二、镜像管理问题
2.1 镜像拉取失败
2.1.1 问题现象
|------------------------------------------------------------------------------------------------------------|
| # 拉取镜像时失败 |
| docker pull nginx:latest |
| Error response from daemon: Get "https://registry-1.docker.io/v2/": |
| net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers) |
2.1.2 常见原因及解决方案
原因1:网络连接问题
|-----------------------------------------|
| # 检查网络连接 |
| ping registry-1.docker.io |
| # 检查DNS解析 |
| nslookup registry-1.docker.io |
| # 配置DNS服务器 |
| sudo tee /etc/resolv.conf <<-'EOF' |
| nameserver 8.8.8.8 |
| nameserver 8.8.4.4 |
| nameserver 1.1.1.1 |
| EOF |
| # 重启网络服务 |
| sudo systemctl restart NetworkManager |
原因2:镜像源访问限制
|----------------------------------------------------|
| # 配置国内镜像加速器 |
| sudo tee /etc/docker/daemon.json <<-'EOF' |
| { |
| "registry-mirrors": [ |
| "https://docker.m.daocloud.io", |
| "https://docker.1ms.run", |
| "https://hub.xdark.top", |
| "https://dockerhub.icu" |
| ] |
| } |
| EOF |
| # 重启Docker服务 |
| sudo systemctl restart docker |
| # 验证配置 |
| sudo docker info | grep -A 10 "Registry Mirrors" |
原因3:代理配置问题
|--------------------------------------------------------------------------|
| # 配置Docker代理 |
| sudo mkdir -p /etc/systemd/system/docker.service.d |
| sudo tee /etc/systemd/system/docker.service.d/http-proxy.conf <<-'EOF' |
| [Service] |
| Environment="HTTP_PROXY=http://proxy.example.com:80" |
| Environment="HTTPS_PROXY=http://proxy.example.com:80" |
| Environment="NO_PROXY=localhost,127.0.0.1" |
| EOF |
| # 重新加载systemd配置 |
| sudo systemctl daemon-reload |
| sudo systemctl restart docker |
2.1.3 高级解决方案
使用离线镜像
|----------------------------------------------------------|
| # 在有网络的环境中导出镜像 |
| docker save nginx:latest > nginx-latest.tar |
| # 传输到目标环境 |
| scp nginx-latest.tar user@target-server:/path/to/save/ |
| # 在目标环境中导入镜像 |
| docker load -i nginx-latest.tar |
配置私有镜像仓库
|-----------------------------------------------------------|
| # 配置私有仓库(以Harbor为例) |
| sudo tee /etc/docker/daemon.json <<-'EOF' |
| { |
| "insecure-registries": ["harbor.example.com"], |
| "registry-mirrors": ["https://harbor.example.com"] |
| } |
| EOF |
| # 登录私有仓库 |
| docker login harbor.example.com -u username -p password |
| # 从私有仓库拉取镜像 |
| docker pull harbor.example.com/library/nginx:latest |
2.2 镜像构建错误
2.2.1 问题现象
|-------------------------------------------------------------------------------------------------|
| # 构建镜像时失败 |
| docker build -t my-app . |
| Sending build context to Docker daemon 2.048kB |
| Error response from daemon: Dockerfile parse error line 1: unknown instruction: NODE_VERSION" |
2.2.2 常见构建错误及解决方案
错误1:Dockerfile语法错误
|-----------------------------|
| # 错误的Dockerfile示例 |
| NODE_VERSION=14 |
| FROM node:${NODE_VERSION} |
| WORKDIR /app |
| COPY . . |
| RUN npm install |
| CMD ["npm", "start"] |
解决方案:
|-----------------------------|
| # 正确的Dockerfile示例 |
| ARG NODE_VERSION=14 |
| FROM node:${NODE_VERSION} |
| WORKDIR /app |
| COPY . . |
| RUN npm install |
| CMD ["npm", "start"] |
错误2:构建上下文问题
|---------------------------------------|
| # 错误:构建上下文包含不必要的文件 |
| # 解决方案:使用.dockerignore文件 |
| echo "node_modules" > .dockerignore |
| echo ".git" >> .dockerignore |
| echo "*.log" >> .dockerignore |
| # 重新构建 |
| docker build -t my-app . |
错误3:网络连接问题
|------------------------|
| # 在构建过程中需要下载依赖但网络不可用 |
| # 解决方案:使用缓存或预下载依赖 |
解决方案:
|----------------------------------------|
| # 使用多阶段构建减少网络依赖 |
| FROM node:14 as builder |
| WORKDIR /app |
| COPY package*.json ./ |
| RUN npm install |
| COPY . . |
| RUN npm run build |
| FROM node:14-alpine |
| WORKDIR /app |
| COPY --from=builder /app/dist ./dist |
| COPY package*.json ./ |
| RUN npm install --production |
| CMD ["npm", "start"] |
2.2.3 构建优化技巧
使用构建缓存
|---------------------------------------|
| # 查看构建缓存 |
| docker builder prune |
| # 清理构建缓存 |
| docker builder prune -f |
| # 使用--no-cache重新构建 |
| docker build --no-cache -t my-app . |
多架构构建
|-----------------------------------------------------------------------------|
| # 启用实验性功能 |
| export DOCKER_CLI_EXPERIMENTAL=enabled |
| # 创建构建器实例 |
| docker buildx create --use --name mybuilder |
| # 构建多架构镜像 |
| docker buildx build --platform linux/amd64,linux/arm64 -t my-app:latest . |
2.3 镜像存储空间不足
2.3.1 问题现象
|-----------------------------------------------------------------------------------------------------|
| # 拉取镜像时提示空间不足 |
| docker pull redis:latest |
| Error response from daemon: write /var/lib/docker/tmp/GetImageBlob123456: no space left on device |
| # 查看磁盘使用情况 |
| df -h |
| Filesystem Size Used Avail Use% Mounted on |
| /dev/sda1 20G 19G 1.2G 95% / |
2.3.2 解决方案
方案1:清理未使用的资源
|---------------------------|
| # 清理所有未使用的镜像、容器、网络和构建缓存 |
| docker system prune -a |
| # 清理未使用的镜像(谨慎使用) |
| docker image prune -a |
| # 清理未使用的容器 |
| docker container prune |
| # 清理未使用的网络 |
| docker network prune |
| # 清理未使用的卷 |
| docker volume prune |
方案2:修改Docker存储位置
|--------------------------------------------------|
| # 停止Docker服务 |
| sudo systemctl stop docker |
| # 创建新的存储目录 |
| sudo mkdir -p /data/docker |
| # 移动现有数据 |
| sudo rsync -avP /var/lib/docker/ /data/docker/ |
| # 修改Docker配置文件 |
| sudo tee /etc/docker/daemon.json <<-'EOF' |
| { |
| "data-root": "/data/docker" |
| } |
| EOF |
| # 启动Docker服务 |
| sudo systemctl start docker |
| # 验证新的存储位置 |
| docker info | grep "Docker Root Dir" |
方案3:使用外部存储
|---------------------------------------------|
| # 挂载外部存储设备 |
| sudo mount /dev/sdb1 /data |
| # 创建软链接 |
| sudo ln -s /data/docker /var/lib/docker |
| # 或者修改配置文件 |
| sudo tee /etc/docker/daemon.json <<-'EOF' |
| { |
| "data-root": "/data/docker" |
| } |
| EOF |
| # 重启Docker服务 |
| sudo systemctl restart docker |
三、容器运行问题
3.1 容器启动失败
3.1.1 问题现象
|---------------------------------------------------------------------------------------|
| # 启动容器时失败 |
| docker run -d --name my-app my-app-image |
| Error response from daemon: failed to create endpoint my-app on network bridge: |
| failed to add interface veth123456 to bridge: operation not supported |
| # 查看容器状态 |
| docker ps -a |
| CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES |
| abc123456789 my-app-image "npm start" 5 seconds ago Exited (1) 4 seconds ago my-app |
3.1.2 诊断步骤
步骤1:查看容器日志
|--------------------------------|
| # 查看容器日志 |
| docker logs my-app |
| # 查看最后几行日志 |
| docker logs --tail 20 my-app |
| # 实时查看日志 |
| docker logs -f my-app |
步骤2:检查容器配置
|----------------------------------------------------------|
| # 查看容器详细信息 |
| docker inspect my-app |
| # 检查容器状态 |
| docker inspect my-app --format='{``{.State.Status}}' |
| # 检查容器退出码 |
| docker inspect my-app --format='{``{.State.ExitCode}}' |
步骤3:手动运行调试
|--------------------------------------------------------------------------------------------------------------|
| # 以交互模式运行容器 |
| docker run -it --rm --name my-app-debug my-app-image /bin/bash |
| # 或者覆盖启动命令 |
| docker run -it --rm --name my-app-debug my-app-image /bin/sh -c "while true; do echo hello; sleep 1; done" |
3.1.3 常见启动失败原因及解决方案
原因1:端口冲突
|-------------------------------------------------------|
| # 检查端口占用 |
| sudo netstat -tlnp | grep :8080 |
| # 解决方案:使用不同端口 |
| docker run -d --name my-app -p 8081:80 my-app-image |
| # 或者停止占用端口的进程 |
| sudo kill -9 <PID> |
原因2:依赖服务未启动
|------------------------------------------------------------------------|
| # 检查依赖服务 |
| docker ps | grep mysql |
| # 启动依赖服务 |
| docker run -d --name mysql -e MYSQL_ROOT_PASSWORD=password mysql:8.0 |
| # 等待依赖服务就绪 |
| docker run -d --name my-app --link mysql:mysql my-app-image |
原因3:环境变量配置错误
|------------------------------------------------------------------------------------|
| # 检查环境变量 |
| docker inspect my-app --format='{``{.Config.Env}}' |
| # 重新运行并设置正确的环境变量 |
| docker run -d --name my-app -e NODE_ENV=production -e DB_HOST=mysql my-app-image |
3.2 容器无法访问网络
3.2.1 问题现象
|--------------------------------------------------|
| # 容器内无法访问外部网络 |
| docker exec my-app ping www.baidu.com |
| ping: www.baidu.com: Name or service not known |
| # 容器间无法通信 |
| docker exec container1 ping container2 |
| ping: container2: Name or service not known |
3.2.2 解决方案
方案1:检查网络配置
|------------------------------------------------------------------------|
| # 查看容器网络配置 |
| docker inspect my-app --format='{``{.NetworkSettings.Networks}}' |
| # 检查DNS配置 |
| docker exec my-app cat /etc/resolv.conf |
| # 手动配置DNS |
| docker run -d --name my-app --dns 8.8.8.8 --dns 8.8.4.4 my-app-image |
方案2:重新创建网络
|--------------------------------------------|
| # 删除现有网络 |
| docker network rm my-network |
| # 创建新的网络 |
| docker network create my-network |
| # 连接容器到新网络 |
| docker network connect my-network my-app |
方案3:检查防火墙设置
|----------------------------------------------------------------|
| # 检查防火墙状态 |
| sudo systemctl status firewalld |
| # 临时关闭防火墙 |
| sudo systemctl stop firewalld |
| # 或者添加Docker规则 |
| sudo firewall-cmd --permanent --zone=public --add-masquerade |
| sudo firewall-cmd --reload |
3.3 容器性能问题
3.3.1 问题现象
|---------------------------------------------------------------------------------|
| # 容器运行缓慢,响应时间长 |
| docker stats my-app |
| CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS |
| abc123456789 my-app 200.50% 1.5GiB / 2GiB 75.00% 1.2GB / 2GB 50MB / 100MB 150 |
3.3.2 性能优化方案
CPU性能优化
|--------------------------------------------------------------|
| # 限制CPU使用 |
| docker run -d --name my-app --cpus=1.5 my-app-image |
| # 设置CPU权重 |
| docker run -d --name my-app --cpu-shares=512 my-app-image |
| # 绑定到特定CPU核心 |
| docker run -d --name my-app --cpuset-cpus=0,1 my-app-image |
内存性能优化
|-------------------------------------------------------------------------|
| # 限制内存使用 |
| docker run -d --name my-app --memory=1g my-app-image |
| # 设置内存交换限制 |
| docker run -d --name my-app --memory=1g --memory-swap=2g my-app-image |
| # 设置内存保留 |
| docker run -d --name my-app --memory-reservation=512m my-app-image |
I/O性能优化
|----------------------------------------------------------------------------|
| # 限制磁盘读取速度 |
| docker run -d --name my-app --device-read-bps=/dev/sda:1mb my-app-image |
| # 限制磁盘写入速度 |
| docker run -d --name my-app --device-write-bps=/dev/sda:1mb my-app-image |
| # 使用tmpfs挂载 |
| docker run -d --name my-app --tmpfs /tmp:rw,size=512m my-app-image |
四、数据与存储问题
4.1 数据卷挂载失败
4.1.1 问题现象
|------------------------------------------------------------------------------------------|
| # 挂载数据卷时失败 |
| docker run -d --name my-app -v /host/path:/container/path my-app-image |
| docker: Error response from daemon: OCI runtime create failed: container_linux.go:380: |
| starting container process caused: process_linux.go:545: |
| container init caused: rootfs_linux.go:76: |
| mounting "/host/path" to rootfs at "/container/path" caused: |
| mount through procfd: not a directory: unknown. |
4.1.2 解决方案
方案1:检查挂载路径
|--------------------------------------------------------------------------|
| # 检查主机路径是否存在 |
| ls -la /host/path |
| # 创建主机路径 |
| sudo mkdir -p /host/path |
| sudo chown -R $USER:$USER /host/path |
| # 重新运行容器 |
| docker run -d --name my-app -v /host/path:/container/path my-app-image |
方案2:使用命名数据卷
|---------------------------------------------------------------------------|
| # 创建命名数据卷 |
| docker volume create my-app-data |
| # 挂载数据卷 |
| docker run -d --name my-app -v my-app-data:/container/path my-app-image |
| # 查看数据卷信息 |
| docker volume inspect my-app-data |
方案3:调整挂载权限
|-----------------------------------------------------------------------------|
| # 使用只读挂载 |
| docker run -d --name my-app -v /host/path:/container/path:ro my-app-image |
| # 设置正确的权限 |
| docker run -d --name my-app -v /host/path:/container/path:Z my-app-image |
4.2 数据丢失问题
4.2.1 问题现象
|-------------------------|
| # 容器删除后数据丢失 |
| docker rm my-app |
| # 数据卷中的文件消失 |
| # 容器重启后数据不一致 |
| docker restart my-app |
| # 发现数据回滚到之前的状态 |
4.2.2 数据保护方案
方案1:使用命名数据卷
|---------------------------------------------------------------------|
| # 创建命名数据卷 |
| docker volume create my-app-data |
| # 挂载到容器 |
| docker run -d --name my-app -v my-app-data:/app/data my-app-image |
| # 删除容器时保留数据卷 |
| docker rm -v my-app # 注意:-v选项会删除匿名卷,但不会删除命名卷 |
方案2:定期备份数据
|-------------------------------------------------------------------------------------------------------------------------------|
| # 备份数据卷 |
| docker run --rm -v my-app-data:/volume -v $(pwd):/backup alpine tar cvf /backup/my-app-data-backup.tar /volume |
| # 恢复数据 |
| docker run --rm -v my-app-data:/volume -v $(pwd):/backup alpine tar xvf /backup/my-app-data-backup.tar -C /volume --strip 1 |
方案3:使用持久化存储
|-----------------------------------------------------------------------------------|
| # 使用绑定挂载 |
| docker run -d --name my-app -v /data/my-app:/app/data my-app-image |
| # 使用网络存储(NFS) |
| docker run -d --name my-app -v nfs-server:/path/to/share:/app/data my-app-image |
4.3 存储空间管理
4.3.1 问题现象
|-----------------------------------------|
| # 数据卷占用过多空间 |
| docker system df |
| TYPE TOTAL ACTIVE SIZE RECLAIMABLE |
| Images 15 10 5.253GB 2.123GB (40%) |
| Containers 10 5 1.2GB 512MB (42%) |
| Local Volumes 20 15 8.5GB 3.2GB (37%) |
| Build Cache 0 0 0B 0B |
4.3.2 存储优化方案
清理未使用的数据卷
|----------------------------------------------|
| # 查看未使用的数据卷 |
| docker volume ls -f dangling=true |
| # 清理未使用的数据卷 |
| docker volume prune |
| # 按条件清理数据卷 |
| docker volume prune --filter "label!=keep" |
数据卷压缩与归档
|--------------------------------------------------------------------------------------|
| # 压缩数据卷内容 |
| docker run --rm -v my-app-data:/data alpine tar czf /data/backup.tar.gz -C /data . |
| # 归档旧数据 |
| docker run --rm -v my-app-data:/data aline mv /data/old-data /data/archive/ |
监控存储使用
|-------------------------------------------------------------------|
| # 监控数据卷使用情况 |
| docker run --rm -v my-app-data:/data alpine du -sh /data/* |
| # 设置存储配额 |
| docker run -d --name my-app --storage-opt size=10G my-app-image |
五、网络连接问题
5.1 容器间通信失败
5.1.1 问题现象
|--------------------------------------------------------------------|
| # 容器间无法通过容器名通信 |
| docker exec web-app ping db-app |
| ping: db-app: Name or service not known |
| # 容器间无法通过IP通信 |
| docker exec web-app ping 172.17.0.3 |
| PING 172.17.0.3 (172.17.0.3) 56(84) bytes of data. |
| ^C |
| --- 172.17.0.3 ping statistics --- |
| 3 packets transmitted, 0 received, 100% packet loss, time 2000ms |
5.1.2 解决方案
方案1:使用自定义网络
|----------------------------------------------------------------------|
| # 创建自定义网络 |
| docker network create my-app-network |
| # 启动容器并连接到网络 |
| docker run -d --name db-app --network my-app-network mysql:8.0 |
| docker run -d --name web-app --network my-app-network nginx:latest |
| # 测试通信 |
| docker exec web-app ping db-app |
方案2:使用--link选项(已废弃,但仍有用)
|--------------------------------------------------------------|
| # 启动数据库容器 |
| docker run -d --name db-app mysql:8.0 |
| # 启动Web应用并链接到数据库 |
| docker run -d --name web-app --link db-app:db nginx:latest |
| # 测试通信 |
| docker exec web-app ping db |
方案3:检查网络配置
|---------------------------------------------------------------------|
| # 查看容器网络配置 |
| docker inspect web-app --format='{``{.NetworkSettings.Networks}}' |
| # 检查防火墙规则 |
| sudo iptables -L -n -v |
| # 检查网络连通性 |
| docker network inspect my-app-network |
5.2 外部访问容器失败
5.2.1 问题现象
|--------------------------------------------------------------------------|
| # 外部无法访问容器服务 |
| curl http://localhost:8080 |
| curl: (7) Failed to connect to localhost port 8080: Connection refused |
| # 检查端口映射 |
| docker port web-app |
| # 无输出 |
5.2.2 解决方案
方案1:正确配置端口映射
|--------------------------------------------------------|
| # 停止容器 |
| docker stop web-app |
| # 重新启动并映射端口 |
| docker run -d --name web-app -p 8080:80 nginx:latest |
| # 验证端口映射 |
| docker port web-app |
| 80/tcp -> 0.0.0.0:8080 |
方案2:检查服务监听地址
|-------------------------------------|
| # 检查容器内服务监听地址 |
| docker exec web-app netstat -tlnp |
| # 修改服务配置监听所有地址 |
| # 在应用配置中设置监听0.0.0.0而不是127.0.0.1 |
方案3:检查防火墙设置
|--------------------------------------|
| # 检查防火墙状态 |
| sudo ufw status |
| # 开放端口 |
| sudo ufw allow 8080 |
| # 或者检查iptables规则 |
| sudo iptables -L -n -v | grep 8080 |
5.3 DNS解析问题
5.3.1 问题现象
|--------------------------------------------------|
| # 容器内无法解析域名 |
| docker exec web-app ping www.baidu.com |
| ping: www.baidu.com: Name or service not known |
| # 检查DNS配置 |
| docker exec web-app cat /etc/resolv.conf |
| nameserver 127.0.0.11 |
| options ndots:0 |
5.3.2 解决方案
方案1:手动配置DNS
|-------------------------------------------------------------------------|
| # 运行容器时指定DNS |
| docker run -d --name web-app --dns 8.8.8.8 --dns 8.8.4.4 nginx:latest |
| # 或者修改Docker守护进程配置 |
| sudo tee /etc/docker/daemon.json <<-'EOF' |
| { |
| "dns": ["8.8.8.8", "8.8.4.4"] |
| } |
| EOF |
| # 重启Docker服务 |
| sudo systemctl restart docker |
方案2:使用主机网络模式
|------------------------------------------------------------|
| # 使用主机网络模式 |
| docker run -d --name web-app --network host nginx:latest |
| # 注意:此模式会降低容器隔离性 |
方案3:检查网络创建
|------------------------------------------------------------------------------------|
| # 重新创建网络 |
| docker network create --subnet=192.168.1.0/24 --gateway=192.168.1.1 my-network |
| # 启动容器并指定DNS |
| docker run -d --name web-app --network my-network --dns 192.168.1.1 nginx:latest |
️ 六、综合排错技巧
6.1 系统化排错方法
6.1.1 问题定位流程
|-----------------------|
| 1. 明确问题现象 |
| ↓ |
| 2. 收集相关信息(日志、配置、状态) |
| ↓ |
| 3. 分析可能原因 |
| ↓ |
| 4. 制定解决方案 |
| ↓ |
| 5. 实施并验证 |
| ↓ |
| 6. 总结经验教训 |
6.1.2 常用排错命令
|-----------------------------------------|
| # 查看Docker系统信息 |
| docker info |
| # 查看容器详细信息 |
| docker inspect <container_name> |
| # 查看镜像详细信息 |
| docker image inspect <image_name> |
| # 查看网络详细信息 |
| docker network inspect <network_name> |
| # 查看数据卷详细信息 |
| docker volume inspect <volume_name> |
| # 查看Docker事件 |
| docker events |
| # 查看Docker磁盘使用 |
| docker system df |
| # 查看Docker版本信息 |
| docker version |
6.2 日志分析技巧
6.2.1 容器日志分析
|-----------------------------------------------------|
| # 实时查看日志 |
| docker logs -f <container_name> |
| # 查看最近N行日志 |
| docker logs --tail 100 <container_name> |
| # 查看特定时间段的日志 |
| docker logs --since 1h <container_name> |
| # 查看带时间戳的日志 |
| docker logs -t <container_name> |
| # 过滤日志内容 |
| docker logs <container_name> | grep "ERROR" |
| # 将日志输出到文件 |
| docker logs <container_name> > container.log 2>&1 |
6.2.2 系统日志分析
|----------------------------------------------|
| # 查看Docker守护进程日志 |
| sudo journalctl -u docker.service |
| # 查看内核日志 |
| dmesg | grep docker |
| # 查看系统日志 |
| sudo tail -f /var/log/syslog | grep docker |
| # 查看审计日志 |
| sudo ausearch -m avc -ts recent |
6.3 性能监控工具
6.3.1 内置监控命令
|------------------------------------------------------------------------------|
| # 实时监控容器资源使用 |
| docker stats |
| # 监控特定容器 |
| docker stats <container_name> |
| # 自定义监控格式 |
| docker stats --format "table {``{.Name}}\t{``{.CPUPerc}}\t{``{.MemUsage}}" |
| # 持续监控并输出到文件 |
| docker stats --no-stream > stats.log |
6.3.2 第三方监控工具
|--------------------------------------------------|
| # 使用cAdvisor监控 |
| docker run -d --name cadvisor -p 8080:8080 \ |
| -v /:/rootfs:ro \ |
| -v /var/run:/var/run:rw \ |
| -v /sys:/sys:ro \ |
| -v /var/lib/docker/:/var/lib/docker:ro \ |
| google/cadvisor:latest |
| # 使用Portainer管理 |
| docker run -d -p 9000:9000 --name portainer \ |
| -v /var/run/docker.sock:/var/run/docker.sock \ |
| portainer/portainer-ce |
七、常见问题速查表
7.1 安装问题速查
| 问题描述 | 可能原因 | 解决方案 |
|---|---|---|
| 服务启动失败 | 存储驱动不兼容 | 修改daemon.json中的storage-driver |
| 权限不足 | 用户不在docker组 | usermod -aG docker $USER |
| 内核版本过低 | 系统内核太旧 | 升级内核或安装旧版Docker |
| 端口冲突 | 端口被占用 | 修改端口或停止占用进程 |
7.2 镜像问题速查
| 问题描述 | 可能原因 | 解决方案 |
|---|---|---|
| 拉取失败 | 网络问题 | 配置镜像加速器 |
| 构建失败 | Dockerfile错误 | 检查语法和依赖 |
| 空间不足 | 磁盘满 | 清理或扩展存储 |
| 签名验证失败 | 镜像源不可信 | 配置可信镜像源 |
7.3 容器问题速查
| 问题描述 | 可能原因 | 解决方案 |
|---|---|---|
| 启动失败 | 配置错误 | 检查日志和配置 |
| 网络不通 | 防火墙或网络配置 | 检查网络设置 |
| 性能差 | 资源限制不当 | 调整资源限制 |
| 数据丢失 | 数据卷配置错误 | 使用命名数据卷 |