一.容器(container)
1.概念
通俗地讲,容器是镜像的运行实体。镜像是静态的只读文件,而容器带有运行时需要的可写文件层,并且容器中的进程属于运行状态。即容器运行着真正的应用进程。容器有初建、运行、停止、暂停和删除五种状态。
虽然容器的本质是主机上运行的一个进程,但是容器有自己独立的命名空间隔离和资源限制。也就是说,在容器内部,无法看到主机上的进程、环境变量、网络等信息,这是容器与直接运行在主机上进程的本质区别。
容器是基于镜像创建的可运行实例,并且单独存在,一个镜像可以创建出多个容器。运行容器化环境时,实际上是在容器内部创建该文件系统的读写副本。 这将添加一个容器层,该层允许修改镜像的整个副本。
2.容器生命周期
容器的生命周期是容器可能处于的状态:
|---------|------|
| created | 初建状态 |
| running | 运行状态 |
| stopped | 停止状态 |
| paused | 暂停状态 |
| deleted | 删除状态 |

|-----------------------------------|------------------------------------------------------------------------------------|
| docker create | 创建容器后,不立即启动运行,容器进入初建状态 |
| docker run | 创建容器,并立即启动运行,进入运行状态 |
| docker start | 容器转为运行状态 |
| docker stop | 容器将转入停止状态 |
| docker kill | 容器在故障(死机)时,执行 kill(断电),容器转入停止状态,这种操作容易丢失数据,除非必要,否则不建议使用 |
| docker restart | 重启容器,容器转入运行状态 |
| docker pause | 容器进入暂停状态 |
| docker unpause | 取消暂停状态,容器进入运行状态 |
| docker rm | 删除容器,容器转入删除状态 |
| killed by out-of-memory(因内存不足被终止) | 宿主机内存被耗尽,也被称为 OOM:非计划终止 这时需要杀死最吃内存的容器 |
| container process exitde(异常终止) | 出现容器被终止后,将进入 Should restart?选择操作: yes 需要重启,容器执行 start 命令,转为运行状态。 no 不需要重启,容器转为停止状态 |
二.容器命令
1)docker create
创建一个新的容器但不启动它。
语法:
docker create [OPTIONS] IMAGE [COMMAND] [ARG...]
关键参数:
|----------------------------------------------|----------------------------|
| -i | 以交互模式运行容器,通常与 -t 同时使用 |
| -P | 随机端口映射,容器内部端口随机映射到主机的端口 |
| -p | 指定端口映射,格式为:主机(宿主)端口:容器端口 |
| -t | 为容器重新分配一个伪输入终端,通常与 -i 同时使用 |
| --name="容器名" | 为容器指定一个名称 |
| -h "mars" | 指定容器的 hostname |
| -e username="ritchie" | 设置环境变量 |
| --cpuset-cpus="0-2" or --cpuset-cpus="0,1,2" | 绑定容器到指定 CPU 运行 |
| -m | 设置容器使用内存最大值 |
| --network="bridge" | 指定容器的网络连接类型 |
| --link=[] | 添加链接到另一个容器 |
| --volume,-v | 绑定一个卷 |
| --rm :shell | 退出的时候自动删除容器 |
| --restart | 自动重启 |

2)docker run
创建一个新的容器并运行一个命令。
语法:
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
关键参数,上面create命令的参数都有,只是多了下面的参数:
|-----|-----------------|
| -d | 后台运行容器,并返回容器 ID |
| -rm | 容器停止后自动删除 |
| -e | 设置系统变量 |

3)docker ps
列出容器。
语法:
docker ps [OPTIONS]
关键参数:
|------------|----------------------------|
| -a | 显示所有的容器,包括未运行的 |
| -f | 根据条件过滤显示的内容 |
| --format | 指定返回值的模板文件。如 json 或者 table |
| -l | 显示 latest 的容器 |
| -n | 列出最近创建的 n 个容器 |
| --no-trunc | 不截断输出 |
| -q | 静默模式,只显示容器编号 |
| -s | 显示总的文件大小 |

4)docker logs
查看容器日志。
语法:
docker logs [OPTIONS] CONTAINER
关键参数:
|-----------------|---------------|
| -f ,--follow | 跟踪日志输出 |
| --since | 显示某个开始时间的所有日志 |
| -t,--timestamps | 显示时间戳 |
| -n,--tail | 仅列出最新 N 条容器日志 |

