问题描述
我尝试启动一个logspout容器,并通过一个docker-compose文件设置日志格式(一个ENV变量).不太困难,如果我用docker-compose up
启动它,一切都很好.但是,当我尝试使用docker swarm init
和docker stack deploy -c docker-compose.yml mystack
启动它时,出现错误:
I try to launch a logspout container and set the log format (an ENV variable) via a docker-compose file. Not too difficult, and if I launch it with docker-compose up
, everything works fine. But when I try to launch it with docker swarm init
and docker stack deploy -c docker-compose.yml mystack
, I get an error:
守护程序的错误响应:rpc错误:代码= InvalidArgument desc =扩展环境失败:扩展环境"RAW_FORMAT = {\" container \:\" {{.Container.Name}} \,\"标签\:{{toJSON .Container.Config.Labels}},\" timestamp \:\" {{.Time.Format \"2006-01-02T15:04:05Z07:00 \"}} \, \"source \":\"{{.Source}} \",\"message \":{{toJSON .Data}}}:模板:扩展:1:未定义函数"toJSON"
我认为我只有swarm而不是docker-compose有错误,因为我要传递给logspout的ENV变量是:
I think I have the error only with swarm and not docker-compose, because the ENV variable I want to pass to logspout is:
RAW_FORMAT:'{"container":"{{.Container.Name}}","labels":{{toJSON .Container.Config.Labels}},"timestamp":"{{.Time .Format"2006-01-02T15:04:05Z07:00"}}," source:" {{.Source}}," message:{{toJSON .Data}}}'
此ENV变量包含一个go模板.但是,在群体模式下,您可以使用go-templates创建服务.因此,似乎swarm尝试(但失败了)解析我只想传递给logspout容器的ENV变量的值.
This ENV variable contains a go template. But with swarm mode, you can create services using go-templates. So it seems that swarm tries (and fails) to parse the value of the ENV variable that I just want to pass to the logspout container.
-
是否可以告诉swarm不要在RAW_FORMAT变量中解析go-template?
Is it a way to tell swarm not to parse the go-template in my RAW_FORMAT variable?
如果没有,是否还有其他方法可以将此变量设置为正确的值?
If not, is there an other way to set this variable to the correct value?
更多...
如果您想重现此问题,这是一个最小的docker-compose文件:
More...
If you want to reproduce this problem, here is a minimal docker-compose file:
version: "3.3"
services:
logspout:
image: gliderlabs/logspout:latest
volumes:
- /etc/hostname:/etc/host_hostname:ro
- /var/run/docker.sock:/var/run/docker.sock
environment:
RAW_FORMAT: '{ "container" : "{{ .Container.Name }}", "labels": {{ toJSON .Container.Config.Labels }}, "timestamp": "{{ .Time.Format "2006-01-02T15:04:05Z07:00" }}", "source" : "{{ .Source }}", "message": {{ toJSON .Data }} }'
如果您在Windows上,则必须先执行$Env:COMPOSE_CONVERT_WINDOWS_PATHS=1
.
If you are on windows, you have to execute $Env:COMPOSE_CONVERT_WINDOWS_PATHS=1
first.
推荐答案
在go模板中,可以使用{{"{{"}}
来转义{{
,因此您的yml文件应如下所示:
In go templates, escaping {{
can be done with {{"{{"}}
, so your yml file should look like this:
version: "3.3"
services:
logspout:
image: gliderlabs/logspout:latest
volumes:
- /etc/hostname:/etc/host_hostname:ro
- /var/run/docker.sock:/var/run/docker.sock
environment:
RAW_FORMAT: '{ "container" : "{{"{{"}} .Container.Name }}", "labels": {{"{{"}} toJSON .Container.Config.Labels }}, "timestamp": "{{"{{"}} .Time.Format "2006-01-02T15:04:05Z07:00" }}", "source" : "{{"{{"}} .Source }}", "message": {{"{{"}} toJSON .Data }} }'
这篇关于Docker swarm尝试解析我的撰写文件中的ENV变量的值(因为其中包含go模板),并给了我一个错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!