Dockerfile中的“ ip route”命令生成错误


2

我创建一个这样的Docker容器:

$sudo docker build -t "logstash-collector" ~/logging/logstash/

$sudo docker run -d \
--user=root \
--name="logstash-collector-01" \
--net=logging \
--cap-add=NET_ADMIN \
logstash-collector

从那里,我可以将其默认网关更改为nginx容器(用于透明负载平衡):

$sudo docker exec -it logstash-collector-01 ip route delete default
$sudo docker exec -it logstash-collector-01 ip route add default via 172.18.0.10

它可以正常工作,并且一切正常:

$sudo docker exec -it logstash-collector-01 ip route 
default via 172.18.0.10 dev eth0 
172.18.0.0/16 dev eth0  proto kernel  scope link  src 172.18.0.3 

但是当我尝试通过将这些命令放在我的〜/ logging / logstash / Dockerfile中来自动执行此操作时,例如:

FROM logstash
COPY logstash.conf /usr/local/share
CMD ["-f", "/usr/local/share/logstash.conf", "--config.reload.automatic"]
CMD ["ip", "route", "delete", "default"]
CMD ["ip", "route", "add", "default", "via", "172.18.0.10"]

我看到它们在构建过程中被执行: Logstash容器构建

但是容器无法启动。 sudo docker logs logstash-collector-01告诉我: RTNETLINK答案:文件存在

如果我在ip route不发出第一个命令的情况下发出第二个命令,则会发生该错误(如果活动路由表中已有一个命令,Linux将不会添加路由)。但是怎么可能呢?我的Dockerfile的CMD命令是否乱序处理?


注意:我还在Dockerfile中使用CMD ["ip","route"...]vs CMD ip route ...语法进行了测试。没有效果。
阿玛尼

Answers:


3

这是因为每个dockerfile只能指定一个CMD。

CMD是容器将要运行的内容(通常是logstash,这是一个长时间运行的,类似于守护程序的进程),因此您在做什么运行最后一个CMD。

参见https://stackoverflow.com/questions/23692470/why-cant-i-use-docker-cmd-multiple-times-to-run-multiple-services#23693804

您可以考虑使用Lo-Fi解决方案,例如使用单个容器的网络在Nginx和Logstash代理之间共享,但随后需要跟踪端口。

更高端的是像kubernetes这样的解决方案,它使这种事情变得更容易。

在这两者之间,您可能会考虑使用consul(/ SkyDNS)来帮助DNS发现。


说得通。我最后只是将这些exec命令放入部署脚本中。
阿玛尼

是的,肯定可以。这确实意味着您的容器现在需要以root(不需要单独的logstash)开头,但是由于您具有功能限制,所以还算不错。
iwaseatenbyagrue
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.