docker的使用

介绍Docker以及Docker中常用的命令

Docker是基于Go语言实现的开源容器项目. Docker项目已经加入了Linux基金会, 并遵循Apache 2.0协议, 全部开源代码均在https://github.com/docker项目仓库进行维护.

Dokder的作用

把一个应用组件打包成一个镜像, 让这个镜像可以在任何安装了Docker的环境上运行. 这个应用组件可以是一个Web应用, 一个编译环境, 也可以是一套数据库平台服务, 甚至是一个操作系统或集群.

Docker的作用原理

创建容器. 让一个应用在容器中运行. 不同的容器相互隔离, 容器之间也可以通过网络相互通信. 容器的创建和停止十分迅速, 几乎跟创建和终止原生应用一致; 另外, 容器自身对系统资源的额外需求也十分有限, 远远低于传统虚拟机.

Docker与虚拟机比较

Docker容器很快, 启动和停止可以在秒级实现, 这相比传统的虚拟机方式(数分钟)要快得多.

Docker容器对系统资源需求henshao, 一台主机可以同时运行数千个Docker容器.

Docker通过类似Git设计理念的操作来方便用户获取, 分发和更新应用镜像, 存储复用, 增量更新.

Docker中核心概念

Docker镜像

Docker镜像类似于虚拟机镜像, 是创建Docker容器的基础.

Docker容器

Docker容器类似于一个轻量级的沙箱, Docker利用容器来运行和隔离应用. 容器是从镜像创建的应用运行实例. 它可以创建, 开始, 停止, 删除, 而这些容器都是彼此相互隔离, 互不可见的.

Docker仓库

Docker仓库类似与代码仓库, 是Docker集中存放镜像文件的场所.

Docker使用

镜像

Docker运行容器前需要本地存在的镜像, 如果镜像不存在, Docker会尝试从默认镜像仓库下载.

获得镜像

1
2
3
4
docker [image] pull NAME[:TAG]

# 例如
docker pull ubuntu:18.04

NAME是镜像仓库名称(用来区分镜像), TAG是镜像的标签(往往用来表示版本信息). 如果不显示指定TAG, 则默认会选择latest标签, 这回下载仓库中最新版本的镜像.

镜像文件一般由若干层组成, 每一层有一个唯一的id, 当不同的镜像包活相同的层时, 本地仅存储了层的一份内容, 减少了存储空间.

列出镜像

1
2
3
docker images 

docker image ls

镜像大小信息只是表示了该镜像的逻辑体积大小, 实际由于相同的镜像层本地只会存储一份, 物理上占用的存储空间会小于各镜像逻辑体积之和.

创建镜像标签副本

1
docker [image] tag 已存在的镜像名:TAG 新的镜像名:新的TAG

查看镜像详情

1
docker [image] inspect NAME:TAG

查看镜像的层数

1
docker [image] history NAME:TAG

删除镜像

1
2
3
docker rmi NAME:TAG [NAME:TAG...]

docker image rm NAME:TAG [NAME:TAG...]

这个会只会删除这个TAG, 只有当只有一个镜像时, 才会删除镜像.

创建镜像

基于已有容器创建
1
docker [container] commit [-m "提交信息"] CONTAINERID [REPOSITORY[:TAG]]
基于本地容器模版导入
1
docker [image] import [-m "提交信息"] file [REPOSITORY[:TAG]]
基于Dockerfile创建

基于Dockerfile创建是最常见的方式. Dockerfile是一个文本文件, 利用给定的指令描述基于父镜像创建新镜像的过程.

1
2
3
4
5
6
7
8
FROM debian:strech-slim

LABEL version="1.0" maintainer="docker user <docker_user@github>"

RUN apt-get update && \
apt-get install -y python3 && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*使用

使用dockerfile

1
docker [image] build -t dockerfile

存出和载入镜像

存出镜像

将镜像保存为一个文件

1
docker [image] save -o 文件名 NAME:TAG
载入镜像

从文件中导入镜像

1
docker [image] load -i 文件名

容器

容器是镜像的一个运行实例. 如果认为虚拟机是模拟运行的一整套操作系统(包括内核, 应用运行态环境和其他系统环境)和跑在上面的应用. 那么Docker容器就是独立运行的一个(或一组)应用, 以及它们所必需的运行环境. 容器名是唯一的, 不能使用相同的容器名.

创建容器

1
2
3
4
5
6
7
8
9
10
11
docker [container] create [OPTION] NAME:TAG

