如何将Docker环境变量传递给Telegraf inputs.exec调用的脚本?含报错排查
问题与解决方案
问题背景
构建运行Telegraf inputs.exec插件的Docker镜像,插件调用exec_oracle_python.sh脚本读取Dockerfile定义的username、password、sid环境变量,启动容器时触发exec format error,且环境变量无法正常传递给脚本;但在Python脚本中硬编码变量时Telegraf运行正常。
报错信息
$ sudo docker run wf-telegraf-python:test6 2022-07-18T19:11:36Z I! Using config file: /etc/telegraf/telegraf.conf 2022-07-18T19:11:36Z I! Starting Telegraf 1.22.0 2022-07-18T19:11:36Z I! Loaded inputs: exec 2022-07-18T19:11:36Z I! Loaded aggregators: 2022-07-18T19:11:36Z I! Loaded processors: 2022-07-18T19:11:36Z I! Loaded outputs: wavefront 2022-07-18T19:11:36Z I! Tags enabled: host=72d8b202e548 2022-07-18T19:11:36Z I! [agent] Config: Interval:1m0s, Quiet:false, Hostname:"72d8b202e548", Flush Interval:10s 2022-07-18T19:11:36Z E! [inputs.exec] Error in plugin: exec: fork/exec /exec_oracle_python.sh: exec format error for command '/exec_oracle_python.sh':
原始配置文件
Dockerfile
FROM <redacted>/telegraf:latest ENV username=\"user\" ENV password=\"123\" ENV sid=\"orcl\" COPY telegraf.conf /etc/telegraf/ COPY /telegraf.d/10-output.conf /etc/telegraf/telegraf.d/ COPY entrypoint.sh /entrypoint.sh COPY py_script.py /py_script.py COPY exec_oracle_python.sh /exec_oracle_python.sh RUN DEBIAN_FRONTEND=noninteractive apt-get update && \ DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends python3 python3-pip python3-setuptools python3-wheel && \ rm -rf /var/lib/apt/lists/* RUN pip3 install requests pyyaml CMD [\"/bin/sh\", \"-c\", \"echo ${username}\"] CMD [\"--config-directory\",\"/etc/telegraf/telegraf.d\"] ENTRYPOINT [ \"/entrypoint.sh\" ]
telegraf.conf(输入插件部分)
[[inputs.exec]] commands = [\"/exec_oracle_python.sh\"] timeout = \"5s\" name_suffix = \"_mycollector\" data_format = \"wavefront\"
exec_oracle_python.sh
python3 py_script.py -u $username -p $password -s $sid
py_script.py
import time import argparse parser = argparse.ArgumentParser() parser.add_argument('-u', '--user', help="Pass the username with SELECT_CATALOG_ROLE role granted", required=True) parser.add_argument('-p', '--passwd', required=True) parser.add_argument('-s', '--sid', help="SID to connect to", required=True) args = parser.parse_args() servcount = 10 t = int(time.time()) mydata = "error.count %d %d source=dev env=staging user=%s password=%s sid=%s" % (servcount, t, args.user, args.passwd, args.sid) print(mydata)
entrypoint.sh
#!/bin/bash set -e if [ "${1:0:1}" = '-' ]; then set -- telegraf "$@" fi if [ $EUID -ne 0 ]; then exec "$@" else setcap cap_net_raw,cap_net_bind_service+ep /usr/bin/telegraf || echo "Failed to set additional capabilities on /usr/bin/telegraf" exec setpriv --reuid telegraf --init-groups "$@" fi
解决方案
1. 修复exec格式错误
报错核心原因是exec_oracle_python.sh缺少脚本解释器声明(shebang),系统无法识别执行方式,同时要确保脚本拥有可执行权限:
- 修改
exec_oracle_python.sh,在第一行添加shebang,并修正Python脚本的绝对路径:#!/bin/bash python3 /py_script.py -u $username -p $password -s $sid - 在Dockerfile中添加权限设置命令:
RUN chmod +x /exec_oracle_python.sh /entrypoint.sh
2. 正确传递Docker环境变量
修正Dockerfile环境变量定义
原始ENV变量多了额外引号,会导致变量值携带无效引号,需删除:
ENV username=user ENV password=123 ENV sid=orcl
解决Dockerfile重复CMD问题
Dockerfile中最后一个CMD会覆盖之前的配置,保留Telegraf启动所需的CMD即可:
# 删除多余的CMD行,只保留 CMD ["--config-directory","/etc/telegraf/telegraf.d"]
确保Telegraf继承环境变量
Telegraf默认会继承容器的环境变量,entrypoint.sh切换到telegraf用户时也会保留这些变量。如果仍有问题,可以直接在Telegraf配置中通过bash执行命令,强制解析环境变量:
[[inputs.exec]] commands = ["/bin/bash -c 'python3 /py_script.py -u $username -p $password -s $sid'"] timeout = "5s" name_suffix = "_mycollector" data_format = "wavefront"
内容的提问来源于stack exchange,提问作者nadir781
相关产品推荐
相关产品推荐

