Tag: ELK

  • ELK-стек для чого?

    ELK-стек для чого?

    В цій статті ви знайдете інформацію щодо ELK-стеку (Elasticsearch, Logstash, Kibana).
    Ця добірка фактично стала стандартом для централізованого збереження та аналізу логів.
    Але насправді це значно потужніший інструмент, аніж деякі його представляють. Розберімося що до чого.

    Elasticsearch – це пошукова система, яка є спадкоємиця проєкту Compass, який своєю чергою побудований на базі Apache Lucene.
    Першочергова ціль була: спрощення масштабування системи. Забігаючи наперед скажу що це дійсно вийшло.
    Зараз позиціонується як розподілений, масштабуємий, RESTful пошуковий та аналітичний механізм.
    Який дозволяє побудувати не тільки систему аналізу логів, а і повноцінний повнотекстовий пошук для сайту, або бізнес орієнтовану аналітичну систему.
    Пошукові індекси у складі багатоНОДової системи, легко масштабуються, балансування підтримується “із коробки”, та не потребує додаткової складної конфігурації.
    Починаючи із версії 5.1.1 має підтримку аналізу української мови, що стане в нагоді для побудови повнотекстового пошуку, наприклад у інтернет-магазині.

    Logstash – це система обробки збору та обробки даних для подальшого збереження цих даних, наприклад в Elasticsearch.
    Та за допомогою багатьох плагінів, дозволяє зберігати данні у різні системи, наприклад: AWS CloudWatch, DataDogHQ, Google BigQuery, Graphite, InfluxDB.
    Повний список можна подивитись: https://www.elastic.co/guide/en/logstash/current/output-plugins.html
    “Із коробки” підтримує збір та парсинг типових системних логів Linux, Nginx, MySQL, Redis.
    Повний модулів можна подивитись: https://www.elastic.co/guide/en/beats/filebeat/current/filebeat-modules.html
    Також за допомогою плагіну Grok, можливо описати фільтри специфічних для проєкту логів, парсити їх та зберігати до Elasticsearch.
    Парсинг специфічних логів це окрема тема, яку я додам трошки пізніше.

    Kibana – система візуалізації та аналізу даних збережених в Elasticsearch. З коробки має налаштовані інтерфейси для візуалізації логів Linux, Nginx, MySQL, Redis.
    Що дозволяє у дуже короткий час отримати готову систему аналізу логів, типової конфігурації, наприклад LAMP(Linux, Apache2, MySQL, PHP).
    Також за допомогою вбудованих інструментів дозволяє побудувати свій інтерфейс, будувати графіки та таблиці.
    Має два типи можливих видів побудови запитів: Kibana Query Language(KQL) та Lucene query syntax(LQS).
    Насправді KQL використовується виключно для фільтрації даних, та не несе ролі агрегації та сортування. Не вміє працювати із регулярними виразами, або нечіткими запитами.
    Для таких цілей необхідно використовувати Lucene query, але він не підтримує автозаповнення.
    Kibana із вебінтерфейсу також дозволяє описати та сконфігурувати індекси у самому Elasticsearch: описати типи полів, життєвий цикл, кількість реплік.

    Яка практична цінність цієї системи?
    Як ми бачимо кожен з окремо взятих інструментів може жити своїм життям навіть поза ELK-стеком.
    Тому якщо нам необхідно побудувати повнотекстовий пошук: Гнучкість пошукових фільтрів, включаючи нечіткий пошук та мультиарендність, коли в рамках одного об’єкта Elasticsearch дозволяє динамічно організувати декілька різних пошукових систем.

    Або у BigData проєктах – автоматична індексація нових JSON-об’єктів, які завантажуються в базу та одразу стають доступними для пошуку, за рахунок відсутності схеми згідно з типовою NoSQL-концепцією. Це дозволяє прискорити прототипування пошукових рішень Big Data.

    Наявність вбудованих аналізаторів тексту дозволяє Elasticsearch автоматично виконувати токенізацію, лематизацію, стемінг та інші перетворення для вирішення NLP-завдань, пов’язаних з пошуком даних.


    Але ми тут розглядаємо саме ELK-стек, тому основна цінність цієї системи, це збір, візуалізація та пошук по логам, який можливо побудувати при незначних витратах часу.

    Як почати використовувати?
    Тут є декілька варіантів, або із використанням репозиторію, або за допомогою контейнерів Docker.
    Хоча розглянемо обидва варіанти, я не буду розписувати покроково, процес встановлення він дуже простий. Тому одразу дам Bash-скрипт:

    #!/bin/bash
    wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo gpg --dearmor -o /usr/share/keyrings/elasticsearch-keyring.gpg
    sudo apt-get install apt-transport-https
    echo "deb [signed-by=/usr/share/keyrings/elasticsearch-keyring.gpg] https://artifacts.elastic.co/packages/8.x/apt stable main" | sudo tee /etc/apt/sources.list.d/elastic-8.x.list
    sudo apt-get update && sudo apt-get install elasticsearch logstash kibana
    # secure http connect to services 9200 - elastic search, 5601 - kibana port, 5044 - logstash
    iptables -I INPUT ! -s 127.0.0.1/32 -p tcp -m tcp --dport 9200 -j ACCEPT
    iptables -I INPUT ! -s 127.0.0.1/32 -p tcp -m tcp --dport 5601 -j ACCEPT
    iptables -I INPUT ! -s 127.0.0.1/32 -p tcp -m tcp --dport 5044 -j ACCEPT
    
    #Enable services
    sudo systemctl enable elasticsearch && sudo systemctl start elasticsearch
    sudo systemctl enable logstash && sudo systemctl start logstash
    sudo systemctl enable kibana && sudo systemctl start kibana
    
    
    ## Echo key for add kibana to elasticstack
    echo "YOUR KEY FOR ENROLLMENT:"
    /usr/share/elasticsearch/bin/elasticsearch-create-enrollment-token -s kibana --url "https://localhost:9200"

    Таким чином ми отримаємо однонодову інсталяцію ELK-стеку, у базовій комплектації готову для роботи.

    Або мультинодовий кластер на Docker-compose, але тут треба буде мати встановлений Docker engine і docker-compose.

    У будь-якій директорії створюємо файли .env та docker-compose.yml
    Вміст файлу ./.env:

    STACK_VERSION=8.2.2
    ES_PORT=127.0.0.1:9200
    KIBANA_PORT=127.0.0.1:5601
    LOGSTASH_PORT=127.0.0.1:5044
    
    ELASTIC_PASSWORD=<set strong password>
    KIBANA_PASSWORD=<set strong password>

    та файлу docker-compose.yml:

    version: "2.2"
    services:
      setup:
        image: docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION}
        volumes:
          - certs:/usr/share/elasticsearch/config/certs
        user: "0"
        command: >
          bash -c '
            if [ x${ELASTIC_PASSWORD} == x ]; then
              echo "Set the ELASTIC_PASSWORD environment variable in the .env file";
              exit 1;
            elif [ x${KIBANA_PASSWORD} == x ]; then
              echo "Set the KIBANA_PASSWORD environment variable in the .env file";
              exit 1;
            fi;
            if [ ! -f config/certs/ca.zip ]; then
              echo "Creating CA";
              bin/elasticsearch-certutil ca --silent --pem -out config/certs/ca.zip;
              unzip config/certs/ca.zip -d config/certs;
            fi;
            if [ ! -f config/certs/certs.zip ]; then
              echo "Creating certs";
              echo -ne \
              "instances:\n"\
              "  - name: es01\n"\
              "    dns:\n"\
              "      - es01\n"\
              "      - localhost\n"\
              "    ip:\n"\
              "      - 127.0.0.1\n"\
              "  - name: es02\n"\
              "    dns:\n"\
              "      - es02\n"\
              "      - localhost\n"\
              "    ip:\n"\
              "      - 127.0.0.1\n"\
              "  - name: es03\n"\
              "    dns:\n"\
              "      - es03\n"\
              "      - localhost\n"\
              "    ip:\n"\
              "      - 127.0.0.1\n"\
              > config/certs/instances.yml;
              bin/elasticsearch-certutil cert --silent --pem -out config/certs/certs.zip --in config/certs/instances.yml --ca-cert config/certs/ca/ca.crt --ca-key config/certs/ca/ca.key;
              unzip config/certs/certs.zip -d config/certs;
            fi;
            echo "Setting file permissions"
            chown -R root:root config/certs;
            find . -type d -exec chmod 750 \{\} \;;
            find . -type f -exec chmod 640 \{\} \;;
            echo "Waiting for Elasticsearch availability";
            until curl -s --cacert config/certs/ca/ca.crt https://es01:9200 | grep -q "missing authentication credentials"; do sleep 30; done;
            echo "Setting kibana_system password";
            until curl -s -X POST --cacert config/certs/ca/ca.crt -u elastic:${ELASTIC_PASSWORD} -H "Content-Type: application/json" https://es01:9200/_security/user/kibana_system/_password -d "{\"password\":\"${KIBANA_PASSWORD}\"}" | grep -q "^{}"; do sleep 10; done;
            echo "All done!";
          '
        healthcheck:
          test: ["CMD-SHELL", "[ -f config/certs/es01/es01.crt ]"]
          interval: 1s
          timeout: 5s
          retries: 120
    
      es01:
        depends_on:
          setup:
            condition: service_healthy
        image: docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION}
        volumes:
          - certs:/usr/share/elasticsearch/config/certs
          - esdata01:/usr/share/elasticsearch/data
        ports:
          - ${ES_PORT}:9200
        environment:
          - node.name=es01
          - cluster.name=${CLUSTER_NAME}
          - cluster.initial_master_nodes=es01,es02,es03
          - discovery.seed_hosts=es02,es03
          - ELASTIC_PASSWORD=${ELASTIC_PASSWORD}
          - bootstrap.memory_lock=true
          - xpack.security.enabled=true
          - xpack.security.http.ssl.enabled=true
          - xpack.security.http.ssl.key=certs/es01/es01.key
          - xpack.security.http.ssl.certificate=certs/es01/es01.crt
          - xpack.security.http.ssl.certificate_authorities=certs/ca/ca.crt
          - xpack.security.http.ssl.verification_mode=certificate
          - xpack.security.transport.ssl.enabled=true
          - xpack.security.transport.ssl.key=certs/es01/es01.key
          - xpack.security.transport.ssl.certificate=certs/es01/es01.crt
          - xpack.security.transport.ssl.certificate_authorities=certs/ca/ca.crt
          - xpack.security.transport.ssl.verification_mode=certificate
          - xpack.license.self_generated.type=${LICENSE}
        mem_limit: ${MEM_LIMIT}
        ulimits:
          memlock:
            soft: -1
            hard: -1
        healthcheck:
          test:
            [
              "CMD-SHELL",
              "curl -s --cacert config/certs/ca/ca.crt https://localhost:9200 | grep -q 'missing authentication credentials'",
            ]
          interval: 10s
          timeout: 10s
          retries: 120
    
      es02:
        depends_on:
          - es01
        image: docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION}
        volumes:
          - certs:/usr/share/elasticsearch/config/certs
          - esdata02:/usr/share/elasticsearch/data
        environment:
          - node.name=es02
          - cluster.name=${CLUSTER_NAME}
          - cluster.initial_master_nodes=es01,es02,es03
          - discovery.seed_hosts=es01,es03
          - bootstrap.memory_lock=true
          - xpack.security.enabled=true
          - xpack.security.http.ssl.enabled=true
          - xpack.security.http.ssl.key=certs/es02/es02.key
          - xpack.security.http.ssl.certificate=certs/es02/es02.crt
          - xpack.security.http.ssl.certificate_authorities=certs/ca/ca.crt
          - xpack.security.http.ssl.verification_mode=certificate
          - xpack.security.transport.ssl.enabled=true
          - xpack.security.transport.ssl.key=certs/es02/es02.key
          - xpack.security.transport.ssl.certificate=certs/es02/es02.crt
          - xpack.security.transport.ssl.certificate_authorities=certs/ca/ca.crt
          - xpack.security.transport.ssl.verification_mode=certificate
          - xpack.license.self_generated.type=${LICENSE}
        mem_limit: ${MEM_LIMIT}
        ulimits:
          memlock:
            soft: -1
            hard: -1
        healthcheck:
          test:
            [
              "CMD-SHELL",
              "curl -s --cacert config/certs/ca/ca.crt https://localhost:9200 | grep -q 'missing authentication credentials'",
            ]
          interval: 10s
          timeout: 10s
          retries: 120
    
      es03:
        depends_on:
          - es02
        image: docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION}
        volumes:
          - certs:/usr/share/elasticsearch/config/certs
          - esdata03:/usr/share/elasticsearch/data
        environment:
          - node.name=es03
          - cluster.name=${CLUSTER_NAME}
          - cluster.initial_master_nodes=es01,es02,es03
          - discovery.seed_hosts=es01,es02
          - bootstrap.memory_lock=true
          - xpack.security.enabled=true
          - xpack.security.http.ssl.enabled=true
          - xpack.security.http.ssl.key=certs/es03/es03.key
          - xpack.security.http.ssl.certificate=certs/es03/es03.crt
          - xpack.security.http.ssl.certificate_authorities=certs/ca/ca.crt
          - xpack.security.http.ssl.verification_mode=certificate
          - xpack.security.transport.ssl.enabled=true
          - xpack.security.transport.ssl.key=certs/es03/es03.key
          - xpack.security.transport.ssl.certificate=certs/es03/es03.crt
          - xpack.security.transport.ssl.certificate_authorities=certs/ca/ca.crt
          - xpack.security.transport.ssl.verification_mode=certificate
          - xpack.license.self_generated.type=${LICENSE}
        mem_limit: ${MEM_LIMIT}
        ulimits:
          memlock:
            soft: -1
            hard: -1
        healthcheck:
          test:
            [
              "CMD-SHELL",
              "curl -s --cacert config/certs/ca/ca.crt https://localhost:9200 | grep -q 'missing authentication credentials'",
            ]
          interval: 10s
          timeout: 10s
          retries: 120
    
      kibana:
        depends_on:
          es01:
            condition: service_healthy
          es02:
            condition: service_healthy
          es03:
            condition: service_healthy
        image: docker.elastic.co/kibana/kibana:${STACK_VERSION}
        volumes:
          - certs:/usr/share/kibana/config/certs
          - kibanadata:/usr/share/kibana/data
        ports:
          - ${KIBANA_PORT}:5601
        environment:
          - SERVERNAME=kibana
          - ELASTICSEARCH_HOSTS=https://es01:9200
          - ELASTICSEARCH_USERNAME=kibana_system
          - ELASTICSEARCH_PASSWORD=${KIBANA_PASSWORD}
          - ELASTICSEARCH_SSL_CERTIFICATEAUTHORITIES=config/certs/ca/ca.crt
        mem_limit: ${MEM_LIMIT}
        healthcheck:
          test:
            [
              "CMD-SHELL",
              "curl -s -I http://localhost:5601 | grep -q 'HTTP/1.1 302 Found'",
            ]
          interval: 10s
          timeout: 10s
          retries: 120
    
      logstash:
        image: docker.elastic.co/logstash/logstash:${STACK_VERSION}
        ports:
          - ${LOGSTASH_PORT}:5044
          - "5000:5000/tcp"
          - "5000:5000/udp"
          - "9600:9600"
        environment:
          LS_JAVA_OPTS: -Xms256m -Xmx256m
    	depends_on:
          es01:
            condition: service_healthy
          es02:
            condition: service_healthy
          es03:
            condition: service_healthy
    	
    volumes:
      certs:
        driver: local
      esdata01:
        driver: local
      esdata02:
        driver: local
      esdata03:
        driver: local
      kibanadata:
        driver: local

    І запустити для чого виконати команду:

    docker-compose up -d

    Після запуску кластера можна під’єднатися до Kibana http://localhost:5601
    використавши логін elastic та пароль зазначений в ELASTIC_PASSWORD

    Далі вже необхідно буде встановити збір логів із серверів. Якщо ми хочемо збирати стандартні логи, то для цього навіть не потрібен Logstash, замість нього достатньо встановити на сервері із якого необхідно збирати логи, Filebeat.


    Filebeat – це легкий агент для збору та надсилання файлів журналювання, який може відправляти данні, або напряму в Elasticsearch, або для подальшого опрацювання до Logstash.

    Для встановлення Filebeat необхідно виконати декілька дій на сервері із Elasticsearch та сервері із якого збираємо логи.
    На сервері звідки беремо логи:

    #!/bin/bash
    curl -L -O --output-dir /tmp https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-8.2.2-amd64.deb 
    sudo dpkg -i /tmp/filebeat-8.2.2-amd64.deb
    sudo rm /tmp/filebeat-8.2.2-amd64.deb
    filebeat modules enable nginx

    Після чого змінюємо конфігурацію модуля /etc/filebeat/modules.d/nginx.yml:

    - module: nginx
      access:
        enabled: true
        var.paths: ["/var/log/nginx/access.log*"]

    Необхідно створити юзера для запису, на сервері з Elasticsearch виконуємо:

    ./bin/elasticsearch-users useradd filebeat

    Вигадуємо пароль, та вводимо його, changeme!23

    Створюємо групу із достатніми правами для інсталяції згідно з офіційною документацією

    curl -k -u "elastic:<ELASTIC_PASSWORD>" -X PUT "https://localhost:9200/_security/role/filebeat_write?pretty" -H 'Content-Type: application/json' -d'
    {
      "cluster": [
        "monitor",
        "read_pipeline",
        "read_ilm",
        "manage"
      ],
      "indices": [
        {
          "names": [
            "filebeat-*"
          ],
          "privileges": [
            "create_doc",
            "view_index_metadata",
            "create_index"
          ]
        },
        {
          "names": [
            "filebeat-*",
            ".ds-filebeat-*"
          ],
          "privileges": [
            "manage",
            "manage_follow_index",
            "all"
          ]
        }
      ]
    }
    '

    Додаємо до груп:

    ./bin/elasticsearch-users roles filebeat -a kibana_admin
    ./bin/elasticsearch-users roles filebeat -a filebeat_writer

    У файлі конфігурації на сервері із Filebeat змінити рядки:

    output.elasticsearch:
      hosts: ["https://myEShost:9200"]
      username: "filebeat" 
      password: "changeme!23"
      
    setup.kibana:
        host: "myKIBANAhostIP:5601" 
        username: "filebeat"  
        password: "changeme!23"

    Причому у блоці із setup.kibana, юзер і пароль, опціональні, Якщо їх не вказати будуть використані із блоку output.elasticsearch.

    Після всіх підготовчих робіт виконуємо команду, яка створить робочі столи і візуалізації для вибраних модулів(в нашому випадку Nginx).

    filebeat setup -e

    Також хочу зазначити що група kibana_admin, необхідна одноразово для створення базових робочих столів із візуалізацією. Можна потім відізвати цю роль:

    ./bin/elasticsearch-users roles filebeat -r kibana_admin

    На цьому базова конфігурація закінчена і можна перейти до Kibana. Та подивитись логи Nginx.


    Додаткові сервери додаються так само, але вже без всіх цих маніпуляцій зі створенням групи й додаванням юзера до неї.
    Або із використанням Ansible розгорнути типові конфігурації Filebeat, на всіх необхідних серверах.

  • Що таке DevOps? Та як стати DevOps Інженером? ч.2

    Що таке DevOps? Та як стати DevOps Інженером? ч.2

    Продовжуємо першу частину статті “Що таке DevOps? Та як стати DevOps Інженером?“.

    Сьогодні більшість компаній перейшли від обслуговування своїх серверів до перенесення своєї інфраструктури до “хмари”.
    Що таке хмара?
    Хмара – це набір сервісів та серверів, які постачальник хмарних технологій здає в оренду замовнику.
    Ще називають Infrastructure as a Service(IaaS) – Інфраструктура як сервіс.
    Такий підхід дозволяє зменшити витрати на обслуговування інфраструктури, зменшити час на зміну конфігурації, вирішити проблеми зі зберіганням бекапів тощо.
    Існує багато різних постачальників хмарних рішень: Amazon Web Services(AWS), Azure, Google Cloud Provider(GCP), DigitalOcean.

    Всі вони мають безліч сервісів: такі як замовлення віртуального сервера, або специфічних, як сервіс черг.
    Безумовним лідером у хмарних технологіях є AWS, тому я рекомендую почати вивчення саме з нього. Станом на 2022 рік вони надають доступ до більш ніж 200+ сервісів.
    Але не лякайтесь на справді нема потреби знати всі ці сервіси, достатньо розумітися на декількох самих необхідних, наприклад: EC2, S3, RDS, EKS, CloudFront.

    Автоматизація

    Безумовно, спочатку, зайти до веб-консолі та запустити один два-три-десять віртуальних серверів, буде не складно.
    Але із часом така рутинна робота, почне напрягати та і де тут автоматизація?
    Тут нам на допомогу приходять різні системи автоматизації, такі як: Ansible, Puppet, Chef.
    Дуже легким у розумінні та обслуговуванні є:
    Ansible – це система яка дозволяє автоматизувати розгортання та обслуговування типових систем. За допомогою великої кількості готових модулів, та можливістю створювати свої.
    Також відмічу систему побудови інфраструктури:
    Terraform – ця система Infrastructure as a Code(IaC) дозволяє описати типову конфігурацію серверів у вигляді коду, які необхідно створити у хмарі, та у декілька команд, розгорнути готову інфраструктуру, або так само легко змінювати її конфігурацію.
    Має багато додаткових модулів, які покривають більшість наявних IaaS постачальників.

    Оркестрація

    Скоріш за все ви зіткнетеся із необхідністю розгортання великої кількості Docker контейнерів, тут вам знадобиться системи оркестрації контейнерів, наприклад: Kubernetes, Docker Swarm, Openshift Container Platform, Rancher та інші.
    Велика кількість проєктів використовує саме Kubernetes, як систему оркестрації. Тому рекомендую звернути увагу на нього у першу чергу.

    Логування

    Після того як ви описали та побудували свою інфраструктуру, особливо якщо вона досить велика, вам необхідно налаштувати централізований збір метрик систем та іх логування.
    Систем моніторингу також дуже багато. Скоріш за все, ви зустрінете на проектах: Zabbix, Nagios, Munin, тощо.
    Zabbix – це інструмент для моніторингу ІТ-інфраструктури, такої як мережі, сервери, віртуальні машини та хмарні сервіси. Збирає та відображає основні показники системи.
    Останнім часом дуже популярним стає Prometheus та система візуалізації метрик Grafana.
    Велике значення у концепції DevOps має логування. Необхідно зберігати як системі логи, так і логи аплікейшену(ПЗ). Особливо це важко стає коли у вас десятки серверів.
    Тут на допомогу приходять системи централізованого збору та агрегації логів: ELK, Graylog, Sentry.
    ELK-stack – це абревіатура трьох популярних сервісів, системи повнотекстового пошуку ElasticSearch, системи збору логів Logstash, та Kibana системи візуалізації та аналізу даних.
    Ця підбірка систем, дозволяє збирати та аналізувати велику кількість логів систем. Та із деякими маніпуляціями навіть специфічні до вашого проєкту логи.

    Скриптинг

    І останнім по рахунку, але не останнім по важливості, знанням для DevOps інженеру – є вміння писати скрипти. Тому треба звернути увагу на BASH скриптинг, знати на непоганому рівні Python, або із нещодавнього Golang.

    Контроль версій

    Також хочу звернути вашу увагу, на те що більшість інструментів що я згадав, мають у своїй основі: конфігураційні файли, файли опису інфраструктури.
    Ці файли, або вихідні коди ПЗ, зберігаються у системі контролю версій, самий популярний наразі – це Git.
    Систем управління контролем версій також багато: Bitbucket, GitHub, GitLab. Вони всі працюють однаково, але більшість open-source проектів використовують GitHub.

    Післямова

    Дуже багато систем і інструментів у кожному із напрямків і це здається дуже важким, як це все знати та пам’ятати. Не лякайтесь, достатньо знати хоча б один із представлених, щоб розуміти як це працює.
    Ці знання дадуть вам змогу претендувати на позицію Junior DevOps.
    Беззаперечно, вся ця інформація хоч і має на своїй меті огляд всіх можливих варіантів, але я міг щось забути. Якщо ви помітили неточність, будь ласка напишіть коментар – я обов’язково виправлю.

    В цілому ця стаття початок великої подорожі, я буду додавати більш поглибленный огляд на кожний інструмент, перевіряйте блог.
    Дякую за ваш час.