Configuring Docker using Ansible
The motive of this project is to configure a system (Managed Node) with Docker using Ansible. Further using the same to launch a web-app on top of a docker container. Step-wise description of the project is given below:
- Configure Docker on the Managed Node.
- Start and enable Docker services.
- Pull the httpd server image from the Docker Hub.
- Run the httpd container and expose it to the public.
- Copy an html code into the Document Root of the webserver.
This will be achieved with complete automation using Playbooks. Playbooks are YAML files which record and execute Ansible’s configuration, deployment, and orchestration functions. To read more, refer to the official documents provided on this link.
The playbook will be available on the GitHub repository provided below:
Some basic pre-requisites:
- A Controller Node: a system with Ansible installed; the playbook will be written on this node.
- Managed Node(s): one or more systems which will be configured with Docker.
- Controller Node must be able to connect to Managed Node via SSH protocol.
In this project I will be using 2 virtual machines, one as the Controller Node and the other as the Managed Node. Both of the machines are using RedHat 8 Linux (RHEL8) as the OS.
To begin with make sure that Ansible is installed on the Managed Node. Check using 'ansible --version' command. If not then install Ansible using yum if the repository is configured. Or better use pip3 command as 'pip3 install ansible'.
A few configurations are required only on the Managed Node:
- Update (or create) the file to be used as inventory which will be having IP of the Managed Node.
- If installing for the first time, then create a file with name 'ansible.cfg' under the directory '/etc/ansible'. Note that the names used MUST be same. Provide the node group, path of file to be used as inventory. The configuration file might be similar to the one as shown below.
[defaults] inventory = /path/to/file/inventory.txt host_key_checking = false
Add the Managed Node to a .txt file to be used as inventory under some node-group. Replace <USER> with some user with appropriate permissions and the <PASSWORD> with the user's password. For eg., USER=root, PASS=root
[nodegroup] ManagedNode_IP ansible_ssh_user=<USER> ansible_ssh_pass=<PASS>
Update the configuration file with the inventory file. Use the commands as shown below to confirm the configurations:
ansible --version cat /etc/ansible/ansible.cfg cat /etc/path/to/inventory.txt ansible all --list-hosts
Test if ansible can connect to Managed Node using ping module. Enter the ad-hoc command on the Controller Node, replace node-group with given name or all:
ansible <node-group> -m ping
Create a file with the extension .yml. This file will act as the playbook used to configure Docker on the Hosts provided. Refer to the playbook on the GitHub repository mentioned above.
On the first line, provide the hosts i.e., Managed Nodes to be configured. Either provide all, node-group or the IP of the Managed Node. And add the keyword tasks just after it as shown:
- hosts: vboxvm - tasks:
The step-wise configurations are given below as a list under 'tasks':
Configuring YUM repository:
Configure the yum repository of Managed Node to download the Docker-CE software.
- name: config yum for docker yum_repository: name: dockerrepo baseurl: https://download.docker.com/linux/centos/7/x86_64/stable/ description: repo for docker ce enabled: true gpgcheck: no
Install the docker rpm package:
This can be done using the 'package' module but it might give error because yum might require the 'nobest' option for RHEL8. So either provide the package name with the version or use 'command' module.
- name: install docker software command: "dnf install docker-ce -y --nobest"
If using package module then use:
- name: install docker software package: name: "docker-ce-3:19.03.2-3.el7.x86_64" state: present
Start docker services:
Using 'service' module.
- name: start using service service: name: "docker" state: started enabled: yes
Note that for docker to run, the firewall of the Managed Node must allow docker services to run. Either disable the firewalld service or update them using Ansible using the firewalld module. Also set the SELinux running on the Managed Node to permissive, may use the selinux module.
For testing, we can disable firewalld service and set SELinux to permissive. Use the commands given below on the Managed Node to do so:
systemctl disable firewalld setenforce 0
Install Docker SDK on Managed Node
To use docker running on the Managed Node, Ansible requires the Docker SDK pre-installed which is a Python library. So first use the package module to install python and then use the pip module to install the Docker SDK.
- name: install software python-36 package: name: python36 state: present - name: install python library for docker pip: name: docker-py
Create directory to store webpages:
Create a directory on the Managed Node using 'file' module to store webpages to be deployed. Then copy a webpage from the Controller Node to the same directory created in Managed Node using 'copy' module.
- name: create directory to store webpages to deploy file: path: "/ansible_docker_webapp" state: directory - name: copy webpages to directory created above copy: src: "/root/ansible_training/index.html" dest: "/ansible_docker_webapp"
Launch Container:
Finally, launch a container with port 80 exposed. Use the 'docker_container' module.
- name: launch Container docker_container: name: webapp_ansible image: httpd state: started exposed_ports: - "80" ports: - "90:80" volumes: - /ansible_docker_webapp:/usr/local/apache2/htdocs/
The playbook is ready to use! Run the command given below to start configuring.
ansible-playbook <PLAYBOOK-FILE-NAME>.yml
Output:
Check Managed Node to confirm. Use the command 'docker ps' as shown:
Use a web browser or curl command on the BaseOS or Controller Node to see the webpage. Use the IP of Managed Node and the Container Port as the URL as shown.
Thus, the playbook was run successfully and the Managed Node has been configured with docker and used the same to launch a container to host a webpage.
And at last I would like to thank my mentor Mr. Vimal Daga and LinuxWorld Informatics