Run Ansible over Docker vs VM - docker

I want to create test environment for ansible-playbook from my PC to Linux server cluster which installs ELK on it, considering whether to run it on a container or a VM.
Obviously using docker should make the process easier and faster to facilitate, but I think there is more depth to this topic beyond the general discussion of choosing Docker versus VM, by focusing on Ansible deployments with relation to storage, networking and privileges management.
What are the considerations for running Ansible deployments on Docker container versus Virtual Machine?

I'd almost never target Ansible against a Docker container.
Ansible's model is much more suited to targeting a VM. If you have an existing Ansible playbook that's targeting a physical system or a cloud instance, a VM will be a good mirror of the operating system environment it expects, but a Docker setup will be very different.
Ansible generally expects to make an ssh connection to its target host, run a Python installed there, and its changes to be reasonably persistent. In contrast a Docker container almost never runs an ssh daemon, frequently won't have Python, and any changes that get made will be lost as soon as the container exits. A typical server-oriented Ansible playbook will do things like set up service configuration and init scripts, but in a Docker system there isn't an init and service configuration is generally injected.
It's probably better here to think of a Docker container as packaging around a single process. You can use bind mounts to inject configuration from the host, and you could use Ansible on the host to start the container, but you wouldn't use Ansible to "set up" a container. If you need software installed in a container then using Docker's native docker build system can get this done in a reproducible way, without needing additional steps after the container is started.
The one prominent exception to the "almost never" is running Molecule tests inside a container, but note that this setup does have the nature of changes being temporary and short-lived (as soon as the test is over you want to tear down the container).

Related

Dealing with dockers and containers in production

I am new to the containers topic and would appreciate if this forum is the right place to ask this question.
I am learning dockers and containers and I now have some skills using the docker commands and dealing with containers. I understand that docker has two main parts, the docket client (docker.exe) and the docker server (dockerd.exe). Now in the development life both are installed on my local machine (I am manually installed them on windows server 2016) followed Nigel Poulton tutorial here https://app.pluralsight.com/course-player?clipId=f1f27565-e2bf-4e58-96f3-bc2c3b160ec9. Now when it comes to the real production life, then, how would I configure my docker client to communicate with a remote docker server. I tried to make some research on the internet but honestly could not find a simple answer for this question. I installed docker for desktop on my windows 10 machine and noticed that it created a hyper-v machine which might be Linux machine, my understanding is that this machine has the docker server that my docker client interacts with but do not understand how is this interaction gets done.
I would appreciate if I get some guidance or clear answer to my inquiries.
In production environments you never have a remote Docker daemon. Generally you interact with Docker either through a dedicated orchestrator (Kubernetes, Docker Swarm, Nomad, AWS ECS), or through a general-purpose system automation tool (Chef, Ansible, Salt Stack), or if you must by directly ssh'ing to the system and running docker commands there.
Remote access to the Docker daemon is something of a security disaster. If you can access the Docker daemon at all, you can edit any file on the host system as root, and pretty trivially take over the whole thing. (Google "Docker cryptojacking" for some real-world examples.) In principle you can secure it with mutual TLS, but this is a tricky setup.
The other important best practice is that Docker images should be self-contained. Don't try to deploy a Docker image to production, and also separately copy your application code. The same Ansible setup that can deploy a Docker container can also install Node directly on the target system, avoiding a layer; it's tricky to copy application code into a Kubernetes volume, especially when Kubernetes pods can restart outside your direct control. Deploy (and test!) your images with all of the code COPYd in a Dockerfile, minimizing the use of bind mounts.

Docker-machine vs Vagrant? [duplicate]

Every Docker image, as I understand, is based on base image - for example, Ubuntu.
And if I want to isolate any process I should deploy ubuntu docker base image (where is difference with Vagrant here?), and create a necessary subimage after it installing on ubuntu image?
So, if Ubuntu is launched on Vagrant and on Docker, where is practice difference?
And if to use docker provider in Vagrant - where here is difference between Vagrant and Docker?
And, in Docker is it possible to isolate processes on some PC without base image without it's sharing to another PC?
Vagrant is a utility to help you automate setting up VMs. Docker is a utility that helps you use containerization in linux.
A virtual machine runs a whole system, and emulates hardware. Containers section off processes in a single running kernel without emulating hardware.
Both a VM and a Docker image may be Ubuntu 14.04, but with the Docker image you don't need to run the whole OS.
For example, if I want to run an nginx container based on ubuntu, I'd end up with only the nginx process running. No upstart/systemd/init is needed. A VM would run an init system, manage its own networking, and run other services as well. The container image approach that uses a linux distro base is mostly for convenience.
It is entirely possible to run Docker containers with very minimal images. A statically compiled binary alone in an image is all you'd need to run a container.
Vagrant : Vagrant is a project that helps the spawning of virtual machines. It started as an command line of VirtualBox, something similar to Gemfile for VM's. You can choose the base image to start with, network, IP, share folders and put it all in a file that anyone can reuse to spawn the same configured machine. Vagrant has different extensions, provisioning options and VM providers. You can run a VirtualBox, VMware and it is extensible enough to be able to create instances on EC2.
Docker : Docker, allows to package an application with all of its dependencies into a standardized unit of software development. So, it reduces a friction between developer, QA and testing. It dynamically change your application, adding new capabilities every single day, scaling out services to quickly changing the problem areas. Docker is putting itself in an excited place as the interface to PaaS be it networking, discovery and service discovery with applications not having to care about underlying infrastructure. Yes, their are still issues with docker in production, but, hopefully, we'll see the solutions to those problems, as docker team and contributors working hard on those issues. As Docker Volume driver allows third-party container data management solutions to provide data volumes for containers which operate on data, such as database, key-value stores, and other stateful applications. The latest version is coming with much more flexibility, complete orchestration build-in, advanced networking, secrets management, etc. As you can see one, rexray, as volume plugin and provides advanced storage functionality. emccode/rexray We're finally starting to agree on more than just images and run time.

