top of page

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

0 comments

Comments


bottom of page