Performance Tuning and Troubleshooting

Are you experiencing issues with containers in your production environment—high CPU usage? Memory overload? Slow I/O? You need a systematic troubleshooting approach.

1. What You'll Learn


2. A Story About an Early Morning Alert

(1) Pain Point: API latency skyrocketed from 50 ms to 5 s

API latency in the production environment skyrocketed from 50 ms to 5 s, leading to a flood of user complaints. Alice used docker stats to discover that while CPU usage wasn’t spiking, I/O wait times were extremely high, and the containers seemed to be “stuck.”

(2) A Systematic Approach to Troubleshooting

Alice used iostat to identify that the log driver was causing the disk I/O to reach its limit; after switching the log driver, the issue was resolved.

BASH
# Step 1: Check resource usage
docker stats --no-stream

# Step 2: Check host IO
iostat -x 1 5

# Step 3: Identify the bottleneck
docker system df -v

(3) Benefits: 5 seconds → 50 milliseconds, 10-minute recovery time

It took only 10 minutes from the alert to the resolution—systematic troubleshooting is 100 times more efficient than simply “trying a reboot.”


3. Performance Troubleshooting Decision Tree

(1) The Four Major Bottlenecks and Their Corresponding Tools

100%
graph TB
    START["Performance Issue"] --> CPU{"CPU High?"}
    CPU -->|Yes| C1["docker stats<br/>top / htop"]
    CPU -->|No| MEM{"High memory usage?"}
    MEM -->|Yes| M1["docker stats<br/>/proc/meminfo"]
    MEM -->|No| IO{"IO Waiting for Gao?"}
    IO -->|Yes| I1["iostat -x<br/>docker system df"]
    IO -->|No| NET{"Slow Internet?"}
    NET -->|Yes| N1["iperf / ping<br/>tcpdump"]

(2) Common Troubleshooting Tools

Tool Function Use Case
docker stats Container Resource Usage CPU/Memory/IO Overview
docker system df Docker Disk Usage Troubleshooting a Full Disk
docker events Container Event Stream OOM/Restart/Abnormal Exit
docker logs Container Logs Application Errors
docker inspect Container Configuration Status/Exit Code/Network
iostat Disk I/O Statistics I/O Bottlenecks
iperf Network Bandwidth Test Network Bottlenecks
nsenter Enter Container Namespace Advanced Debugging

4. Troubleshooting CPU Bottlenecks

▶ Example: Monitoring Resources with docker stats (Difficulty: ⭐)

BASH
# Real-time stats for all containers
docker stats

# One-time snapshot
docker stats --no-stream

# Custom format
docker stats --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.NetIO}}\t{{.BlockIO}}"

▶ Example: The stress container simulates CPU load (Difficulty: ⭐⭐)

BASH
# Run stress to simulate CPU load
docker run --rm --name stress-test \
  --cpus=1 \
  progrium/stress --cpu 1 --timeout 30s

# Monitor with docker stats (in another terminal)
docker stats stress-test --no-stream

5. Troubleshooting Memory Bottlenecks

(1) Common Memory Issues

Symptom Exit Code Cause Solution
OOM Kill 137 Exceeded the --memory limit Increase the limit or optimize memory usage
Memory Leak Gradual Increase Application Bug Analyzing a Heap Dump
High cache usage 0 File system cache Normal behavior (can be reclaimed)

▶ Example: Simulating a Container OOM (Difficulty: ⭐⭐⭐)

BASH
# Start container with 50 MB memory limit
docker run -d --name oom-test \
  --memory=50m \
  --restart=on-failure:3 \
  progrium/stress --vm 1 --vm-bytes 100M --timeout 10s

# Watch for OOM events
docker events --filter event=oom --since 1m

# Check exit code
docker inspect oom-test --format='ExitCode: {{.State.ExitCode}}, OOMKilled: {{.State.OOMKilled}}'

6. Troubleshooting Disk I/O Bottlenecks

▶ Example: docker system df Disk Analysis (Difficulty: ⭐⭐)

BASH
# Show Docker disk usage
docker system df

# Detailed breakdown
docker system df -v
💻 Output:

TEXT
TYPE            TOTAL   ACTIVE  SIZE      RECLAIMABLE
Images          12      5       4.2GB     2.8GB (66%)
Containers      8       3       350MB     280MB (80%)
Local Volumes   5       3       1.2GB     500MB (41%)
Build Cache     45      0       800MB     800MB (100%)

▶ Example: Disk Cleanup Policy (Difficulty: ⭐⭐)

BASH
# Remove unused data (images, containers, volumes, build cache)
docker system prune

# More aggressive: remove all unused images (not just dangling)
docker system prune -a

# Remove build cache only
docker builder prune

# Remove volumes (WARNING: deletes data)
docker volume prune

(1) Comparison of Storage Drivers

Drivers Performance Stability Recommendation
overlay2 High ✅ Stable ✅ Default recommendation
aufs Chinese ⚠️ Old kernel ❌ Deprecated
devicemapper Low ⚠️ Complex configuration ❌ Not recommended
zfs Medium ✅ Stable Specific scenarios
btrfs Medium ⚠️ Unstable ❌ Not recommended

7. Network Troubleshooting

▶ Example: iperf Network Bandwidth Test (Difficulty: ⭐⭐⭐)

BASH
# Start iperf3 server in a container
docker run -d --name iperf-server --network host networkstatic/iperf3 -s

# Run iperf3 client from another container
docker run --rm --network host networkstatic/iperf3 -c localhost -t 10

