敲黑板
Package docker-ce is not available, but is referred to by another package.
如果提示未发现可用的 docker-ce 包时,检查系统镜像源是否正确(如果不能翻墙时, 使用国内的镜像源修改 /etc/apt/source.list)
Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get http://%2Fvar%2Frun%2Fdocker.sock/v1.24/images/json: dial unix /var/run/docker.sock: connect: permission denied
执行 docker 相关命令时提示, 表示 docker 权限不足
使用 sudo 命令运行 docker 命令
将当前用户加入到 docker 组中
1 | [root@localhost ~]# cat /etc/group | grep docker |
1 | groupadd docker # 添加 docker 用户组 |
概念
架构
命令
镜像
是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)
镜像由多个层组成, 每层叠加之后, 从外部看来就如一个独立的对象
UnionFS 联合文件系统
镜像加速
/etc/docker/daemon.json
配置文件修改默认镜像源
1 | { |
镜像操作
镜像的操作命令可直接用在 docker
或 docker image
命令后面
- images 查看本地镜像列表, 作用同
image ls
- rmi 删除本地镜像, 作用同
image rm
- tag 给镜像文件创建标签
- build 从 Dockerfile 构建镜像
- load|import 导入镜像归档文件
- save 保存镜像到归档文件
- history 查看镜像的历史信息
- pull [OPTIONS] NAME[:TAG|@DIGEST] 从远程仓库拉取镜像
镜像导入和导出
1 | [root@localhost ~]# docker [image] save -o # 归档一个或多个镜像文件 |
批量删除多个镜像
1 | docker rmi -f $(docker images -aq) |
从容器构建镜像
1 | docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]] # 从容器构建镜像, 提交到本地仓库 |
- -a, --author 提交作者
- -m, --message 提交信息
- -p, --pause 提交过程中是否中断容器运行, 默认为 true
1 | [root@localhost ~]# docker images # 显示所有镜像 |
从 Dockerfile 构建镜像
.
上下文路径
- -f 指定配置文件, 默认
${PWD}/Dockerfile
- -t 指定新创建的镜像名称和标签
- --no-cache 构建镜像时不使用缓存
- --compress 使用 gzip 压缩构建上下文环境
- --label 设置镜像元数据
- --network 设置构建过程中
RUN
指令的网络模式 - --build-arg 通过命令行设置构建镜像过程中的参数, 可以覆盖
ARG
设置的参数
1 | docker build -f /path/to/Dockerfile -t name:tag . |
容器
容器独立运行的一个或一组应用,是镜像运行时的实体, 它可以被启动、开始、停止、删除. 每个容器之间都是相互隔离的, 保证安全的平台
- 应用容器化 将应用整合到容器中并且运行起来的这个过程
1 | [root@localhost ~]# docker ps -a # 查看所有容器信息 |
容器操作
容器的操作命令可直接用在 docker
或 docker container
命令后面
create 创建新容器
run 创建并启动一个容器
start|stop|kill 启动|停止容器
pause 暂停容器
restart 重启容器
rename 重命名容器
events 获取 docker 服务器的实时事件
diff 显示容器文件系统的前后变化
ps 查看容器列表, 作用同
container ls
inspect 查看容器详细信息, 作用同
container inspect
logs 输出容器运行日志
- -f, --follow 实时输出容器运行日志
- -n, --tail 查看指定行数
- -t, --timestamps 输出日志添加时间戳
rm 删除容器
port 查看容器映射端口
export 导出容器为归档文件
wait 阻塞一个或多个容器直到停止运行, 并打印容器的退出码
1 | [root@localhost ~]# docker wait centos01 # 阻塞一个或多个容器直到停止运行, 并打印容器的退出码 |
运行
如果本地不存在镜像时则先从远程拉取镜像(docker pull 镜像名)
1 | docker run --name 'helloWorld' -it 镜像名 在启动的容器里执行的命令 |
--name 容器名称
-d 后台方式运行
-i,--interactive 即使没有附加也保持 STDIN 打开, 如果需要执行命令则需要开启这个选项
-t,--tty 分配一个伪终端进行执行, 一个连接用户的终端与容器 stdin 和 stdout 的桥梁
-P 将容器内部使用的网络端口映射到宿主机随机端口上
-p 指定容器的端口
- -p 主机 IP:主机端口:容器端口/协议
- -p 主机端口:容器端口/协议
- -p 容器端口/协议
-e 设置容器运行的环境变量
-w 设置容器内部的工作目录
-h, --hostname 设置容器的主机名
-v, --volume 设置容器数据卷映射
--mount 挂载文件系统
--temps 挂载临时文件系统
--volumes-from 指定继承的数据卷容器
--label 设置容器的元数据
--ip 设置容器 IP 地址
--link 连接到另一个容器
--network 连接到指定的网络, 默认为 docker0
--privileged 授予此容器扩展权限
--entrypoint 覆盖镜像文件中默认的 ENTRYPOINT
--restart string 当容器退出后的重启策略
--read-only 只读模式挂在容器文件系统
--add-host list 添加主机 ip 映射
--dns list 设置 dns 服务
--rm 测试时临时运行容器关闭后自动删除容器
1 | docker run -d --rm -p 6666:80 --name nginx01 nginx |
1 | [root@localhost ~]# docker images # 查看本地所有镜像 |
- 示例:最简单的 nginx 服务集群
1 | [root@localhost ~]# docker images # 查看所有镜像 |
进入容器
exec 和 attach
- exec
- 进入容器打开一个新的终端
- 退出容器, 容器正常运行
- attach
- 进入容器打开正在运行的终端
- 退出容器, 容器自动停止
1 | [root@localhost ~]# docker ps -a # 查看所有容器信息 |
文件拷贝 cp
- -a, --archive 复制文档的所有信息
拷贝宿主机到容器内
1 | docker cp [宿主机路径] [容器标识]:[容器内路径] |
1 | # 拷贝宿主机文件到 a441e0564165 /user/local 下 |
拷贝容器内到宿主机
1 | docker cp [容器标识]:[容器内路径] [宿主机路径] |
1 | [root@localhost ~]# ls /home/ |
容器环境变量和工作目录
- -e 运行容器时指定环境变量
- -w 容器工作目录
1 | [root@localhost ~]# docker exec -it -e PATH=/usr/local/v12.22.1/bin:$PATH centos01 node -v |
容器导入和导出
export 从容器中导出为归档文件
import 从归档文件中导入为镜像文件
1 | [root@localhost ~]# docker [container] export -o centos01.tar.gz centos01 # 归档容器 |
删除所有容器
1 | docker rm -f $(docker ps -aq) |
查看容器资源使用情况统计
1 | docker stats |
数据卷
卷就是目录或者文件,存在于一个或多个容器中,由 docker 挂载到容器中,卷的设计目的就是数据的持久化,完全独立于容器的生存周期, 因此 Docker 不会在容器删除时删除其挂载的数据
- create 创建数据卷
- inspect 显示数据卷的详细信息
- ls 显示所有数据卷
- rm 删除数据据按
- prune 移除所有未使用的本地数据卷
特点
- 卷中的更改可以直接生效
- 数据卷可在容器之间共享数据
- 数据卷中的更改不会包含在镜像的更新中
- 数据卷的生命周期一直持续到没有容器使用它为止
数据卷类型
默认挂载数据卷的权限为 RW
可以在挂载数据卷时指定数据卷的权限 -v [source/path]:[destination/path]:[rw]
- --mount 不指定 type 选项默认为 volume
- -v 不能建立 tmpfs mounts
对比项 | –volume 或 -v | –mount type=bind |
---|---|---|
若是主机路径不存在 | 自动建立 | 命令报错 |
对比项 | bind mount | volume |
---|---|---|
Source 位置 | 用户指定 | /var/lib/docker/volumes/ |
Source 为空 | 覆盖 dest 为空 | 保留 dest 内容 |
Source 非空 | 覆盖 dest 内容 | 覆盖 dest 内容 |
Source 种类 | 文件或目录 | 只能是目录 |
可移植性 | 一般(自行维护) | 强(docker 托管) |
宿主直接访问 | 容易(仅需 chown) | 受限(需登陆 root 用户)* |
volume mounts
指定 docker 挂载区域, Docker 管理宿主机文件系统的一部分(/var/lib/docker/volumes)
1 | docker volume create [OPTIONS] [VOLUME] # 创建数据卷 |
bind mounts
是宿主机任意文件系统, 可以存储在宿主机系统的任意位置
1 | docker run --mount type=bind,source=${PWD}/${CONTAINER_NAME}/app,destination=/app centos01 /bin/bash |
tmpfs mounts
临时挂载到宿主机系统的内存中, 不会写入宿主机的文件系统
1 | docker run --mount type=tmpfs,tmpfs-size=512M,destination=/path/in/container |
挂载数据卷
-v 挂载方式
-v 容器内路径 匿名挂载
1 | [root@localhost ~]# docker run -tid --name centos01 -v /centosVolume centos /bin/bash |
-v 卷名:容器内路径 具名挂载
- 如果
不需要
对容器内的数据卷挂载点进行写操作
时, 使用具名挂载方式备份容器内数据到宿主机中
1 | [root@localhost ~]# docker run -tid --name centos02 -v summary:/myVolume centos /bin/bash |
-v /宿主机路径:容器内路径 指定路径挂载
- 如果
需要
对容器内的数据卷挂载点进行写操作
时, 使用指定路径挂载方式, 此方式会将宿主机中的数据卷挂载点数据覆盖容器内指定路径
1 | [root@localhost ~]# docker run -tid --name centos03 -v ${PWD}/react-app/:/containerVolume centos /bin/bash |
--mount 挂载方式
--mount 具名挂载
1 | [root@localhost ~]# docker run -tid --name centos04 --mount type=volume,source=applet_ui,destination=/appletVolume centos /bin/bash |
--mount 指定路径挂载
1 | [root@localhost ~]# docker run -tid --name centos05 --mount type=bind,source=${PWD}/applet_uni,destination=/uniVolume centos /bin/bash |
共享数据卷
- --volumes-from 创建数据卷容器共享数据
1 | # 创建容器并挂载数据卷 |
Dockerfile
- .dockerignore 构建上下文忽略文件
Dockerfile 是用来构建 Docker 镜像的一个指令脚本, 脚本中的每条指令执行一次都会在镜像上新建一层
指令
FROM 构建镜像时的基础镜像层
MAINTAINER(deprecated) 维护者信息, 使用
LABEL
指令代替EXPOSE 对外暴露端口
1
2EXPOSE 80/tcp
EXPOSE 80/udpADD 复制指令, 增强版的
COPY
指令, 支持文件解压和远程 URL 资源COPY 复制指令, 从上下文目录中复制文件或者目录到容器里指定路径
1
2# [--chown=<user>:<group>] 可选参数,用户改变复制到容器内文件的拥有者和属组
COPY ["src", "dest"]RUN 构建镜像时执行的命令 可以存在多条指令
1
2
3
4
5RUN yum -y install vim
# 合并多个相同作用的指令以减少新建镜像层数
RUN yum -y install wget \
&& wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz" \
&& tar -xvf redis.tar.gzCMD 容器运行时执行的命令, 如果存在多个
CMD
指令, 仅最后一个生效ENTRYPOINT 容器运行时执行的命令, 参数不会被
docker run
的命令行参数覆盖, 如果存在多个ENTRYPOINT
指令,仅最后一个生效1
2
3
4
5ENTRYPOINT '<exec_cmd>' '<param1>'
ENTRYPOINT ["<executeable>","<param1>","<param2>",...]
CMD '<exec_cmd>' '<param1>'
CMD ["<可执行文件或命令>","<param1>","<param2>",...]ARG 构建参数, 作用与 ENV 一致, ARG 中的环境变量仅在
Dockerfile
内有效ENV 设置持久化环境变量, 如果只想在构建构建阶段有效使用
ARG
指令1
2
3
4
5ARG VERSION1 1
ARG VERSION=1
ENV NAME1 hello
ENV NAME2=helloVOLUME 定义匿名数据卷, 在启动容器时会自动挂载到 /var/lib/docker/volumes/
1
2
3
4
5# 出于可移植和分享的考虑, 不支持 具名挂载 和 指定路径挂载 在 Dockerfile 中配置
# 只能使用 匿名挂载 配置方式
# 因为宿主机目录是依赖于特定宿主机的, 并不能够保证在所有的宿主机上都存在这样的目录
VOLUME ["<路径1>", "<路径2>"...]
VOLUME <路径> <路径>WORKDIR 为
RUN
,CMD
,ENTRYPOINT
,COPY
,ADD
指定工作目录USER 指定执行后续命令的用户和用户组, 用户名和用户组必须提前存在
1
2
3WORKDIR /usr/local
USER <用户名>[:<用户组>]LABEL 给镜像添加元数据
SHELL 允许重写默认的 shell
STOPSIGNAL 设置当容器退出时系统调用的指令
ONBUILD 当前镜像作为其他镜像的基础镜像构建时触发
1
ONBUILD ADD . /app/src
HEALTHCHECK 指定监控 docker 容器服务的运行状态的方式
ADD 和 COPY
- ADD 复制指令, 增强版的
COPY
指令, 支持文件解压和远程 URL 资源 - COPY 复制指令, 从上下文目录中复制文件或者目录到容器里指定路径
ARG 和 ENV
- ENV 设置持久化环境变量, 如果只想在构建构建阶段有效使用
ARG
指令 - ARG 构建参数, 作用与 ENV 一致, ARG 中的环境变量仅在
Dockerfile
内有效
VOLUME
CMD 和 ENTRYPOINT
区别
- CMD 情况下, run 后面的参数将作为整体替换
CMD
配置项中的命令
1 | # Dockerfile |
1 | # /bin/bash ls -al 命令会整体替换 Dockerfile 中的 CMD 指令 |
- ENTRYPOINT 情况下,
docker run
后面的参数将作为 ENTRYPOINT 配置项指令的一部分
1 | # Dockerfile |
1 | # run 后面的参数作为 ENTRYPOINT 配置项命令参数的一部分 |
- CMD 和 ENTRYPOINT 同时存在时, CMD 作为 ENTRYPOINT 配置项命令的一部分, 与书写位置没有关系
1 | # Dockerfile |
是否传参 | Dockerfile 配置项指令 | 传参运行 |
---|---|---|
Docker 命令 | docker run nginx | docker run nginx /etc/nginx/new.conf |
衍生出的实际命令 | nginx -c /etc/nginx/nginx.conf | nginx -c /etc/new.conf |
使用场景
- Dockerfile 应至少指定一个 CMD 或 ENTRYPOINT 指令
- ENTRYPOINT 应在将容器作为可执行文件时定义
- CMD 应该用作为 ENTRYPOINT 命令定义默认参数或在容器中执行临时命令的一种方式
- CMD 使用替代参数运行容器时将被覆盖
No ENTRYPOINT | ENTRYPOINT entry p1_entry | ENTRYPOINT [‘entry’,’p1_entry’] | |
---|---|---|---|
No CMD | error, not allowed | /bin/sh -c entry p1_entry | entry p1_entry |
CMD [‘cmd’,’p1_cmd’] | cmd p1_cmd | /bin/sh -c entry p1_entry | entry p1_entry cmd p1_cmd |
CMD [‘p1_cmd’,’p2_cmd’] | p1_cmd p2_cmd | /bin/sh -c entry p1_entry | entry p1_entry p1_cmd p2_cmd |
CMD cmd p1_cmd | /bin/sh -c cmd p1_cmd | /bin/sh -c entry p1_entry | entry p1_entry /bin/sh -c cmd p1_cmd |
镜像优化
- 合并多个相同作用的指令以减少新建镜像层数
- 使用较小的基础镜像
- 使用 .dockerignore 文件, 从构建上下文中忽略指定的文件
- 在 RUN 之后放置 COPY 指令, 有助于 docker 能够更好的使用缓存功能
- 在安装后删除软件包
- 使用 Docker 镜像缩容工具
应用
- Dockerfile 配置文件
1 | # Dockerfile |
构建镜像
1 | # 构建镜像并指定镜像名称和版本号, 最后的 . 很重要,表示在当前目录下进行构建, 可以使用 |
查看镜像信息
镜像配置信息
1 | [root@localhost workspace]# docker image inspect hello:v1.0 |
镜像历史信息
1 | [root@localhost workspace]# docker image history hello:v1.0 |
查看容器状态
1 | [root@localhost workspace]# docker container inspect hello-v1 |