Docker 第四天学习指南:端口映射与服务访问
一、学习目标
-
理解容器端口映射的概念和作用
-
掌握
-p参数的各种用法 -
实战:运行 Nginx 容器并通过浏览器访问
-
了解容器的资源限制(CPU、内存)
二、端口映射详解
1. 为什么需要端口映射?
容器拥有自己独立的网络命名空间,容器内的端口(如 Nginx 的 80)只暴露在容器内部。要从宿主机或外部网络访问容器内的服务,必须将宿主机端口映射到容器端口。
外部访问流程:
浏览器 → 宿主机IP:宿主机端口 → 容器IP:容器端口 → 服务
2. 端口映射命令 -p
基本语法:
docker run -p [宿主机IP:]宿主机端口:容器端口[/协议] 镜像名
常用形式:
| 格式 | 示例 | 说明 |
|---|---|---|
-p 宿主机端口:容器端口 |
-p 8080:80 |
宿主机所有IP的8080映射到容器80 |
-p IP:宿主机端口:容器端口 |
-p 127.0.0.1:8080:80 |
只绑定本地回环地址 |
-p 容器端口 |
-p 80 |
随机映射宿主机端口(较少用) |
-p 宿主机端口:容器端口/udp |
-p 53:53/udp |
指定 UDP 协议(默认 TCP) |
-P(大写) |
-P |
将容器所有 EXPOSE 的端口随机映射 |
3. 端口映射示例
# 基础用法:宿主机8080 → 容器80
docker run -d -p 8080:80 nginx
# 绑定多个端口
docker run -d -p 8080:80 -p 8443:443 nginx
# 绑定到指定IP(多网卡时有用)
docker run -d -p 127.0.0.1:8080:80 nginx
# UDP 端口映射(如 DNS)
docker run -d -p 53:53/udp --name dns-server some-dns
# 随机端口映射(查看命令:docker port 容器名)
docker run -d -P nginx
docker port 容器名 # 查看随机映射的端口
4. 查看端口映射
# 方法1:docker ps(显示 PORTS 列)
docker ps
# 方法2:docker port 命令
docker port 容器名
# 输出:80/tcp -> 0.0.0.0:8080
# 方法3:docker inspect
docker inspect 容器名 | grep -A 5 "PortBindings"
三、实战:运行 Nginx 并访问
步骤 1:拉取 Nginx 镜像(可选)
docker pull nginx:alpine # 轻量级版本
步骤 2:后台运行 Nginx 并映射端口
docker run -d --name my-nginx -p 8080:80 nginx:alpine
-
-d:后台运行 -
--name my-nginx:容器命名 -
-p 8080:80:宿主机 8080 → 容器 80 -
nginx:alpine:使用轻量版 Nginx
步骤 3:验证容器运行状态
docker ps
# 输出示例:
# CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
# abcd1234 nginx:alpine "/docker-entrypoint.…" 5 seconds ago Up 4 seconds 0.0.0.0:8080->80/tcp my-nginx
步骤 4:访问 Nginx 欢迎页
方式一:使用 curl 命令
curl http://localhost:8080
# 或
curl http://127.0.0.1:8080
应该能看到 HTML 输出,包含 "Welcome to nginx"。
方式二:浏览器访问
打开浏览器,地址栏输入 http://localhost:8080 或 http://你的虚拟机IP:8080(如果是远程服务器)。
步骤 5:修改 Nginx 默认页面(可选)
# 进入容器
docker exec -it my-nginx /bin/sh
# 修改首页
echo "<h1>Hello from Docker!</h1>" > /usr/share/nginx/html/index.html
# 退出容器
exit
# 刷新浏览器,页面内容已改变
步骤 6:停止并清理
docker stop my-nginx
docker rm my-nginx
四、资源限制
1. 为什么要限制资源?
默认情况下,容器可以无限制使用宿主机资源。为防止某个容器耗尽所有 CPU 或内存,需要设置资源限制。
2. 内存限制
# 语法
docker run -m <值> --memory-swap <值> ...
# 常用参数
-m, --memory # 最大内存限制(如 -m 512m)
--memory-swap # 内存+swap的总限制(-m 512m --memory-swap 1g → 内存512M + swap512M)
--memory-reservation # 软限制,尽力保证
--memory-swappiness # 容器使用swap的倾向(0-100,默认60)
--oom-kill-disable # 超出内存时是否杀死容器
# 示例
docker run -d --name limited-nginx -m 256m nginx
单位说明:b(字节)、k(KB)、m(MB)、g(GB)
3. CPU 限制
# 方式一:指定 CPU 份额(相对权重,默认1024)
--cpu-shares 512 # 该容器 CPU 权重为 512,其他为 1024 时,它占用一半
# 方式二:限制使用的 CPU 核心数(推荐)
--cpus 1.5 # 最多使用 1.5 个 CPU 核心
# 方式三:指定使用哪些 CPU 核心(绑定)
--cpuset-cpus "0,2" # 只使用 CPU 0 和 2
--cpuset-cpus "0-3" # 使用 CPU 0-3
# 方式四:CPU 时间配额(更精细)
--cpu-period 100000 # 调度周期(微秒)
--cpu-quota 50000 # 每个周期内分配的时间(微秒),即 0.5 核
4. 综合示例:同时限制 CPU 和内存
docker run -d \
--name limited-nginx \
-p 8080:80 \
--cpus 0.5 \
--memory 256m \
--memory-swap 512m \
nginx
限制:
-
最多使用 0.5 个 CPU 核心
-
内存上限 256MB
-
swap 上限 512MB(即额外 256MB swap)
5. 查看资源使用情况
# 实时查看所有容器资源使用
docker stats
# 查看特定容器
docker stats limited-nginx
# 不持续刷新(只显示一次)
docker stats --no-stream
# 格式化输出
docker stats --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}"
6. 压力测试资源限制(可选)
使用 stress 工具测试:
# 运行一个 Ubuntu 容器,安装 stress
docker run -it --name stress-test --memory 256m ubuntu:22.04 /bin/bash
# 在容器内安装 stress
apt update && apt install -y stress
# 尝试分配 300MB 内存(超出限制)
stress --vm 1 --vm-bytes 300M --vm-keep
# 观察容器是否被 OOM Kill(可能需要另开终端查看 docker stats)
五、综合实战:运行一个 WordPress 博客(多容器)
这个实战会用到端口映射和资源限制,同时引入多容器协作的概念(更多内容在后续 Docker Compose 中深入)。
# 1. 运行 MySQL 容器(后台,限制资源)
docker run -d \
--name wordpress-db \
-e MYSQL_ROOT_PASSWORD=rootpass \
-e MYSQL_DATABASE=wordpress \
-e MYSQL_USER=wpuser \
-e MYSQL_PASSWORD=wppass \
--memory 512m \
--cpus 0.5 \
mysql:8.0
# 2. 运行 WordPress 容器,映射端口 8888:80
docker run -d \
--name wordpress-app \
-p 8888:80 \
-e WORDPRESS_DB_HOST=wordpress-db:3306 \
-e WORDPRESS_DB_USER=wpuser \
-e WORDPRESS_DB_PASSWORD=wppass \
-e WORDPRESS_DB_NAME=wordpress \
--memory 256m \
--cpus 0.3 \
wordpress:latest
# 3. 查看容器状态
docker ps
# 4. 浏览器访问 http://localhost:8888,完成 WordPress 安装向导
# 5. 清理(运行完后可删除)
docker stop wordpress-app wordpress-db
docker rm wordpress-app wordpress-db
六、端口映射常见问题
Q1:端口已被占用怎么办?
错误信息:bind: address already in use
解决方案:
# 换一个宿主机端口
docker run -d -p 8081:80 nginx
# 或杀死占用端口的进程(Linux)
sudo lsof -i :8080
sudo kill -9 <PID>
Q2:如何让容器使用宿主机的网络栈(不隔离)?
docker run -d --network host nginx
此时容器直接使用宿主机的 IP 和端口(-p 无效),访问 http://宿主机IP 即可。
Q3:容器内服务监听在 127.0.0.1 而非 0.0.0.0?
有些应用默认只监听本地回环,需要在容器内修改配置为 0.0.0.0。
Q4:Windows/macOS 上无法通过 localhost 访问?
Docker Desktop 默认可以,如果不行尝试使用 127.0.0.1 或 192.168.x.x(docker0 网桥 IP)。
七、资源限制最佳实践
-
生产环境必须设置资源限制,防止容器失控影响宿主机
-
内存限制要留有余地:
-m设置的值应略高于应用正常运行所需 -
CPU 限制使用
--cpus更直观(Docker 1.13+) -
监控资源使用:
docker stats或集成监控系统(Prometheus + cAdvisor) -
测试时模拟限制:使用压力工具验证限制是否生效
八、课后练习
练习 1:运行多个 Nginx 实例
# 启动三个 Nginx,映射不同端口
docker run -d --name web1 -p 8081:80 nginx
docker run -d --name web2 -p 8082:80 nginx
docker run -d --name web3 -p 8083:80 nginx
# 分别 curl 验证
curl http://localhost:8081
curl http://localhost:8082
curl http://localhost:8083
# 清理
docker stop web1 web2 web3 && docker rm web1 web2 web3
练习 2:资源限制实验
# 启动一个内存限制为 128M 的 Ubuntu 容器
docker run -it --memory 128m ubuntu:22.04 /bin/bash
# 安装 stress
apt update && apt install -y stress
# 分配 200M 内存(预期 OOM kill)
stress --vm 1 --vm-bytes 200M --timeout 10s
# 观察结果
练习 3:查看端口映射的多种方法
# 启动 Redis 容器,映射 6379
docker run -d --name myredis -p 6380:6379 redis
# 使用不同方式查看映射
docker port myredis
docker inspect myredis | grep -A 5 "PortBindings"
docker ps --format "table {{.Names}}\t{{.Ports}}"
# 清理
docker stop myredis && docker rm myredis
九、下一步预告
第五天将学习:
-
数据持久化(Volume 挂载)
-
解决容器删除后数据丢失的问题
-
docker cp文件复制
今日检查清单:
-
理解端口映射的作用和语法
-
能成功运行 Nginx 并通过浏览器访问
-
掌握查看端口映射的方法
-
能设置容器的 CPU 和内存限制
-
会使用
docker stats监控资源
更多推荐



所有评论(0)