ELK Stack Docker
ELK is an acronym for Elasticsearch, Logstash, and Kibana. ELK consists of various software tools such as Elasticsearch (log searching tool), Logstash (data router and data processing tool), and Kibana(data visualization tool). All these three tools constitute a full analytical tool. Elasticsearch is a NoSQL database that uses the Lucene search engine. Logstash is a transportation pipeline that is used to populate Elasticsearch with data and Kibana is a dashboard working on top of Elasticsearch and provides data analysis through visualizations and dashboards. This blog gives you a glance at the ELK stack in Docker topics that covers Docker compose, Elasticsearch container, Logstash container, Kibana container, NGINX container, filebeat configuration. Before getting through these concepts, let us comprehend the basic terms of Elasticsearch, Logstash, and Kibana in more detail.
What is ElasticSearch?
Elasticsearch allows you to search, analyze, and store extensive volume data. This is utilized as a basic engine to authorize the applications that fulfill the search stipulations. Elasticsearch also acts as a NoSQL database, and it is based on the Lucene Search Engine. It provides easy management, simple deployment, and maximum reliability. It also offers sophisticated queries for performing detailed analysis and stores the data.
What is Logstash?
Logstash acts as a data collection pipeline tool. It collects the data inputs and stores them into ElasticSearch. It gathers various kinds of data from various data sources and makes it accessible for future reference. Logstash can combine the data from distinct sources and standardize the data into your essential destinations. Following are the three elements of Logstash:
Input: Sending the logs for processing them into the machine-understandable format.
Filter: It is a group of conditions for performing a specific action or an event.
Output: It acts as a decision-maker to a processed log or event.
What is Kibana?
It is the data visualization tool that completes the ELK Stack. Kibana is used to visualize Elasticsearch documents, and it assists the developers in analyzing them. The Kibana Dashboards provide various responsive geospatial data, graphs, and diagrams for visualizing the difficult queries. The Kibana is used to view, search, and interact with the data saved in the Elasticsearch directories. Through Kibana, advanced data analysis can be performed, and the data is visualized in various charts, maps, and tables.
Installation of Docker
You may face impediments while installing/configuring elastic stack if you are a new user. The automation of the installation procedure using Docker will reduce the time and complexities of the installation procedure to a great extent. So let’s start the procedure right from installing Docker to visualizing Apache logs in Kibana Dashboard.
Install Docker Compose
Apply the following set of commands to install Docker. Ignore this step if you have already set up the environment for Docker.
$ yum install wget
$ wget -qO- https://get.docker.com/ | sh
$ systemctl enable docker.service
$ systemctl start docker.service
$ systemctl status docker.service
ElasticSearch Container
Begin the containerizing elastic stack starting with elasticsearch. Create a root folder where each component of an elastic stack will be clubbed together.
$ mkdir ~/docker-elk
Navigate to the root folder of an elastic stack and create folders for elasticsearch and associated configurations/storage for elasticsearch.
$ cd ~/docker-elk
$ mkdir -p elasticsearch/{config,storage}
$ chown -R 1000:1000 elasticsearch/storage/
The config and storage folders will be used to define “docker volumes” in the docker-compose file at a later stage. The docker volume will enable a folder in the host machine to remain attached with the folders in the containers and will always remain in sync with each other.
Create a Dockerfile for elasticsearch which is a way to place all the commands needed to assemble an image.
$ cd ~/docker-elk/elasticsearch
$ vi Dockerfile
ARG ELK_VERSION
FROM docker.elastic.co/elasticsearch/elasticsearch:${ELK_VERSION}
Define the version of elasticsearch that you want to containerize in the environment file.
$ vi ~/docker-elk/.env
ELK_VERSION=7.5.1
Now proceed by creating an elasticsearch configuration file in the config folder. Having an ES configuration file in the host machine will enable us to easily tweak the settings and mount it in the container using docker volume.
$ vi ~/docker-elk/elasticsearch/config/elasticsearch.yml
cluster.name: "docker-cluster"
network.host: 0.0.0.0
discovery.zen.minimum_master_nodes: 1
discovery.type: single-node
logger.level: DEBUG
All the files and folders needed for defining elasticsearch containers through docker-compose is now ready. Proceed with creating a docker-compose file in the root of the project which is ~/docker-elk.
$ vi ~/docker-elk/docker-compose.yml
version: '3'
services:
elasticsearch:
container_name: elasticsearch
build:
context: elasticsearch
args:
ELK_VERSION: $ELK_VERSION
volumes:
- ./elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml
- ./elasticsearch/storage:/usr/share/elasticsearch/data:rw
ports:
- "9200:9200"
- "9300:9300"
Elk Stack Training
- Master Your Craft
- Lifetime LMS & Faculty Access
- 24/7 online expert support
- Real-world & Project Based Learning
environment:
- ELASTIC_PASSWORD="changeme"
- ES_JAVA_OPTS=-Xmx256m -Xms256m
- discovery.type=single-node
- bootstrap.memory_lock=true
- http.cors.allow-origin=*
ulimits:
memlock:
soft: -1
hard: -1
networks:
elk:
driver: bridge
Build the container using the following commands:
$ cd ~/docker-elk
$ docker-compose bui
ld elasticsearch
Start the container in detached mode by using the following command:
$ docker-compose up -d elasticsearch
List the container using the following command:
$ docker ps -a
Ping the ES container from your host machine with the following instructions:
$ curl http://127.0.0.1:9200/
{
"name" : "a85bd40e10de",
"cluster_name" : "docker-cluster",
"cluster_uuid" : "cnGc-4uLSIWS-bFwr8ywug",
"version" : {
"number" : "7.5.1",
"build_flavor" : "default",
"build_type" : "docker",
"build_hash" : "3ae9ac9a93c95bd0cdc054951cf95d88e1e18d96",
"build_date" : "2019-12-16T22:57:37.835892Z",
"build_snapshot" : false,
"lucene_version" : "8.3.0",
"minimum_wire_compatibility_version" : "6.8.0",
"minimum_index_compatibility_version" : "6.0.0-beta1"
},
"tagline" : "You Know, for Search"
}
To find any useful information, you can navigate to the shell of the elasticsearch container, execute the following command to get the result:
$ docker exec -it elasticsearch /bin/bash
Logstash Container
Like before, create the following folders for logstash and its configuration settings in the root of the project.
- config: This folder will hold logstash system-wide configuration settings.
- pipeline: This folder will hold logstash configuration settings for each log file that you want to process.
- logfile: This contains the log file which includes network logs, Apache logs, etc.
$ cd ~/docker-elk
$ mkdir -p logstash/{config,pipeline,logfile}
Create Dockerfile for Logstash by applying the following instructions.
$ vi ~/docker-elk/logstash/Dockerfile
ARG ELK_VERSION
FROM docker.elastic.co/logstash/logstash-oss:${ELK_VERSION}
RUN logstash-plugin install logstash-input-beats
USER root
RUN mkdir -p /home/logstash/logfile
RUN chown -R logstash:logstash /home/logstash/logfile/
Let us now create a Logstash configuration file by implementing the following instructions.
$ vi ~/docker-elk/logstash/config/logstash.yml
http.host: "0.0.0.0"
path.config: /usr/share/logstash/pipeline
The Apache access and error log are used to test the Logstash pipeline configuration. Filebeat is used for streaming the apache log events to logstash in real-time.
Create a pipeline configuration for logstash that will accept apache log events in port number 5000 and after applying appropriate filters push them to elasticsearch container.
$ vi ~/docker-elk/logstash/pipeline/01.apache.conf
input {
beats {
port => 5000
type => apache
}
}
filter {
if [type] == "apache" {
grok {
match => { "message" => "%{COMBINEDAPACHELOG}" }
}
}
}
output {
if [type] == "apache" {
elasticsearch {
hosts => ["http://elasticsearch:9200"]
index => "apache-combined-%{+YYYY.MM.dd}"
}
stdout { codec => rubydebug }
}
}
All the necessary configuration settings for logstash are in place to define services for it in the docker-compose. Edit the docker-compose file and add the following content to it.
Subscribe to our youtube channel to get new updates..!
$ vi ~/docker-elk/docker-compose.yml
...
...
logstash:
container_name: logstash
build:
context: logstash
args:
ELK_VERSION: $ELK_VERSION
volumes:
- ./logstash/config/logstash.yml:/usr/share/logstash/config/logstash.yml
- ./logstash/pipeline:/usr/share/logstash/pipeline
ports:
- "5000:5000"
networks:
- elk
depends_on:
- elasticsearch
...
...
Build a Logstash container using the following command.
$ docker-compose build logstash
Run the Logstash container without detached mode to view the logstash startup logs in the terminal with the following command.
$ docker-compose up logstash
If everything works correctly, Press CTRL+C, and run the logstash container again in detached mode. Use the following command.
$ docker-compose up -d logstash
List the container by applying the following command.
$ docker ps -a
Kibana Container
To start with containerizing Kibana, create folders meant for it by the name config that will hold Kibana configurations. Implement the following commands:
$ cd ~/docker-elk
$ mkdir -p kibana/config
Create a Dockerfile to assemble an image for the latest kibana. Implement the following instructions.
$ vi ~/docker-elk/kibana/Dockerfile
ARG ELK_VERSION
FROM docker.elastic.co/kibana/kibana:${ELK_VERSION}
Edit and create a Kibana Configuration file by implementing the following instructions.
$ vi ~/docker-elk/kibana/config/kibana.yml
server.name: kibana
server.host: "0"
server.basePath: "/kibana"
elasticsearch.hosts: http://elasticsearch:9200
apm_oss.enabled: true
xpack.apm.enabled: true
xpack.apm.ui.enabled: true
logging.dest: stdout
Finally, append the Kibana service in the docker file by implementing the following instructions.
$ vi docker-compose.yml
…
…
kibana:
container_name: kibana
build:
context: kibana/
args:
ELK_VERSION: $ELK_VERSION
volumes:
- ./kibana/config/:/usr/share/kibana/config
ports:
- "5601:5601"
environment:
- ELASTICSEARCH_PASSWORD="changeme"
networks:
- elk
depends_on:
- elasticsearch
Build and run kibana with the following commands:
$ docker-compose build kibana
$ docker-compose up -d kibana
List the Kibana container by applying the following command:
$ docker ps -a
NGINX Container
The primary cause to add an NGINX container is to provide password-protected access to the Kibana interface through the reverse proxy. Create folders for the NGINX container in the root of the docker project and subsequently create two subfolders by the name public and data.
$ cd ~/docker-elk
$ mkdir -p nginx/{public,data,etc}
Create a simple index file for NGINX. Implement the following instructions.
$ vi nginx/public/index.html
It Works
Create an NGINX configuration file by implementing the following instructions.
$ vi ~/docker-elk/nginx/etc/nginx.conf
worker_processes 4;
events {
worker_connections 1024;
}
http {
server {
listen 80;
server_name IP_OR_DOMAIN ;
location / {
root /usr/share/nginx/html;
index index.html;
}
location /elastic/ {
proxy_pass http://elasticsearch:9200/;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
auth_basic "Restricted Content";
auth_basic_user_file /etc/nginx/.htpasswd.user;
}
location /kibana/ {
proxy_pass http://kibana:5601/;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
rewrite ^/kibana/(.*)$ /$1 break;
auth_basic "Restricted Content";
auth_basic_user_file /etc/nginx/.htpasswd.user;
}
}
}
For password-protected access to kibana, you need to install httpd-tools and create the user/password using htpasswd. Use the following commands:
$ yum install httpd-tools
$ cd ~/docker-elk/nginx/etc
$ htpasswd -c .htpasswd.user admin
Define docker service for NGINX with the following instructions.
$ vi ~/docker-elk/docker-compose.yml
…
…
nginx:
image: nginx:alpine
container_name: nginx
volumes:
- './nginx/etc/nginx.conf:/etc/nginx/nginx.conf:ro'
- './nginx/public:/usr/share/nginx/html:ro'
- './nginx/etc/.htpasswd.user:/etc/nginx/.htpasswd.user:ro'
links:
- elasticsearch
- kibana
depends_on:
- elasticsearch
- kibana
ports:
- '80:80'
networks:
- elk
Run the NGINX container with the following command:
$ docker-compose up -d nginx
List the NGINX container by using the following command:
$ docker ps -a
Once the NGINX container is up and running, access the kibana interface by using http://SERVER_IP/kibana
Check the logs of any container using the following command:
$ docker logs container_name_or_id
e.g. docker logs elasticsearch
List all the running containers using the following command:
$ docker ps -a
IMAGE
Test elasticsearch container:
Open your favorite web browser and point it to http://SERVER_IP/elastic
IMAGE
Filebeat Configuration(Client-Side):
ELK stack is now up and running, and begins to test the setup by streaming Apache logs from any remote system using filebeat. You could also prefer some other log events such as NGINX, CISCO syslog, and more. But make sure you have the correct logstash pipeline configuration in place.
Install filebeat implementing the following instructions:
$ wget [https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-6.5.0-amd64.deb](https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-6.5.0-amd64.deb)
$ dpkg -i filebeat-6.5.0-amd64.deb
Configure filebeat with the following instructions:
$ vi /etc/filebeat/filebeat.yml
...
...
filebeat.inputs:
- type: log
enabled: true
paths:
- /var/log/apache2/*.log
...
...
output.logstash:
# The Logstash hosts
hosts: ["123.45.67.89:5000"]
...
...
Run filebeat by using the following command:
$ filebeat -e -d "*"
Find the ES index in the kibana dashboard by navigating to management -> index patterns -> Create Index patterns and type apache-combined-* in the text box to finish the process.
IMAGE
Conclusion:
Thus by implementing the instructions that are discussed so far, you have now successfully dockerized the ELK stack. You can also proceed further by creating a few more logstash pipelines to stream log events from various sources.
Categories
- Azure DevOps Tutorial
- DevOps Lifecycle
- DevOps Skills
- Python For DevOps
- DevOps Periodic Table
- DevOps Tutorial
- Azure Pipelines
- Continuous Delivery vs Continuous Deployment
- Chef vs Ansible
- DevOps Testing Tools
- Azure Data Factory Tutorial
- Linux Commands For Devops
- DevOps Prerequisites
- DevOps Tools
- How to Become a DevOps Engineer
- DevOps Certification
- What is Puppet in DevOps
- DevOps vs Agile
- DevOps Engineer Skills
- What is Azure DevOps
- Chef vs Puppet
- What Does a DevOps Engineer Do
- DevOps Engineer Roles and Responsibilities
- Azure DevOps Certification
- Azure DevOps Interview Questions
- DevOps Interview Questions