Se la tua azienda ha vincoli di bilancio, l’acquisto di prodotti autorizzati come Splunk per l’infrastruttura di registrazione potrebbe non essere fattibile. Fortunatamente, esiste una potente alternativa open supply: Elk (Elasticsearch, Logstash e Kibana). Elk offre robuste funzionalità di registrazione e visualizzazione.
In una startup in cui ho lavorato, la minimizzazione dei costi è stata una priorità , quindi ho implementato ELK per la registrazione.
In questo articolo, ti guiderò attraverso l’impostazione e la configurazione della versione gratuita dello stack ELK su GCP usando Terraform e Ansible. Tuttavia, le stesse istruzioni possono essere seguite per distribuirlo su altre piattaforme cloud come AWS e Azure.
Perché scegliere Elk?
Dopo una ricerca approfondita, ho deciso di implementare lo stack ELK su GCP utilizzando macchine virtuali (VM) per la registrazione a causa della sua facilità d’uso, dashboard ricchi e processo di configurazione diretta. Mentre avrei potuto schierarlo su un cluster GKE, al momento ho optato per le macchine virtuali per vari motivi.
Elasticsearch è un motore di ricerca e analisi open supply che consente di raccogliere e analizzare i registri da più fonti, tra cui dispositivi IoT, server di applicazioni, server Net e servizi cloud. Lo stack di Elk è costituito dai seguenti componenti:
-
Elasticsearch – memorizza i dati di registro di archiviazione e indici
-
Logstash – Filtri e formati dei registri prima dell’ingestione
-
Kibana – Fornisce un’interfaccia utente grafica (GUI) per la ricerca e la visualizzazione dei registri
-
Filebeat – Uno shipper di tronchi leggero installato come agente su macchine che generano tronchi
Figura 1
Prerequisiti
Prima di impostare ELK, assicurati di avere quanto segue:
-
Un account cloud (Google Cloud, AWS o Azure). Questa guida utilizza GCP.
-
Terraform e Ansible installati sulla macchina locale.
-
Autenticazione corretta configurata tra la macchina locale e il supplier cloud (Google Cloud o qualsiasi altro) con le autorizzazioni di accesso richieste per Terraform e Ansible.
Parte 1: configurazione di infrastrutture ELK utilizzando Terraform su GCP
Lo stack ELK è costituito da vari nodi, ciascuno dei quali serve una funzione specifica per migliorare la scalabilità e il failover:
-
Nodi padroni – Gestire le operazioni e l’indicizzazione del cluster.
-
Nodi di dati – Memorizza i dati di registro per la ricerca e l’analisi.
-
Nodo kibana – Fornisce una GUI per la visualizzazione e l’analisi del registro.
-
Nodo Logstash – Filtri, trasforma e ingerisce i registri da varie fonti.
Mentre tutte le funzionalità possono essere combinate su un singolo nodo, separarle in un ambiente di produzione migliora la scalabilità e la tolleranza ai guasti, a seconda del carico di lavoro.
Crea i seguenti file in una cartella in cui si prevede di eseguire il codice Terraform o clonare il mio repository git, che contiene tutto il codice: GitHub – Pradeep -Gaddamidi/Elk.
1. Create_elk_instances.tf
locals {
config = var.environment_config(terraform.workspace)
situations = (for key, worth in native.config.nodes : {
identify = key
machine_type = (
can(regex("master_.*", worth)) ? native.config.master_machine_type :
can(regex("kibana_.*", worth)) ? native.config.kibana_machine_type :
can(regex("logstash_.*", worth)) ? native.config.logstash_machine_type :
native.config.node_machine_type
)
zone = (
can(regex(".*_zoneb", worth)) ? native.config.region_zones(1) :
can(regex(".*_zonec", worth)) ? native.config.region_zones(2) :
native.config.region_zones(0)
)
network_tags = native.config.network_tags
ssh_keys = native.config.ssh_keys
static_ip_name = key # Modify or depart null as wanted
service_account_name = "elastic" # Modify or depart null as wanted
disk_name = key # Modify or depart null as wanted
disk_type = "pd-standard" # Modify as wanted
disk_size = (
can(regex("master_.*", worth)) ? native.config.master_disk_size :
can(regex("kibana_.*", worth)) ? native.config.kibana_disk_size :
can(regex("logstash_.*", worth)) ? native.config.logstash_disk_size :
native.config.node_disk_size
)
disk_zone = (
can(regex(".*_zoneb", worth)) ? native.config.region_zones(1) :
can(regex(".*_zonec", worth)) ? native.config.region_zones(2) :
native.config.region_zones(0)
)
disk_project = native.config.project_name
})
}
module "gcp_instance" {
supply = "../../modules/gcp_custom_instance"
gce_image = native.config.gce_image
subnet = native.config.subnet
area = native.config.area # Present solely when creating static IPS
situations = native.situations
use_common_service_account = native.config.use_common_service_account # Present solely when creating a standard service account accross all of the situations
}
2. Variabili.tf
variable "environment_config" {
description = "Configuration per surroundings"
sort = map(object({
project_name = string
area = string
region_zones = checklist(string)
master_machine_type = string
node_machine_type = string
kibana_machine_type = string
logstash_machine_type= string
network_tags = checklist(string)
community = string
subnet = string
gce_image = string
ca_bucket_location = string
backup_bucket = string
master_disk_size = quantity
node_disk_size = quantity
kibana_disk_size = quantity
logstash_disk_size = quantity
use_common_service_account = bool
machine_access_scopes= checklist(string)
nodes = map(string)
ssh_keys = checklist(string)
}))
default = {
nonprod = {
project_name = "nonprod-infra-monitoring"
area = "us-central1"
region_zones = ("us-central1-a", "us-central1-b")
master_machine_type = "n1-standard-2"
node_machine_type = "n1-standard-2"
kibana_machine_type = "n1-standard-2"
logstash_machine_type= "n1-standard-2"
network_tags = ("elastic", "nonprod")
community = "initiatives/nonprod-networking/international/networks/nonprod-vpc"
subnet = "initiatives/nonprod-networking/areas/us-central1/subnetworks/nonprod-sub01"
gce_image = "debian-cloud/debian-12"
ca_bucket_location = "nonprod-elastic-certificates"
backup_bucket = "nonprod-elastic-backup"
master_disk_size = 100
node_disk_size = 510
kibana_disk_size = 100
logstash_disk_size = 100
use_common_service_account = true
machine_access_scopes = ("cloud-platform")
ssh_keys = ()
nodes = {
"nonprod-elastic-master-node1" = "master_zonea"
"nonprod-elastic-data-node1" = "data_zonea"
"nonprod-elastic-data-node2" = "data_zoneb"
"nonprod-elastic-kibana" = "kibana_zonea"
"nonprod-elastic-logstash" = "logstash_zonea"
}
}
prod = {
project_name = "prod-infra-monitoring"
area = "us-central1"
region_zones = ("us-central1-a", "us-central1-b", "us-central1-c")
master_machine_type = "n2-standard-2"
node_machine_type = "n2-highmem-4"
kibana_machine_type = "n2-standard-2"
logstash_machine_type= "n2-standard-2"
network_tags = ("elastic", "prod")
community = "initiatives/prod-networking/international/networks/prod-vpc"
subnet = "initiatives/prod-networking/areas/us-central1/subnetworks/prod-sub01"
gce_image = "debian-cloud/debian-12"
ca_bucket_location = "prod-elastic-certificates"
backup_bucket = "prod-elastic-backup"
master_disk_size = 100
node_disk_size = 3000
kibana_disk_size = 100
logstash_disk_size = 100
use_common_service_account = true
machine_access_scopes = ("cloud-platform")
ssh_keys = ()
nodes = {
"elastic-master-node1" = "master_zonea"
"elastic-master-node2" = "master_zoneb"
"elastic-master-node3" = "master_zonec"
"elastic-data-node1" = "data_zonea"
"elastic-data-node2" = "data_zonea"
"elastic-data-node3" = "data_zoneb"
"elastic-data-node4" = "data_zoneb"
"elastic-data-node5" = "data_zonea"
"elastic-data-node6" = "data_zoneb"
"elastic-kibana" = "kibana_zonea"
"elastic-logstash" = "logstash_zonea"
"elastic-logstash2" = "logstash_zoneb"
"elastic-logstash3" = "logstash_zonec"
}
}
}
}
Ho creato un modulo personalizzato per fornire istanze GCP e l’ho utilizzato in create_elk_instances.tf
file. Tuttavia, puoi anche utilizzare il modulo Terraform ufficiale di GCP per creare istanze VM.
module "gcp_instance" {
 supply         = "./modules/gcp_custom_instance"
IL ./modules/gcp_custom_instance
La cartella deve avere i file, gcp_custom_vm.tf
E variables_custom.tf
).
Di seguito è riportato il codice per il mio modulo personalizzato:
3. GCP_Custom_vm.tf
locals {
common_service_account_email = var.use_common_service_account ? google_service_account.common_service_account(0).e-mail : null
}
useful resource "google_compute_instance" "google-compute-instance" {
for_each = { for index, inst in var.situations : inst.identify => inst }
identify = every.worth.identify
machine_type = every.worth.machine_type
zone = every.worth.zone
# allow_stopping_for_update = true
tags = every.worth.network_tags
metadata = {
ssh-keys = be a part of("n", every.worth.ssh_keys)
}
boot_disk {
initialize_params {
picture = var.gce_image
}
}
network_interface {
subnetwork = var.subnet
network_ip = every.worth.static_ip_name != null ? google_compute_address.static_ips(every.worth.static_ip_name).handle : null
}
dynamic "service_account" {
for_each = every.worth.service_account_name != null ? (1) : ()
content material {
scopes = var.machine_access_scopes
e-mail = var.use_common_service_account ? google_service_account.common_service_account(0).e-mail : google_service_account.individual_service_account(every.worth.identify).e-mail
}
}
dynamic "attached_disk" {
for_each = every.worth.disk_name != null ? (1) : ()
content material {
supply = google_compute_disk.google-compute-disk(every.worth.disk_name).self_link
device_name = "${every.worth.disk_name}-data"
mode = "READ_WRITE"
}
}
}
useful resource "google_compute_disk" "google-compute-disk" {
for_each = { for index, inst in var.situations : inst.disk_name => inst if inst.disk_name != null }
identify = "${every.worth.disk_name}-data"
sort = every.worth.disk_type
measurement = every.worth.disk_size
zone = every.worth.disk_zone
challenge = every.worth.disk_project
}
useful resource "google_service_account" "common_service_account" {
depend = var.use_common_service_account ? 1 : 0
account_id = var.use_common_service_account ? lookup(var.situations(0), "service_account_name", null) : null
display_name = "Service Account"
}
useful resource "google_service_account" "individual_service_account" {
for_each = { for index, inst in var.situations : inst.service_account_name => inst if inst.service_account_name != null && !var.use_common_service_account }
account_id = every.worth.service_account_name
display_name = "Service account for ${every.worth.identify}"
}
useful resource "google_compute_address" "static_ips" {
# Solely embrace situations which have static_ip_name outlined
for_each = { for index, inst in var.situations : inst.static_ip_name => inst if inst.static_ip_name != null }
identify = every.worth.static_ip_name
address_type = "INTERNAL"
area = var.area
subnetwork = var.subnet
}
output "common_service_account_email" {
worth = native.common_service_account_email
description = "The e-mail of the widespread service account"
}
4. VARIABES_CUSM.TF
variable "situations" {
description = "Checklist of occasion configurations"
sort = checklist(object({
identify = string
machine_type = string
zone = string
network_tags = optionally available(checklist(string))
ssh_keys = optionally available(checklist(string))
static_ip_name = optionally available(string)
service_account_name = optionally available(string)
disk_name = optionally available(string)
disk_type = optionally available(string)
disk_size = optionally available(quantity)
disk_zone = optionally available(string)
disk_project = optionally available(string)
}))
}
variable "gce_image" {
description = "GCE picture for the situations"
sort = string
default = "debian-cloud/debian-12"
}
variable "subnet" {
description = "Subnet for the community"
sort = string
}
variable "area" {
description = "GCP area"
sort = string
default = "us-central1"
}
variable "use_common_service_account" {
description = "Flag to find out if a standard service account needs to be used for all situations"
sort = bool
default = false
}
variable "machine_access_scopes" {
description = "Scopes for machine entry"
sort = checklist(string)
default = ("cloud-platform")
}
Assegnare le autorizzazioni agli account di servizio creati in precedenza nel codice:
locals {
bucket_config = var.environment_config(terraform.workspace)
}
useful resource "google_storage_bucket_iam_binding" "elastic-backup" {
bucket = native.bucket_config.backup_bucket
position = "roles/storage.objectAdmin"
members = native.config.use_common_service_account ? ("serviceAccount:${module.gcp_instance.common_service_account_email}") : ()
}
useful resource "google_storage_bucket_iam_binding" "elastic-certs" {
bucket = native.bucket_config.ca_bucket_location
position = "roles/storage.objectViewer"
members = native.config.use_common_service_account ? ("serviceAccount:${module.gcp_instance.common_service_account_email}") : ()
}
Crea i secchi GCP utilizzati per certificati e backup elastici:
useful resource "google_storage_bucket" "elastic-backup" {
identify = native.bucket_config.backup_bucket
location = "US"
storage_class = "STANDARD"
uniform_bucket_level_access = true
}
useful resource "google_storage_bucket" "elastic-certs" {
identify = native.bucket_config.ca_bucket_location
location = "US"
storage_class = "STANDARD"
uniform_bucket_level_access = true
}
È possibile utilizzare i comandi Terraform di seguito per creare le risorse di cui sopra:
terraform workspace set nonprod (if you happen to use workspaces)
terraform init
terraform plan
terraform apply
È possibile aggiungere nuovi nodi se necessario aggiornando le variabili, cioè aggiungendo nuovi nodi alla sezione nodi del file e reinserisci il codice Terraform. Ciò fornirà automaticamente i nuovi nodi di dati. Ora che l’infrastruttura ELK è impostata, il passo successivo è installare e configurare il software program ELK.
Parte 2: configurare l’infrastruttura ELK utilizzando Ansible
Prerequisiti
1. La generazione di certificati richiesta per la comunicazione sicura tra vari nodi elastici può essere automatizzata. Tuttavia, ho scelto di generarli manualmente seguendo le information degli alci.
Una volta generati i certificati, mettici sul secchio GCP elastic-certificates
.
2. Assicurati che i file di host Ansible siano organizzati come di seguito:
-
Tutti i dati e i nodi principali sono raggruppati sotto il
elastic
sezione -
Nodi di kibana sotto
kibana
sezione -
Nodi di logstash sotto
logstash
-
Nodi di dati sotto
information
-
Nodi principali sotto
grasp
Crea i seguenti file in una cartella in cui si prevede di eseguire il playbook Ansible. Quindi, eseguire il playbook Ansible qui sotto per installare e configurare ELK.
Ansible.yaml
---
- identify: Set up Elasticsearch pre-reqs on Debian
hosts: all
change into: sure
duties:
- identify: Replace apt repository
apt:
update_cache: sure
- identify: Set up default-jre
apt:
identify:
- default-jre
state: current
- identify: Add Elasticsearch GPG key
apt_key:
url: https://artifacts.elastic.co/GPG-KEY-elasticsearch
state: current
- identify: Set up apt-transport-https
apt:
identify: apt-transport-https
state: current
- identify: Add Elasticsearch repository
apt_repository:
repo: "deb https://artifacts.elastic.co/packages/8.x/apt steady primary"
state: current
filename: elastic-8.x
- identify: Replace apt repository
apt:
update_cache: sure
- identify: Set up Elasticsearch on Debian
hosts: elastic
change into: sure
duties:
- identify: Set up Elasticsearch
apt:
identify: elasticsearch=8.11.2
state: current
- identify: Allow Elasticsearch service
ansible.builtin.systemd:
identify: elasticsearch.service
enabled: sure
- identify: Set up Kibana on Debian
hosts: kibana
change into: sure
duties:
- identify: Set up Kibana
apt:
identify: kibana=8.11.2
state: current
- identify: Allow kibana service
ansible.builtin.systemd:
identify: kibana.service
enabled: sure
- identify: Set up logstash on Debian
hosts: logstash
change into: sure
duties:
- identify: Set up logstash
apt:
identify: logstash=1:8.11.2-1
state: current
- identify: Allow logstash service
ansible.builtin.systemd:
identify: logstash.service
enabled: sure
- identify: Copy the kibana.yml configuration file to the kibana nodes
hosts: kibana
change into: sure
duties:
- identify: Copy a kibana.yml file
template:
src: "{{ playbook_dir }}/recordsdata/kibana.j2"
dest: /and many others/kibana/kibana.yml
- identify: Copy the pipelines.yml configuration file to the logstash nodes
hosts: logstash
change into: sure
duties:
- identify: Copy a logstash pipelines.yml file
template:
src: "{{ playbook_dir }}/recordsdata/logstash.j2"
dest: /and many others/logstash/conf.d/pipelines.conf
- identify: Copy the elasticsearch_node.yml configuration file to the nodes
hosts: information
gather_facts: sure
change into: sure
duties:
- identify: Get zone information from metadata server
ansible.builtin.uri:
url: http://metadata.google.inside/computeMetadata/v1/occasion/zone
methodology: GET
return_content: sure # Ensures that the content material is returned
headers:
Metadata-Taste: "Google"
register: zone_info
check_mode: no
- identify: Extract the zone identify
set_fact:
zone_name: "{{ zone_info.content material.break up("https://dzone.com/")(-1) }}"
- identify: Copy a elasticsearch_node.yml file
template:
src: "{{ playbook_dir }}/recordsdata/elasticsearch_node.j2"
dest: /and many others/elasticsearch/elasticsearch.yml
- identify: Copy the elasticsearch_node.yml configuration file to the nodes
hosts: grasp
gather_facts: sure
change into: sure
duties:
- identify: Copy a elasticsearch_master.yml file
template:
src: "{{ playbook_dir }}/recordsdata/elasticsearch_master.j2"
dest: /and many others/elasticsearch/elasticsearch.yml
- identify: Obtain the certificates from the GCS bucket
hosts: elastic
change into: sure
duties:
- identify: certificates
command: gsutil cp gs://nonprod-elastic-certificates/* /and many others/elasticsearch/certs
- identify: Obtain the certificates from the GCS bucket
hosts: kibana
change into: sure
duties:
- identify: certificates
command: gsutil cp gs://nonprod-elastic-certificates/elasticsearch-ca.pem /and many others/kibana
- identify: Obtain the certificates from the GCS bucket
hosts: logstash
change into: sure
duties:
- identify: certificates
command: gsutil cp gs://nonprod-elastic-certificates/elasticsearch-ca.pem /usr/share/logstash/pipeline/elasticsearch-ca.pem
I file di configurazione richiesti dal playbook Ansible devono essere inseriti in recordsdata
listing. I file previsti sono elencati di seguito:
1. ElaSticSearch_Master.j2
node.identify: {{ ansible_default_ipv4.handle }}
node.roles: ( grasp )
discovery.seed_hosts:
- 10.x.x.x
- 10.x.x.x
- 10.x.x.x
#cluster.initial_master_nodes:
# - 10.x.x.x
# - 10.x.x.x
# - 10.x.x.x
community.host : {{ ansible_default_ipv4.handle }}
cluster.identify: prod-monitoring
path:
information: /mnt/disks/elasticsearch
logs: /var/log/elasticsearch
cluster.routing.allocation.consciousness.attributes: zone
cluster.routing.allocation.consciousness.power.zone.values: us-central1-a,us-central1-b
xpack.safety.http.ssl.enabled: true
xpack.safety.http.ssl.keystore.path: /and many others/elasticsearch/certs/http.p12
xpack.safety.enabled: true
xpack.safety.transport.ssl.enabled: true
xpack.safety.audit.enabled: true
xpack.safety.transport.ssl.verification_mode: certificates
xpack.safety.transport.ssl.keystore.path: /and many others/elasticsearch/certs/elastic-certificates.p12
xpack.safety.transport.ssl.client_authentication: required
xpack.safety.transport.ssl.truststore.path: /and many others/elasticsearch/certs/elastic-certificates.p12
xpack.license.self_generated.sort: primary
Alcuni punti da notare sulla configurazione dei nodi grasp elastici sopra:
-
Stiamo utilizzando una licenza di base (gratuita), non premium.
-
Quando Ansible viene eseguito sul nodo principale, inserisce automaticamente l’indirizzo IPv4 del nodo principale per impostazione predefinita.
-
Risocco
cluster.initial_master_nodes
soltanto Quando si crea il cluster per la prima volta. -
La sicurezza è abilitata tra:
- Nodi padroni usando
xpack.safety.transport.ssl.enabled
- Nodi di dati e kibana/logstash utilizzando
xpack.safety.http.ssl.enabled
- Nodi padroni usando
2. ElaSticsearch_node.j2
node.identify: {{ ansible_default_ipv4.handle }}
node.roles: ( information, remodel, ingest )
discovery.seed_hosts:
- 10.x.x.x
- 10.x.x.x
- 10.x.x.x
#cluster.initial_master_nodes:
# - 10.x.x.x
# - 10.x.x.x
# - 10.x.x.x
community.host : {{ ansible_default_ipv4.handle }}
cluster.identify: prod-monitoring
path:
information: /mnt/disks/elasticsearch
logs: /var/log/elasticsearch
node.attr.zone: {{ zone_name }}
xpack.safety.http.ssl.enabled: true
xpack.safety.http.ssl.keystore.path: /and many others/elasticsearch/certs/http.p12
xpack.safety.enabled: true
xpack.safety.transport.ssl.enabled: true
xpack.safety.audit.enabled: true
xpack.safety.transport.ssl.verification_mode: certificates
xpack.safety.transport.ssl.keystore.path: /and many others/elasticsearch/certs/elastic-certificates.p12
xpack.safety.transport.ssl.client_authentication: required
xpack.safety.transport.ssl.truststore.path: /and many others/elasticsearch/certs/elastic-certificates.p12
xpack.license.self_generated.sort: primary
3. kibana.j2
elasticsearch.hosts: ("https://10.x.x.x:9200","https://10.x.x.x:9200","https://10.x.x.x:9200","https://10.x.x.x:9200")
server.identify: kibana
server.host: {{ ansible_default_ipv4.handle }}
server.port: 443
elasticsearch.username: 'kibana_system'
elasticsearch.password: 'somepassxxxxx'
elasticsearch.ssl.certificateAuthorities: ('/and many others/kibana/elasticsearch-ca.pem')
elasticsearch.ssl.verificationMode: 'certificates'
server.ssl.enabled: true
server.ssl.certificates: /and many others/ssl/kibana/kibana-cert.crt
server.ssl.key: /and many others/ssl/kibana/kibana-key.key
server.publicBaseUrl: https://elastic.firm.xyz
xpack.encryptedSavedObjects.encryptionKey: zxy123f1318d633817xyz1234
xpack.reporting.encryptionKey: 1xfsyc4ad24176a902f2xyz123
xpack.safety.encryptionKey: cskcjsn60e148a70308d39dxyz123
logging:
appenders:
file:
sort: file
fileName: /var/log/kibana/kibana.log
structure:
sort: json
root:
appenders:
- default
- file
pid.file: /run/kibana/kibana.pid
4. lOgstash.j2
enter {
beats {
port => 5044
}
tcp {
port => 50000
}
tcp {
port => 5000
codec => "line"
sort => "syslog"
}
http {
port => 5050
}
google_pubsub {
sort => "pubsub"
project_id => "my-project-123"
matter => "cloud_functions_logs"
subscription => "cloud_functions_logs-sub"
### json_key_file => "/and many others/logstash/keys/logstash-sa.json"
codec => "json"
}
google_pubsub {
sort => "pubsub"
project_id => "my-project-123"
matter => "cloud_run_logs"
subscription => "cloud_run_logs-sub"
### json_key_file => "/and many others/logstash/keys/logstash-sa.json"
codec => "json"
}
}
filter {
grok {
match => { "message" => "^%{SYSLOGTIMESTAMP:timestamp} %{SYSLOGHOST:hostname} %{DATA:program}(?:(%{POSINT:pid}))?: %{GREEDYDATA:log_message}" }
}
date {
match => ( "timestamp", "MMM d HH:mm:ss", "MMM dd HH:mm:ss" )
goal => "@timestamp"
}
kv "
value_split => "="
mutate {
remove_field => ( "timestamp" )
convert => { "pid" => "integer" }
}
}
### Add your filters / logstash plugins configuration right here
output {
elasticsearch {
hosts => ("https://10.x.x.x:9200","https://10.x.x.x:9200","https://10.x.x.x:9200","https://10.x.x.x:9200")
consumer => "logstash_writer"
password => "mypassxyz"
index => "logs-my-index-%{+yyyy.MM.dd}"
motion => "create"
ssl => true
cacert => '/usr/share/logstash/pipeline/elasticsearch-ca.pem'
}
}
Alcuni punti da notare sulla configurazione di Logstash sopra:
-
Nella configurazione di Logstash sopra, utilizziamo vari filtri come
grok
,date
,kv
Emutate
per abbinare e modificare i registri in arrivo. Regola in base alle tue esigenze. -
In entrambi
kibana.j2
Elogstash.j2
per “Elasticsearch.hosts”, è possibile specificare tutti i nodi di dati come elenco, consentendo che le richieste siano distribuite round-robin su di esse. In alternativa, configurare un bilanciamento del carico interno con nodi di dati come backend e fornire solo l’IP del bilanciamento del carico. -
Assicurarsi che il
index
Elogstash_writer
Gli utenti vengono creati tramite la console Kibana. Inoltre, configurare gli indici necessari per ingerire dati da altre fonti come FileBeat e assegnare le autorizzazioni adeguate ai rispettivi utenti. -
I dati possono essere ingeriti in Elasticsearch tramite Logstash, consentendo il filtro necessario, oppure possono essere inviati direttamente ai nodi di dati utilizzando agenti come FileBeat.
-
Se stai conservando uno dei precedenti
.j2
I file jinja in un repository git e contengono informazioni sensibili, crittografarli utilizzandoansible-vault
. Fare riferimento a Documentazione ansible Per saperne di più sull’usoansible-vault
.
Ecco la configurazione FileBeat se si desidera spedire i registri direttamente dalle applicazioni Docker. Puoi anche usarlo per spedire i registri da qualsiasi altra applicazione.
filebeat.conf
logging.json: true
logging.degree: information
logging.metrics.enabled: false
setup.kibana.host: ${KIBANA_HOST}
setup.ilm.enabled: true
output.elasticsearch:
hosts: ${ELASTIC_HOST}
indices:
- index: "audit-%{+yyyy.MM.dd}"
when.has_fields: ("_audit")
- index: "logs-%{+yyyy.MM.dd}"
when.has_fields: ("app", "env")
- index: "invalid-stream-%{+yyyy.MM.dd}"
when.has_fields: ("error.information", "error.message")
filebeat.autodiscover:
suppliers:
- sort: docker
templates:
- config:
- sort: container
paths:
- /var/lib/docker/containers/${information.docker.container.id}/*.log
processors:
- decode_json_fields:
fields: ("message")
process_array: false
max_depth: 1
goal: ""
overwrite_keys: false
add_error_key: true
Una volta impostato ELK, è possibile configurare backup di dati chiamati snapshot nel bucket GCS ‘elastic-backup’ tramite la console kibana.
Conclusione
Con i dati ingeriti da varie fonti, come FileBeat, nel cluster di Elasticsearch, è possibile accedere all’interfaccia utente di Kibana per i registri di ricerca (Figura 2), creare visualizzazioni, monitorare i registri e impostare gli avvisi in modo efficace.
Installando e configurando lo stack Open-Supply ELK, è possibile ridurre significativamente i costi di licenza, pagando solo per l’infrastruttura GCP utilizzata. Terraform e Ansible Automation ti aiutano a salire e funzionare rapidamente, consentendo un facile ridimensionamento con il minimo sforzo.
Buona fortuna! Sentiti libero di connetterti con me LinkedIn.