Looking for $${{host_name}} macro, in addition to $${{service_name}}

I have a use-case that needs $${{host_name}} when writing yaml configs.

I read the docs on Scheduling and it’s nice that there are $${stack_name} and $${service_name} “macros”, that we can use in our yaml configs.

However, the killer app for my org is to deploy collectd as a “global” service (global=true).
This is has the nice property of running one collectd per host (awesome & exactly what we need).

BUT when starting the container, I need to set environment variables that pass the hostname to the collectd container. Rancher has the ability to set “environment:” in yaml, but I need the ability to insert $${{host_name}} to define some of those env vars.

This is important because stats originated by collectd are identified/associated with the HOST (eg. CPU, disk space, memory). The stats are originated by collectd and sent to an influxdb service (which is also managed by Rancher).

Again, this is a perfect use-case for a “global” service, but without the ability to set env vars on a per-host basis, I am not sure it is deployable.

I believe there will be other use-cases that need to stuff $${{host_name}} in env vars and other parts of the yaml.

There are two ways to get this info - push it in via the environment, or have the container itself get it via the metadata API. The latter would allow you to identify the hostname. In your collectd Dockerfile, wrap the startup of collectd with a small script that calls this URL, e.g.:

MY_HOSTNAME=$(curl http://rancher-metadata/2015-12-19/self/host/hostname)

That’ll give you the hostname for this current host, which you can then inject into collectd as required.

Does that work for you?

1 Like

Thanks @Upayavira
Good idea. I didn’t think of the metadata service for this.

The downside of this:
I have to special-case my container images now to be Rancher-aware, and I was trying to avoid that. I’d like to keep the container images generic so they can be deployed by any tool (and by people who don’t use Rancher).

Moreover, I’d like to use general-purpose container images built by other people (Docker Hub images).

It would be great if Rancher had a hook to run a script after it started a container.
Like a wrap-up script that is independent of the container image itself.
Then something like this use-case could be accommodated, with containers that are not Rancher-aware.
Is this possible to do, eg. when you create a Rancher service?

I would say what you do is create your generic, Docker only image, then a thin wrapper around it that just calls the metadata service and defers back to the original at that point. That way, you’ve got the best of both worlds, for the price of two Dockerfiles and two images. Not quite what you’re asking for, but I’m not deep enough into Rancher to know whether what you suggest is likely to be possible.

1 Like

Thanks @Upayavira
Yes, I think a thin Dockerfile around the generic Dockerfile will be close to what I need.
I’m going to try that. Thanks!

This is what I did:

Thin container is Rancher-specific and adds a bash script that uses the Rancher metadata service to set the hostname environment var:

#!/bin/bash
# Set hostname env var for collectd container using Rancher's metadata service.
HOST_NAME=$(curl -s http://rancher-metadata/2015-12-19/self/host/hostname)

if [[ -z $HOST_NAME ]]
then
  echo "Failed to get host's hostname from rancher-metadata API." > debug
fi

# Run the container's collectd daemon
/root/run.sh

Dockerfile just adds on top of the generic collectd container:

FROM donn/collectd-docker
ADD get_hostname_and_run.sh /root/get_hostname_and_run.sh
RUN chmod +x /root/get_hostname_and_run.sh
CMD ["/root/get_hostname_and_run.sh"]

Source files:

I had exactly the same issue when trying to start a Rancher management stack (Percona master+slave + several Rancher HA) from a rancher compose.
I solved it like this:
services:
rancher-server:
image: rancher/server:v1.4.1
entrypoint:
- /bin/bash
command:
- -c
- /usr/bin/entry --db-host percona-master --db-user rancher --db-name rancherdb --db-pass xxx --advertise-address $$(curl -s http://rancher-metadata/latest/self/host/hostname)

In this example, /usr/bin/entry is the original entrypoint in the rancher/server image

Happy hacking!

Thanks for sharing the URL. I added it in a jar start-script to use the hostname for JMX connections.