# Test between two containers on different networks
docker run --rm --network app-net networkstatic/iperf3 -c db -t 5

▶ Example: Docker Events Event Tracing (Difficulty: ⭐⭐)

BASH
# Monitor container lifecycle events
docker events --filter type=container

# Filter for specific events
docker events --filter event=oom --filter event=die --filter event=restart

# Time-based filter
docker events --since "2024-01-15T03:00:00" --until "2024-01-15T04:00:00"

8. Advanced Debugging: nsenter

▶ Example: nsenter to enter a container namespace (Difficulty: ⭐⭐⭐)

BASH
# Get container's main PID
PID=$(docker inspect --format='{{.State.Pid}}' myapp)

# Enter the container's network namespace for debugging
nsenter -t $PID -n tcpdump -i eth0 -c 100 port 8080

# Enter the container's process namespace
nsenter -t $PID -p -m strace -p 1
💡 Tip: nsenter operates at a lower level than docker exec—it enters the container’s Linux namespace directly, without requiring a shell inside the container. It’s suitable for debugging scratch or distroless images.


9. Troubleshooting Guide: Common Problems and Solutions

Symptom Troubleshooting Command Common Causes Solution
Frequent container restarts docker ps -a + docker logs OOM / Application crashes Increase memory / Fix bugs / Restart policy
Disk space full docker system df -v Logs/images/volumes piling up docker system prune + Log rotation
Network connection timed out docker exec ping + nc Network configuration error Check network/DNS/port
Slow Build docker build --progress=plain Cache Expired Adjust COPY Order
Container startup failed docker logs + docker inspect Configuration error/missing dependencies Fix configuration/check dependencies
High IO Wait iostat -x Log driver/heavy writes Switch log driver/optimize writes

10. Complete Example: Troubleshooting and Resolving Container OOM Issues

BASH
# ============================================
# Complete walkthrough: OOM diagnosis and fix
# Covers: stats, events, logs, inspect, fix
# ============================================

# 1. Deploy the problematic container
docker run -d \
  --name leaky-app \
  --memory=100m \
  --restart=on-failure:5 \
  -p 8080:8080 \
  myapp:1.0

# 2. Monitor resource usage
docker stats leaky-app --no-stream

# 3. Simulate memory leak (trigger OOM)
docker exec leaky-app python -c "
import itertools
data = []
for i in itertools.count():
    data.append('x' * 1024 * 1024)  # 1 MB each
    if i % 10 == 0:
        import time; time.sleep(0.1)
"

# 4. Capture OOM event
docker events --filter container=leaky-app --filter event=oom --since 1m

# 5. Check exit code and OOM status
docker inspect leaky-app --format='
ExitCode: {{.State.ExitCode}}
OOMKilled: {{.State.OOMKilled}}
Memory Limit: {{.HostConfig.Memory}}
'

# 6. Check application logs for memory patterns
docker logs --tail 100 leaky-app 2>&1 | grep -i "memory\|alloc\|oom"

# 7. Fix: increase memory limit
docker stop leaky-app && docker rm leaky-app
docker run -d \
  --name leaky-app \
  --memory=512m \
  --restart=on-failure:5 \
  --log-opt max-size=10m \
  --log-opt max-file=3 \
  -p 8080:8080 \
  myapp:1.0

# 8. Set up monitoring alert
docker events --filter event=oom | while read event; do
  echo "ALERT: OOM detected at $(date)" >> /var/log/docker-alerts.log
done

❓ FAQ

Q How do you troubleshoot container performance issues in a layered approach?
A A four-step method: ① Use docker stats to view an overview of CPU, memory, and I/O; ② Select the appropriate tool based on the highest metric (CPU → top, memory → smem, I/O → iostat, network → iperf); ③ Pinpoint the specific container or process; ④ Analyze application logs to find the root cause.
Q Which is better, overlay2 or aufs?
A overlay2 is better; it is Docker’s default and only recommended storage driver. aufs has been deprecated and is no longer supported in Docker 24 and later. overlay2 offers better performance, a simpler implementation, and more active community support.
Q How do I free up space when a container’s disk is full?
A docker system df -v Check what’s taking up the most space → Clean up accordingly: ① Images: docker image prune -a; ② Build cache: docker builder prune; ③ Containers: docker container prune; ④ Volumes: docker volume prune (Proceed with caution—this will delete data); ⑤ All: docker system prune -a.
Q How do I troubleshoot slow container I/O?
Adocker stats Check the BlockIO column; ② On the host iostat -x 1, check %util and await; ③ docker system df -v Check storage driver usage; ④ Common causes: the log driver has filled the disk, too many overlay2 layers, or a bind mount to a slow disk.
Q How do I test network latency for containers?
A Use iperf3: server container iperf3 -s, client container iperf3 -c server. Test throughput and latency. To test between containers, they must be on the same network or use the --network host option.

📖 Summary


📝 Exercises

  1. Basic Exercise (Difficulty ⭐): Use the stress container to simulate CPU load, and use docker stats to monitor changes in CPU usage.
  2. Advanced Exercise (Difficulty ⭐⭐): Use docker system df -v to analyze disk usage, run docker system prune -a to clean up, and compare the difference in disk space before and after the cleanup.
  3. Challenge (Difficulty: ⭐⭐⭐): Use iperf3 to test the network bandwidth between two containers and compare the performance differences between bridge networks and host networks.
Web-Tutorial.com

Web-Tutorial Tech Team

A team of developers maintaining programming tutorials. Each tutorial is written and reviewed by developers with expertise in that field. We work to keep our content accurate and reliable — if you spot an issue, please let us know.

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