5)docker attach
连接到正在运行中的容器。
语法:
docker attach [OPTIONS] CONTAINER
关键参数:
|-------------|-------------------------------------------------------|
| --sig-proxy | 是否将所有信号代理,默认是 true,如果设置为 false,退出的话不会影响容器,否则退出会导致容器退出 |
6)docker exec
在容器中执行命令。
语法:
docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
关键参数:
|--------------|-----------------------------------------|
| -d | 分离模式: 在后台运行 |
| -i | 即使没有附加也保持 STDIN 打开 |
| -t | 分配一个伪终端 |
| -e | 设置环境变量 |
| -u,--user | 指定用户 "<name|uid>[:<group|gid>]" |
| -w,--workdir | 指定工作目录 |
7)docker start
启动停止的容器。
语法:
docker start [OPTIONS] CONTAINER [CONTAINER...]

8)docker stop
停止运行的容器。
语法:
docker stop [OPTIONS] CONTAINER [CONTAINER...]
关键参数:
|----|-------|
| -s | 发送的信号 |

9)docker restart
重启容器。
语法:
docker restart [OPTIONS] CONTAINER [CONTAINER...]
关键参数:
|----|-------|
| -s | 发送的信号 |

10)docker kill
强制退出容器。
语法:
docker kill [OPTIONS] CONTAINER [CONTAINER...]
关键参数:
|----|-------|
| -s | 发送的信号 |

11)docker top
查看容器中运行的进程信息,支持ps命令参数
语法:
docker top CONTAINER [ps OPTIONS]

12)docker stats
显示容器资源的使用情况,包括:CPU、内存、网络 I/O等。
语法:
docker stats [OPTIONS] [CONTAINER...]
关键参数:
|-------------|-------------------------|
| --all ,-a | 显示所有的容器,包括未运行的 |
| --format | 指定返回值的模板文件。如 table,json |
| --no-stream | 展示当前状态就直接退出了,不再实时更新 |
| --no-trunc | 不截断输出 |
返回报文:
|---------------------|------------------------|
| CONTAINER ID 与 NAME | 容器 ID 与名称 |
| CPU % 与 MEM % | 容器使用的 CPU 和内存的百分比 |
| MEM USAGE / LIMIT | 容器正在使用的总内存,以及允许使用的内存总量 |
| NET I/O | 容器通过其网络接口发送和接收的数据量 |
| BLOCK I/O | 容器从主机上的块设备读取和写入的数据量 |
| PIDs | 容器创建的进程或线程数 |

13)docker container inspect
查看容器详细信息。
语法:
docker container inspect [OPTIONS] CONTAINER [CONTAINER...]
关键参数:
|----|-------------------------|
| -f | 指定返回值的模板文件。如 table、json |
| -s | 显示总的文件大小 |

14)docker port
用于列出指定的容器的端口映射,或者查找将PRIVATE_PORT NAT到面向公众的端口。
语法:
docker port CONTAINER [PRIVATE_PORT[/PROTO]]
15)docker cp
在容器和宿主机之间拷贝文件。
语法:
docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH|-
docker cp [OPTIONS] 容器名或ID:容器内文件路径 宿主机目标路径|-
docker cp [OPTIONS] SRC_PATH|- CONTAINER:DEST_PATH
docker cp [OPTIONS] 宿主机源文件路径|- 容器名或ID:容器内目标路径
16)docker diff
检查容器里文件结构的更改。
语法:
docker diff CONTAINER

17)docker commit
从容器创建要给新的镜像。
语法:
docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
关键参数:
|----|--------------------------------|
| -a | 提交的镜像作者 |
| -c | 使用 Dockerfile 指令来创建镜像;可以修改启动指令 |
| -m | 提交时的说明文字 |
| -p | 在 commit 时,将容器暂停 |
18)docker pause
暂停容器中所有的进程。
语法:
docker pause CONTAINER [CONTAINER...]
细节半圆:

19)docker unpause
恢复容器中所有的进程。
语法:
docker unpause CONTAINER [CONTAINER...]

20)docker rm
删除停止的容器。
语法:
docker rm [OPTIONS] CONTAINER [CONTAINER...]
关键参数:
|----|---------------------------|
| -f | 通过 SIGKILL 信号强制删除一个运行中的容器 |
21)docker export
导出容器内容为tar文件。
语法:
docker export [OPTIONS] CONTAINER
关键参数:
|----|-------|
| -o | 写入到文件 |
22)docker wait
阻塞运行直到容器停止,然后打印出它的退出代码。
语法:
docker wait CONTAINER [CONTAINER...]
23)docker rename
重命名容器。
语法:
docker rename CONTAINER NEW_NAME

