ansible-podman-collections icon indicating copy to clipboard operation
ansible-podman-collections copied to clipboard

[DISCUSSION] How to replace easily Docker by Podman for Ansible Docker users?

Open sshnaidm opened this issue 4 years ago • 5 comments

Issue: Right now a lot of Ansible users deploy Docker containers using docker_* modules of Ansible. Because Docker is not supported on RHEL-8/CnetOS-8 officially and user might want still to use their playbooks and roles, instead of rewriting them. Podman is supposed to replace Docker in RH-8 distros. Current there are a few podman_* modules. How can we make migration of docker_* users as easy and transparent as possible? For example task:

- name: Run some docker container
  docker_container:
    name: grafana
    image: grafana
    detach: true
    ports:
      - 3000:3000
    env:
      GF_INSTALL_PLUGINS: "grafana-clock-panel,grafana-simple-json-datasource"

What is the best solution (considering collections) that can allow user to continue using this task in Podman only host? The ideal situation is:

- hosts: all
  collections:
    - containers.whatever
  tasks:
... all tasks of users as is ....

Currently options on the table are (additional are welcome!):

  1. To create action modules in containers.whatever collection. It will pick up podman and docker collections and each action module will trigger either docker or podman module, depending on what is on the host. Kind of package module model.
  2. To make current Ansible Podman module similar to Docker one in options (they're almost are) and hack command line "docker" instead of "podman". Rename it to 'generic' or even to containers.docker. Most of usual things would work. Some, like pods and other specific, will be available for Podman only.
  3. To write a new generic container module basing on podman API v2, which should be a copy of Docker-Py. Write it from scratch with support of both Docker and Podman as underlying engines.
  4. If podman API v2 will be similar to Docker-Py, then hack current Ansible Docker module for additional required things to support Podman. May require some sort of environment variables support, new/old options, and god knows what else.

Also there is an opened question what to do with specific Podman features like pods, play-kube and others. And what to do with Ansible Docker Compose feature.

sshnaidm avatar May 15 '20 21:05 sshnaidm

Amazingly, option 2 works as is:

- name: Run docker hidden in podman
  containers.podman.podman_container:
    name: test-container
    image: alpine
    state: present
    executable: docker
    env:
      MYSQL_ROOT_PASSWORD: "2211"
"podman_actions": [
        "docker run --name test-container --env MYSQL_ROOT_PASSWORD=2211 --detach=True alpine"
    ]
$ docker ps -a
CONTAINER ID        IMAGE                  COMMAND             CREATED             STATUS                      PORTS                    NAMES
13a5bc49ead3        alpine                 "/bin/sh"           21 minutes ago      Exited (0) 21 minutes ago                            test-container

So a little action plugin which will replace executable and maybe some options is very doable.

sshnaidm avatar May 15 '20 22:05 sshnaidm

Would any of these options include unifying the output of the modules- or is the assumption that podman would change to match the docker output? For example to lookup an exposed port at the moment:

  • docker_container: registered_fact.ansible_facts.docker_container.NetworkSettings.Ports['8888/tcp'].0.HostPort
  • containers.podman.podman_container: registered_fact.container.NetworkSettings.Ports.0.hostPort

If it's not feasible to have them behave identically could the Ansible service module be an example to follow- if you're doing something simple use the generic module/wrapper, but if you depend on particular outputs or features use e.g. the systemd module instead?

manics avatar May 17 '20 22:05 manics

@manics thanks, that's a really important question. A lot of tasks rely on docker module outputs and of course it shouldn't break. I think there could be a few approaches:

  1. Podman project tries to be compliant with docker outputs and if we see inconsistency or difference, we can always report it. Of course not everything could and should be fixed.
  2. We can catch podman output and if there are well known issues, just hack it to be compatible with docker output format. The same we should do with input arguments if there are different names for example.

Regarding option to explicitly set an engine, I think it would be totally reasonable to have it, like use_engine: docker use_engine: podman. The main goal of course will be to make them their outputs and functionality as close as possible.

sshnaidm avatar May 17 '20 23:05 sshnaidm

I think the easiest path depends on how the docker modules are implemented.

  1. If those modules call docker CLI, then just add support for a variable that indicates the CLI program to use. Then pass that variable to the role before running.
  2. If those modules call docker API, then just run podman v2 API server and add the DOCKER_HOST environment variable pointing to podman's socket before running the role.

yajo avatar Jul 13 '20 06:07 yajo

So if you want to replace docker with podman with your collection in ansible playbooks:

How to port my playbook? https://github.com/ReinerNippes/selfhosted_on_docker

Just pulling and starting a container isn't enough. You have to provide also networking similar to docker.

Do you see any chance for this in the near future?

ReinerNippes avatar Aug 12 '20 11:08 ReinerNippes