Docker-Cheatsheet

📖 节选自 Awesome CheatSheet/Docker CheatSheet,对来自官方文档及 Docker Links 中链接内容的归档整理,包含了日常工作中常用的
Docker 概念与命令,如果对于Linux 常用操作尚不熟悉的可以参考 Linux Commands CheatSheet。
Docker CheatSheet | Docker 配置与实践清单
容器是在操作系统中建立隔离上下文的一种方法。实际上,这意味着它们中的每一个都有一个单独的包含了一组已安装的软件和相关配置的虚拟文件系统。由于它们是相互隔离的,因此任何容器都不能直接访问或影响其他容器或底层宿主操作系统。

虚拟机最大的瓶颈在于其需要特殊硬件虚拟化技术支持,并且携带完整的操作系统;而

安装与配置
Docker CE
这里我们使用科大的
# 更改 Ubuntu 默认源地址
$ sudo sed -i 's/archive.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list
# 安装必备的系统命令
$ sudo apt-get install -y python-software-properties
$ curl -fsSL https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
$ sudo add-apt-repository "deb [arch=amd64] https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu $(lsb_release -cs) stable"
$ sudo apt-get update
$ apt-cache policy docker-ce # 列举 docker-ce 版本
$ apt-get install docker-ce=17.03.2-ce....
Daemon Configuration
# 配置开机自启动
$ sudo systemctl enable docker
# 取消开机自启动
$ sudo systemctl disable docker
我们还需要修改存储路径,指定镜像存储地址,允许远程访问;此时我们可以修改/etc/docker/daemon.json
,此处以修改服务为例:
# 使用 systemctl 命令行修改
$ sudo systemctl edit docker.service
# 或者查找配置地址并使用 Vim 修改
$ systemctl status docker
# 修改文件内容
[Service]
ExecStart=
ExecStart=/usr/bin/dockerd -H fd:// -H tcp://127.0.0.1:2375 -H unix:///var/run/docker.sock --insecure-registry 10.196.108.176:5000 --dns 114.114.114.114 --dns 8.8.8.8 --dns 8.8.4.4 -g /mnt
然后重启服务:
# 重新载入服务配置
$ sudo systemctl daemon-reload
# 重启 Docker
$ sudo systemctl restart docker.service
# 判断是否配置成功
$ sudo netstat -lntp | grep dockerd
Docker Swarm
# 在主节点启动 Swarm
$ docker swarm init
# 查看 Swarm 密钥
$ docker swarm join-token -q worker
# 在主节点启动 Procontainer
$ docker run -it -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock portainer/portainer
# 在主节点启动 Registry
$ docker run -d -p 5000:5000 --restart=always --name registry registry:2
# 将子节点加入到 Swarm
$ docker swarm join \
--token ${TOKEN} \
10.196.108.176:2377
常用配置
代理
鉴于
$ docker run -i -t -e SERVER_ADDR=ss.server.ip -e SERVER_PORT=port -e PASSWORD=123456 bluebu/shadowsocks-privoxy
如果需要手动安装,需要先安装
$ apt install python3-pip
$ pip3 install https://github.com/shadowsocks/shadowsocks/archive/master.zip -U
写入你的配置文件到例如 config.json
:
{
"server": "...",
"server_port": ...,
"local_port": 1080,
"password": "..."
"method": "chacha20-ietf-poly1305",
"timeout": 600
}
启动:
$ sslocal -c config.json
这时一个
listen-address 0.0.0.0:8118 # 所有 interface 上监听流量
forward-socks5 / 127.0.0.1:1080 . # 流量导向本机上的 ss 代理
这时可以访问一下不存在的网站测试一下:
HTTP_PROXY=127.0.0.1:8118 HTTPS_PROXY=127.0.0.1:8118 curl https://www.google.com
下面修改各台机器的1.1.1.2
1.1.1.3
和1.1.1.4
[Environment]
Environment="HTTP_PROXY=127.0.0.1:8118" "HTTPS_PROXY=127.0.0.1:8118" "NO_PROXY=localhost,127.0.0.1,1.1.1.2,1.1.1.3,1.1.1.4"
...
环境变量 NO_PROXY
顾名思义,它不支持
存储与日志
线上系统中我们往往也需要对于
镜像
镜像描述了
构建与拉取
编写完成docker build
命令来创建镜像;关于docker build [ 选项 ] 路径
,该命令将读取指定路径下.dockerignore
文件
镜像的完整-t
选项指定镜像的标签信息,譬如:
$ sudo docker build -t myrepo/myapp /tmp/test1/
$ docker build -t username/image_name:tag_name .
$ docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]
# 拉取镜像
$ docker pull image_name
# 将某个容器保存为镜像
$ docker commit -m “commit message” -a “author” container_name username/image_name:tag
# 保存镜像
$ docker save --output saved-image.tar my-image:1.0.0
$ docker save my-image:1.0.0 > saved-image.tar
$ docker save my_image:my_tag | gzip > my_image.tar.gz
# 导入镜像
$ docker load --input saved-image.tar
$ docker load < saved-image.tar
镜像管理
docker images
命令会列举出全部的镜像
$ docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
mynewimage latest 4d2eab1c0b9a 5 minutes ago 278.1 MB
ubuntu 14.04 ad892dd21d60 11 days ago 275.5 MB
<none> <none> 6b0a59aa7c48 11 days ago 169.4 MB
<none> <none> 6cfa4d1f33fb 7 weeks ago 0 B
- 已使用镜像
(used image): 指所有已被容器(包括已停止的)关联的镜像。即docker ps -a 看到的所有容器使用的镜像。 - 未引用镜像
(unreferenced image): 没有被分配或使用在容器中的镜像,但它有Tag 信息。 - 悬空镜像
(dangling image): 未配置任何Tag (也就无法被引用)的镜像,所以悬空。这通常是由于镜像build 的时候没有指定-t 参数配置Tag 导致的。
# 列举未使用的
$ docker images --filter "dangling=true"
# 删除所有无用的镜像
$ docker rmi $(docker images -q -f dangling=true)
Dockfile
#
开头的注释行。一般的,INSTRUCTION arguments
,指令包括 FROM
、MAINTAINER
、RUN
等。例如:
#
# MongoDB Dockerfile
#
# https://github.com/dockerfile/mongodb
#
# Pull base image.
FROM dockerfile/ubuntu
ENV SOURCE http://downloads-distro.mongodb.org/repo/ubuntu-upstart
# Install MongoDB.
RUN \
apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 7F0CEB10 && \
echo 'deb $SOURCE dist 10gen' > /etc/apt/sources.list.d/mongodb.list && \
apt-get update && \
apt-get install -y mongodb-org && \
rm -rf /var/lib/apt/lists/*
ENV PATH /usr/local/mongo/bin:$PATH
# Define mountable directories.
VOLUME ["/data/db"]
# Define working directory.
WORKDIR /data
# Define default command.
CMD ["mongod"]
# Expose ports.
# - 27017: process
# - 28017: http
EXPOSE 27017
EXPOSE 28017
其中,一开始必须指明所基于的镜像名称,接下来推荐说明维护者信息。后面则是镜像操作指令,例如 RUN
指令,RUN
指令将对镜像执行跟随的命令。每运行一条 RUN
指令,镜像添加新的一层,并提交。最后是 CMD
指令,来指定运行容器时的操作命令。
指令名 | 格式 | 描述 | 备注 |
---|---|---|---|
FROM | 格式为 FROM <image> 或FROM <image>:<tag> |
第一条指令必须为 FROM 指令 |
如果在同一个FROM 指令 |
MAINTAINER | 格式为 MAINTAINER <name> |
指定维护者信息, | |
RUN | RUN <command> 或RUN ["executable", "param1", "param2"] |
前者将在/bin/sh -c ;后者则使用 exec 执行。指定使用其它终端可以通过第二种方式实现,例如 RUN ["/bin/bash", "-c", "echo hello"] |
每条 RUN 指令将在当前镜像基础上执行指定命令,并提交为新的镜像。当命令较长时可以使用 \ 来换行, |
CMD | 支持三种格式CMD ["executable","param1","param2"] exec 执行,推荐方式;CMD command param1 param2 在 /bin/sh 中执行,提供给需要交互的应用;CMD ["param1","param2"] 提供给 ENTRYPOINT 的默认参数; |
指定启动容器时执行的命令,每个CMD 命令。如果指定了多条命令,只有最后一条会被执行。如果用户启动容器时候指定了运行的命令,则会覆盖掉 CMD 指定的命令 |
|
EXPOSE | EXPOSE <port> [<port>...] |
告诉 |
在启动容器时需要通过 |
ENV | ENV<key><value> 。指定一个环境变量,会被后续 RUN 指令使用,并在容器运行时保持 |
||
ADD | ADD<src><dest> |
该命令将复制指定的 <src> 到容器中的 <dest> , |
<src> 可以是 |
COPY | COPY <src><dest> |
复制本地主机的<src> dest |
当使用本地目录为源目录时,推荐使用 COPY |
ENTRYPOINT | ENTRYPOINT ["executable", "param1", "param2"] ,使用指定可执行文件执行;ENTRYPOINT command param1 param2 ,会在 |
配置容器启动后执行的命令,并且不可被 docker run 提供的参数覆盖。每个ENTRYPOINT ,当指定多个时,只有最后一个起效, |
|
VOLUME | VOLUME ["/data"] |
创建一个可以从本地主机或其他容器挂载的挂载点,一般用来存放数据库和需要保持的数据等 | |
USER | USER daemon |
指定运行容器时的用户名或RUN 也会使用指定用户 |
|
WORKDIR | WORKDIR /path/to/workdir |
为后续的 RUN 、CMD 、ENTRYPOINT 指令配置工作目录 |
可以使用多个 WORKDIR 指令,后续命令如果参数是相对路径,则会基于之前命令指定的路径 |
当服务不需要管理员权限时,可以通过该命令指定运行用户。并且可以在之前创建所需要的用户,例如:RUN groupadd -r postgres && useradd -r -g postgres postgres
;要临时获取管理员权限可以使用 gosu
,而不推荐 sudo
。
RUN、
ENTRYPOINT ["/bin/echo", "Hello"]
CMD ["world"]
# docker run -it <image>
# Hello world
# docker run -it <image> John
# Hello John
--init
参数来允许
FROM ubuntu:latest
RUN apt-get update && apt-get install -y supervisor
RUN mkdir -p /var/log/supervisor
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
COPY my_first_process my_first_process
COPY my_second_process my_second_process
CMD ["/usr/bin/supervisord"]
Registry
$ docker run -d -p 5000:5000 --restart=always --name registry registry:2
参考上文描述我们可知,镜像名的前缀即表示该镜像所属的
# 拉取公共镜像
$ docker pull ubuntu:16.04
# 为镜像添加 Registry 信息
$ docker tag ubuntu:16.04 custom-domain:5000/my-ubuntu
# 将其推送到私有镜像库
$ docker push custom-domain:5000/my-ubuntu
# 从私有镜像库中拉取镜像
$ docker pull custom-domain:5000/my-ubuntu
我们也可以指定镜像库的存放地址:
-v /mnt/registry:/var/lib/registry
很多情况下我们的内部仓库并不会配置
{ "insecure-registries": ["myregistry.example.com:5000"] }
有时候我们也需要为私有仓库配置权限认证,那么首先需要添加
$ mkdir auth
$ docker run \
--entrypoint htpasswd \
registry:2 -Bbn cscan cscancscan > ~/auth/htpasswd
$ openssl req -new -newkey rsa:4096 -days 365 \
-subj "/CN=localhost" \
-nodes -x509 \
-keyout ~/certs/domain.key \
-out ~/certs/domain.crt
然后可以使用
registry-srv:
restart: always
image: registry:2
ports:
- 5000:5000
environment:
REGISTRY_HTTP_TLS_CERTIFICATE: /certs/domain.crt
REGISTRY_HTTP_TLS_KEY: /certs/domain.key
REGISTRY_AUTH: htpasswd
REGISTRY_AUTH_HTPASSWD_PATH: /auth/htpasswd
REGISTRY_AUTH_HTPASSWD_REALM: Registry Realm
volumes:
- /opt/registry:/var/lib/registry
- ~/certs:/certs
- ~/auth:/auth
接下来使用
$ docker-compose up -d
# 登录到镜像服务器
$ docker login myregistrydomain.com:5000
多阶段构建
随着
# First stage: complete build environment
FROM maven:3.5.0-jdk-8-alpine AS builder
# add pom.xml and source code
ADD ./pom.xml pom.xml
ADD ./src src/
# package jar
RUN mvn clean package
# Second stage: minimal runtime environment
From openjdk:8-jre-alpine
# copy jar from the first stage
COPY --from=builder target/msb-1.0.jar msb.jar
# run jar
CMD ["java", "-jar", "msb.jar"]
对于
在前面阶段的
FROM image[:tag | @digest] AS stage
在后续阶段的
COPY --from=stage ...
同理,多阶段构建同样可以很方便地将多个彼此依赖的项目通过一个
容器

启停控制
docker create
: 创建一个容器但是不启动。docker rename
: 允许重命名容器。docker run
: 在同一个操作中创建并启动一个容器。docker rm
: 删除容器。docker update
: 更新容器的资源限制。
容器会在结束命令之后自动退出,使用以下的命令选项可以将容器保持在激活状态:
-
-i
即使在没有附着的情况下依然保持STDIN 处于开启。单纯使用-i 命令是不会出现root@689d580b6416:/
这种前缀 -
-t
分配一个伪TTY 控制台
# 创建,并且启动某个容器以执行某个命令
$ docker run -ti --name container_name image_name command
# 创建,启动容器执行某个命令然后删除该容器
$ docker run --rm -ti image_name command
# 创建,启动容器,并且映射卷与端口,同时设置环境变量
$ docker run -it --rm -p 8080:8080 -v /path/to/agent.jar:/agent.jar -e JAVA_OPTS=”-javaagent:/agent.jar” tomcat:8.0.29-jre8
# 创建容器,指定网络
$ docker run --network=<NETWORK>
# 直接使用宿主机的网络
$ docker run --rm -d --network host --name my_nginx nginx
# 指定标签
$ docker run -l my-label --label com.example.foo=bar ubuntu bash
默认情况下,创建容器时,它不会将其任何端口发布到外部世界。要使端口可用于
标志值 | 描述 |
---|---|
-p 8080:80 |
将容器的 |
-p 8080:80/udp |
将容器的 |
-p 8080:80/tcp -p 8080:80/udp |
将容器的 |
# 启动/停止某个容器
$ docker [start|stop] container_name
# 在某个容器内执行某条命令
$ docker exec -ti container_name command.sh
# 查看某个容器的输出日志
$ docker logs -ft container_name
状态查询
docker ps 查看运行中的所有容器。docker logs 从容器中获取日志。( 你也可以使用自定义日志驱动,不过在1.10 中,它只支持json-file 和journald) docker inspect 查看某个容器的所有信息( 包括IP 地址) 。docker events 从容器中获取事件(events) 。docker port 查看容器的公开端口。docker top 查看容器中活动进程。docker stats 查看容器的资源使用情况统计信息。docker diff 查看容器的FS 中有变化文件信息。
# 根据条件过滤查询
$ docker ps --filter "name=nostalgic"
# 显示正在运行的容器列表
$ docker stats --all
# 批量查看日志
for i in $(docker ps -qf name=wsat_slave*); do echo "==================$i" && docker logs $i | grep aisec; done
管理配置
创建容器时也可以容器的重启策略,即是当容器出错退出或者宿主机重启时候,容器的应对策略;重启策略同样会保证相关联的容器以正确的顺序重启,避免意外的错误。
no: 不进行重启on-failure: 当容器以非零状态码退出时重启容器unless-stopped: 当某个容器被显性关闭或者Docker 本身关闭或重启时重启always: 无论出现任何情况都重启容器
# 设置重启策略
# Off, On-failure, Unless-stopped, Always
$ docker run -dit — restart unless-stopped [CONTAINER]
可以通过多种过滤条件来进行容器的移除:
# 关闭所有正在运行的容器
$ docker kill $(docker ps -q)
# 批量重启容器
$ docker restart $(docker ps -a -q)
# 根据 ID或Name 移除
$ docker rm idOrName
# 移除所有停止的容器
$ docker rm $(docker ps -a -q)
# 根据状态移除
$ docker rm $(docker ps -q -f 'status=exited')
# 根据标签移除
$ docker rm $(docker ps -a | grep rabbitmq | awk '{print $1}')
$ docker rm $(docker ps -a | grep "46 hours ago")
我们也可以对容器中的文件进行导入导出操作
docker cp 在容器和本地文件系统之间复制文件或文件夹。docker export 将容器的文件系统切换为压缩包(tarball archive stream) 输出到STDOUT 。
资源配额
我们可以使用 docker stats
命令来查看
$ docker stats redis1 redis2
CONTAINER CPU % MEM USAGE / LIMIT MEM % NET IO BLOCK IO
redis1 0.07% 796 KB / 64 MB 1.21% 788 B / 648 B 3.568 MB / 512 KB
Memory
$ docker run -it -m 300M ubuntu:14.04 /bin/bash
CPU
在线上环境中,我们即希望能够尽量避免
# 指定容器可占用的 CPU 核编号,0-3 表示占用四个核,1,3 表示占用两个核
$ docker run -it --cpuset-cpus="1,3" ubuntu /bin/bash
# 最多允许占用单 CPU 50% 的计算资源,如果双核 CPU,则可以设置为 1.5 等
$ docker run -it --cpus=".5" ubuntu /bin/bash
# 不同的值能够指定不同的容器权重,用于动态分配 CPU 资源
$ docker run -it --cpu-shares="512" ubuntu /bin/bash
-
CPU Set 保障了容器的CPU 核数,安全性较强,但是整体资源利用率低。如果容器实际并不需要如此多核的CPU 资源来处理任务则会造成资源浪费,并且导致其他容器上的任务无法利用该容器上的CPU 空闲时间片,人为阻断了CPU 闲时复用的能力。 -
CPU Share 允许通过共享的方式获得CPU 资源,不同的容器共享一定总量的CPU 计算能力,每个容器都绑定全量核,而每个容器获取一定份额的CPU 计算力。该模式下,每个容器的CPU 资源分配不再以整核分配,而是可精细到CPU 时间片份额的粒度,并且是连续的CPU 核能力值。当整机闲时,可以让较为繁忙的业务获得整机空闲。采用CPU 资源共享的机制,其资源隔离性没有set 模式强,对于极个别CPU 资源敏感型业务,有可能出现偶尔等待CPU 时间片的情况,而影响业务稳定性。对于极少数的这类业务,我们容许继续使用CPU set 模式。
Storage
如果使用
# 限制单个容器最多占用 20G 空间,将应用于任何新建容器。
$ --storage-opt dm.basesize=20G
如果是
$ btrfs qgroup limit -e 50G /var/lib/docker/btrfs/subvolumes/<CONTAINER_ID>
授予对单个设备访问权限
docker run -it --device=/dev/ttyUSB0 debian bash
授予所有设备访问权限
docker run -it --privileged -v /dev/bus/usb:/dev/bus/usb debian bash
资源配置
Volume | 数据卷
容器运行时应该尽量保持容器存储层不发生写操作,对于数据库类需要保存动态数据的应用,其数据库文件应该保存于卷
数据卷是一个可供一个或多个容器使用的特殊目录,它绕过
-
数据卷可以在容器之间共享和重用
-
对数据卷的修改会立马生效
-
对数据卷的更新,不会影响镜像
-
卷会一直存在,直到没有容器使用
-
数据卷的使用,类似于
Linux 下对目录或文件进行mount 。
For example,
# the following creates a tmpfs volume called foo with a size of 100 megabyte and uid of 1000.
$ docker volume create --driver local \
--opt type=tmpfs \
--opt device=tmpfs \
--opt o=size=100m,uid=1000 \
foo
nother example that uses nfs to mount the /path/to/dir in rw mode from 192.168.1.1:
$ docker volume create --driver local \
--opt type=nfs \
--opt o=addr=192.168.1.1,rw \
--opt device=:/path/to/dir \
foo
$ docker run -d \
-it \
--name devtest \
-v myvol2:/app \
nginx:latest
"Mounts": [
{
"Type": "volume",
"Name": "myvol2",
"Source": "/var/lib/docker/volumes/myvol2/_data",
"Destination": "/app",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
],
-v
# 挂载目录
$ sudo docker run -d -P --name web -v /src/webapp:/opt/webapp training/webapp python app.py
# 挂载文件
$ sudo docker run --rm -it -v ~/.bash_history:/.bash_history ubuntu /bin/bash
# Docker 挂载数据卷的默认权限是读写,用户也可以通过 `:ro` 指定为只读。
$ sudo docker run -d -P --name web -v /src/webapp:/opt/webapp:ro
training/webapp python app.py
注意:
VOLUME /data
Network | 网络
bridge
: 默认的网络驱动,常用于多个应用运行与独立容器中并且需要相互通讯的时候。host
: 移除容器与Docker 主机之间的网络隔离,直接使用宿主机所在的网络。底层与宿主机共用一个Network Namespace ,容器将不会虚拟出自己的网卡,配置自己的IP 等,而是使用宿主机的IP 和端口。overlay
: Overlay 网络用语连接多个Docker Daemon ,保证Docker Swarm 服务的正常运行;独立的容器与Swarm 服务,或者不同宿主机上的容器同样能够通过Overlay 进行通信。none
: 对于指定容器禁止所有的网络通信。macvlan
: Macvlan 网络会允许直接为容器分配MAC 地址,使其作为真正的物理设备接入到宿主机所在的网络中。
我们使用
$ docker network ls
NETWORK ID NAME DRIVER SCOPE
f707aa0ef50d bridge bridge local
97dd7a032d96 host host local
d5a1bed0b12d none null local
桥接模式下,当
桥接模式下,创建一个
# 创建新的网络
$ docker network create --driver bridge isolated
# 指定网段,宿主机会作为默认网关
$ docker network create --driver=bridge --subnet=192.168.2.0/24 --gateway=192.168.2.10 new_subnet
# 创建时将某个容器连接到网络
$ docker run --network=isolated -itd --name=docker-nginx nginx
# 将某个运行中容器连接到某个网络,在该网络内可以通过容器名自由访问
$ docker network connect multi-host-network container1
DNS
默认情况下,容器从
- -h HOSTNAME or –
hostname=HOSTNAME 设定容器的主机名,它会被写到容器内的/etc/hostname 和/etc/hosts 。但它在容器外部看不到,既不会在docker ps 中显示,也不会在其他的容器的/etc/hosts 看到。 - –
link=CONTAINER_NAME:ALIAS 选项会在创建容器的时候,添加一个其他容器的主机名到/etc/hosts 文件中,让新容器的进程可以使用主机名ALIAS 就可以连接它。 - –
dns=IP_ADDRESS 添加DNS 服务器到容器的/etc/resolv.conf 中,让容器用这个服务器来解析所有不在/etc/hosts 中的主机名。 - –
dns-search=DOMAIN 设定容器的搜索域,当设定搜索域为.example.com 时,在搜索一个名为host 的 主机时,DNS 不仅搜索host ,还会搜索host.example.com 。注意:如果没有上述最后2 个选项,Docker 会默认用主机上的/etc/resolv.conf 来配置容器。
空间清理
ps -s
参数来显示二者的空间占用情况
# 查看当前目录下的文件空间占用
$ du -h --max-depth=1 | sort
# 空间占用总体分析
$ docker system df
# 输出空间占用细节
$ docker system df -v
# 输出容器的空间占用
$ docker ps -s
docker system prune
指令能够进行自动地空间清理,其默认会清除已停止的容器、未被任何容器所使用的卷、未被任何容器所关联的网络、所有悬空镜像
# 一并清除所有未使用的镜像和悬空镜像
$ docker system prune --all
# 列举悬空镜像
$ docker images -f dangling=true
# 删除全部悬空镜像
$ docker image prune
# 删除所有未被使用的镜像
$ docker image prune -a
# 删除指定模式的镜像
$ docker images -a | grep "pattern" | awk '{print $3}' | xargs docker rmi
# 删除全部镜像
$ docker rmi $(docker images -a -q)
# 删除全部停止的容器
$ docker rm $(docker ps -a -f status=exited -q)
# 根据指定模式删除容器
$ docker rm $(docker ps -a -f status=exited -f status=created -q)
$ docker rm $(docker ps -a | grep rabbitmq | awk '{print $1}')
# 删除全部容器
$ docker stop $(docker ps -a -q)
$ docker rm $(docker ps -a -q)
# 列举并删除未被使用的卷
$ docker volume ls -f dangling=true
$ docker volume prune
# 根据指定的模式删除卷
$ docker volume prune --filter "label!=keep"
# 删除未被关联的网络
$ docker network prune
$ docker network prune --filter "until=24h"
我们也可以手动指定日志文件的尺寸或者清空日志文件
# 设置日志文件最大尺寸
$ dockerd ... --log-opt max-size=10m --log-opt max-file=3
# 清空当前日志文件
truncate -s 0 /var/lib/docker/containers/*/*-json.log
服务治理
Docker Compose
# 指定 Docker Compose 文件版本
version: "3"
services:
web:
# 指定从本地目录进行编译
build: .
# 指定导出端口
ports:
- "5000:5000"
# 替换默认的 CMD 命令
command: python app.py
# 将本地目录绑定到容器内目录
volumes:
- .:/code
redis:
# 镜像的 ID
image: "redis:alpine"
这里用到的
FROM python:3.4-alpine
ADD . /code
WORKDIR /code
RUN pip install -r requirements.txt
CMD ["python", "app.py"]
值得注意的是,我们在代码中直接使用服务名作为连接地址,即可访问到
cache = redis.Redis(host='redis', port=6379)
然后使用
# 交互式启动
$ docker-compose up
# 守护进程式启动
$ docker-compose up -d
# 查看运行情况
$ docker-compose ps
# 关闭
$ docker-compose stop
# 移除内部卷
$ docker-compose down --volumes
在涉及到数据存储的场景下,我们同样可以指定
version: "3.2"
services:
web:
image: nginx:alpine
volumes:
- type: volume
source: mydata
target: /data
volume:
nocopy: true
- type: bind
source: ./static
target: /opt/app/static
db:
image: postgres:latest
volumes:
- "/var/run/postgres/postgres.sock:/var/run/postgres/postgres.sock"
- "dbdata:/var/lib/postgresql/data"
volumes:
mydata:
dbdata:
如果某个数据卷天然需要映射到本地文件,则可以指定
volumes:
wsat_etc:
driver: local
driver_opts:
o: bind
type: none
device: /etc/wsat/
Docker Swarm

使用
# 创建一个新的服务
$ docker service create \
--image nginx \
--replicas 2 \
nginx
# 更新服务
$ docker service update \
--image nginx:alpine \
nginx
# 删除服务
$ docker service rm nginx
# 缩容,而不是直接删除服务
$ docker service scale nginx=0
# 扩容
$ docker service scale nginx=5
# 列出所有的服务
$ docker service ls
# 列出一个服务的所有实例(包括服务的健康状况)
$ docker service ps nginx
# 服务的详细信息
$ docker service inspect nginx
# 增加和删除DNS
$ docker service update --dns-add 222.222.222.222 tender_hofstadter
$ docker service update --dns-rm 222.222.222.222 tender_hofstadter
# 增加和删除端口映射
$ docker service update --publish-add 80:80 xenodochial_ritchie
$ docker service update --publish-rm 80:80 xenodochial_ritchie
我们也可以使用
$ docker stack deploy application
version: "3"
services:
web:
image: registry.gitlab.com/example/example # you need to use external image
command: npm run prod
ports:
- 80:80
deploy:
replicas: 6
update_config:
parallelism: 2
delay: 10s
restart_policy:
condition: on-failure