我尝试启动logspout容器并通过docker-compose文件设置日志格式(ENV变量)。不太难,如果我用docker-compose up
推出它,一切正常。但是当我尝试使用docker swarm init
和docker stack deploy -c docker-compose.yml mystack
启动它时,我收到一个错误:
来自守护程序的错误响应:rpc错误:code = InvalidArgument desc = expand env failed:expand env“RAW_FORMAT = {\”container \“:\”{{.Container.Name}} \“,\”labels \“:{{ 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变量是:
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模板。但是使用swarm模式,你可以create services using go-templates。因此,似乎swarm尝试(并且失败)来解析我想要传递给logspout容器的ENV变量的值。
如果你想重现这个问题,这里有一个最小的docker-compose文件:
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
。
在go模板中,可以使用{{
来转义{{"{{"}}
,因此你的yml文件应如下所示:
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 }} }'
你可以通过{{`
string `}}
扭曲
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 }} }`}}'
另一个例子
LDAP_SEARCH_FILTER={{`(sAMAccountName={{username}})`}}