# 常用选项
-i 保持容器的标准输入打开
-t 分配一个伪终端, 并将其绑定到容器的标准输入上
-d 保持后台运行
-p 指定如何映射到本地主机端口
--name (容器名) 给容器取别名
--rm=true|false 容器退出后, 是否删除容器
--restart=true|false 容器的重启策略

创建的容器处于停止状态, 需要使用使用启动容器命令才能使用.

启动容器

1
docker [container] start 容器ID

进程号可以通过docker ps -a获得

终止容器

1
docker [container] stop [-t 时间] 容器ID

stop该命令会首先先容器发送STGTERM信号, 等待一段超时时间后(默认为10秒), 再发送SIGKILL信号终止容器.

1
docker [container] kill 容器ID

直接发送SIGKILL强行终止容器

创建并启动容器

1
docker [container] run [OPTION] NAME:TAG [命令] 

等价于执行docker [container] create, 再执行docker [container] start命令. 命令执行完毕后容器被自动终止.

重启容器

1
docker [container] restart CONTAINER

容器重命令

1
docker [container] rename CONTAINER NEWNAME

查看容器状态

1
2
3
docker ps [-a]

docker container ls [-a]

查看容器输出

1
2
3
4
docker [container] logs

# 常用选项
-t 显示时间戳信息

暂停和恢复容器

1
2
3
docker [container] pause 容器名

docker [container] unpause 容器名

清除处于停止状态的容器

1
docker container prune

进入容器

进入原先的程序
1
docker [container] attach 容器名

如果在这个程序中退出, 容器会终止.

开启新的程序
1
docker [container] exec [-it] 容器名 COMMAND [ARG...]

如果在这个程序中退出, 容器不会退出, 最开始的程序还在运行.

删除容器

1
2
3
4
docker [container] rm [OPTION] 容器ID

# 常用选项
-f 强行终止容器,并删除容器

如果不加-f选项, 只能删除退出状态的容器.

导入和导出容器

导出容器

导出一个已经创建的容器到一个文件, 不管此时这个容器是否处于运行状态.

1
docker [container] export -o 文件名 CONTAINER
导入容器
1
docker [image] import [-m "提交信息"] file [REPOSITORY[:TAG]]

这个会生成一个镜像, 这个与load命令的区别在于, 这个是容器的快照.

查看容器

查看容器详情
1
docker container inspect CONTAINER
查看容器内的进程
1
docker [container] top CONTAINER

这个进程就是宿主机的进程

查看容器资源使用情况
1
docker [container] stats CONTAINER

容器和主机间复制文件

1
2
3
docker [container] cp CONTAINER:SRC_PATH DEST_PATH

docker [container] cp DEST_PATH CONTAINER:SRC_PATH

查看端口映射

1
docker [container] port CONTAINER

这个用docker container inspect CONTAINER也可以查到.

设置容器开启策略

1
2
3
4
5
6
7
8
docker [container] [--restart=(no|on-failure:[maxretries]|always)] CONTAINER

docker [container] update --restart=(no|on-failure:[maxretries]|always)] CONTAINER

# 参数说明
no: 容器退出不重启, 默认
on-failure: 只有容器退出状态为非0时, 才重新启动容器
always: 无论容器退出状态如何, 总是重启容器

Docker数据管理

数据卷是一个可供容器使用的特殊目录, 它将主机操作系统目录直接映射进容器. 需要在容器创建的时候就必须挂上去, 在docker run或者docker create时.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 创建数据卷
docker volume create -d local 数据卷名

# 查看数据卷详情
docker volume inspect

# 列出已有的数据卷
docker volume ls

# 清理无用数据卷
docker volume prune

# 删除数据卷
docker volume rm

创建的数据卷会放在/var/lib/docker/volumes路径下.

使用数据卷

1
docker [container] (run|create) --mount type=(vloume|bind|tmpfs) source=(主机绝对路径|数据卷名), destination=容器(绝对|相对)路径,(ro|rw)

如果容器内的路径不存在, 会自动创建. 默认数据卷是rw的. 挂载文件时可能出现问题, 尽量挂载目录.

--mount-v是相互取代的.

端口映射与容器互联

端口映射实现容器访问

用于主机和容器交互.

1
docker [container] (run|create) [-p (HostPort:ContainerPort|IP:HostPort:ContainerPort|IP::ContainerPort)[/(tcp/udp)]] IMAGE

可以有多个端口映射. 默认是tcp.

