记录Docker学习。重点学习Docker基础和Compose,实践了几个小型项目,下一步运用熟练。
0x01 基本概念
镜像(Image):root文件系统(分层存储,体积小)
容器(Container):实质是基于镜像的进程,相当于镜像的实例(在镜像基础上加一层容器运行时的存储层)
仓库(Registry):集中存储、分发镜像的服务(包含多个仓库,每个仓库可包含多个标签)
国内加速
0x02 安装Docker
0x03 使用镜像
镜像实现原理
很多层构成,使用 Uinon FS 将这些不同的层结合到一个镜像中去
1 获取镜像
1 2
| $ docker pull [选项] [仓库地址] 仓库名:标签 如:docker pull ubuntu:14.04
|
2 列出镜像
因镜像多层存储,可以继承、复用,故镜像体积和并非是实际硬盘消耗
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| $ docker image ls # 查看镜像、容器、数据卷所占用空间 $ docker sysytem df
# 列出部分镜像 $ docker image ls [镜像名] # 使用filter过滤 $ docker image ls -f since/before=xxx # 列出镜像的ID $ docker image ls -q # 列出镜像摘要 $ docker image ls --digests # 指定格式列出 $ docekr image ls --format "{ {.ID}}:{ {.Repository}}"
|
悬虚镜像:新旧镜像同名,使得旧镜像被取消从而仓库名、标签都为
1 2 3 4
| # 显示悬虚镜像 $ docker image ls -f dangling=true # 删除悬虚镜像 $ docker image prune
|
中间层镜像:其他镜像所依赖的镜像(不可删除)
1 2
| # 显示中间层镜像 $ docker image ls -a
|
3 删除镜像
1 2
| $ docker image rm [选项][镜像] # 注:镜像可以是:长/短ID、镜像名、镜像摘要
|
4 镜像运行
1 2 3 4 5 6
| # 启动镜像, 用nginx镜像启动一个命名为webserver的容器,并映射到80端口 $ docker run --name webserver -d -p 80:80 nginx # 进入镜像 $ docker exec -it [容器名字] [shell] # 查看改动 $ docker diff [容器名字]
|
5 镜像保存
1 2
| # 把容器保存为镜像, 给原来镜像新添加一层,形成新镜像,自己定制的黑箱镜像。慎用! $ docker commit [选项] <容器ID> [容器名字]
|
6 镜像定制
定制每一层所添加的配置、文件来定制镜像(Dockerfile脚本一键化来快速构建)
什么是Dockerfile?其是包含了一条条命令的文本文件,每一条命令为一层,每一条命令描述该层如何构建。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| FROM:指定基础镜像,必须有且为第一条命令。(scratch为空白镜像,不以任何系统为基础。不需要系统支持,比较适合Go语言) RUN:执行命令行命令。 - shell格式:命令行格式 - exec格式:RUN \["可执行文件" , "参数1" , "参数2"\],像是函数调用中的格式 COPY:复制文件 - 命令行:COPY [--chown=<user>:<group>] <源路径>...<目标路径> - 函数调用:COPY [--chown=<user>:<group>] ["<源路径>",..."<目标路径>"]
ADD:更高级的文件复制 <源路径>可以是URL或者tar压缩文件,下载后默认权限为600(最好不要用)
CMD:容器启动命令 - shell格式:CMD <命令>(实际是被包装为sh -c 的参数进行执行) - exec格式:CMD ["可执行文件", "参数1", "参数2"....](被解析为JSON数组)
ENTRYPOINT:入口点(目的同CMD,指定容器启动程序及参数) - shell格式: - exec格式: CMD内容作为参数传到 RNTRYPOINT(目的可以加后续参数)
ENV:设置环境变量(后续指令中可以使用环境变量,而升级只需要改变环境变量版本,利于维护Dockerfile) - ENV <key> <value> - ENV <key1>=<value1> <key2>=<value2>...
ARG:构建参数 - ARG <参数名>[=<默认值>] - ARG同EVN,但是其环境变量在容器运行时不会存在。
VOLUME:定义匿名卷(尽量爆出容器存储层不发生写操作) - VOLUME ["<路径1>", "路径2"...] - VOLUME <路径>
EXPOSE:声明端口(帮助使用者理解镜像服务的守护段,方便配置映射;运行时随机端口映射随机映射EXPOSE的端口) - EXPOSE <端口1> [<端口2>...]
WORKDIR:指定工作目录(指定工作目录,如果没有自动创建) - WORKDIR <工作目录路径> 保证各层的当前目录就被改为制定的目录
USER:指定当前用户(同WORKDIR,改变环境状态并影响以后的层。改变之后各层的执行RUN、CMD、ENRTRYPOINT这类命令的身份) - USER <用户名>[:<用户组>]
HEALTHCHECK:健康检查 - HEALTHCHECK [选项] CMD <命令>:设置检查容器健康的命令 - HEALTHCHECK NONE:屏蔽基础镜像的健康检查 支持下列选项: --interval=<间隔>(两次检查间隔,默认30s) --timeout=<时长>(超时时间,默认30s) --retries=<次数>(失败次数限制,超过则unhealthy)
ONBUILD:为他人做嫁衣裳 - ONBULID <其他指令>(其他指令当以当前的镜像为基础镜像 构建下一季镜像的时候才会被执行)
|
- 层数问题:每个shell命令一个RUN则每个命令构建一层,耗费资源!(目前最大可建127层)
- 解决:\换行格式化(清晰、排障),&&串联。 最后清理删除无关文件(比如apt缓存文件,避免镜像臃肿)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| # Dockerfile构建镜像 $ docker build [选项] <上下文路径/URL> # build原理:远程调用Docker服务端的Docker引擎来实现。(若最后为".",打包本地址内容上传到Docker引擎)
# Git repo构建镜像 $ docker build[http://github.com/twang2218/gitlab-ce-zh.git]
# tar压缩包构建 $ docker build http://server/context.tar.gz
# 从标准输出中读取Dockerfile进行构建 $ docker build - < Dockerfile(或cat Dockerfile | docker build -)
# 从标准输入中读取上下文压缩包进行构建 $ docker build - < context.tar.gz
|
7 其他制作镜像的方式
1 2
| # 压缩包可以是本地文件、远程web文件。从镜像/目录展开并直接作为镜像第一层提交 $ docker import [选项] <文件>|<URL>| - [<仓库名>[:<标签>]]
|
- 2 Docker save 和 Docker load
1 2 3 4 5 6
| # 将镜像保存为一个文件,然后传输到另外一个位置上,再加载进去 # 保存 $ docker save [仓库名] -o [filename] $ docker save [仓库名] | gzip > filename.tar.gz # 加载 $ docker load -i filename.tar.gz
|
0x04 操作容器
1 启动
1 2 3 4 5 6 7 8 9 10 11 12
| $ docker run -t -i unbuntu:18.04 /bin/bash -t:分配伪终端,绑定到容器的标准输入上 -i:让容器的标准输入保持打开 流程: 检查本地是否存在指定镜像,没有就在公有仓下载 利用景象创建并启动一个容器 分配一个文件系统,并在只读的镜像层外面挂载一层可读写层 从宿主主机配置的网桥借口中桥街一个虚拟借口到容器中去 从地址池配置一个ip地址给容器 执行用户指定的应用程序 执行完毕后容器被终止
|
1 2
| $ docker container start $ docker container restart
|
2 守护态运行
1 2 3 4
| # 后台运行,不需要直接把执行命令的结构输出在当前宿主机下 $ docker run -d # 获取容器输出的信息 $ docker container logs
|
3 终止容器
1 2
| docker container stop # 对于一个只启动了终端的容器,exit 或 ctrl+d 退出终端时,所创建的容器立刻停止。
|
4 进入容器
1 2 3 4 5
| # 从stdin中exit会导致容器停止 $ docker attach ID/名
# 从stdin中exit不会导致容器停止 $ docker exec -it ID/名
|
5 导出和导入容器
1 2 3 4
| # 导出容器 $ docker export ID > xxx.tar # 导入容器, 与load区别:容器快照将丢弃所所有的历史记录和元数据可以重新指定标签元素 $ docker import URL/文件
|
6 删除容器
1 2 3 4 5 6
| # 删除终止的容器 $ docker container rm xxx # 删除正在运行容器 $ docker container rm -f xxx # 清理所有终止的容器 $ docker container prune
|
0x05访问仓库
1 Docker Hub
2 私有仓库
官方工具:docker-registry
3 高级私有仓库
4 Nexus3.x的私有仓库
0x06数据管理
1 数据卷(类似于 Linux 的 mount)
- 可供一个或多个容器共享使用和重用
- 对数据卷的修改会立马生效
- 对数据卷的更新不会影响镜像
- 数据卷默认一直存在,即使容器被删除
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| # 创建数据卷 $ docker volume create my-vol # 查看所有的数据卷 $ docker valume ls # 查看指定数据卷的信息 $ docker valume inspect xxx # 启动一个挂载数据卷的容器 $ --mount source=xxx, target=/xxxx # 查看容器的数据卷具体信息 $ docker inspect xxx # 删除数据卷 $ docker volume rm xxx # 删除容器同时删除数据卷 $ docker rm -v # 清理无主的数据卷 $ docker volume prune
|
2 挂载主机目录
1 2 3 4
| # 挂载主机的/sec/webapp到/opt/webapp目录 $ --mount type=bind,source=/src/webapp,target=/opt/webapp # 默认权限为:读写, 添加命令只读 $ --mount type=bind,source=/src/webapp,target=/opt/webapp,readonly
|
1 2
| # 可用来记录容器输入果的命令 $ --mount type=bild,source=$HOME/.bash_historytarget=/root/.bash_history
|
0x07 使用网络
1 外部访问容器
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| # 随机映射49000-49900的端口 -P # 指定要映射的端口(可以多次使用来绑定多个端口) -p # 映射所有借口地址 -p 5000:5000 # 映射到指定地址的指定端口 -p 127.0.0.1:5000:5000 # 映射到指定地址的任意端口 -p 127.0.0.1::5000 # 可以用udp来指定udp端口 -p 127.0.0.1:5000:5000/udp # 查看映射端口配置 docker port
|
2 容器互联
1 2 3 4 5 6 7 8
| # 老习惯 --link # 新建网络, 注:-d 参数指定 Docker 网络类型,有 bridge、overlay(适用于Swarm mode) $ docker network create -d bridge my-net # 链接容器, 可以使用 Ping 命令来证明 $ docker run -it --rm --name busybox1 --network my-net busybos sh # 多个容器互联 Docker Compose
|
3 配置DNS
Docker利用虚拟文件来挂载容器的3个相关配置文件
容器中mount命令可以看到挂载的信息(宿主主机DNS信息发生更新后,所有Docker容器的DNS配置通过/etc/resolv.conf文件立刻得到更新)
1 2 3 4 5 6 7 8 9 10
| # 自动配置:在`/etc/docker/daemon.json`文件中增加以下内容 { "dns":[ "114.114.114.114", "8.8.8.8" ] } # 可以使用下面命令来证明其已经生效 $ docker run -it --rm ubuntu:18.04 cat etc/resolv.conf
# 手动配置: # 设定主机名: h HOSTNAME 或 --hostname=HOSTNAME(写到容器内的/etc/hostname和/etc/hosts) 添加DNS服务器到容器的 `/etc/resolv.conf中:--dns=IP_ADDRESS`(让容器用这个服务器来解析所有不在/etc/hosts中的主机名) 设定容器的搜索域:`--dns-search=DOMAIN`
|
0x08 高级网络配置
0x09 Docker三剑客之Compose
1 简介
2 安装卸载
1 2 3 4 5 6 7
| # python pip $ sudo pip install -U docker-compose $ sudo pip uninstall docker-compose
# curl 下载后 $ chmod +x /usr/local/bin/docker-compse $ sudo rm /usr/local/bin/docker-compose
|
3 使用
1 写好每个容器的Dockerfile
2 写好yml链接文件
3 docker-compose up
4 命令说明
命令对象:默认项目(项目中所有的服务都会受影响),也可为项目中的服务或容器
1 2 3 4 5 6 7
| $ docker-compse [-f=...] [options] [COMMAND] [ARGS...] `-f:`指定Compse模版文件,默认为docker-compose.yml `-p:`指定项目名称,默认将使用所在目录名 `--x-networking:Docker:`的可拔插网络后端特性 --x-network-driver DRIVER:`指定网络后端的驱动,默认为bridge `--verbose:`输出更多调试信息 `-v:`打印版本信息
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
| # build, 构建(重新构建)项目中的服务容器(可随时重新构建项目) $ docker-compose build [option] [SERVICE...] `--fore-rm:`删除构建过程中的临时容器 `--no-cache:`构建过程不使用cache(cache加长构建过程) `--pull:`始终尝试通过pull来获取更新版本的镜像 # config, 验证Compose文件格式是否正常(正确显示匹配,错误显示原因) # down, 停止up命令所启动的容器,并移除网络 # exec, 进入指定的容器 # images, 列出Compose文件中包含的镜像
# kill, 发送DIGKILL信号来强制停止服务容器 $ Docker-compose kill [option] [SERVICE...] -s:指定发送的信号 # logs, 查看服务器的输出(默认使用不同颜色区分,--no-color来关闭颜色) $ docker-compose logs [][]
# pause, 暂停一个服务容器 $ docker-compose pause [] # port, 打印某个容器端口所映射的公共端口 $ docker-compose port [] `--protocol=proto:`指定端口协议,默认tcp可指定udp `--index=index:`指定命令容器的序号 # ps, 列出项目所有容器 -q:只打印ID # pull, 拉取服务依赖的镜像 $ docker-compose pull [][] `--ignore-pull-failures:`忽略拉取镜像过程中的错误 # push, 推送服务依赖的镜像到Docker镜像仓库
# restart, 重启 $ docker-compose restart [][] -t:重启前停止容器的超时
# rm, 删除所有(停止状态的)服务容器 $ docker-compose rm [][] -f:强制直接删除 -v:删除容器所挂在的数据卷 # run, 在指定服务上执行一个命令,默认启动关联容器(--no--deps关闭) $ docker-compose run [option] [-p PORT...] [-e KEY=VAL...] SERVOCE [COMMAND][ARGS...] -d:后台运行容器 `--name NAME:`为容器指定一个名字 `--entrypoint CMD:`覆盖默认的容器启动指令 `-e KEY=VAL:` 设置环境变量值,可多次使用选项来设置多个环境变量 `-u:`指定运行容器的用户名或uid `--no-deps:`关闭自动启动关联 `--rm:`运行命令后自动删除容器,d模式下将忽略 `-p:`映射容器端口到本地主机 `--service-ports:`配置服务端口并映射到本地主机 `-T:`不分配伪tty(tty命令无法执行)
# scale, 设置指定服务运行的容器个数 $ docker-compse scale [optins][service=$num] -t:停止容器时超时
# start, 启动已经存在的服务容器 $ docker-compose start []
# stop, 停止运行的容器 $ docker-compose stop [][] -t:停止容器的时候超时
# top, 查看各个服务器内运行的进程
# unpause, 恢复暂停的服务 $ docker-compose unpause []
# up, 自动构建镜像、(重新)创建服务、启动服务、关联服务相关容器, Ctrl+c停止所有容器, 服务容器已经存在,则尝试停止所有容器并重新创建 $ docker up [][] `-d:`在后台启动并运行所有容器 `--no-color:`不使用颜色来区分不同的服务的通知台输出 `--no-deps:`不启动服务器所链接的容器 `--force-recreate:`强制重新创建容器 `--no-recreate:`如果容器已经存在则不重新创建 `--no-build:`不自动构建缺失的服务镜像 `-t:`停止容器的时候超时
# version, 打印版本信息
|
5 yml模版文件
默认 YAML 格式的 docker-compose.yml
注意:每个服务必须通过 image 指令指定镜像或 build 指令(需要 Dockerfile )等来自动构建生成镜像
如果使用 build 指令,在 Dockerfile 中设置的选项(如:CMD、EXPOSE、VOLUME、ENV等)将会自动被获取无需再 Docfile.yml 文件中再次设置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
| # 指定Dockerfile所在文件夹的路径(绝对或相对yml) # 也可以:context指令指定Dockerfile所在文件夹的路径 ,使用dockerfile指令指定Docfile文件名,args指令指定构建镜像时的变量、chahce_from指定构建镜像的缓存 build
# 指定容器的内核能力(capacity)分配 cap_add / cap_drop - cap_add: -ALL cap_drop: -NET_ADMIN
# 覆盖容器启动后默认执行的命令 command
configs deploy # 仅用于Swarm mode
cgroup_parent # 指定父cgroup组,继承该组的资源限制
container_name , 如:container_name: docker-web-container # 指定容器名称,默认:项目名称-服务名称-序号
devices # 指定设备映射关系
depends_on # 解决容器的依赖和启动先后问题,先启动depends_on
dns # 自定义DNS服务器,可以是值、列表
dns_search # 配置DNS搜索域,可以是值、列表
tmpfs # 挂载一个tmpfs文件系统到容器
env_file # 从文件中获取环境变量,可以为单独的文件路径或列表(若-f指定模版文件则变量的路径基于模版文件) # 注:环境变量文件中每一行必须符合格式
environment # 设置环境变量,支持数组或字典格式 # 只给定名称的变量会自动获取运行Compose主机上对应变量的值,可以防止泄漏不必要的数据
expose # 暴漏端口,但不映射到宿主机,只被链接的服务访问
external_links # 链接 yml 外部的容器
extra_hosts # 指定额外的host名称映射信息
healthcheck # 通过命令检查容器是否健康运行
image # 指定为镜像名称或ID
labels # 为容器添加Docker元数据(metadata)信息
links # 不推荐使用
logging # 配置日志选项 dirver:支持三种日志驱动类型:`"json-file","syslog","none"` options:配置日志驱动的相关参数
network_mode # 设置网络模式
networks # 配置容器链接的网络
pid # 跟主机系统共享进程命名空间
ports # 暴漏端口信息
secrets # 存储敏感数据,如mysql服务密码
security_opt # 指定容器模版标签(label)机制的默认属性(用户、角色、类型、级别等)
stop_signal # 设置另一个信号来停止容器,默认 SIGUSR1
sysctls # 配置容器内核参数
ulimits # 指定容器的ulimits限制值
volumes # 数据卷所挂载路径设置 # 可设置宿主机路径(HOST:CONTAINER)或加上访问模式(HOST:CONTSAINER:ro)
其他 # 基本与docker run中对应参数的功能一致
读取变量 # Compose模版文件支持动态读取主机的系统环境变量和当前目录下的.env文件中的变量
|
0x10 Docker三剑客之Machine
0x11 Docker三剑客之Docker Swarm
0x12 安全
0x13 底层实现