R / Richie全部文章 ↑

Linux · 2 分钟阅读

05. 操作 Docker 容器

容器是镜像的运行实例。比虚拟机轻量,共享宿主机内核,只打包必要的运行环境。

启动

# 一次性执行
docker run centos:7 /bin/echo "Hello"

# 交互终端
docker run -it --rm centos:7 bash

docker run 实际做的事:

  1. 检查本地有没有该镜像,没有就拉
  2. 用镜像创建并启动容器
  3. 挂载可写层
  4. 配置网络(从 bridge 网桥获得虚拟接口和 IP)
  5. 执行用户命令
  6. 命令退出后容器终止

容器管理

docker container ls -a          # 全部容器
docker ps                       # 运行中
docker ps -s                    # 含磁盘占用
docker ps -q                    # 只输出 ID

docker container start <id>     # 启动已终止
docker container stop <id>      # 停止
docker container restart <id>
docker container rm <id>
docker container prune          # 清掉所有已终止

后台运行

-d 让容器在后台跑:

docker run -d centos:7 /bin/sh -c 'while true; do echo hello; sleep 1; done'
docker logs -f <id>

容器会不会持续运行取决于启动命令本身;-d 只是让 Docker 不阻塞在前台。

进入容器

# 推荐:exec 起新进程,不影响原进程
docker exec -it <id> bash

# attach 进入主进程的 stdin
docker attach <id>              # 退出主进程 = 容器停止

exec 是日常调试的选择;attach 风险大,少用。

导出与导入

# 容器快照(不含历史)
docker export <id> > app.tar
cat app.tar | docker import - myrepo/app:v1

# 镜像归档(保留历史)
docker save nginx:1.27 > nginx.tar
docker load < nginx.tar

import 出来的镜像丢历史;load 是镜像标准做法。

删除

docker container rm <id>          # 已停止
docker container rm -f <id>       # 强制
docker container prune            # 全部已停止

几条经验

  • 容器名要有意义;自动生成的 nostalgic_morse 没人看得懂
  • 一个容器一个进程,别把所有东西塞进同一个镜像
  • 容器内 PID 1 必须能处理 SIGTERM,否则 docker stop 超时
  • 日志、状态、配置走 sidecar,别糅在业务容器里

参考