24)docker container prune
删除所有停止的容器。
语法:
docker container prune [OPTIONS]
关键参数:
|-------------|-----------|
| -f, --force | 不提示是否进行确认 |
25)docker update
更新容器配置。
语法:
docker update [OPTIONS] CONTAINER [CONTAINER...]
关键参数:
|---------------|--------------------------------|
| --cpus | cpu 数量 |
| --cpuset-cpus | 使用哪些 cpu |
| --memory | 内存限制 |
| --memory-swap | 交换内存 |
| --cpu-period | 是用来指定容器对 CPU 的使用要在多长时间内做一次重新分配 |
| --cpu-quota | 是用来指定在这个周期内,最多可以有多少时间用来跑这个容器 |
三.操作实例
1.批量处理
|---------------------------------------------|---------------------|
| 命令 | 解释 |
| docker container ls -qf name=xxx | 根据名称过滤得到容器编号 |
| docker container ls --filter status=running | 根据状态过滤容器信息 |
| docker container ls -aq | 静默获取全部容器 id |
| docker container ls --filter ancestor=xxx | 过滤镜像名为 xxx 的容器信息 |
| docker container ls --filter ancestor=xxx | 过滤镜像 id 为 xxx 的容器信息 |
参数:
|----|---------------------------|
| -a | 表示打印所有的容器信息,包括正在运行和已退出的 |
| -q | 表示只返回容器ID |
| -f | 表示基于给的条件过滤 等价于 --filter选项 |
1)批量删除容器
docker container rm $(docker container ls -aq)
2)按照状态过滤删除已经退出的容器
docker container rm $(docker container ls -q --f status=exited)
2.容器交互模式
1)attached 模式
docker container run -p 80:80 nginx
通过上面是方式创建容器就是 attached 模式,这样容器会在前台运行。
访问服务器网址的时候,每访问一次,命令窗口就会打印一次日志,Docker 容器
的日志会实时的展现到窗口并且占用此端口。
如果是在 Linux 服务器上,按 Ctrl+C 就会停止掉 Docker 服务,很容易误操作,
所以我们需要一个更好的,更稳定的模式,对应的是 detached 模式
attached 模式仅适用于容器和程序的调试阶段。

2)detached 模式
在 docker container run -p 80:80 nginx 命令基础上加一个-d 或者--detach选项表示 detached 模式, 即在后台执行。
在后台运行,启动后只显示容器 ID,并且可以输入任何命令。
就算关掉窗口依然继续运行,停止和删除容器都需要使用 shell 命令,减少了很多的误操作。
比起 attached 模式更建议使用。
3)interactive 模式
当我们创建好一个容器之后, 可能需要去容器内部获取一些信息或执行一些命令,就需要进入到交互式模式。例如创建一个 Ubuntu 容器之后,需要到系统里输入各种 Shell 命令和系统进行交互就需要进入交互式模式才可以完成。
docker run -it --name nginx -p 80:80 41f689c20910 bash
docker run -d --name nginx -p 80:80 41f689c20910
docker exec -it nginx bash

