如何在 docker 图像 运行 时执行 运行 命令?

How to run commands when a docker image runs?

我有一个 consul docker 图像,它是 docker-compose 环境的一部分。

我必须 运行 docker 容器内的命令 consul acl bootstrap,我相信在 commandentrypoint 中提及它会覆盖默认命令为consul设置,除了默认命令外,如何执行?

docker-compose 中没有允许您在容器启动后运行命令的选项。

您可以做的是构建您自己的映像,该映像将在启动时执行您想要的操作。为此,您需要:

  1. 找出容器的默认启动(ENTRYPOINTCMD 组合)。
  2. 创建一个 shell 脚本,它将调用带有所需参数的入口点,之后它将调用您的命令。
  3. 创建一个基于原始图像的 Dockerfile,复制图像中的 shell 脚本并将入口点更改为您的脚本
  4. 将您的图像和 docker 文件添加到 docker-compose(将当前的 consul 图像更改为指向您的图像并构建脚本)

这里是一个入口点示例 shell 脚本,它可以用来启动您的特定脚本。将您的代码放在 execute_after_start() 函数中。

entrypoint.sh

#!/bin/bash
set -e

execute_before_start() {
    echo "Execute befor start" > /running.txt
}

execute_after_start() {
    sleep 1
    echo "Execute after start" >> /running.txt
}

execute_before_start
echo "CALLING ENTRYPOINT WITH CMD: $@"
exec /old_entrypoint.sh "$@" &
daemon_pid=$!
execute_after_start
wait $daemon_pid
echo "Entrypoint exited" >> running.txt

脚本将启动 execute_before_start。当此命令结束时,将使用 CMD 提供的参数启动原始入口点并并行(这是 execute 末尾的 &)它将启动 execute_after_start. execute_after_start结束后,会等待原入口点停止。

我在示例中使用 sleep 作为一种简单的方法来确保一些延迟,以便入口点可以接受命令。根据入口点,可能有更智能的方法来确保入口点已准备好接受命令。

正如其他人评论的那样,在容器启动后无法编写 运行 附加命令。

或者,您可以通过指定 acl.tokens.master in the Consul server's configuration. The easiest way to do this with the Docker image is to pass the configuration using the CONSUL_LOCAL_CONFIG environment variable (see Docker-Consul: Using the container).

明确指定主令牌的秘密 ID

例如:

---
version: "3.8"
services:
  consul:
    image: consul
    ports:
      - "8500:8500/tcp"
    environment:
      CONSUL_LOCAL_CONFIG: >
        {"acl": {"enabled": true, "tokens": {"master": "A8D89992-A3DB-46E3-A528-8F97CFEDB183"} }}

这具有将令牌硬编码到您的 Compose 配置中的明显缺点,但也避免了尝试 运行 consul acl bootstrap 使用自定义入口点的复杂性。

您只需在集群首次初始化时提供该环境变量即可。之后,Consul 将此令牌数据保存在安装在 /consul/data 的 Docker 卷中。需要使用 consul acl token/v1/acl/token API 端点对令牌(包括主令牌)进行任何修改。