← Docker 容器

Docker 容器

Docker入门指南:概念、安装与基本使用

·Docker 容器

把 Docker 看成一条栈:客户端、引擎、containerd、runc、内核隔离,上面再叠镜像仓库和 Compose。下面按这条线讲安装、命令、镜像导入导出、构建和编排,细节文章链到本栏目其它篇。

Docker技术入门指南

1. Docker简介

Docker 把应用和依赖打进可移植的镜像,再在隔离的容器里跑。和虚拟机比,它不带完整客户机内核,启动快、占盘少;隔离靠 Linux 的 namespace、cgroup 和联合文件系统,不是再开一台 OS。

日常开发里,它解决三件事:环境一致(我机器能跑、你机器也能跑)、依赖收拢(不再污染宿主机)、多服务并排(MySQL、Redis、Nginx 各一个容器)。

1.1 核心概念

名词一句话类比
镜像 Image只读分层模板,含文件系统和启动命令安装盘 / 类
容器 Container镜像加上可写层后的一次运行实例装好并开机的那台
仓库 Registry存镜像、按名字和标签取应用商店
数据卷 Volume容器删了还能留下的数据外接盘
网络 Network容器之间、容器和宿主机怎么连通网段 / 交换机

镜像用 名字:标签 标识,例如 nginx:1.27。不写标签等于 latest,生产里不要依赖这个浮动标签。

1.2 技术栈与架构

你敲的 docker 只是客户端。真正干活的是一条栈:

docker / docker compose          客户端,说话
        │  Unix socket 或 TCP
   dockerd(Docker Engine)      API、编排镜像/容器/网络/卷
        │
   containerd                    管容器生命周期
        │
   runc                          按 OCI 规范把进程拉起来
        │
   Linux 内核                    namespace / cgroup / overlayfs

安装包里的 docker-ce 是引擎,docker-ce-cli 是命令行,containerd.io 是运行时,docker-compose-plugin 提供 docker compose。缺哪一块,对应层就罢工。

再往上,不是引擎本身,但是同一套工作流里会碰到:

对象之间的关系可以记成:Dockerfile 构建出镜像 → 镜像推到仓库 → 仓库拉下来 run 成容器 → 容器挂卷、进网络。后面几节按这个顺序走。

2. 安装Docker

Linux 用官方仓库装 CE,不要用十年前的 docker.io 包凑合。macOS / Windows 用 Docker Desktop,底层仍是 Linux 虚拟机 + 同一套引擎。国内机器拉官方 GPG 慢时,可改用发行版文档里的镜像站,命令结构不变。

2.1 Ubuntu安装

sudo apt-get update
sudo apt-get install -y ca-certificates curl gnupg

sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
  | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
  https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo $VERSION_CODENAME) stable" \
  | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

2.2 CentOS / 类 RHEL

sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
sudo yum install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

Rocky / Alma 同样走这套仓库。装完必须启动守护进程,见下一小节。

2.3 装完立刻做的三件事

sudo systemctl enable --now docker
sudo docker version
sudo docker run --rm hello-world

docker version 能同时看到 Client 和 Server,只有一边有字,说明守护进程没起来。把当前用户加进 docker 组后,才可以去掉 sudo,步骤见 将用户添加到 Docker 用户组。能进这个组等于能控宿主机,只给可信账号。

3. Docker基本操作

3.1 服务管理

sudo systemctl start docker
sudo systemctl enable docker
sudo systemctl status docker
sudo systemctl restart docker

配置在 /etc/docker/daemon.json(镜像加速、日志驱动、insecure-registries)。改完要 restart docker。

3.2 镜像操作

docker search nginx
docker pull nginx:1.27
docker images
docker image ls
docker image inspect nginx:1.27
docker image history nginx:1.27
docker tag nginx:1.27 myregistry.example.com/web/nginx:1.27
docker rmi nginx:1.27

pull 默认走 Docker Hub。国内常要配镜像加速,或直接从阿里云等仓库拉,见 推送到阿里云镜像仓库。

3.3 镜像导出和导入

内网机器上不了 Hub、机房间搬家、给别人一个 U 盘离线包,都用这一对命令。搬镜像用 save / load,分层和标签都在;不要和容器的 export / import 搞混。

# 导出:一个或多个镜像打成 tar,层还在
docker save -o nginx.tar nginx:1.27
docker save nginx:1.27 redis:7 | gzip > stack.tar.gz

# 导入到另一台(先 scp / rsync 把文件拷过去)
docker load -i nginx.tar
gunzip -c stack.tar.gz | docker load

# 看导入后有没有标签
docker images

另一台执行 load 后,名字和标签与导出时一致,可以直接 docker run。文件可以很大,传输用 rsync 或分卷压缩。

容器文件系统另有一对命令,用途不同:

# 把「正在跑 / 已停止的容器」拍成一层根文件系统,丢掉构建历史
docker export -o nginx-fs.tar mynginx
docker import nginx-fs.tar myapp:from-container
save / loadexport / import
对象镜像容器的文件系统快照
分层与历史保留拍扁成一层
标签一起带走要在 import 时自己起名
典型用途离线分发、备份、换机从脏容器抠一份根盘,很少当常规发布

