Docker 学习心得
文件共享
文件挂载
如果你想将宿主机中的文件或目录挂载至容器中,可以在启动容器时使用 --volume
或 -v
参数.
--volume|-v <host_path>:<container_path>[:permission]
host_path
为要挂载的宿主机目录路径,必须为绝对路径container_path
为挂载在容器中的目标路径permission
为挂载目录的权限,默认为读写rw
; 可指定为只读ro
一些例子
1 | # 将宿主机的 Downloads 目录挂载在容器的 `/var/downloads` 中 |
从容器中复制文件到宿主机
如果你想将容器中的文件复制到宿主机中,可以使用 docker cp
命令
docker cp <container_id>:<container_source_path> <host_target_path>
container_id
容器 IDcontainer_source_path
要拷贝容器内文件的路径host_target_path
要放置在宿主机内的路径
一些例子
1 | # 将容器 nginx 中的配置文件复制到宿主机的家目录中 |
从宿主机复制文件到容器中
从宿主机复制文件到容器中可以使用 文件挂载 (--volume
) 的方法,但这种方法不能在运行中的容器中使用,如果你真的想这么做,也有一些稍微麻烦些的办法。
将宿主机的文件系统直接挂载在容器内,可以参考这篇文章 http://dockerone.com/article/149
先将容器中需要备份的文件使用
docker cp
复制出来,然后重新运行该容器并使 用docker run --volume
挂载文件.通过 sshfs 挂载文件目录.
先将容器停掉,然后使用
docker commit
创建一个新的镜像,最后启动该镜像进行文件挂载.
通信
容器间通信的一些 Q&A
如果不声明
network
字段, 在同一个 docker compose 之间可以通信吗?可以。
如果不指定一个特定的 network, docker 会指定容器在一个名为
docker0
的默认网桥中如果不声明
expose
选项, 那么同一网络中的其他容器可以访问该容器吗?可以。
但如果启动docker守护进程时指定了
--icc=false
选项,则不可以。
建议声明, 声明该选项有助于使用者了解容器内暴露了那些端口出来供使用。在同一个网络中不同的容器使用了同一个端口会有冲突吗?
不会。
不同的容器使用不同的 host, 所以哪怕两个容器使用了同样的端口,也不会与其他容器冲突。
expose
和ports
字段有什么区别?如果容器内的端口需要在宿主环境访问,则需提供
ports
字段expose
字段在默认情况下是可选的,即使不声明也可以在同一个网络中使用该容器的端口
容器相关
健康检查
如果你想知道容器内应用是否被正常启动了,你可以在启动时指定健康检查测试相关参数.
比如你在启动一个 web 应用容器后,开开心心准备用这个服务,却发现访问不到,启动成功了但没有完全成功,有点气人。
这时候你可以通过设置健康检查命令 curl -f http://localhost:8080 || exit 1
来检查应用真的启动了,而不是因为各种原因导致容器启动了但是内部的应用没启动成功,而造成一种成功了的假象。
用于健康检查的测试命令会在容器内执行,命令退出代码为 非零
或超时没有成功则视为测试失败,等待下一次测试。
参数 | 作用 (涉及时间的选项均可指定 秒:s 分:m 时:h 等) |
---|---|
interval |
执行测试间隔时间。默认 30s |
timeout |
超时时间,执行测试如果超过了这个时间,则视为失败。默认 30s |
retries |
重试次数,如果测试连续失败次数如果超过了该值,则容器健康状态会被置为不健康 (unhealthy ) |
start_period |
在容器启动多久之后开始第一次检查。默认 0s |
在 Dockerfile
中的用法示例
1 | HEALTHCHECK --interval=10s --timeout=3s \ |
在 docker-compose.yml
中的示例
1 | version: '3.8' |
在
docker-compose.yml
中使用时
- 会覆盖镜像中自带的健康检查命令
start_period
参数需要version >= 3.4
- 可根据容器的健康状态来成为
depends-on
执行条件(条件语法需要version >= 3.8
)
设置了健康检查后,会在容器列表中看到一列多的内容
1 | docker ps |
还可以在 docker inspect 中帮助排查问题
1 | docker inspect --format '{{json .State.Health}}' loki | jq . |
需要注意的是,健康检查的测试命令会在重启内执行,所以测试命令容器内可执行。比如在 alpine
版本的镜像中是不含 curl
程序的,这时你可以用 wget
来代替。
一些连通性检查的例子
1 | # 检查 本机 8080 端口是否能连通 |