3.容器自启动
|---------------------------------------------|-------------------------------------------------------------------|
| docker run --restart=no [容器名] | 默认值不自动重启 |
| docker run --restart=on-failure:3 [容器名] | on-failure 若容器的退出状态非 0,则 docker 自动重启容器,还可以指定重启次数,若超过指定次数未能启动容器则放弃 |
| docker run --restart=always [容器名] | always 容器退出时总是重启 |
| docker run --restart=unless-stopped [容器名] | unless-stopped 容器退出时总是重启,但不考虑 Docker 守护进程启动时就已经停止的容器 |
如果容器启动时没有设置--restart 参数,则通过下面命令进行更新:docker update --restart=always [容器名] 。
四.Docker Compose 容器编排
Docker 是一个轻量化的应用程序,Docker 官方推荐每个 Docker 容器中只运行一个进程。
如果一个应用需要涉及到 MySQL、nginx 等环境, 那么我们需要分别为应用、数据库和 nginx 创建单独的 docker 容器,然后分别启动容器。
想象一下,当我们构建好 Docker 之后,每次启动应用,都至少需要 docker run三次, 或者写一些脚本来实现, 这样会比较繁琐。
另外,这些 docker 容器都是分散独立的,也不方便镜像管理。那既然这些 docker容器 都是为了同一个应用服务,我们就应该把它们放到一起,这就引出了 docker compose 来解决这类型的问题。
1.介绍
docker-compose 是 Docker 官方的开源项目,使用 python 编写,实现上调用了Docker 服务的 API 进行容器管理及编排,其官方定义为定义和运行多个 Docker 容器的应用。
docker-compose 中有两个非常重要的概念:
服务 ( service ):一个应用的容器,实际上可以包括若干运行相同镜像的容器实例。
项目( project ):由一组关联的应用容器组成的一个完整业务单元,在 dockercompose.yml 文件中定义, 整个 docker-compose.yml 定义一个项目。
Compose 的默认管理对象是项目,通过子命令对项目中的一组容器进行便捷地生命周期管理。
通过 compose 可以方便的管理多个服务。
使用场景:
单主机部署---快速搭建一个单节点开发或者测试环境,方便使用。
不同环境隔离---通过指定 project 来运行不同的环境,实现隔离的目的。
2.功能
Compose 使用的步骤:
1)使用 docker-compose.yml 定义构成应用程序的服务,这样它们可以在隔离环境中
一起运行;
2)最后,执行 docker compose up 命令来启动并运行整个应用程序。
Compose 具有管理应用程序整个生命周期的命令:
1)启动,停止和重建服务
2)查看正在运行的服务的状态
3)流式传输运行服务的日志输出
4)在服务上运行一次性命令
3.文件
文档:Compose file reference | Docker Docs
文件基本结构:
version: "3.8" # 定义版本, 表示当前使用的 docker-compose 语法的版本
services: # 服务,可以存在多个
servicename: # 服务名字,它也是内部 bridge 网络可以使用的 DNS name,如果不是集群模式相于docker run 的时候指定的一个名称,
#集群(Swarm)模式是多个容器的逻辑抽象
image: # 必选,镜像的名字
command: # 可选,如果设置,则会覆盖默认镜像里的 CMD 命令
environment: # 可选,等价于 docker container run 里的 --env 选项设置环境变量
volumes: # 可选,等价于 docker container run 里的 -v 选项 绑定数据卷
networks: # 可选,等价于 docker container run 里的 --network 选项指定网络
ports: # 可选,等价于 docker container run 里的 -p 选项指定端口映射
expose: # 可选,指定容器暴露的端口
build: #构建目录
depends_on: #服务依赖配置
env_file: #环境变量文件
servicename2:
image:
command:
networks:
ports:
servicename3:
#...
volumes: # 可选,等价于 docker volume create
networks: # 可选,等价于 docker network create
常见字段格式语法:
1)image
指定容器运行的镜像。以下格式都可以:
image: redis
image: redis:5
image:
redis@sha256:0ed5d5928d4737458944eb604cc8509e245c3e19d02ad83935398bc4b991aac7
image: library/redis
image: docker.io/library/redis
image: my_private.registry:5000/redis
2)command
覆盖容器启动的默认命令。
command: ["bundle", "exec", "thin", "-p", "3000"]
command: bundle exec thin -p 3000
3)entrypoint
覆盖容器默认的entrypoint。
entrypoint: /code/entrypoint.sh
entrypoint:
- php
- -d
- zend_extension=/usr/local/lib/php/extensions/no-debug-nonzts-20100525/xdebug.so
- -d
- memory_limit=-1
- vendor/bin/phpunit
4)environment
添加环境变量。可以使用数组或字典、任何布尔值,布尔值需要用引号引起来,以确保YML解析器不会将其转换为True或False。
#map 语法
environment:
RACK_ENV: development
SHOW: "true"
USER_INPUT:
#数组语法
environment:
- RACK_ENV=development
- SHOW=true
- USER_INPUT
5)networks
指定容器运行的网络。
配置容器网络:
services:
frontend:
image: awesome/webapp
networks:
- front-tier
- back-tier
monitoring:
image: awesome/monitoring
networks:
- admin
backend:
image: awesome/backend
networks:
back-tier:
aliases:
- database
admin:
aliases:
- mysql
networks:
front-tier:
back-tier:
admin:
配置网络驱动和子网信息:
services:
frontend:
image: awesome/webapp
networks:
front-tier:
ipv4_address: 172.16.238.10
networks:
front-tier:
ipam:
driver: default
config:
- subnet: "172.16.238.0/24"
6)volumes
将主机的数据卷或者文件挂载到容器里。
#短语法
services:
db:
image: postgres:latest
volumes:
- "/localhost/postgres.sock:/var/run/postgres/postgres.sock"
- "/localhost/data:/var/lib/postgresql/data"
#完整语法
services:
backend:
image: awesome/backend
volumes:
- type: volume
#命名卷
source: db-data
target: /data
volume:
nocopy: true
#绑定卷
- type: bind
source: /var/run/postgres/postgres.sock
target: /var/run/postgres/postgres.sock
volumes:
db-data:
7)ports
指定端口映射。以下格式都可以:
#完整语法
ports:
- target: 80
host_ip: 127.0.0.1
published: 8080
protocol: tcp
mode: host
- target: 80
host_ip: 127.0.0.1
published: 8000-9000
protocol: tcp
mode: host
#短语法
ports:
- "3000"
- "3000-3005"
- "8000:8000"
- "9090-9091:8080-8081"
- "49100:22"
- "127.0.0.1:8001:8001"
- "127.0.0.1:5000-5010:5000-5010"
- "6060:6060/udp"
8)expose
暴露端口,但不映射到宿主机,只被连接的服务访问。仅可以指定内部端口为参数:
expose:
- "3000"
- "8000"
9)build
指定为构建镜像上下文路径。
例如 webapp 服务,指定为从上下文路径 ./dir/Dockerfile 所构建的镜像:
version: "3.7"
services:
webapp:
build: ./dir
或者,作为具有在上下文指定的路径的对象,以及可选的 Dockerfile 和 args:
version: "3.7"
services:
webapp:
build:
context: ./dir
dockerfile: Dockerfile-alternate
args:
buildno: 1
labels:
- "com.example.description=Accounting webapp"
- "com.example.department=Finance"
- "com.example.label-with-empty-value"
# context:上下文路径。
# dockerfile:指定构建镜像的 Dockerfile 文件名。
# args:添加构建参数,这是只能在构建过程中访问的环境变量。
# labels:设置构建镜像的标签。
10)depends_on
设置依赖关系。
docker compose up :以依赖性顺序启动服务。在以下示例中,先启动 db 和
redis ,才会启动 web。
docker compose up SERVICE :自动包含 SERVICE 的依赖项。在以下示例中,docker compose up web 还将创建并启动 db 和 redis。
docker compose stop :按依赖关系顺序停止服务。在以下示例中,web 在 db 和
redis 之前停止。
version: "3.7"
services:
web:
build: .
depends_on:
- db
- redis
redis:
image: redis
db:
image: postgres
可以指定条件,healthy 需要配置 healthcheck 来完成
services:
web:
build: .
depends_on:
db:
condition: service_healthy
redis:
condition: service_started
redis:
image: redis
db:
image: postgres
11)env_file
从文件添加环境变量。可以是单个值或列表的多个值。
env_file: .env
env_file:
- ./common.env
- ./apps/web.env
- /opt/secrets.env
4.命令
命令文档:docker compose | Docker Docs
这里只是介绍几个常用的命令,详细的命令可以看命令文档。
对于 Compose 来说,大部分命令的对象既可以是项目本身,也可以指定为项目中的服务或者容器。如果没有特别的说明,命令对象将是项目,这意味着项目中所有的服务都会受到命令影响。
docker-compose 命令的基本的使用格式为:
docker compose [OPTIONS] COMMAND [ARGS...]
参数:
|-------------------|--------------------------------------------------|
| -f,--file | 指定使用的 Compose 模板文件,默认为 docker-compose.yml,可以多次指定 |
| -p,--project-name | 指定项目名称,默认将使用所在目录名称作为项目名 |
1)docker compose up
该命令的作用十分强大,它会尝试自动完成包括构建镜像、(重新)创建服务、启动服务并关联服务相关容器的一系列操作,可以直接通过该命令来启动一个项目。
语法:
docker compose up [options] [SERVICE...]
参数:
|------------------|--------------------------------------------|
| -d | 在后台运行服务容器, 推荐在生产环境下使用该选项 |
| --force-recreate | 强制重新创建容器,不能与 --no-recreate 同时使用 |
| --no-recreate | 如果容器已经存在了,则不重新创建,不能与 --force-recreate 同时使用 |
2)docker compose down
停止所有容器,并删除容器和网络。
语法:
docker compose down [options] [SERVICE...]
参数:
|--------------|--------------|
| -v,--volumes | 删除容器同时删除目录映射 |
3)docker compose run
该命令可以在指定服务容器上执行相关的命令。
语法:
docker compose run ubuntu ping docker.com
docker compose run [options] SERVICE [COMMAND] [ARGS...]
参数:
|-------------------|--------------------------|
| -d | 后台运行容器 |
| --name NAME | 为容器指定一个名字 |
| --entrypoint CMD | 覆盖默认的容器启动指令 |
| -e KEY=VAL | 设置环境变量值,可多次使用选项来设置多个环境变量 |
| -u, --user="" | 指定运行容器的用户名或者 uid |
| --rm | 运行命令后自动删除容器 |
| -p,--publish=[] | 映射容器端口到本地主机 |