首页 > 解决方案 > 码头集装箱“启动后”活动

问题描述

我是 docker 新手,我开始构建、部署和维护遥测服务(grafana、prometheus 等)。我遇到的一件事是我需要使用一些默认/预配置设置(仪表板、用户、组织、数据源......)来启动 grafana。Grafana 允许在其配置文件中进行一些启动配置,但不允许其所有功能(用户、组织、...)。在(如果我没有使用)docker 之外,我使用 ansible 脚本来配置 grafana 不支持的部分。但是,当我构建自定义 grafana 映像(使用允许的启动配置)并稍后启动该映像的 grafana 容器时,是否可以指定“启动后” docker文件中的命令或步骤?我把它想象成每次部署我的图像容器时,一些步骤是配置该容器的问题。有什么建议么?我还需要使用 ansible 或其他类似的工具来管理它吗?

标签: docker

解决方案


这比听起来更棘手。继续使用 Ansible 在启动后对其进行配置可能是在简单明了、已有代码和使用标准 Docker 工具和映像之间的一个很好的折衷方案。

如果这是针对测试环境,一种可能性是保留 Grafana 配置和数据目录的参考副本。您必须将这些与 Docker 映像分开分发。

mkdir grafana
docker run \
  -v $PWD/grafana/config:/etc/grafana \
  -v $PWD/grafana/data:/var/lib/grafana \
  ... \
  grafana/grafana
...
tar cvzf grafana.tar.gz grafana

获得 tar 文件后,您可以从已知配置重新启动系统:

tar xvzf grafana.tar.gz
docker run \
  -v $PWD/grafana/config:/etc/grafana \
  -v $PWD/grafana/data:/var/lib/grafana \
  ... \
  grafana/grafana

一些标准的 Docker Hub 数据库镜像能够通过入口点脚本进行首次配置;我将在此处参考mysql图像的入口点脚本。基本技术包括:

  1. 确定启动容器的命令是否实际启动服务器如果这是第一次启动
  2. 启动服务器,作为后台进程,记录它的 pid。
  3. 等待服务器可用。
  4. 实际做第一次初始化。
  5. 停止作为后台进程启动的服务器。
  6. 继续exec "$@"照常“真正”启动服务器。

这里的基本约束是,一旦一切完成,您希望服务器进程成为容器中唯一运行的东西。这意味着像这样的命令docker stop将直接向服务器发出信号,如果服务器发生故障,它是主容器进程,因此将导致容器退出。一旦入口点脚本将自己替换为服务器作为主容器进程(通过execimg 它),您就不能再做任何启动后的工作了。这导致启动服务器的临时副本以执行初始化工作的顺序。

一旦相关内容通常存储在持久数据目录或外部数据库中,就完成了这项初始化工作。

SO 问题有一个常见的快捷方式,即在后台启动一个服务器进程,然后使用类似的东西tail -f /dev/null作为实际的主容器进程。这意味着docker stop它将向进程发出信号tail,但不会告诉服务器它即将关闭;这也意味着如果服务器确实发生故障,由于tail进程仍在运行,容器将不会退出。我不鼓励这条捷径。


推荐阅读