【问题标题】:Docker Swarm Secrets Not Evaluating Correctly in Compose on PortainerDocker Swarm 秘密在 Portainer 上的 Compose 中未正确评估
【发布时间】:2022-12-12 13:50:28
【问题描述】:

我正在尝试将我用 python 编写的 Discord Bot 部署到我的家庭服务器上的 VM(运行 Portainer)。但是,我遇到了让 Portainer 正确评估机器人令牌秘密的问题。我已经用名称 HU3BOT_DISCORD_TOKEN 定义了秘密,并且正在使用以下撰写文件:

version: "3.9"
services:
  hu3bot:
    image:  drak3/hu3bot:latest
    environment:
     - DISCORD_TOKEN=/run/secrets/HU3BOT_DISCORD_TOKEN
     - DISCORD_CHANNEL="3d_printing"
     - PRINTER_HOST=voron.srv
     - CAM_PORT_MAIN=8081
     - CAM_PORT_ALT=8080
     - MOONRAKER_API_PORT=7125
     - WEB_URL='https://fluidd.drak3.io'
    secrets:
    - HU3BOT_DISCORD_TOKEN

# the secret is a discord bot token
secrets:
  HU3BOT_DISCORD_TOKEN:
    external: true

在本地,我可以使用没有问题的 .env 文件运行脚本。我可以像本地容器一样做。但是,当我尝试使用我定义的秘密时,我无法正确评估它。我在我的代码中添加了一些打印语句,并且根据我如何格式化 DISCORD_TOKEN=/run/secrets/HU3BOT_DISCORD_TOKEN 行,令牌将被评估为 Null(None 类型 <class 'NoneType'>)或作为内容为字符串 @ 987654328@。

我已经尝试了以下所有格式组合,但它们要么是秘密的名称,要么是 Null:

  • DISCORD_TOKEN=/run/secrets/HU3BOT_DISCORD_TOKEN
  • DISCORD_TOKEN= /run/secrets/HU3BOT_DISCORD_TOKEN
  • DISCORD_TOKEN:/run/secrets/HU3BOT_DISCORD_TOKEN
  • DISCORD_TOKEN: /run/secrets/HU3BOT_DISCORD_TOKEN
  • "DISCORD_TOKEN=/run/secrets/HU3BOT_DISCORD_TOKEN"
  • "DISCORD_TOKEN= /run/secrets/HU3BOT_DISCORD_TOKEN"
  • "DISCORD_TOKEN:/run/secrets/HU3BOT_DISCORD_TOKEN"
  • "DISCORD_TOKEN: /run/secrets/HU3BOT_DISCORD_TOKEN"

雪上加霜的是,我还有一个不同的堆栈,可以从一个秘密中提取一个 webhook(比如:WATCHTOWER_NOTIFICATION_SLACK_HOOK_URL=/run/secrets/DISCORD_WEBHOOK_WATCHTOWER),它工作正常。

秘密的内容与此有什么关系吗?老实说,我无法解释这一点,非常感谢任何帮助或建议。

更新:

对于那些在我之后遇到类似问题的人,感谢 Chris Becke,我意识到我一定是误解了 docker secrets 的实际工作方式。我之前认为字符串 /run/secrets/secret_name 可以用作秘密值本身的文字代表,并且通过将它们传递给环境变量,它相当于只在那里拥有原始秘密。这种误解很可能是由于我在使用其他人的图像撰写文件时只使用了秘密。我猜他们有某种代码来区分值是环境变量还是 docker 秘密路径。将此类代码添加到我的机器人后,该值按预期进行评估。 This 是一个有用的答案。

【问题讨论】:

    标签: docker docker-compose yaml docker-swarm portainer


    【解决方案1】:

    设置环境变量只是将其设置为您提供的文字值。

    正确处理机密需要注入脚本以将机密读入环境变量。是这样的:

    services:
      some-service:
        image: whatever
        entrypoint:
        - /bin/sh
        - -c
        - |
          read -r DISCORD_TOKEN < /run/secrets/HU3BOT_DISCORD_TOKEN
          exec $$0 "$$@"
        command: previous command
    

    您需要查找容器以前的 CMD 和 ENTRYPOINT 值,并确保新流链接到旧流。设置entrypoint 会自动清除任何现有的CMD,因此您需要完全指定它是否存在。

    同样值得注意的是,许多 Docker 镜像(Postgres 等)支持通过处理带有 FILE 后缀的变量来从文件初始化环境变量。

    例如Docker Postgres 镜像会将“POSTGRES_PASSWORD_FILE”指定的文件读入“POSTGRES_PASSWORD”

    如果在构建 Hu3Bot 图像时考虑到了这种用法,那么将 DISCORD_TOKEN_FILE 设置为秘密路径可能会起作用。

    【讨论】:

    • 感谢您的回复。虽然我没有使用这个确切的解决方案,但您的评论让我意识到我需要将 /run/secrets/HU3BOT_DISCORD_TOKEN 视为文件,而不是秘密本身。我的误解很可能是因为这是我创建的第一张需要保密的图片。过去,我只是使用别人的图像,并传入/run/secrets/name 路径。添加代码以从环境变量或文件中获取值后,它的行为符合预期。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多