> For the complete documentation index, see [llms.txt](https://www.devops.buzz/public/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://www.devops.buzz/public/kubernetes/elk.md).

# ELK

## Deploy Elasticsearch

### Setup the host node

The `vm.max_map_count` kernel setting needs to be set to at least 262144 for production use. Make sure the node(s) that will host Elasticsearch have the following config:

```bash
sysctl -w vm.max_map_count=262144
```

Create the data dir:

```bash
mkdir /storage/storage-001/mnt-elasticsearch
chown nobody:nogroup /storage/storage-001/mnt-elasticsearch/
```

### Create the namespace

Connect to your kubectl workstation and create the namespace:

```bash
kubectl create namespace elk
```

### Create the ConfigMap

Create Elasticsearch config file:

```bash
cat <<EOF >>elasticsearch.yml

cluster.name: "docker-cluster"
network.host: 0.0.0.0
discovery.zen.minimum_master_nodes: 1
discovery.type: single-node

EOF
```

Create its `ConfigMap`:

```bash
kubectl -n elk \
  create configmap cm-elasticsearch \
  --from-file=elasticsearch.yml \
  -o yaml --dry-run | kubectl apply -f -
```

{% hint style="info" %}
If you need to update the `ConfigMap`, run:

```bash
kubectl -n elk \
  create configmap cm-elasticsearch \
  --from-file=elasticsearch.yml \
  -o yaml --dry-run | kubectl apply -f -
```

Then run:

```
kubectl -n elk scale deployment/elasticsearch --replicas=0
kubectl -n elk scale deployment/elasticsearch --replicas=1
```

{% endhint %}

### Deploy Elasticsearch

Run:

```bash
kubectl create -f - <<EOF

apiVersion: apps/v1
kind: Deployment
metadata:
  name: elasticsearch
  namespace: elk
  labels:
    app: elasticsearch
spec:
  replicas: 1
  selector:
    matchLabels:
      app: elasticsearch
  template:
    metadata:
      labels:
        app: elasticsearch
    spec:
      securityContext:
        runAsUser: 65534
        fsGroup: 65534
      hostNetwork: true
      containers:
      - name: elasticsearch
        image: docker.elastic.co/elasticsearch/elasticsearch:6.7.0
                   
        ports:
        - containerPort: 9200
        - containerPort: 9300
        
        env:
        - name: discovery.type
          value: "single-node"

        volumeMounts:              
          - name: config-volume
            mountPath: /usr/share/elasticsearch/config/elasticsearch.yml
            subPath: elasticsearch.yml
            
          - name: mnt-elasticsearch
            mountPath: /usr/share/elasticsearch/data

      volumes:
        - name: config-volume
          configMap:
           name: cm-elasticsearch
           
        - name: mnt-elasticsearch
          hostPath:
            path: /storage/storage-001/mnt-elasticsearch
            
      nodeSelector:
        kubernetes.io/hostname: k8snode

EOF
```

{% hint style="info" %}
Check the latest docker image here <https://www.elastic.co/downloads/past-releases> and here <https://www.docker.elastic.co/>
{% endhint %}

### Create Elasticsearch service

Run:

```bash
kubectl create -f - <<EOF
        
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: elasticsearch
  name: srv-elasticsearch
  namespace: elk
spec:
  externalTrafficPolicy: Cluster
  ports:
  - name: "port-9200"
    nodePort: 30920
    port: 9200
    protocol: TCP
    targetPort: 9200
  - name: "port-9300"
    nodePort: 30930
    port: 9300
    protocol: TCP
    targetPort: 9300
  selector:
    app: elasticsearch
  sessionAffinity: None
  type: NodePort

EOF
```

### Test

Get indices:

```bash
curl PUT-YOUR-NODE-IP-HERE:30920
curl PUT-YOUR-NODE-IP-HERE:30920/_cat/indices?v
```

Post content:

```bash
curl -H "Content-Type: application/json" -XPOST "http://<HOST>:<PORT>/YOUR-INDEX/YOUR-TYPE/optionalUniqueId" -d "{ \"field\" : \"value\"}"
```

Another example of post:

```bash
curl -X POST -H "Content-Type: application/json" -H "Cache-Control: no-cache" -d '{
"user" : "Arun Thundyill Saseendran",
"post_date" : "2009-03-23T12:30:00",
"message" : "trying out Elasticsearch"
}' "http://<HOST>:<IP>/sampleindex/sampletype/"
```

## Deploy Logstash

### Create the ConfigMap (config file)

Create the config file:

```bash
cat <<EOF >>logstash.yml

http.host: "0.0.0.0"
path.config: /usr/share/logstash/pipeline

EOF
```

Create its `ConfigMap`:

```bash
kubectl -n elk \
  create configmap cm-config-logstash \
  --from-file=logstash.yml \
  -o yaml --dry-run | kubectl apply -f -
```

{% hint style="info" %}
If you need to update the `ConfigMap`, run:

```bash
kubectl -n elk \
  create configmap cm-config-logstash \
  --from-file=logstash.yml \
  -o yaml --dry-run | kubectl apply -f -
```

Then run:

```
kubectl -n elk scale deployment/logstash --replicas=0
kubectl -n elk scale deployment/logstash --replicas=1
```

{% endhint %}

### Create the ConfigMap (pipeline)

Create the config file:

```bash
cat <<EOF >>logstash.conf

#input {
#	tcp {
#		port => 5959
#	}
#}

input {
	http {
		port => 5959
		response_headers => {
			"Access-Control-Allow-Origin" => "*"
			"Content-Type" => "application/json"
			"Access-Control-Allow-Headers" => "Origin, X-Requested-With, Content-Type, Accept"
		}
	}
}

## Add your filters / logstash plugins configuration here

output {
	elasticsearch {
		hosts => "PUT-YOUR-HOST-HERE:PUT-YOUR-PORT-HERE"
	}
}

EOF
```

{% hint style="info" %}
Replace `output.elasticsearch.hosts` with your Elasticsearch host and port.
{% endhint %}

Create its `ConfigMap`:

```bash
kubectl -n elk \
  create configmap cm-pipeline-logstash \
  --from-file=logstash.conf \
  -o yaml --dry-run | kubectl apply -f -
```

{% hint style="info" %}
If you need to update the `ConfigMap`, run:

```bash
kubectl -n elk \
  create configmap cm-pipeline-logstash \
  --from-file=logstash.conf \
  -o yaml --dry-run | kubectl apply -f -
```

Then run:

```
kubectl -n elk scale deployment/logstash --replicas=0
kubectl -n elk scale deployment/logstash --replicas=1
```

{% endhint %}

### Deploy

**Connect to your node** and create the data dir:

```bash
mkdir -p /storage/storage-001/mnt-logstash
chown nobody:nogroup /storage/storage-001/mnt-logstash
```

**Connect to your kubectl workstation and** run:

```bash
kubectl create -f - <<EOF

apiVersion: apps/v1
kind: Deployment
metadata:
  name: logstash
  namespace: elk
  labels:
    app: logstash
spec:
  replicas: 1
  selector:
    matchLabels:
      app: logstash
  template:
    metadata:
      labels:
        app: logstash
    spec:
      securityContext:
        runAsUser: 65534
        fsGroup: 65534
      hostNetwork: true
      containers:
      - name: logstash
        image: docker.elastic.co/logstash/logstash:6.7.0
                   
        ports:
        - containerPort: 5959
        
        env:
        - name: discovery.type
          value: "single-node"

        volumeMounts:              
          - name: config-volume
            mountPath: /usr/share/logstash/config/logstash.yml
            subPath: logstash.yml

          - name: pipeline-volume
            mountPath: /usr/share/logstash/pipeline/logstash.conf
            subPath: logstash.conf
            
          - name: mnt-logstash
            mountPath: /usr/share/logstash/data

      volumes:
        - name: config-volume
          configMap:
           name: cm-config-logstash

        - name: pipeline-volume
          configMap:
           name: cm-pipeline-logstash
           
        - name: mnt-logstash
          hostPath:
            path: /storage/storage-001/mnt-logstash
            
      nodeSelector:
        kubernetes.io/hostname: k8snode

EOF
```

{% hint style="info" %}
Check the latest docker image here <https://www.elastic.co/downloads/past-releases> and here <https://www.docker.elastic.co/>
{% endhint %}

### Create service

Run:

```bash
kubectl create -f - <<EOF
        
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: logstash
  name: srv-logstash
  namespace: elk
spec:
  externalTrafficPolicy: Cluster
  ports:
  - name: "port-5959"
    nodePort: 30595
    port: 5959
    protocol: TCP
    targetPort: 5959
  selector:
    app: logstash
  sessionAffinity: None
  type: NodePort

EOF
```

### Test

Get service info:

```
curl -XGET 'PUT-YOUR-HOST-HERE:9600/_node/logging?pretty'
```

Telnet test:

```bash
telnet PUT-NODE-HOST-HERE 30595
```

## Deploy Kibana

### Create the ConfigMap

Create the config file:

```bash
cat <<EOF >>kibana.yml

server.name: kibana
server.host: "0"
elasticsearch.hosts: [ "http://PUT-YOUR-HOST-HERE:30920" ]
xpack.monitoring.ui.container.elasticsearch.enabled: true

EOF
```

{% hint style="info" %}
Replace `elasticsearch.hosts` with your Elasticsearch host and port.
{% endhint %}

Create its `ConfigMap`:

```bash
kubectl -n elk \
  create configmap cm-kibana \
  --from-file=kibana.yml \
  -o yaml --dry-run | kubectl apply -f -
```

{% hint style="info" %}
If you need to update the `ConfigMap`, run:

```bash
kubectl -n elk \
  create configmap cm-kibana \
  --from-file=kibana.yml \
  -o yaml --dry-run | kubectl apply -f -
```

Then run:

```
kubectl -n elk scale deployment/kibana --replicas=0
kubectl -n elk scale deployment/kibana --replicas=1
```

{% endhint %}

### Deploy

**Connect to your node** and create the data dir:

```bash
mkdir /storage/storage-001/mnt-kibana
chown nobody:nogroup /storage/storage-001/mnt-kibana/
```

**Connect to your kubectl workstation and** run:

```bash
kubectl create -f - <<EOF

apiVersion: apps/v1
kind: Deployment
metadata:
  name: kibana
  namespace: elk
  labels:
    app: kibana
spec:
  replicas: 1
  selector:
    matchLabels:
      app: kibana
  template:
    metadata:
      labels:
        app: kibana
    spec:
      securityContext:
        runAsUser: 65534
        fsGroup: 65534
      hostNetwork: true
      containers:
      - name: kibana
        image: docker.elastic.co/kibana/kibana:6.7.0
                   
        ports:
        - containerPort: 5601
        
        env:
        - name: ELASTICSEARCH_HOSTS
          value: "http://PUT-YOUR-HOST-HERE:30920"

        volumeMounts:
          - name: config-volume
            mountPath: /usr/share/kibana/config/kibana.yml
            subPath: kibana.yml
                          
          - name: mnt-kibana
            mountPath: /usr/share/kibana/data

      volumes:
        - name: config-volume
          configMap:
           name: cm-kibana
           
        - name: mnt-kibana
          hostPath:
            path: /storage/storage-001/mnt-kibana
            
      nodeSelector:
        kubernetes.io/hostname: k8snode

EOF
```

{% hint style="info" %}
Replace `spec.template.spec.containers.env` with your Elasticsearch host and port.
{% endhint %}

{% hint style="info" %}
Check the latest docker image here <https://www.elastic.co/downloads/past-releases> and here <https://www.docker.elastic.co/>
{% endhint %}

### Create service

Run:

```bash
kubectl create -f - <<EOF
        
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: kibana
  name: srv-kibana
  namespace: elk
spec:
  externalTrafficPolicy: Cluster
  ports:
  - name: "port-5601"
    nodePort: 30560
    port: 5601
    protocol: TCP
    targetPort: 5601
  selector:
    app: kibana
  sessionAffinity: None
  type: NodePort

EOF
```

### Test

Curl test:

```bash
curl http://PUT-YOUR-HOST-HERE:30560
```

## Deploy filebeat

Example to stream log files from `/elk/*.log` to `elasticsearch`.

```bash
cat <<EOF >>filebeat.docker.yml

filebeat:
  config:
    modules:
      path: ${path.config}/modules.d/*.yml
      reload.enabled: false
    
  autodiscover:
    providers:
      - type: docker
        hints.enabled: true

  prospectors:  
  - input_type: log
    paths:
      - /elk/*.log

#output.logstash:
#  hosts: ["PUT-YOUR-IP-HERE:30595"]

output.elasticsearch:
  hosts: ["http://PUT-YOUR-IP-HERE:30920"]
  #index: "filebeat-%{[beat.version]}-%{+yyyy.MM.dd}"
  #index: "test-filebeat"

logging:
  files:
    rotateeverybytes: 10485760 # = 10MB


EOF
```

Text:

```bash
docker run -tid \
  --name=filebeat \
  --user=root \
  --volume="$(pwd)/filebeat.docker.yml:/usr/share/filebeat/filebeat.yml:ro" \
  --volume="/elk:/elk:ro" \
  --volume="/var/lib/docker/containers:/var/lib/docker/containers:ro" \
  --volume="/var/run/docker.sock:/var/run/docker.sock:ro" \
  docker.elastic.co/beats/filebeat:6.7.0 filebeat
```

Text:

```bash
command
```

Text:

```bash
command
```

Text:

```bash
command
```

Text:

```bash
command
```

Text:

```bash
command
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://www.devops.buzz/public/kubernetes/elk.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