日常说「导出镜像」,指 save。export 出来的包不能当可复现构建,也没有 Dockerfile 里那些层缓存。

3.4 容器操作

docker run -d --name mynginx --restart unless-stopped -p 8080:80 nginx:1.27
docker ps
docker ps -a
docker logs -f --tail 100 mynginx
docker exec -it mynginx sh
docker stop mynginx
docker start mynginx
docker restart mynginx
docker rm mynginx
docker rm -f mynginx

常用 run 参数:-d 后台,--name 好记的名字,-p 宿主:容器 端口,-e 环境变量,-v 挂载,--network 指定网络,--memory / --cpus 限额,--restart 重启策略(no / on-failure / always / unless-stopped)。

看资源:docker stats。拷文件:docker cp ./index.html mynginx:/usr/share/nginx/html/。容器是无状态的,改里面的文件不提交的话,删容器就没了;要固化应写回 Dockerfile 或挂卷。

4. 用 Dockerfile 构建镜像

自己的应用不要只 docker commit。用文本把构建写死,别人才能复现。

FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["python", "-m", "http.server", "8000"]
# 同目录放 .dockerignore,把 .git、.venv、__pycache__ 排除掉
docker build -t myapp:0.1 .
docker run --rm -p 8000:8000 myapp:0.1

要点:基础镜像尽量小且钉死版本;能合并的 RUN 合并,善用层缓存(依赖文件先于源码 COPY);多阶段构建把编译器和源码留在 builder,最终镜像只留运行文件。完整例子见 构建自定义 JDK 镜像。

5. Docker网络

驱动什么时候用
bridge默认。单机多个容器互访,再 -p 暴露到宿主
host容器直接用宿主网络栈,少一层 NAT,隔离也少一层
none没有网卡,只跑本地计算
macvlan给容器独立 MAC,出现在物理网段上(要交换机配合)
overlay多主机叠加网,Swarm / 部分编排会用
docker network create appnet
docker run -d --name web --network appnet nginx:1.27
docker run -d --name api --network appnet myapp:0.1
docker network inspect appnet

同一自定义网络里,容器可以用名字当主机名(http://web)。不要都挤在默认 bridge 上只靠 -p 绕一圈。Compose 会自动建项目网络,见第 7 节。

6. 数据管理

容器可写层一删就没。数据库、上传文件、配置必须放到卷里。

方式写法适合
命名卷-v mydata:/var/lib/mysql数据库等「只要持久、不管落在哪」
绑定挂载-v /opt/site:/usr/share/nginx/html开发时改宿主文件立刻生效
tmpfs--tmpfs /tmp敏感临时文件,不落盘
docker volume create mydata
docker volume ls
docker volume inspect mydata
docker run -d --name db -v mydata:/var/lib/mysql mysql:8.0
docker run -d --name web -v /srv/www:/usr/share/nginx/html nginx:1.27

命名卷在 Linux 上一般在 /var/lib/docker/volumes/。备份卷可以再开一个容器把目录打 tar,或停库后拷宿主目录。MySQL / Redis 的卷怎么挂,见 快速部署 MySQL 和 Redis。

7. Docker Compose

两个以上容器、还要共用网络和卷,就不要手敲一串 docker run。Compose V2 是插件,命令是 docker compose(中间有空格)。YAML 里不必再写已废弃的 version:。

services:
  web:
    image: nginx:1.27
    ports:
      - "8080:80"
    volumes:
      - ./html:/usr/share/nginx/html
    depends_on:
      - api
  api:
    build: ./api
    environment:
      DATABASE_URL: mysql://root:secret@db:3306/app
  db:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: secret
    volumes:
      - dbdata:/var/lib/mysql
volumes:
  dbdata:
docker compose up -d
docker compose ps
docker compose logs -f api
docker compose down

语法和排障见 Compose 基础使用;PHP 整套栈见 Compose 部署 PHP 环境。

8. 镜像仓库

本机 docker images 只是缓存。团队共享、CI 构建产物、生产拉取,都要经过 Registry:docker login → docker tag → docker push,另一边 docker pull。

地址长这样:registry.example.com/项目/镜像:标签。阿里云 ACR 的登录和推送步骤在 推送镜像到阿里云。离线、不能打通仓库时,退回第 3.3 节的 save / load。

9. 最佳实践

10. 常见问题排查

容器立刻退出:前台进程结束了。看 docker logs;docker inspect 里的 State.ExitCode 和 Error。

docker logs --tail 200 mynginx
docker inspect mynginx --format '{{.State.Status}} {{.State.ExitCode}} {{.State.Error}}'

磁盘被吃满:

docker system df
docker system prune
docker volume prune   # 会删未挂载的卷,先确认没有要留的库

网络不通:是否在同一 docker network;-p 是否写反;宿主机防火墙是否放行;docker exec 进去做连通性检查。

docker network inspect appnet
docker exec -it mynginx sh

权限 / 连不上 daemon:Cannot connect to the Docker daemon 多半是服务没起,或当前用户不在 docker 组且没用 sudo。

11. 本栏目接着读