Is it safe to run docker in docker on Openshift?

I built Docker image on server that can run CI-CD for Jenkins. Because some builds use Docker, I installed Docker inside my image, and in order to allow the inside Docker to run, I had to give it --privilege.
All works good, but I would like to run the docker in docker, on Openshift (or Kubernetes). The problem is with getting the --privilege permissions.
Is running privilege container on Openshift is dangerous, and if so why and how much?
A privileged container can reboot the host, replace the host's kernel, access arbitrary host devices (like the raw disk device), and reconfigure the host's network stack, among other things. I'd consider it extremely dangerous, and not really any safer than running a process as root on the host.
I'd suggest that using --privileged at all is probably a mistake. If you really need a process to administer the host, you should run it directly (as root) on the host and not inside an isolation layer that blocks the things it's trying to do. There are some limited escalated-privilege things that are useful, but if e.g. your container needs to mlock(2) you should --cap-add IPC_LOCK for the specific privilege you need, instead of opening up the whole world.
(My understanding is still that trying to run Docker inside Docker is generally considered a mistake and using the host's Docker daemon is preferable. Of course, this also gives unlimited control over the host...)
In short, the answer is no, it's not safe. Docker-in-Docker in particular is far from safe due to potential memory and file system corruption, and even mounting the host's docker socket is unsafe in effectively any environment as it effectively gives the build pipeline root privileges. This is why tools like Buildah and Kaniko were made, as well as build images like S2I.
Buildah in particular is Red Hat's own tool for building inside containers but as of now I believe they still can't run completely privilege-less.
Additionally, on Openshift 4, you cannot run Docker-in-Docker at all since the runtime was changed to CRI-O.

How to run a bash script in the host from a docker container and get the result

I have a Jenkins that is running inside of a docker container. Outside of the Docker container in the host, I have a bash script that I would like to run from a Jenkins pipeline inside of the container and get the result of the bash script.
You can't do that. One of the major benefits of containers (and also of virtualization systems) is that processes running in containers can't make arbitrary changes or run arbitrary commands on the host.
If managing the host in some form is a major goal of your task, then you need to run it directly on the host, not in an isolation system designed to prevent you from doing this.
(There are ways to cause side effects like this to happen: if you have an ssh daemon on the host, your containerized process could launch a remote command via ssh; or you could package whatever command in a service triggered by a network request; but these are basically the same approaches you'd use to make your host system manageable by "something else", and triggering it from a local Docker container isn't different from triggering it from a different host.)

Docker vs Vagrant

Every Docker image, as I understand, is based on base image - for example, Ubuntu.
And if I want to isolate any process I should deploy ubuntu docker base image (where is difference with Vagrant here?), and create a necessary subimage after it installing on ubuntu image?
So, if Ubuntu is launched on Vagrant and on Docker, where is practice difference?
And if to use docker provider in Vagrant - where here is difference between Vagrant and Docker?
And, in Docker is it possible to isolate processes on some PC without base image without it's sharing to another PC?
Vagrant is a utility to help you automate setting up VMs. Docker is a utility that helps you use containerization in linux.
A virtual machine runs a whole system, and emulates hardware. Containers section off processes in a single running kernel without emulating hardware.
Both a VM and a Docker image may be Ubuntu 14.04, but with the Docker image you don't need to run the whole OS.
For example, if I want to run an nginx container based on ubuntu, I'd end up with only the nginx process running. No upstart/systemd/init is needed. A VM would run an init system, manage its own networking, and run other services as well. The container image approach that uses a linux distro base is mostly for convenience.
It is entirely possible to run Docker containers with very minimal images. A statically compiled binary alone in an image is all you'd need to run a container.
Vagrant : Vagrant is a project that helps the spawning of virtual machines. It started as an command line of VirtualBox, something similar to Gemfile for VM's. You can choose the base image to start with, network, IP, share folders and put it all in a file that anyone can reuse to spawn the same configured machine. Vagrant has different extensions, provisioning options and VM providers. You can run a VirtualBox, VMware and it is extensible enough to be able to create instances on EC2.
Docker : Docker, allows to package an application with all of its dependencies into a standardized unit of software development. So, it reduces a friction between developer, QA and testing. It dynamically change your application, adding new capabilities every single day, scaling out services to quickly changing the problem areas. Docker is putting itself in an excited place as the interface to PaaS be it networking, discovery and service discovery with applications not having to care about underlying infrastructure. Yes, their are still issues with docker in production, but, hopefully, we'll see the solutions to those problems, as docker team and contributors working hard on those issues. As Docker Volume driver allows third-party container data management solutions to provide data volumes for containers which operate on data, such as database, key-value stores, and other stateful applications. The latest version is coming with much more flexibility, complete orchestration build-in, advanced networking, secrets management, etc. As you can see one, rexray, as volume plugin and provides advanced storage functionality. emccode/rexray We're finally starting to agree on more than just images and run time.

Resources