The Tech Platform

Jan 26, 20214 min

DEPLOY WEBSERVER ON DOCKER USING ANSIBLE

Ansible:

Ansible is an open-source software provisioning, configuration management, and application-deployment tool enabling infrastructure as code. It runs on many Unix-like systems, and can configure both Unix-like systems as well as Microsoft Windows. It includes its own declarative language to describe system configuration


 
Docker:

Docker is a set of platform as a service (PaaS) products that use OS-level virtualization to deliver software in packages called containers. Containers are isolated from one another and bundle their own software, libraries and configuration files; they can communicate with each other through well-defined channels. All containers are run by a single operating system kernel and therefore use fewer resources than virtual machines.

Now you must have got a basic idea about what ansible and docker is. In this story I’ll demonstrate how to launch webserver on Docker container using ansible. This can be done in a few ways but I’ll demonstrate the following:

  1. Directly interact with Docker daemon and launch the webserver.

  2. Use Kubernetes to launch the same on docker.

**This story does not cover installation of ansible on the controller node.
 

Pre-requisites:

  1. Ansible installed and configured.

  2. Kubernetes Cluster(I have used minikube for this story).

Process:
 

Direct interaction with the docker daemon

1. First we have to specify the hosts(The hosts should have been already added to the inventory of ansible configuration file) where the tasks have to be carried out.

- hosts: worker

In my case the hosts have been grouped under worker in the inventory. I have configured only 1 node for this task but multiple ones can be configured to do the same.


 
2. I have used a bunch of variables as it gives it flexibility.

vars:
 
- pname: "docker-ce-18.09.1-3.el7.x86_64"
 
default_container_name: webserver
 
default_container_image: httpd:latest
 

Now I shall specify the tasks.
 

3. We need to create a docker.repo for docker installation.

- name: "Docker"
 
yum_repository:
 
name: docker
 
description: docker YUM repo
 
baseurl: https://download.docker.com/linux/centos/7/x86_64/stable/
 
gpgcheck: no


 
4. Next comes the package installation part that will install Docker on our node.

- package:
 
name: "{{ pname }}"
 
state: present


 
5. To interact with the docker daemon ansible needs the docker SDK for python.

- name: Install Docker Module for Python
 
pip:
 
name: docker-py


 
6. Now that Docker is installed and SDK is downloaded we can start the service.

- service:
 
name: "docker"
 
state: started


 
7. Now we have to pull the image from Docker Hub. I have used the httpd official image here.

- name: Pull default Docker image
 
docker_image:
 
name: "{{ default_container_image }}"
 
source: pull


 
8. A webserver is absolutely useless if there is no webpage to show. So I am first copying my webpage from the controller node to the worker node and then I will mount it on the docker container as a volume.

- copy:
 
src: "index.html"
 
dest: "/root/html"
 
ignore_errors: yes


 
9. Now that everything is done we can launch the container.

- name: Create default containers
 
docker_container:
 
name: "{{ default_container_name }}"
 
image: "{{ default_container_image }}"
 
state: present
 
exposed_ports:
 
- 80/tcp
 
- 80/udp
 
published_ports:
 
- 0.0.0.0:8086:80/tcp
 
- 0.0.0.0:8086:80/udp
 
volumes:
 
- /root/html/:/usr/local/apache2/htdocs/


 
Then on the terminal rin the following command

ansible-playbook <playbook-name>

This will launch the container and we will be able to see the webpage at http://<ip for worker node>:<target port(8086 here)>.

Webpage

I have used a very simple html file as my webpage. You can do loads of other modifications as per your needs.


 
Using Kubernetes


 
Kubernetes is an open-source container-orchestration system for automating computer application deployment, scaling, and management. It was originally designed by Google and is now maintained by the Cloud Native Computing Foundation.


 
Kubernetes has it own script for writing manifest files. Just like ansible it also uses yaml language.
 
I have created a webos.yml manifest file that will create configure the webserver.


 
webos.yml


 
apiVersion: v1
 
kind: Service
 
metadata:
 
name: webos
 
namespace: deploy
 
labels:
 
app: webos
 
spec:
 
ports:
 
- port: 80
 
nodePort: 30001
 
selector:
 
app: webos
 
type: NodePort---apiVersion: v1
 
kind: PersistentVolumeClaim
 
metadata:
 
name: webos-pv-claim
 
namespace: deploy
 
labels:
 
app: webos
 
spec:
 
accessModes:
 
- ReadWriteOnce
 
resources:
 
requests:
 
storage: 20Gi---apiVersion: apps/v1
 
kind: Deployment
 
metadata:
 
name: webos
 
namespace: deploy
 
labels:
 
app: webos
 
spec:
 
selector:
 
matchLabels:
 
app: webos
 
template:
 
metadata:
 
namespace: deploy
 
labels:
 
app: webos
 
spec:
 
containers:
 
- image: httpd:latest
 
name: webos
 
ports:
 
- containerPort: 80
 
name: webos
 
volumeMounts:
 
- name: webos-ps
 
mountPath: /usr/local/apache2/htdocs
 
volumes:
 
- name: webos-ps
 
persistentVolumeClaim:
 
claimName: webos-pv-claim
 

\Now lets move on to the portion of ansible.
 

1. Start the minikube VM


 
2. Select the hosts. I have used the same worker group in this case.

- hosts: worker

3. Create the tasks. To use kubernetes we have to configure kubectl on the worker node.

- name: Kubectl
 
shell: curl -LO "https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl"
 
- name: kubectl permission
 
shell: chmod +x ./kubectl
 
- name: kubectl bin
 
shell: mv -f ./kubectl /usr/local/bin/kubectl
 
ignore_errors: yes


 
4. Kubectl needs a kubernetes config file. Using ansible copy the config file and all the certificates and keys to the worker node. Here all of them have been bundled under the kubecnf directory.

- copy:
 
src: "/root/kubecnf"
 
dest: "/root"
 
ignore_errors: yes
 
- name: kubeconfig
 
shell: mv -u /root/kubecnf/.kube /root/
 
ignore_errors: yes


 
5. Copy the code for webpage to the worker node.

- copy:
 
src: "/root/task1/index.html"
 
dest: "/root"
 
ignore_errors: yes


 
6. Ansible needs the Kubernetes and Openshift module to interact with the kubernetes cluster. Install them using pip.

- name: Install kubernetes Module for Python
 
pip:
 
name: kubernetes- name: Install Openshift Module for Python
 
pip:
 
name: Openshift


 
7. Create a custom Namespace under which the pods, services etc. will be lauched.

- name: Create a k8s namespace
 
k8s:
 
name: deploy
 
api_version: v1
 
kind: Namespace
 
state: present


 
8. Create the deployment. The lookup plugin will take the kubernetes manifest file from your controller and create the deployment, pvc, service etc.

- name: Create a Deployment by reading the definition from a local file
 
k8s:
 
state: present
 
definition: "{{ lookup('file', '/root/task1/webos.yml') }}"
 

9. Now we can copy the code to the pod. Since the deployment takes some time to create, a buffer spanning few seconds will give the deployment enough time to create before copying the code to the pods.

- name: buffer
 
shell: sleep 20- name: kubectl cp
 
shell: kubectl cp /root/index.html deploy/"$(kubectl get pod -n deploy|grep webos|awk '{print $1}')":/usr/local/apache2/htdocs/

10. Use the following command to launch the whole setup.

ansible-playbook <playbook-name>

Webserver will be launched at http://<minikube ip>:<nodeport> .
 


 

 

Source: medium

The Tech Platform

www.thetechplatform.com

    0