容器管理
容器是镜像的运行实例,可额外配置数据持久化和网络映射。
容器的基本操作¶
运行容器¶
Bash
# 基本命令
docker run [OPTIONS] <image>
# 后台运行容器
docker run -d <image>
# 指定容器名称
docker run --name <容器名> <image>
# 自动重启
docker run --restart always <image>
# 容器停止后自动删除
docker run --rm <image>
# 交互式运行(-i 保持 STDIN 打开,-t 分配伪终端)
docker run -it <image>
# 设置环境变量
docker run -e MYSQL_ROOT_PASSWORD=<password> <image>
以下参数也较为常见,将会在下面的内容中详细描述:
-v:挂载目录或数据卷-p:端口映射(宿主机端口: 容器端口)--network:指定网络
监控容器¶
打印容器列表:
打印容器日志:
Bash
# 查看容器的日志
docker logs <容器名或容器 ID>
# 实时查看日志
docker logs -f <容器名或容器 ID>
# 查看最近 100 行日志
docker logs --tail 100 <容器名或容器 ID>
# 查看带时间戳的日志
docker logs -t <容器名或容器 ID>
# 查看指定时间后的日志
docker logs --since 2024-01-01T10:00:00 <容器名或容器 ID>
打印容器信息:
Bash
# 查看容器详细配置
docker inspect <容器名或容器 ID>
# 查看特定信息(使用 --format)
docker inspect --format='{{.NetworkSettings.IPAddress}}' <容器名或容器 ID>
# 查看容器内进程
docker top <容器名或容器 ID>
# 实时监控容器的系统资源占用情况
docker stats [<容器名或容器 ID>]
启停容器¶
Bash
# 停止运行中的容器
docker stop <容器名或容器 ID>
# 强制停止容器
docker kill <容器名或容器 ID>
# 启动已停止的容器
docker start <容器名或容器 ID>
# 重启容器
docker restart <容器名或容器 ID>
# 暂停容器
docker pause <容器名或容器 ID>
# 恢复暂停的容器
docker unpause <容器名或容器 ID>
Tip
重新运行容器不需要重新添加 docker run 时设置的参数,因为这些配置都被持久化在对应的容器元数据中了,Linux 中容器元数据的持久化路径为 /var/lib/docker/containers/<CONTAINER_ID>/。
进入容器¶
Bash
# 进入正在运行的容器(推荐方式)
docker exec -it <容器名或ID> /bin/bash
# 如果容器中没有 bash,可以使用 sh
docker exec -it <容器名或ID> /bin/sh
# 以 root 用户进入
docker exec -it -u root <容器名或ID> /bin/bash
# 执行单条命令
docker exec <容器名或ID> ls -la /app
容器与宿主机文件传输¶
Bash
# 从容器复制文件到宿主机
docker cp <容器名或容器 ID>:<容器路径> <宿主机路径>
# 从宿主机复制文件到容器
docker cp <宿主机路径> <容器名或容器 ID>:<容器路径>
# 示例
docker cp mycontainer:/app/log.txt ./log.txt
docker cp ./config.yaml mycontainer:/app/config.yaml
删除容器¶
Bash
# 删除已停止的容器
docker rm <容器名或ID>
# 强制删除运行中的容器
docker rm -f <容器名或ID>
# 删除所有已停止的容器
docker container prune
配置数据持久化¶
Docker 容器的文件系统是临时的,容器删除后数据会丢失,所以有必要进行数据持久化。可将容器数据持久化在数据卷 (Volume) 中,也可以持久化在本地指定路径。两者的区别主要体现在:
| 特性 | 数据卷 | 本地路径 |
|---|---|---|
| 管理方式 | Docker 管理 | 用户手动管理 |
| 存储位置 | Docker 专用目录 | 任意宿主机路径 |
| 性能 | 较好 | 取决于文件系统 |
| 适用场景 | 生产环境 | 开发环境、配置文件 |
| 可移植性 | 高 | 低 |
挂载到数据卷¶
管理数据卷:
Bash
# 创建数据卷
docker volume create <volume>
# 查看所有数据卷
docker volume ls
# 查看数据卷详细信息
docker volume inspect <volume>
# 删除数据卷
docker volume rm <volume>
# 删除所有未使用的数据卷
docker volume prune
挂载数据卷:
Bash
# 运行容器时挂载到数据卷
docker run -v <volume>:</container/path/to/app> <image>
# 示例:MySQL 数据持久化
docker volume create mysql-data
docker run -d \
--name mysql \
-v mysql-data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=password \
mysql:latest
挂载到本地路径¶
Bash
# 运行容器时挂载到本地路径
docker run -v </host/path>:</container/path/to/app> <image>
# 只读挂载(防止容器修改宿主机文件)
docker run -v </host/path>:</container/path/to/app>:ro <image>
# 示例:挂载目录(开发环境)
docker run -d \
--name web-dev \
-v /home/user/project:/app \
-p 8080:80 \
nginx:latest
# 示例:挂载单个文件
docker run -d \
-v /host/config.yaml:/app/config.yaml
-p 8080:80 \
nginx:latest
配置网络¶
Docker 的网络功能允许容器之间以及容器与外部进行通信。Docker 支持多种网络模式:
- bridge(桥接网络):默认模式,容器通过虚拟网桥连接,可访问外部网络;
- host(主机网络):容器直接使用宿主机网络栈,性能最好但隔离性差;
- none(无网络):容器没有网络连接;
- container:与其他容器共享网络命名空间;
- 自定义网络:用户创建的网络,支持容器名称解析。
查看网络¶
管理网络¶
Bash
# 创建自定义桥接网络
docker network create <net>
# 创建指定子网的网络
docker network create \
--driver bridge \
--subnet 172.20.0.0/16 \
--gateway 172.20.0.1 \
my-network
# 删除网络
docker network rm <net>
# 删除所有未使用的网络
docker network prune
容器加入网络¶
Bash
# 创建容器时指定网络
docker run --network <net> <image>
# 将已存在的容器连接到网络
docker network connect <net> <continer>
# 断开容器与网络的连接
docker network disconnect <net> <continer>
容器间通信¶
在同一自定义网络中的容器可以通过容器名相互访问:
Bash
# 创建自定义网络
docker network create app-network
# 启动数据库容器
docker run -d \
--name mysql-db \
--network app-network \
-e MYSQL_ROOT_PASSWORD=password \
mysql:latest
# 启动应用容器
docker run -d \
--name web-app \
--network app-network \
-e DB_HOST=mysql-db \
myapp:latest
# 在 web-app 容器中可以直接通过 mysql-db 访问数据库
# 例如:mysql -h mysql-db -u root -p
测试容器间连通性:
Bash
# 进入容器 A
docker exec -it <容器A> /bin/bash
# 通过容器名 ping 容器 B
ping <容器B>
# 或者直接执行
docker exec <容器A> ping -c 3 <容器B>
端口映射¶
将容器端口映射到宿主机,使外部可以访问容器服务:
Bash
# 基本端口映射
docker run -d -p <宿主机端口>:<容器端口> <镜像名>
# 示例
docker run -d -p 8080:80 nginx:latest
# 映射到所有网络接口
docker run -d -p 0.0.0.0:8080:80 nginx:latest
# 映射到指定 IP
docker run -d -p 192.168.1.100:8080:80 nginx:latest
# 映射多个端口
docker run -d \
-p 8080:80 \
-p 8443:443 \
nginx:latest
# 映射 UDP 端口
docker run -d -p 53:53/udp dns-server:latest
# 随机映射端口
docker run -d -P nginx:latest
# 查看端口映射
docker port <容器名或ID>
使用 host 网络模式¶
容器 DNS 配置¶
Bash
# 自定义 DNS 服务器
docker run -d \
--dns 8.8.8.8 \
--dns 8.8.4.4 \
nginx:latest
# 添加 hosts 记录
docker run -d \
--add-host myhost:192.168.1.100 \
nginx:latest
多容器编排¶
一台机器或者一个服务往往需要多个容器进行协作,Docker Compose 就派上用场了。Docker Compose 是用于定义和运行多容器 Docker 编排工具,使用 YAML 配置。
Docker Compose 常用命令¶
Bash
# 启动所有服务
docker-compose up -d
# 停止所有服务
docker-compose down
# 查看服务状态
docker-compose ps
# 查看服务日志
docker-compose logs -f
# 重启服务
docker-compose restart
# 构建镜像
docker-compose build
# 扩展服务实例
docker-compose up -d --scale web=3
Docker Compose 示例配置¶
创建 docker-compose.yml 文件:
YAML
version: '3.8'
services:
web:
image: nginx:latest
ports:
- "8080:80"
volumes:
- ./html:/usr/share/nginx/html
networks:
- app-network
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: password
MYSQL_DATABASE: mydb
volumes:
- db-data:/var/lib/mysql
networks:
- app-network
networks:
app-network:
driver: bridge
volumes:
db-data: