Why Even Run Docker Containers with Ansible?
Well, I'm running my stuff in a Swarm. The problem is that Swarm does not (yet) allow you to configure Linux Kernel Capabilities on a container. But you can configure them with
docker run. Lame.
Fortunately, I'm using Ansible to deploy some things on this server, so I have things in place already to use it to run a container.
I'm using Traefik as my Reverse Proxy. Traefik works best for dynamic service discovery through the use of Container Labels, or Service Labels. The distinction is very important, depending upon how you're scheduling your containers.
What's weird though, is with the labels shown below for my Ansible play... I would get cryptic errors about type conversion. YAML tries to implicitly detect the type of the value (See Ansible Docs on YAML for more detail).
labels: traefik.port: 9980
Will yield this error:
msg: 'Error creating container: 500 Server Error: Internal Server Error ("json: cannot unmarshal number into Go value of type string")'
labels: traefik.enable: true
Will yield this error
msg: 'Error creating container: 500 Server Error: Internal Server Error ("json: cannot unmarshal bool into Go struct field ContainerConfigWrapper.Labels of type string")'
To avoid YAML interpreting the type for the value of a dictionary, enclose the value in quotes:
labels: traefik.enable: "true" traefik.port: "9980"
Ansible Troubleshooting Tip
One pain about Ansible is the inconsistency with configuration files. It's just all over the place with presenting data structures..
- Ansible's config file,
ansible.cfg, by default is in an
iniformat. Same for
hosts, except that can be in YAML too.
stdoutfrom Ansible is not composed in a very structured way, by default.
But you can have it output things in a more consistent way (since plays are written in YAML). Export this environment variable to make verbose output print as YAML:
And here's example output of an error when using
-vvv flags, but much more readable than default:
The full traceback is: File "/tmp/ansible_xhulz3r_/ansible_module_docker_container.py", line 1966, in container_create new_container = self.client.create_container(image, **create_parameters) File "/usr/lib/python3/dist-packages/docker/api/container.py", line 449, in create_container return self.create_container_from_config(config, name) File "/usr/lib/python3/dist-packages/docker/api/container.py", line 460, in create_container_from_config return self._result(res, True) File "/usr/lib/python3/dist-packages/docker/api/client.py", line 226, in _result self._raise_for_status(response) File "/usr/lib/python3/dist-packages/docker/api/client.py", line 222, in _raise_for_status raise create_api_error_from_http_exception(e) File "/usr/lib/python3/dist-packages/docker/errors.py", line 31, in create_api_error_from_http_exception raise cls(e, response=response, explanation=explanation) fatal: [184.108.40.206]: FAILED! => changed=false invocation: module_args: api_version: null auto_remove: false blkio_weight: null cacert_path: null capabilities: - MKNOD