容器互联

容器的互联是一种让多个容器中的应用进行快速交互的方式.

1
docker [container] (create|run) --link name:alias NAME:TAG

alias是用来更新环境变量的, 可以自定义, 和容器名解耦. alias作为域名来使用的.

使用Dockerfile创建镜像

Dockerfile的使用#进行注释. 名称只能为Dockfile, 是更具文件名来找的.

一般而言, Dockerfile主体内容分为四部分: 基础镜像信息, 维护者信息, 镜像操作指令和容器启动时执行命令.

主体部分首先使用FROM指令指明所基于的镜像名称, 接下来一般是使用LABEL指令说明维护者信息. 后面则是镜像操作指令, 例如RUN指令将对镜像执行跟随的命令. 每运行一条RUN指令, 镜像添加新的一层, 并提交. 最后是CMD指令, 来执行运行容器时的操作命令.

指令说明

配置指令

指令 作用 格式 说明
ARG 定义创建镜像过程中使用的变量 ARG <name>=<value> 当镜像编译成功后, ARG指定的变量将不再存在(ENV指定的变量将在镜像中保留)
FROM 指定所创建镜像的基础镜像 FROM <image>:<tag> 任何Dockerfile中第一条指令必须为FROM指令
LABEL 为生成的镜像添加元数据标签信息 LABLE <key>=<value> 这些信息可以用来辅助滤出特定镜像
EXPOSE 声明镜像内服务监听的端口 EXPOSE <port>... 这个指令只起到声明作用, 并不会自动完成端口映射. 也不是暴露了才能用
ENV 指定环境变量 ENV <key>=<value>... 指定环境变量, 在镜像生成过程中会被后续RUN指令使用, 在镜像启动的容器中也会存在. 可以在执行`docker (create
ENTRYPOINT 指定镜像的默认入口命令 ENTRYPOINT ["executable", "param1", "param2"]: exec调用执行; ENTRYPOINT command param1 param2: shell中执行 Dockerfile中如果有多个, 只有最后一个有效. 如果使用exec模式, CMD指令会被作为参数来指定. 如果使用shell模式, 会忽略CMD指令
VOLUME 创建数据卷点 VOLUME ["/data"] 这个相当于-v的匿名挂载. 宿主机的目录可以通过docker [container] inspect中的Mounts字段查看
WORKDIR 配置工作目录 WORKDIR /path/to/workdir 为后续的RUN, CMD, ENTRYPOINT指令配置工作目录
ONBUILD 创建子镜像时指定自动执行的操作指令 ONBUILD [INSTRUCTION] 指定当基于所生成镜像创建子镜像时, 自动执行的操作命令

操作指令

指令 作用 格式 说明
RUN 运行指定指令 RUN <command> 每条RUN指令将在当前镜像基础上执行指定命令, 并提交为新的镜像层. 当命令较长时可以使用\来换行
CMD 启动容器时指定默认执行的命令 CMD ["executable", "param1", "param2"];CMD command param1 param2; CMD ["param1", "param2"] Dockerfile中如果有多个, 只有最后一个有效.
ADD 添加命令到镜像 ADD <src> [<src>...] <dest> 该命令将复制指定的<src>路径下内容到容器中的<dest>路径下. 其中<src>可以是Dockerfile所在目录的一个相对路径URL, tar文件, <dest>可以是镜像内的绝对路径, 或者相对于工作目录WORKDIR的相对路径; <dest>如果不存在, 会自动创建; <dest>如果以/结尾会被认为是目录, 如果不以/结尾, 会被认为是文件; 可以指定多个<src>, 但<dest>必须以/结尾; <tar>文件将会自动解压, 把里面的内容放到<dest>目录下, 相当于tar -x
COPY 复制内容到镜像 COPY <src> [<src>...] <dest> ADD类似, 但是不支持URLtar文件(解压). 如果使用本地路径作为源目录时, 推荐使用COPY

创建镜像

1
docker [image] build -t NAME:TAG PATH

该命令将读取指定路径下(包括子目录)的Dockerfile, 默认使用指定路径下的, 不使用子目录下的, 并将该路径下的所有数据作为上下文发送给Docker守护线程.

如果上下文过大, 会导致发送大量数据给守护线程, 延缓创建过程. 因此除非是生成镜像所必需的文件, 不然不要放在上下文路径下.

如果创建镜像成功, 会返回最终镜像的ID.

-------------本文结束感谢您的阅读-------------