I create a Docker container like this:
$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
And from there I can change its default gateway to an nginx container (for transparent load balancing):
$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
And it works, and everything's fine:
$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
But when I try to automate this by putting those commands in my ~/logging/logstash/Dockerfile like:
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"]
I see them getting executed during build:
But the container fails to launch. sudo docker logs logstash-collector-01
tells me:
RTNETLINK answers: File exists
That error happens if I issue the second ip route
command without issuing the first one (Linux won't add a route if one is already in its active routing table). But how can this be? Are my Dockerfile's CMD commands processing out of order?
This is because you can only specify one CMD per dockerfile.
CMD is what the container will be running (which would normally be logstash, a long-running, daemon-like process), so what are you doing is only running the last CMD.
See https://stackoverflow.com/questions/23692470/why-cant-i-use-docker-cmd-multiple-times-to-run-multiple-services#23693804
You could consider a lo-fi solution like using a single container's network to share between nginx and the logstash agents, but you then need to keep track of ports.
Higher up the chain are solutions like kubernetes that make this kind of thing easier.
In between, you might look into consul(/SkyDNS) to help with DNS discovery.