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:
Directly interact with Docker daemon and launch the webserver.
Use Kubernetes to launch the same on docker.
**This story does not cover installation of ansible on the controller node.
Pre-requisites:
Ansible installed and configured.
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
Comments