One place for hosting & domains

      комплекс

      Установка Elasticsearch, Logstash и Kibana (комплекс Elastic) в Ubuntu 18.04


      Автор выбрал Internet Archive для получения пожертвования в рамках программы Write for DOnations.

      Введение

      Комплекс Elastic Stack (прежнее название — комплекс ELK) представляет собой набор программного обеспечения Elastic с открытым исходным кодом, обеспечивающий возможности поиска, анализа и визуализации журналов, сгенерированных любым источником в любом формате (централизованное ведение журнала). Централизованное ведение журнала очень полезно для выявления проблем с серверами или приложениями, поскольку обеспечивает возможности поиска всех журнальных записей в одном месте. Также данная возможность позволяет выявлять проблемы, распространяющиеся на несколько серверов, посредством сопоставления их журналов за определенный период времени.

      Комплекс Elastic Stack имеет четыре основных компонента:

      • Elasticsearch: распределенная поисковая система RESTful, которая сохраняет все собранные данные.
      • Logstash: элемент обработки данных комплекса Elastic, отправляющий входящие данные в Elasticsearch.
      • Kibana: веб-интерфейс для поиска и визуализации журналов.
      • Beats: компактные элементы переноса данных одиночного назначения, которые могут отправлять данные с сотен или тысяч компютеров в Logstash или Elasticsearch.

      В этом обучающем модуле вы научитесь устанавливать Elastic Stack на сервере Ubuntu 18.04. Вы научитесь устанавливать все компоненты Elastic Stack, в том числе Filebeat, инструмент для перенаправления и централизации журналов и файлов, а также настраивать эти компоненты для сбора и визуализации системных журналов. Кроме того, поскольку компонент Kibana обычно доступен только через localhost, мы будем использовать Nginx в качестве прокси для обеспечения доступа через браузер. Мы установим все эти компоненты на одном сервере, который будем называть нашим сервером Elastic Stack.

      Примечание. При установке Elastic Stack необходимо использовать одну и ту же версию для всего комплекса. В этом обучающем модуле мы установим последние версии компонентов комплекса. На момент написания это Elasticsearch 6.4.3, Kibana 6.4.3, Logstash 6.4.3 и Filebeat 6.4.3.

      Предварительные требования

      Для этого обучающего модуля вам потребуется следующее:

      • Сервер Ubuntu 18.04, настроенный в соответствии с указаниями обучающего модуля «Начальная настройка сервера для Ubuntu 18.04», включая пользователя без привилегий root с привилегиями sudo и настроенный брандмауэр ufw. Требования сервера комплекса Elastic к ресурсам процессора, оперативной памяти и хранения данных зависят от объема журналов, который вы планируете собирать. В этом обучающем модуле мы будем использовать для нашего комплекса Elastic сервер VPS со следующими спецификациями:

        • ОС: Ubuntu 18.04
        • ОЗУ: 4 ГБ
        • ЦП: 2
      • На сервере должно быть установлено программное обеспечение Java 8, которое требуется для Elasticsearch и Logstash. Обратите внимание, что версия Java 9 не поддерживается. Для установки следуйте указаниям раздела «Установка Oracle JDK» нашего руководства по установке Java 8 в Ubuntu 18.04.

      • На сервере должен быть установлен Nginx, который мы позднее настроим как обратный прокси для Kibana. Для настройки следуйте указаниям нашего обучающего модуля «Установка Nginx в Ubuntu 18.04».

      Кроме того, поскольку комплекс Elastic используется для доступа ценной информации о вашем сервере, которую вам нужно защищать, очень важно обеспечить защиту сервера сертификатом TLS/SSL. Это необязательно, но настоятельно рекомендуется.

      Однако поскольку вы будете вносить изменения в серверный блок Nginx в ходе выполнения этого обучающего модуля, разумнее всего будет пройти обучающий модуль «Let’s Encrypt в Ubuntu 18.04» после прохождения второго шага настоящего обучающего модуля. Если вы планируете настроить на сервере Let’s Encrypt, вам потребуется следующее:

      • Полностью квалифицированное доменное имя (FQDN). В этом обучающем модуле мы будем использовать имя example.com. Вы можете купить доменное имя на Namecheap, получить его бесплатно на Freenom или воспользоваться услугами любого предпочитаемого регистратора доменных имен.
      • На вашем сервере должны быть настроены обе нижеследующие записи DNS. В руководстве «Введение в DigitalOcean DNS» содержится подробная информация по их добавлению.

        • Запись A, где example.com указывает на публичный IP-адрес вашего сервера.
        • Запись A, где www.example.com указывает на публичный IP-адрес вашего сервера.

      Шаг 1 — Установка и настройка Elasticsearch

      Компоненты комплекса Elastic отсутствуют в репозиториях пакетов Ubuntu по умолчанию. Однако их можно установить с помощью APT после добавления списка источников пакетов Elastic.

      Все пакеты комплекса Elastic подписаны ключом подписи Elasticsearch для защиты вашей системы от поддельных пакетов. Ваш диспетчер пакетов будет считать надежными пакеты, для которых проведена аутентификация с помощью ключа. На этом шаге вы импортируете открытый ключ Elasticsearch GPG и добавить список источников пакетов Elastic для установки Elasticsearch.

      Для начала запустите следующую команду для импорта открытого ключа Elasticsearch GPG в APT:

      • wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add -

      Затем добавьте список источников Elastic в каталог sources.list.d, где APT будет искать новые источники:

      • echo "deb https://artifacts.elastic.co/packages/6.x/apt stable main" | sudo tee -a /etc/apt/sources.list.d/elastic-6.x.list

      Затем обновите списки пакетов, чтобы APT мог прочитать новый источник Elastic:

      Установите Elasticsearch с помощью следующей команды:

      • sudo apt install elasticsearch

      После завершения установки Elasticsearch используйте предпочитаемый текстовый редактор для редактирования главного файла конфигурации Elasticsearch с именем elasticsearch.yml. Мы будем использовать nano:

      • sudo nano /etc/elasticsearch/elasticsearch.yml

      Примечание. Файл конфигурации Elasticsearch имеет формат YAML, и это значит, что отступы имеют большое значение! Не добавляйте никакие дополнительные пробелы при редактировании этого файла.

      Elasticsearch прослушивает весь трафик порта 9200. Вы можете захотеть ограничить внешний доступ к вашему экземпляру Elasticsearch, чтобы посторонние не могли читать ваши данные или отключать ваш кластер Elasticsearch через REST API. Найдите строку с указанием network.host, уберите с нее значок комментария и замените значение на localhost, чтобы она выглядела следующим образом:

      /etc/elasticsearch/elasticsearch.yml

      . . .
      network.host: localhost
      . . .
      

      Сохраните и закройте файл elasticsearch.yml, нажав CTRL+X, а затем Y и ENTER, если вы используете nano. Затем запустите службу Elasticsearch с помощью systemctl:

      • sudo systemctl start elasticsearch

      Затем запустите следующую команду, чтобы активировать Elasticsearch при каждой загрузке сервера:

      • sudo systemctl enable elasticsearch

      Вы можете протестировать работу службы Elasticsearch, отправив запрос HTTP:

      • curl -X GET "localhost:9200"

      Вы получите ответ, содержащий базовую информацию о локальном узле:

      Output

      { "name" : "ZlJ0k2h", "cluster_name" : "elasticsearch", "cluster_uuid" : "beJf9oPSTbecP7_i8pRVCw", "version" : { "number" : "6.4.2", "build_flavor" : "default", "build_type" : "deb", "build_hash" : "04711c2", "build_date" : "2018-09-26T13:34:09.098244Z", "build_snapshot" : false, "lucene_version" : "7.4.0", "minimum_wire_compatibility_version" : "5.6.0", "minimum_index_compatibility_version" : "5.0.0" }, "tagline" : "You Know, for Search" }

      Мы настроили и запустили Elasticsearch, и теперь можем перейти к установке Kibana, следующего компонента комплекса Elastic.

      Шаг 2 — Установка и настройка информационной панели Kibana

      Согласно официальной документации, Kibana следует устанавливать только после установки Elasticsearch. Установка в этом порядке обеспечивает правильность установки зависимостей компонентов.

      Поскольку вы уже добавили источник пакетов Elastic на предыдущем шаге, вы можете просто установить все остальные компоненты комплекса Elastic с помощью apt:

      Затем активируйте и запустите службу Kibana:

      • sudo systemctl enable kibana
      • sudo systemctl start kibana

      Поскольку согласно настройкам Kibana прослушивает только localhost, мы должны задать обратный прокси, чтобы разрешить внешний доступ. Для этого мы используем Nginx, который должен быть уже установлен на вашем сервере.

      Вначале нужно использовать команду openssl для создания административного пользователя Kibana, которого вы будете использовать для доступа к веб-интерфейсу Kibana. Для примера мы назовем эту учетную запись kibanaadmin, однако для большей безопасности мы рекомендуем выбрать нестандартное имя пользователя, которое будет сложно угадать.

      Следующая команда создаст административного пользователя Kibana и пароль и сохранит их в файле htpasswd.users. Вы настроите Nginx для использования этого имени пользователя и пароля и моментально прочитаете этот файл:

      • echo "kibanaadmin:`openssl passwd -apr1`" | sudo tee -a /etc/nginx/htpasswd.users

      Введите и подтвердить пароль в диалоговом окне. Запомните или запишите эти учетные данные, поскольку они вам потребуются для доступа к веб-интерфейсу Kibana.

      Теперь мы создадим файл серверного блока Nginx. В качестве примера мы присвоим этому файлу имя example.com, хотя вы можете дать ему более описательное имя. Например, если вы настроили записи FQDN и DNS для этого сервера, вы можете присвоить этому файлу имя FQDN:

      • sudo nano /etc/nginx/sites-available/example.com

      Добавьте в файл следующий блок кода, заменив example.com для соответствия FQDN или публичному IP-адресу вашего сервера. Этот код настраивает Nginx для перенаправления трафика HTTP вашего сервера в приложение Kibana, которое прослушивает порт localhost:5601. Также он настраивает Nginx для чтения файла htpasswd.users и требует использования базовой аутентификации.

      Если вы выполнили предварительный обучающий модуль по Nginx до конца, возможно вы уже создали этот файл и заполнили его. В этом случае удалите из файла все содержание и добавьте следующее:

      /etc/nginx/sites-available/example.com

      server {
          listen 80;
      
          server_name example.com;
      
          auth_basic "Restricted Access";
          auth_basic_user_file /etc/nginx/htpasswd.users;
      
          location / {
              proxy_pass http://localhost:5601;
              proxy_http_version 1.1;
              proxy_set_header Upgrade $http_upgrade;
              proxy_set_header Connection 'upgrade';
              proxy_set_header Host $host;
              proxy_cache_bypass $http_upgrade;
          }
      }
      

      Завершив редактирование, сохраните и закройте файл.

      Затем активируйте новую конфигурацию, создав символическую ссылку на каталог sites-enabled. Если вы уже создали файл серверного блока с тем же именем, что и в обучающем модуле по Nginx, вам не нужно выполнять эту команду:

      • sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/example.com

      Затем проверьте конфигурацию на синтаксические ошибки:

      Если в результатах будут показаны какие-либо ошибки, вернитесь и еще раз проверьте правильность изменений в файле конфигурации. Когда вы увидите на экране результатов сообщение syntax is ok, перезапустите службу Nginx:

      • sudo systemctl restart nginx

      Если вы следовали указаниям модуля по начальной настройке сервера, у вас должен быть включен брандмауэр UFW. Чтобы разрешить соединения с Nginx, мы можем изменить правила с помощью следующей команды:

      • sudo ufw allow 'Nginx Full'

      Примечание. Если вы выполнили предварительный обучающий модуль Nginx, вы могли уже создать правило UFW, разрешающее профилю Nginx HTTP доступ через брандмауэр. Поскольку профиль Nginx Full разрешает трафик HTTP и HTTPS на брандмауэре, вы можете безопасно удалить ранее созданное правило. Для этого нужно использовать следующую команду:

      • sudo ufw delete allow 'Nginx HTTP'

      Теперь приложение Kibana доступно через FQDN или публичный IP-адрес вашего сервера комплекса Elastic. Вы можете посмотреть страницу состояния сервера Kibana, открыв следующий адрес и введя свои учетные данные в диалоге:

      http://your_server_ip/status
      

      На этой странице состояния отображается информация об использовании ресурсов сервера, а также выводится список установленных плагинов.

      |Страница состояния Kibana

      Примечание. Как указывалось в разделе предварительных требований, рекомендуется включить на сервере SSL/TLS. Вы можете следовать указаниям этого модуля, чтобы получить бесплатный сертификат SSL для Nginx в Ubuntu 18.04. После получения сертификата SSL/TLS вы можете вернуться и завершить прохождение этого обучающего модуля.

      Теперь информационная панель Kibana настроена и мы перейдем к установке следующего компонента: Logstash.

      Шаг 3 — Установка и настройка Logstash

      Хотя Beats может отправлять данные напрямую в базу данных Elasticsearch, мы рекомендуем использовать для обработки данных Logstash. Это позволит вам собирать данные из разных источников, преобразовывать их в общий формат и экспортировать в другую базу данных.

      Установите Logstash с помощью следующей команды:

      • sudo apt install logstash

      После установки Logstash вы можете перейти к настройке. Файлы конфгурации Logstash имеют формат JSON и находятся в каталоге /etc/logstash/conf.d. При настройке полезно представлять Logstash как конвейер, который принимает данные с одной стороны, обрабатывает их и отправляет в пункт назначения (в данном случае в Elasticsearch). Конвейер Logstash имеет два обязательных элемента, input и output, а также необязательный элемент filter. Плагины ввода потребляют данные источника, плагины фильтра обрабатывают данные, а плагины вывода записывают данные в пункт назначения.

      Конвейер Logstash

      Создайте файл конфигурации с именем 02-beats-input.conf, где вы настроите ввод данных Filebeat:

      • sudo nano /etc/logstash/conf.d/02-beats-input.conf

      Вставьте следующую конфигурацию input. В ней задается ввод beats, который прослушивает порт TCP 5044.

      /etc/logstash/conf.d/02-beats-input.conf

      input {
        beats {
          port => 5044
        }
      }
      

      Сохраните и закройте файл. Затем создайте файл конфигурации с именем 10-syslog-filter.conf, куда мы добавим фильтр для системных журналов или syslogs:

      • sudo nano /etc/logstash/conf.d/10-syslog-filter.conf

      Вставьте следующую конфигурацию фильтра syslog. В этом примере конфигурация системных журналов взята из официальной документации по Elastic. Этот фильтр используется для синтаксического анализа входящих системных журналов, их структуризации и преобразования в удобный для использования вид с помощью панелей Kibana:

      /etc/logstash/conf.d/10-syslog-filter.conf

      filter {
        if [fileset][module] == "system" {
          if [fileset][name] == "auth" {
            grok {
              match => { "message" => ["%{SYSLOGTIMESTAMP:[system][auth][timestamp]} %{SYSLOGHOST:[system][auth][hostname]} sshd(?:[%{POSINT:[system][auth][pid]}])?: %{DATA:[system][auth][ssh][event]} %{DATA:[system][auth][ssh][method]} for (invalid user )?%{DATA:[system][auth][user]} from %{IPORHOST:[system][auth][ssh][ip]} port %{NUMBER:[system][auth][ssh][port]} ssh2(: %{GREEDYDATA:[system][auth][ssh][signature]})?",
                        "%{SYSLOGTIMESTAMP:[system][auth][timestamp]} %{SYSLOGHOST:[system][auth][hostname]} sshd(?:[%{POSINT:[system][auth][pid]}])?: %{DATA:[system][auth][ssh][event]} user %{DATA:[system][auth][user]} from %{IPORHOST:[system][auth][ssh][ip]}",
                        "%{SYSLOGTIMESTAMP:[system][auth][timestamp]} %{SYSLOGHOST:[system][auth][hostname]} sshd(?:[%{POSINT:[system][auth][pid]}])?: Did not receive identification string from %{IPORHOST:[system][auth][ssh][dropped_ip]}",
                        "%{SYSLOGTIMESTAMP:[system][auth][timestamp]} %{SYSLOGHOST:[system][auth][hostname]} sudo(?:[%{POSINT:[system][auth][pid]}])?: s*%{DATA:[system][auth][user]} :( %{DATA:[system][auth][sudo][error]} ;)? TTY=%{DATA:[system][auth][sudo][tty]} ; PWD=%{DATA:[system][auth][sudo][pwd]} ; USER=%{DATA:[system][auth][sudo][user]} ; COMMAND=%{GREEDYDATA:[system][auth][sudo][command]}",
                        "%{SYSLOGTIMESTAMP:[system][auth][timestamp]} %{SYSLOGHOST:[system][auth][hostname]} groupadd(?:[%{POSINT:[system][auth][pid]}])?: new group: name=%{DATA:system.auth.groupadd.name}, GID=%{NUMBER:system.auth.groupadd.gid}",
                        "%{SYSLOGTIMESTAMP:[system][auth][timestamp]} %{SYSLOGHOST:[system][auth][hostname]} useradd(?:[%{POSINT:[system][auth][pid]}])?: new user: name=%{DATA:[system][auth][user][add][name]}, UID=%{NUMBER:[system][auth][user][add][uid]}, GID=%{NUMBER:[system][auth][user][add][gid]}, home=%{DATA:[system][auth][user][add][home]}, shell=%{DATA:[system][auth][user][add][shell]}$",
                        "%{SYSLOGTIMESTAMP:[system][auth][timestamp]} %{SYSLOGHOST:[system][auth][hostname]} %{DATA:[system][auth][program]}(?:[%{POSINT:[system][auth][pid]}])?: %{GREEDYMULTILINE:[system][auth][message]}"] }
              pattern_definitions => {
                "GREEDYMULTILINE"=> "(.|n)*"
              }
              remove_field => "message"
            }
            date {
              match => [ "[system][auth][timestamp]", "MMM  d HH:mm:ss", "MMM dd HH:mm:ss" ]
            }
            geoip {
              source => "[system][auth][ssh][ip]"
              target => "[system][auth][ssh][geoip]"
            }
          }
          else if [fileset][name] == "syslog" {
            grok {
              match => { "message" => ["%{SYSLOGTIMESTAMP:[system][syslog][timestamp]} %{SYSLOGHOST:[system][syslog][hostname]} %{DATA:[system][syslog][program]}(?:[%{POSINT:[system][syslog][pid]}])?: %{GREEDYMULTILINE:[system][syslog][message]}"] }
              pattern_definitions => { "GREEDYMULTILINE" => "(.|n)*" }
              remove_field => "message"
            }
            date {
              match => [ "[system][syslog][timestamp]", "MMM  d HH:mm:ss", "MMM dd HH:mm:ss" ]
            }
          }
        }
      }
      

      Сохраните и закройте файл после завершения.

      Наконец, создайте файл конфигурации 30-elasticsearch-output.conf:

      • sudo nano /etc/logstash/conf.d/30-elasticsearch-output.conf

      Вставьте следующую конфигурацию output. Этот вывод настраивает Logstash для хранения данных Beats в Elasticsearch, запущенном на порту localhost:9200, в индексе с названием используемого компонента Beat. В этом обучающем модуле используется компонент Beat под названием Filebeat:

      /etc/logstash/conf.d/30-elasticsearch-output.conf

      output {
        elasticsearch {
          hosts => ["localhost:9200"]
          manage_template => false
          index => "%{[@metadata][beat]}-%{[@metadata][version]}-%{+YYYY.MM.dd}"
        }
      }
      

      Сохраните и закройте файл.

      Если вы you хотите добавить фильтры для других приложений, использующих ввод Filebeat, присваивайте файлам имена, чтобы их можно было сортировать между конфигурациями ввода и вывода. Это значит, что имена файлов должны начинаться с двузначных чисел от 02 до 30.

      Протестируйте свою конфигурацию Logstash с помощью следующей команды:

      • sudo -u logstash /usr/share/logstash/bin/logstash --path.settings /etc/logstash -t

      Если ошибок синтаксиса нет, вы увидите сообщение Configuration OK спустя несколько секунд. Если вы не увидите этого сообщения, проверьте ошибки вывода и обновите конфигурацию для их исправления.

      Если тестирование конфигурации выполнено успешно, запустите и активируйте Logstash, чтобы изменения конфигурации вступили в силу:

      • sudo systemctl start logstash
      • sudo systemctl enable logstash

      Теперь Logstash работает нормально и полностью настроен, и мы можем перейти к установке Filebeat.

      Шаг 4 — Установка и настройка Filebeat

      Комплекс Elastic Stack использует несколько компактных элементов транспортировки данных (Beats) для сбора данных из различных источников и их транспортировки в Logstash или Elasticsearch. Ниже перечислены компоненты Beats, доступные в Elastic:

      • Filebeat: собирает и отправляет файлы журнала.
      • Metricbeat: собирает метрические показатели использования систем и служб.
      • Packetbeat: собирает и анализирует данные сети.
      • Winlogbeat: собирает данные журналов событий Windows.
      • Auditbeat: собирает данные аудита Linux и отслеживает целостность файлов.
      • Heartbeat: отслеживает доступность услуг посредством активного зондирования.

      В этом обучающем модуле мы используем Filebeat для перенаправления локальных журналов в комплекс Elastic Stack.

      Установите Filebeat с помощью apt:

      • sudo apt install filebeat

      Затем настройте Filebeat для подключения к Logstash. Здесь мы изменим образец файла конфигурации, входящий в комплектацию Filebeat.

      Откройте файл конфигурации Filebeat:

      • sudo nano /etc/filebeat/filebeat.yml

      Примечание. Как и в Elasticsearch, файл конфигурации Filebeat имеет формат YAML. Это означает, что в файле учитываются отступы, и вы должны использовать точно такое количество пробелов, как указано в этих инструкциях.

      Filebeat поддерживает разнообразные выводы, но обычно события отправляются только напрямую в Elasticsearch или в Logstash для дополнительной обработки. В этом обучающем модуле мы будем использовать Logstash для дополнительной обработки данных, собранных Filebeat. Filebeat не потребуется отправлять данные в Elasticsearch напрямую, поэтому мы отключим этот вывод. Для этого мы найдем раздел output.elasticsearch и поставим перед следующими строками значок комментария #:

      /etc/filebeat/filebeat.yml

      ...
      #output.elasticsearch:
        # Array of hosts to connect to.
        #hosts: ["localhost:9200"]
      ...
      

      Затем настроим раздел output.logstash. Уберите режим комментариев для строк output.logstash: и hosts: ["localhost:5044"], удалив значки #. Так мы настроим Filebeat для подключения к Logstash на сервере комплекса Elastic Stack через порт 5044, который мы ранее задали для ввода Logstash:

      /etc/filebeat/filebeat.yml

      output.logstash:
        # The Logstash hosts
        hosts: ["localhost:5044"]
      

      Сохраните и закройте файл.

      Функции Filebeat можно расширить с помощью модулей Filebeat. В этом обучающем модуле мы будем использовать модуль system, который собирает и проверяет данные журналов, созданных службой регистрации систем в распространенных дистрибутивах Linux.

      Давайте активируем его:

      • sudo filebeat modules enable system

      Вы увидите список включенных и отключенных модулей с помощью следующей команды:

      • sudo filebeat modules list

      Вы увидите примерно следующий список:

      Output

      Enabled: system Disabled: apache2 auditd elasticsearch icinga iis kafka kibana logstash mongodb mysql nginx osquery postgresql redis traefik

      Filebeat по умолчанию настроен для использования путей по умолчанию для системных журналов и журналов авторизации. Для целей данного обучающего модуля вам не нужно ничего изменять в конфигурации. Вы можете посмотреть параметры модуля в файле конфигурации /etc/filebeat/modules.d/system.yml.

      Затем загрузите в Elasticsearch шаблон индекса. Индекс Elasticsearch — это коллекция документов со сходными характеристиками. Индексы идентифицируются по имени, которое используется для ссылки на индекс при выполнении различных операций внутри него. Шаблон индекса применяется автоматически при создании нового индекса.

      Используйте следующую команду для загрузки шаблона:

      • sudo filebeat setup --template -E output.logstash.enabled=false -E 'output.elasticsearch.hosts=["localhost:9200"]'

      Output

      Loaded index template

      В комплект Filebeat входят образцы информационных панелей Kibana, позволяющие визуализировать данные Filebeat в Kibana. Прежде чем вы сможете использовать информационные панели, вам нужно создать шаблон индекса и загрузить информационные панели в Kibana.

      При загрузке информационных панелей Filebeat подключается к Elasticsearch для проверки информации о версиях. Для загрузки информационных панелей при включенном Logstash необходимо отключить вывод Logstash и активировать вывод Elasticsearch:

      • sudo filebeat setup -e -E output.logstash.enabled=false -E output.elasticsearch.hosts=['localhost:9200'] -E setup.kibana.host=localhost:5601

      Вы получите следующий результат:

      Output

      2018-09-10T08:39:15.844Z INFO instance/beat.go:273 Setup Beat: filebeat; Version: 6.4.2 2018-09-10T08:39:15.845Z INFO elasticsearch/client.go:163 Elasticsearch url: http://localhost:9200 2018-09-10T08:39:15.845Z INFO pipeline/module.go:98 Beat name: elk 2018-09-10T08:39:15.845Z INFO elasticsearch/client.go:163 Elasticsearch url: http://localhost:9200 2018-09-10T08:39:15.849Z INFO elasticsearch/client.go:708 Connected to Elasticsearch version 6.4.2 2018-09-10T08:39:15.856Z INFO template/load.go:129 Template already exists and will not be overwritten. Loaded index template Loading dashboards (Kibana must be running and reachable) 2018-09-10T08:39:15.857Z INFO elasticsearch/client.go:163 Elasticsearch url: http://localhost:9200 2018-09-10T08:39:15.865Z INFO elasticsearch/client.go:708 Connected to Elasticsearch version 6.4.2 2018-09-10T08:39:15.865Z INFO kibana/client.go:113 Kibana url: http://localhost:5601 2018-09-10T08:39:45.357Z INFO instance/beat.go:659 Kibana dashboards successfully loaded. Loaded dashboards 2018-09-10T08:39:45.358Z INFO elasticsearch/client.go:163 Elasticsearch url: http://localhost:9200 2018-09-10T08:39:45.361Z INFO elasticsearch/client.go:708 Connected to Elasticsearch version 6.4.2 2018-09-10T08:39:45.361Z INFO kibana/client.go:113 Kibana url: http://localhost:5601 2018-09-10T08:39:45.455Z WARN fileset/modules.go:388 X-Pack Machine Learning is not enabled Loaded machine learning job configurations

      Теперь вы можете запустить и активировать Filebeat:

      • sudo systemctl start filebeat
      • sudo systemctl enable filebeat

      Если вы правильно настроили комплекс Elastic, Filebeat начнет отправлять системный журнал и журналы авторизации в Logstash, откуда эти данные будут загружаться в Elasticsearch.

      Чтобы подтвердить получение этих данных в Elasticsearch необходимот отправить в индекс Filebeat запрос с помощью следующей команды:

      • curl -XGET 'http://localhost:9200/filebeat-*/_search?pretty'

      Вы увидите примерно следующий результат:

      Output

      ... { "took" : 32, "timed_out" : false, "_shards" : { "total" : 3, "successful" : 3, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : 1641, "max_score" : 1.0, "hits" : [ { "_index" : "filebeat-6.4.2-2018.10.10", "_type" : "doc", "_id" : "H_bZ62UBB4D0uxFRu_h3", "_score" : 1.0, "_source" : { "@version" : "1", "message" : "Oct 10 06:22:36 elk systemd[1]: Reached target Local File Systems (Pre).", "@timestamp" : "2018-10-10T08:43:56.969Z", "host" : { "name" : "elk" }, "source" : "/var/log/syslog", "input" : { "type" : "log" }, "tags" : [ "beats_input_codec_plain_applied" ], "offset" : 296, "prospector" : { "type" : "log" }, "beat" : { "version" : "6.4.2", "hostname" : "elk", "name" : "elk" } } }, ...

      Если в результатах показано 0 совпадений, Elasticsearch не выполняет загрузку журналов в индекс, который вы искали, и вам нужно проверить настройки на ошибки. Если вы получили ожидаемые результаты, перейдите к следующему шагу, где мы увидим, как выполняется навигация по информационным панелям Kibana.

      Шаг 5 — Изучение информационных панелей Kibana

      Давайте получше познакомимся с веб-интерфейсом Kibana, который мы установили на одном из предыдущих шагов.

      Откройте в браузере FQDN или публичный IP-адрес вашего сервера Elastic Stack. После ввода учетных данных, заданных на шаге 2, вы увидите главную страницу Kibana:

      Главная страница Kibana

      Нажмите ссылку Discover в левой панели навигации для обзора интерфейса. Выберите на странице Discover заранее настроенный индекс filebeat- для просмотра данных Filebeat. По умолчанию при этом будут выведены все данные журналов за последние 15 минут. Ниже вы увидите гистограмму с событиями журнала и некоторыми сообщениями журнала:

      Страница Discover

      Здесь вы можете искать и просматривать журналы, а также настраивать информационные панели. Сейчас на этой странице будет немного данных, потому что вы собираете системные журналы только со своего сервера Elastic Stack.

      Используйте левую панель навигации для перехода на страницу Dashboard и выполните на этой странице поиск информационных панелей Filebeat System. На этой странице вы можете искать образцы информационных панелей, входящих в комплектацию модуля system в Filebeat.

      Например, вы можете просматривать подробную статистику по сообщениям системного журнала:

      Информационная панель Syslog

      Также вы сможете видеть, какие пользователи использовали команду sudo и когда:

      Информационная панель Sudo

      В Kibana имеется множество других функций, в том числе функции фильтрации и составления диаграмм, так что вы можете свободно их исследовать.

      Заключение

      В этом обучающем модуле вы научились устанавливать и настраивать комплекс Elastic Stack для сбора и анализа данных системных журналов. Помните, что вы можете отправлять в Logstash практически любые типы данных журнала и индексированных данных с помощью Beats, однако данные будут более полезны, если они будут проанализированы и структурированы с помощью фильтра Logstash, который преобразует данные в единый формат, легко читаемый Elasticsearch.



      Source link

      Как настроить комплекс регистрации данных Elasticsearch, Fluentd и Kibana (EFK) в Kubernetes


      Введение

      При запуске разнообразных служб и приложений в кластере Kubernetes централизованный комплекс регистрации данных кластерного уровня поможет быстро сортировать и анализировать большие объемы данных журналов подов. В числе популярных централизованных решений регистрации данных нельзя не назвать комплекс Elasticsearch, Fluentd, and Kibana (EFK).

      Elasticsearch — распределенный и масштабируемый механизм поиска в реальном времени, поддерживающий полнотекстовый и структурированный поиск, а также аналитику. Он обычно используется для индексации больших журналов и поиска в них данных, но также его можно использовать и для поиска во многих различных видах документов.

      Elasticsearch обычно развертывается вместе с Kibana, мощным интерфейсом визуализации данных, который выступает как панель управления Elasticsearch. Kibana позволяет просматривать данные журналов Elasticsearch через веб-интерфейс и создавать информационные панели и запросы для быстрого получения ответов на вопросы и аналитических данных по вашим приложениям Kubernetes.

      В этом обучающем модуле мы используем Fluentd для сбора данных журнала и их преобразования и отправки на сервер Elasticsearch. Fluentd — популярный сборщик данных с открытым исходным кодом, который мы настроим на узлах Kubernetes для отслеживания файлов журнала контейнеров, фильтрации и преобразования данных журнала и их доставки в кластер Elasticsearch, где они будут индексироваться и храниться.

      Для начала мы настроим и запустим масштабируемый кластер Elasticsearch, а затем создадим службу и развертывание Kibana в Kubernetes. В заключение мы настроим Fluentd как DaemonSet, который будет запускаться на каждом рабочем узле Kubernetes.

      Предварительные требования

      Прежде чем начать прохождение этого обучающего модуля, вам потребуется следующее:

      • Кластер Kubernetes 1.10+ с включенным контролем доступа на основе ролей (RBAC)

        • Убедитесь, что кластер имеет достаточно ресурсов для развертывания комплекса EFK. Если ресурсов недостаточно, добавьте в кластер еще рабочие узлы. Мы развернем кластер Elasticsearch с 3 подами (при необходимости вы можете масштабировать развертывание до 1 пода), а также один под Kibana. На каждом рабочем узле также будет запущен под Fluentd. Используемый в этом обучающем модуле кластер будет состоять из 3 рабочих узлов и управляемого уровня управления.
      • Инструмент командной строки kubectl, установленный на локальном компьютере и настроенный для подключения к вашему кластеру. Дополнительную информацию об установке kubectl можно найти в официальной документации.

      Проверив наличие этих компонентов, вы можете начинать прохождение этого обучающего модуля.

      Шаг 1 — Создание пространства имен

      Прежде чем разворачивать кластер Elasticsearch, мы создадим пространство имен, куда установим весь инструментарий ведения журналов. Kubernetes позволяет отделять объекты, работающие в кластере, с помощью виртуального абстрагирования кластеров через пространства имен. В этом обучающем модуле мы создадим пространство имен kube-logging, куда установим компоненты комплекса EFK. Это пространство имен также позволит нам быстро очищать и удалять комплекс журналов без потери функциональности кластера Kubernetes.

      Для начала исследуйте существующие пространства имен в вашем кластере с помощью команды kubectl:

      kubectl get namespaces
      

      Вы должны увидеть следующие три начальных пространства имен, которые предустанавливаются в кластерах Kubernetes:

      Output

      • NAME STATUS AGE
      • default Active 5m
      • kube-system Active 5m
      • kube-public Active 5m

      Пространство имен default содержит объекты, которые создаются без указания пространства имен. Пространство имен kube-system содержит объекты, созданные и используемые системой Kubernetes, в том числе kube-dns, kube-proxy и kubernetes-dashboard. Это пространство имен лучше регулярно очищать и не засорять его рабочими задачами приложений и инструментария.

      Пространство имен kube-public — это еще одно автоматически создаваемое пространство имен, которое можно использовать для хранения объектов, которые вы хотите сделать доступными и читаемыми во всем кластере, в том числе для пользователей, которые не прошли аутентификацию.

      Для создания пространства имен kube-logging откройте файл kube-logging.yaml в своем любимом текстовом редакторе, например nano:

      В редакторе вставьте следующий код YAML объекта пространства имен:

      kube-logging.yaml

      kind: Namespace
      apiVersion: v1
      metadata:
        name: kube-logging
      

      Затем сохраните и закройте файл.

      Здесь мы зададим kind объекта Kubernetes как объект Namespace. Чтобы узнать больше об объектах Namespace, ознакомьтесь с кратким обзором пространств имен в официальной документации по Kubernetes. Также мы зададим версию Kubernetes API, используемую для создания объекта (v1), и присвоим ему name kube-logging.

      После создания файла объекта пространства имен kube-logging.yaml создайте пространство имен с помощью команды kubectl create с флагом -f имя файла:

      • kubectl create -f kube-logging.yaml

      Вы должны увидеть следующий результат:

      Output

      namespace/kube-logging created

      Теперь вы можете проверить, было ли пространство имен создано успешно:

      Теперь вы должны увидеть новое пространство имен kube-logging:

      Output

      NAME STATUS AGE default Active 23m kube-logging Active 1m kube-public Active 23m kube-system Active 23m

      Теперь мы можем развернуть кластер Elasticsearch в изолированном пространстве имен logging, предназначенном для журналов.

      Шаг 2 — Создание набора Elasticsearch StatefulSet

      Мы создали пространство имен для нашего комплекса ведения журналов, и теперь можем начать развертывание его компонентов. Вначале мы развернем кластер Elasticsearch из 3 узлов.

      В этом руководстве мы будем использовать 3 пода Elasticsearch, чтобы избежать проблемы «разделения мозга», которая встречается в сложных кластерах с множеством узлов и высоким уровнем доступности. Такое «разделение мозга» происходит, когда несколько узлов не могут связываться с другими узлами, и в связи с этим выбирается несколько отдельных основных узлов. В случае с 3 узлами, если один узел временно отключается от кластера, остальные два узла могут выбрать новый основной узел, и кластер будет продолжать работу, пока последний узел будет пытаться снова присоединиться к нему. Дополнительную информацию можно найти в документах «Новая эпоха координации кластеров в Elasticsearch» и «Конфигурации голосования».

      Создание службы без главного узла

      Для начала мы создадим службу Kubernetes без главного узла с именем elasticsearch, которая будет определять домен DNS для 3 подов. Служба без главного узла не выполняет балансировку нагрузки и не имеет статического IP-адреса. Дополнительную информацию о службах без главного узла можно найти в официальной документации по Kubernetes.

      Откройте файл с именем elasticsearch_svc.yaml в своем любимом редакторе:

      • nano elasticsearch_svc.yaml

      Вставьте следующий код YAML службы Kubernetes:

      elasticsearch_svc.yaml

      kind: Service
      apiVersion: v1
      metadata:
        name: elasticsearch
        namespace: kube-logging
        labels:
          app: elasticsearch
      spec:
        selector:
          app: elasticsearch
        clusterIP: None
        ports:
          - port: 9200
            name: rest
          - port: 9300
            name: inter-node
      

      Затем сохраните и закройте файл.

      Мы определяем Service с именем elasticsearch в пространстве имен kube-logging и присваиваем ей ярлык app: elasticsearch. Затем мы задаем для .spec.selector значение app: elasticsearch, чтобы служба выбирала поды с ярлыком app: elasticsearch. Когда мы привязываем Elasticsearch StatefulSet к этой службе, служба возвращает записи DNS A, которые указывают на поды Elasticsearch с ярлыком app: elasticsearch.

      Затем мы задаем параметр clusterIP: None, который делает эту службу службой без главного узла. В заключение мы определяем порты 9200 и 9300, которые используются для взаимодействия с REST API и для связи между узлами соответственно.

      Создайте службу с помощью kubectl:

      • kubectl create -f elasticsearch_svc.yaml

      Вы должны увидеть следующий результат:

      Output

      service/elasticsearch created

      Еще раз проверьте создание службы с помощью команды kubectl get:

      kubectl get services --namespace=kube-logging
      

      Вы должны увидеть следующее:

      Output

      NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE elasticsearch ClusterIP None <none> 9200/TCP,9300/TCP 26s

      Мы настроили службу без главного узла и стабильный домен .elasticsearch.kube-logging.svc.cluster.local для наших подов. Теперь мы можем создать набор StatefulSet.

      Создание набора StatefulSet

      Набор Kubernetes StatefulSet позволяет назначать подам стабильный идентификатор и предоставлять им стабильное и постоянное хранилище. Elasticsearch требуется стабильное хранилище, чтобы его данные сохранялись при перезапуске и изменении планировки подов. Дополнительную информацию о рабочей задаче StatefulSet можно найти на странице Statefulsets в документации по Kubernetes.

      Откройте файл с именем elasticsearch_statefulset.yaml в своем любимом редакторе:

      • nano elasticsearch_statefulset.yaml

      Мы изучим каждый раздел определения объекта StatefulSet, вставляя в этот файл блоки.

      Для начала вставьте следующий блок:

      elasticsearch_statefulset.yaml

      apiVersion: apps/v1
      kind: StatefulSet
      metadata:
        name: es-cluster
        namespace: kube-logging
      spec:
        serviceName: elasticsearch
        replicas: 3
        selector:
          matchLabels:
            app: elasticsearch
        template:
          metadata:
            labels:
              app: elasticsearch
      

      В этом блоке мы определяем объект StatefulSet под названием es-cluster в пространстве имен kube-logging. Затем мы связываем его с ранее созданной службой elasticsearch, используя поле serviceName. За счет этого каждый под набора StatefulSet будет доступен по следующему адресу DNS: es-cluster-[0,1,2].elasticsearch.kube-logging.svc.cluster.local, где [0,1,2] соответствует назначенному номеру пода в виде обычного целого числа.

      Мы задали 3 копии (пода) и устанлвили для селектора matchLabels значение app: elasticseach, которое мы также отразим в разделе .spec.template.metadata. Поля .spec.selector.matchLabels и .spec.template.metadata.labels должны совпадать.

      Теперь мы можем перейти к спецификации объекта. Вставьте следующий блок кода YAML непосредственно под предыдущим блоком:

      elasticsearch_statefulset.yaml

      . . .
          spec:
            containers:
            - name: elasticsearch
              image: docker.elastic.co/elasticsearch/elasticsearch:7.2.0
              resources:
                  limits:
                    cpu: 1000m
                  requests:
                    cpu: 100m
              ports:
              - containerPort: 9200
                name: rest
                protocol: TCP
              - containerPort: 9300
                name: inter-node
                protocol: TCP
              volumeMounts:
              - name: data
                mountPath: /usr/share/elasticsearch/data
              env:
                - name: cluster.name
                  value: k8s-logs
                - name: node.name
                  valueFrom:
                    fieldRef:
                      fieldPath: metadata.name
                - name: discovery.seed_hosts
                  value: "es-cluster-0.elasticsearch,es-cluster-1.elasticsearch,es-cluster-2.elasticsearch"
                - name: cluster.initial_master_nodes
                  value: "es-cluster-0,es-cluster-1,es-cluster-2"
                - name: ES_JAVA_OPTS
                  value: "-Xms512m -Xmx512m"
      

      Здесь мы определяем поды в наборе StatefulSet. Мы присвоим контейнерам имя elasticsearch и выберем образ Docker docker.elastic.co/elasticsearch/elasticsearch:7.2.0. Сейчас вы можете изменить метку образа, чтобы она соответствовала вашему собственному образу Elasticsearch или другой версии образа. Для целей настоящего обучающего модуля тестировалась только версия Elasticsearch 7.2.0.

      Мы используем поле resources, чтобы указать, что контейнеру требуется всего гарантировать всего десятую часть ресурсов vCPU с возможностью увеличения загрузки до 1 vCPU (что ограничивает использование ресурсов подом при первоначальной обработке большого объема данных или при пиковой нагрузке). Вам следует изменить эти значения в зависимости от ожидаемой нагрузки и доступных ресурсов. Дополнительную информацию о запросах ресурсов и ограничениях можно найти в официальной документации по Kubernetes.

      Мы откроем и назовем порты 9200 и 9300 для REST API и связи между узлами соответственно. Мы зададим volumeMount с именем data, который будет монтировать постоянный том с именем data в контейнер по пути /usr/share/elasticsearch/data. Мы определим VolumeClaims для набора StatefulSet в другом блоке YAML позднее.

      В заключение мы зададим в контейнере несколько переменных среды:

      • cluster.name: имя кластера Elasticsearch, в данном обучающем модуле это k8s-logs.
      • node.name: имя узла, которое мы устанавливаем как значение поля .metadata.name с помощью valueFrom. Оно разрешается как es-cluster-[0,1,2] в зависимости от назначенного узлу порядкового номера.
      • discovery.seed_hosts: это поле использует список потенциальных главных узлов в кластере, инициирующем процесс обнаружения узлов. Поскольку в этом обучающем модуле мы уже настроили службу без главного узла, наши поды имеют домены в форме es-cluster-[0,1,2].elasticsearch.kube-logging.svc.cluster.local, так что мы зададим соответствующее значение для этой переменной. Используя разрешение DNS в локальном пространстве имен Kubernetes мы можем сократить это до es-cluster-[0,1,2].elasticsearch. Дополнительную информацию об обнаружении Elasticsearch можно найти в официальной документации по Elasticsearch.
      • cluster.initial_master_nodes: в этом поле также задается список потенциальных главных узлов, которые будут участвовать в процессе выбора главного узла. Обратите внимание, что для этого поля узлы нужно указывать по имени node.name, а не по именам хостов.
      • ES_JAVA_OPTS: здесь мы задаем значение -Xms512m -Xmx512m, которое предписывает JVM использовать минимальный и максимальный размер выделения памяти 512 МБ. Вам следует настроить эти параметры в зависимости от доступности ресурсов и потребностей вашего кластера. Дополнительную информацию можно найти в разделе «Настройка размера выделяемой памяти».

      Следующий блок, который мы будем вставлять, выглядит следующим образом:

      elasticsearch_statefulset.yaml

      . . .
            initContainers:
            - name: fix-permissions
              image: busybox
              command: ["sh", "-c", "chown -R 1000:1000 /usr/share/elasticsearch/data"]
              securityContext:
                privileged: true
              volumeMounts:
              - name: data
                mountPath: /usr/share/elasticsearch/data
            - name: increase-vm-max-map
              image: busybox
              command: ["sysctl", "-w", "vm.max_map_count=262144"]
              securityContext:
                privileged: true
            - name: increase-fd-ulimit
              image: busybox
              command: ["sh", "-c", "ulimit -n 65536"]
              securityContext:
                privileged: true
      

      В этом блоке мы определяем несколько контейнеров инициализации, которые запускаются до главного контейнера приложения elasticsearch. Каждый из этих контейнеров инициализации выполняется до конца в заданном порядке. Дополнительную информацию о контейнерах инициализации можно найти в официальной документации по Kubernetes.

      Первый такой контейнер с именем fix-permissions запускает команду chown для смены владельца и группы каталога данных Elasticsearch на 1000:1000, UID польздователя Elasticsearch. По умолчанию Kubernetes монтирует каталог данных как root, что делает его недоступным для Elasticsearch. Дополнительную информацию об этом шаге можно найти в документации по Elasticsearch «Замечания по использованию в производстве и значения по умолчанию».

      Второй контейнер с именем increase-vm-max-map запускает команду для увеличения предельного количества mmap в операционной системе, которое по умолчанию может быть слишком низким, в результате чего могут возникать ошибки памяти. Дополнительную информацию об этом шаге можно найти в официальной документации по Elasticsearch.

      Следующим запускается контейнер инициализации increase-fd-ulimit, который запускает команду ulimit для увеличения максимального количества дескрипторов открытых файлов. Дополнительную информацию об этом шаге можно найти в документации по Elasticsearch «Замечания по использованию в производстве и значения по умолчанию».

      Примечание. В документе «Замечания по использованию в производстве и значения по умолчанию» для Elasticsearch также указывается возможность отключения подкачки для повышения производительности. В зависимости от вида установки Kubernetes и провайдера, подкачка может быть уже отключена. Чтобы проверить это, выполните команду exec в работающем контейнере и запустите cat /proc/swaps для вывода активных устройств подкачки. Если этот список пустой, подкачка отключена.

      Мы определили главный контейнер приложений и контейнеры инициализации, которые будут запускаться перед ним для настройки ОС контейнера. Теперь мы можем доставить в наш файл определения объекта StatefulSet заключительную часть: блок volumeClaimTemplates.

      Вставьте следующий блок volumeClaimTemplate:

      elasticsearch_statefulset.yaml

      . . .
        volumeClaimTemplates:
        - metadata:
            name: data
            labels:
              app: elasticsearch
          spec:
            accessModes: [ "ReadWriteOnce" ]
            storageClassName: do-block-storage
            resources:
              requests:
                storage: 100Gi
      

      В этом блоке мы определяем для StatefulSet шаблоны volumeClaimTemplates. Kubernetes использует эти настройки для создания постоянных томов для подов. В приведенном выше блоке мы использовали имя data (это name, на которое мы уже ссылались в определении volumeMounts), и присвоили ему тот же ярлык app: elasticsearch, что и для набора StatefulSet.

      Затем мы задаем для него режим доступа ReadWriteOnce, и это означает, что его может монтировать для чтения и записи только один узел. В этом обучающем модуле мы определяем класс хранения do-block-storage, поскольку мы используем для демонстрации кластер DigitalOcean Kubernetes. Вам следует изменить это значение в зависимости от того, где вы запускаете свой кластер Kubernetes. Дополнительную информацию можно найти в документации по постоянным томам.

      В заключение мы укажем, что каждый постоянный том должен иметь размер 100 ГиБ. Вам следует изменить это значение в зависимости от производственных потребностей.

      Полная спецификация StatefulSet должна выглядеть примерно так:

      elasticsearch_statefulset.yaml

      apiVersion: apps/v1
      kind: StatefulSet
      metadata:
        name: es-cluster
        namespace: kube-logging
      spec:
        serviceName: elasticsearch
        replicas: 3
        selector:
          matchLabels:
            app: elasticsearch
        template:
          metadata:
            labels:
              app: elasticsearch
          spec:
            containers:
            - name: elasticsearch
              image: docker.elastic.co/elasticsearch/elasticsearch:7.2.0
              resources:
                  limits:
                    cpu: 1000m
                  requests:
                    cpu: 100m
              ports:
              - containerPort: 9200
                name: rest
                protocol: TCP
              - containerPort: 9300
                name: inter-node
                protocol: TCP
              volumeMounts:
              - name: data
                mountPath: /usr/share/elasticsearch/data
              env:
                - name: cluster.name
                  value: k8s-logs
                - name: node.name
                  valueFrom:
                    fieldRef:
                      fieldPath: metadata.name
                - name: discovery.seed_hosts
                  value: "es-cluster-0.elasticsearch,es-cluster-1.elasticsearch,es-cluster-2.elasticsearch"
                - name: cluster.initial_master_nodes
                  value: "es-cluster-0,es-cluster-1,es-cluster-2"
                - name: ES_JAVA_OPTS
                  value: "-Xms512m -Xmx512m"
            initContainers:
            - name: fix-permissions
              image: busybox
              command: ["sh", "-c", "chown -R 1000:1000 /usr/share/elasticsearch/data"]
              securityContext:
                privileged: true
              volumeMounts:
              - name: data
                mountPath: /usr/share/elasticsearch/data
            - name: increase-vm-max-map
              image: busybox
              command: ["sysctl", "-w", "vm.max_map_count=262144"]
              securityContext:
                privileged: true
            - name: increase-fd-ulimit
              image: busybox
              command: ["sh", "-c", "ulimit -n 65536"]
              securityContext:
                privileged: true
        volumeClaimTemplates:
        - metadata:
            name: data
            labels:
              app: elasticsearch
          spec:
            accessModes: [ "ReadWriteOnce" ]
            storageClassName: do-block-storage
            resources:
              requests:
                storage: 100Gi
      

      Когда вы будете удовлетворены конфигурацией Elasticsearch, сохраните и закройте файл.

      Теперь мы развернем набор StatefulSet с использованием kubectl:

      • kubectl create -f elasticsearch_statefulset.yaml

      Вы должны увидеть следующий результат:

      Output

      statefulset.apps/es-cluster created

      Вы можете отслеживать набор StatefulSet, развернутый с помощью kubectl rollout status:

      • kubectl rollout status sts/es-cluster --namespace=kube-logging

      При развертывании кластера вы увидите следующие результаты:

      Output

      Waiting for 3 pods to be ready... Waiting for 2 pods to be ready... Waiting for 1 pods to be ready... partitioned roll out complete: 3 new pods have been updated...

      После развертывания всех подов вы можете использовать запрос REST API, чтобы убедиться, что кластер Elasticsearch функционирует нормально.

      Для этого вначале нужно перенаправить локальный порт 9200 на порт 9200 одного из узлов Elasticsearch (es-cluster-0) с помощью команды kubectl port-forward:

      • kubectl port-forward es-cluster-0 9200:9200 --namespace=kube-logging

      В отдельном окне терминала отправьте запрос curl к REST API:

      • curl http://localhost:9200/_cluster/state?pretty

      Результат должен выглядеть следующим образом:

      Output

      { "cluster_name" : "k8s-logs", "compressed_size_in_bytes" : 348, "cluster_uuid" : "QD06dK7CQgids-GQZooNVw", "version" : 3, "state_uuid" : "mjNIWXAzQVuxNNOQ7xR-qg", "master_node" : "IdM5B7cUQWqFgIHXBp0JDg", "blocks" : { }, "nodes" : { "u7DoTpMmSCixOoictzHItA" : { "name" : "es-cluster-1", "ephemeral_id" : "ZlBflnXKRMC4RvEACHIVdg", "transport_address" : "10.244.8.2:9300", "attributes" : { } }, "IdM5B7cUQWqFgIHXBp0JDg" : { "name" : "es-cluster-0", "ephemeral_id" : "JTk1FDdFQuWbSFAtBxdxAQ", "transport_address" : "10.244.44.3:9300", "attributes" : { } }, "R8E7xcSUSbGbgrhAdyAKmQ" : { "name" : "es-cluster-2", "ephemeral_id" : "9wv6ke71Qqy9vk2LgJTqaA", "transport_address" : "10.244.40.4:9300", "attributes" : { } } }, ...

      Это показывает, что журналы k8s-logs нашего кластера Elasticsearch успешно созданы с 3 узлами: es-cluster-0, es-cluster-1 и es-cluster-2. В качестве главного узла выступает узел es-cluster-0.

      Теперь ваш кластер Elasticsearch запущен, и вы можете перейти к настройке на нем клиентского интерфейса Kibana.

      Шаг 3 — Создание развертывания и службы Kibana

      Чтобы запустить Kibana в Kubernetes, мы создадим службу с именем kibana, а также развертывание, состоящее из одной копии пода. Вы можете масштабировать количество копий в зависимости от ваших производственных потребностей и указывать тип LoadBalancer, чтобы служба запрашивала балансировку нагрузки на подах развертывания.

      В этом случае мы создадим службу и развертывание в одном и том же файле. Откройте файл с именем kibana.yaml в своем любимом редакторе:

      Вставьте следующую спецификацию службы:

      kibana.yaml

      apiVersion: v1
      kind: Service
      metadata:
        name: kibana
        namespace: kube-logging
        labels:
          app: kibana
      spec:
        ports:
        - port: 5601
        selector:
          app: kibana
      ---
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: kibana
        namespace: kube-logging
        labels:
          app: kibana
      spec:
        replicas: 1
        selector:
          matchLabels:
            app: kibana
        template:
          metadata:
            labels:
              app: kibana
          spec:
            containers:
            - name: kibana
              image: docker.elastic.co/kibana/kibana:7.2.0
              resources:
                limits:
                  cpu: 1000m
                requests:
                  cpu: 100m
              env:
                - name: ELASTICSEARCH_URL
                  value: http://elasticsearch:9200
              ports:
              - containerPort: 5601
      

      Затем сохраните и закройте файл.

      В этой спецификации мы определили службу с именем kibana в пространстве имен kube-logging и присвоить ему ярлык app: kibana.

      Также мы указали, что она должна быть доступна на порту 5601, и использовали ярлык app: kibana для выбора целевых подов службы.

      В спецификации Deployment мы определим развертывание с именем kibana и укажем, что нам требуется 1 копия пода.

      Мы будем использовать образ docker.elastic.co/kibana/kibana:7.2.0. Сейчас вы можете заменить этот образ на собственный частный или публичный образ Kibana, который вы хотите использовать.

      Мы укажем, что нам требуется гарантировать для пода не менее 0.1 vCPU и не более 1 vCPU при пиковой нагрузке. Вам следует изменить эти значения в зависимости от ожидаемой нагрузки и доступных ресурсов.

      Теперь мы используем переменную среды ELASTICSEARCH_URL для установки конечной точки и порта для кластера Elasticsearch. При использовании Kubernetes DNS эта конечная точка соответствует названию службы elasticsearch. Этот домен разрешится в список IP-адресов для 3 подов Elasticsearch. Дополнительную информацию о Kubernetes DNS можно получить в документе DNS для служб и подов.

      Наконец мы настроим для контейнера Kibana порт 5601, куда служба kibana будет перенаправлять запросы.

      Когда вы будете удовлетворены конфигурацией Kibana, вы можете развернуть службу и развертывание с помощью команды kubectl:

      • kubectl create -f kibana.yaml

      Вы должны увидеть следующий результат:

      Output

      service/kibana created deployment.apps/kibana created

      Вы можете проверить успешность развертывания, запустив следующую команду:

      • kubectl rollout status deployment/kibana --namespace=kube-logging

      Вы должны увидеть следующий результат:

      Output

      deployment "kibana" successfully rolled out

      Чтобы получить доступ к интерфейсу Kibana, мы снова перенаправим локальный порт на узел Kubernetes, где запущена служба Kibana. Получите подробную информацию о поде Kibana с помощью команды kubectl get:

      • kubectl get pods --namespace=kube-logging

      Output

      NAME READY STATUS RESTARTS AGE es-cluster-0 1/1 Running 0 55m es-cluster-1 1/1 Running 0 54m es-cluster-2 1/1 Running 0 54m kibana-6c9fb4b5b7-plbg2 1/1 Running 0 4m27s

      Здесь мы видим, что наш под Kibana имеет имя kibana-6c9fb4b5b7-plbg2.

      Перенаправьте локальный порт 5601 на порт 5601 этого пода:

      • kubectl port-forward kibana-6c9fb4b5b7-plbg2 5601:5601 --namespace=kube-logging

      Вы должны увидеть следующий результат:

      Output

      Forwarding from 127.0.0.1:5601 -> 5601 Forwarding from [::1]:5601 -> 5601

      Откройте в своем браузере следующий URL:

      http://localhost:5601
      

      Если вы увидите следующую приветственную страницу Kibana, это означает, что вы успешно развернули Kibana в своем кластере Kubernetes:

      Приветственный экран Kibana

      Теперь вы можете перейти к развертыванию последнего компонента комплекса EFK: сборщика данных журнала Fluentd.

      Шаг 4 — Создание набора демонов Fluentd

      В этом обучающем модуле мы настроим Fluentd как набор демонов. Это тип рабочей задачи Kubernetes, запускающий копию указанного пода на каждом узле в кластере Kubernetes. Используя контроллер набора демонов, мы развернем под агента регистрации данных Fluentd на каждом узле нашего кластера. Дополнительную информацию об архитектуре регистрации данных можно найти в документе «Использование агента регистрации данных узлов» в официальной документации по Kubernetes.

      В Kubernetes приложения в контейнерах записывают данные в stdout и stderr, и их потоки регистрируемых данных записываются и перенаправляются в файлы JSON на узлах. Под Fluentd отслеживает эти файлы журналов, фильтрует события журналов, преобразует данные журналов и отправляет их на сервенюу часть регистрации данных Elasticsearch, которую мы развернули на шаге 2.

      Помимо журналов контейнеров, агент Fluentd также отслеживает журналы системных компонентов Kubernetes, в том числе журналы kubelet, kube-proxy и Docker. Полный список источников, отслеживаемых агентом регистрации данных Fluentd, можно найти в файле kubernetes.conf, используемом для настройки агента регистрации данных. Дополнительную информацию по регистрации данных в кластерах Kubernetes можно найти в документе «Регистрация данных на уровне узлов» в официальной документации по Kubernetes.

      Для начала откройте файл fluentd.yaml в предпочитаемом текстовом редакторе:

      Мы снова будем вставлять определения объектов Kubernetes по блокам с указанием дополнительного контекста. В этом руководстве мы используем спецификацию набора демонов Fluentd, предоставленную командой обслуживания Fluentd. Также команда обслуживания Fluentd предоставляет полезный ресурс Kuberentes Fluentd.

      Вставьте следующее определение служебной учетной записи:

      fluentd.yaml

      apiVersion: v1
      kind: ServiceAccount
      metadata:
        name: fluentd
        namespace: kube-logging
        labels:
          app: fluentd
      

      Здесь мы создаем служебную учетную запись fluentd, которую поды Fluentd будут использовать для доступа к Kubernetes API. Мы создаем ее в пространстве имен kube-logging и снова присваиваем ей ярлык app: fluentd. Дополнительную информацию о служебных учетных записях в Kubernetes можно найти в документе «Настройка служебных учетных записей для подов» в официальной документации по Kubernetes.

      Затем вставьте следующий блок ClusterRole:

      fluentd.yaml

      . . .
      ---
      apiVersion: rbac.authorization.k8s.io/v1
      kind: ClusterRole
      metadata:
        name: fluentd
        labels:
          app: fluentd
      rules:
      - apiGroups:
        - ""
        resources:
        - pods
        - namespaces
        verbs:
        - get
        - list
        - watch
      

      Здесь мы определяем блок ClusterRole с именем fluentd, которому мы предоставляем разрешения get, list и watch для объектов pods и namespaces. ClusterRoles позволяет предоставлять доступ к ресурсам в кластере Kubernetes, в том числе к узлам. Дополнительную информацию о контроле доступа на основе ролей и ролях кластеров можно найти в документе «Использование авторизации RBAC» в официальной документации Kubernetes.

      Теперь вставьте следующий блок ClusterRoleBinding:

      fluentd.yaml

      . . .
      ---
      kind: ClusterRoleBinding
      apiVersion: rbac.authorization.k8s.io/v1
      metadata:
        name: fluentd
      roleRef:
        kind: ClusterRole
        name: fluentd
        apiGroup: rbac.authorization.k8s.io
      subjects:
      - kind: ServiceAccount
        name: fluentd
        namespace: kube-logging
      

      В этом блоке мы определяем объект ClusterRoleBinding с именем fluentd, которй привязывает роль кластера fluentd к служебной учетной записи fluentd. Это дает служебной учетной записи fluentd разрешения, заданные для роли кластера fluentd.

      Сейчас мы можем начать вставку спецификации набора демонов:

      fluentd.yaml

      . . .
      ---
      apiVersion: apps/v1
      kind: DaemonSet
      metadata:
        name: fluentd
        namespace: kube-logging
        labels:
          app: fluentd
      

      Здесь мы определяем набор демонов с именем fluentd в пространстве имен kube-logging и назначаем ему ярлык app: fluentd.

      Вставьте следующий раздел:

      fluentd.yaml

      . . .
      spec:
        selector:
          matchLabels:
            app: fluentd
        template:
          metadata:
            labels:
              app: fluentd
          spec:
            serviceAccount: fluentd
            serviceAccountName: fluentd
            tolerations:
            - key: node-role.kubernetes.io/master
              effect: NoSchedule
            containers:
            - name: fluentd
              image: fluent/fluentd-kubernetes-daemonset:v1.4.2-debian-elasticsearch-1.1
              env:
                - name:  FLUENT_ELASTICSEARCH_HOST
                  value: "elasticsearch.kube-logging.svc.cluster.local"
                - name:  FLUENT_ELASTICSEARCH_PORT
                  value: "9200"
                - name: FLUENT_ELASTICSEARCH_SCHEME
                  value: "http"
                - name: FLUENTD_SYSTEMD_CONF
                  value: disable
      

      Здесь мы сопоставляем ярлык app: fluentd, определенный в .metadata.labels и назначаем для набора демонов служебную учетную запись fluentd. Также мы выбираем app: fluentd как поды, управляемые этим набором демонов.

      Затем мы определяем допуск NoSchedule для соответствия эквивалентному вызову в главных узлах Kubernetes. Это гарантирует, что набор демонов также будет развернут на главных узлах Kubernetes. Если вы не хотите запускать под Fluentd на главных узлах, удалите этот допуск. Дополнительную информацию о вызовах и допусках Kubernetes можно найти в разделе «Вызовы и допуски» в официальной документации по Kubernetes.

      Теперь мы начнем определять контейнер пода с именем fluentd.

      Мы используем официальный образ v1.4.2 Debian от команды, обслуживающей Fluentd. Если вы хотите использовать свой частный или публичный образ Fluentd или использовать другую версию образа, измените тег image в спецификации контейнера. Файл Dockerfile и содержание этого образа доступны в репозитории fluentd-kubernetes-daemonset на Github.

      Теперь мы настроим Fluentd с помощью нескольких переменных среды:

      • FLUENT_ELASTICSEARCH_HOST: мы настроим службу Elasticsearch без главных узлов, которую мы определили ранее: elasticsearch.kube-logging.svc.cluster.local. Это разрешается список IP-адресов для 3 подов Elasticsearch. Скорее всего, реальный хост Elasticsearch будет первым IP-адресом, который будет выведен в этом списке. Для распределения журналов в этом кластере вам потребуется изменить конфигурацию плагина вывода Fluentd Elasticsearch. Дополнительную информацию об этом плагине можно найти в документе «Плагин вывода Elasticsearch».
      • FLUENT_ELASTICSEARCH_PORT: в этом параметре мы задаем ранее настроенный порт Elasticsearch 9200.
      • FLUENT_ELASTICSEARCH_SCHEME: мы задаем для этого параметра значение http.
      • FLUENTD_SYSTEMD_CONF: мы задаем для этого параметра значение disable, чтобы подавить вывод systemd, который не настроен в контейнере.

      Вставьте следующий раздел:

      fluentd.yaml

      . . .
              resources:
                limits:
                  memory: 512Mi
                requests:
                  cpu: 100m
                  memory: 200Mi
              volumeMounts:
              - name: varlog
                mountPath: /var/log
              - name: varlibdockercontainers
                mountPath: /var/lib/docker/containers
                readOnly: true
            terminationGracePeriodSeconds: 30
            volumes:
            - name: varlog
              hostPath:
                path: /var/log
            - name: varlibdockercontainers
              hostPath:
                path: /var/lib/docker/containers
      

      Здесь мы указываем предельный объем памяти 512 МиБ в поде FluentD и гарантируем выделение 0,1 vCPU и 200 МиБ памяти. Вы можете настроить эти ограничения ресурсов и запросы в зависимости от ожидаемого объема журнала и доступных ресурсов.

      Затем мы смонтируем пути хостов /var/log и /var/lib/docker/containers в контейнер, используя varlog и varlibdockercontainers volumeMounts. Эти тома определяются в конце блока.

      Последний параметр, который мы определяем в этом блоке, — это параметр terminationGracePeriodSeconds, дающий Fluentd 30 секунд для безопасного выключения при получении сигнала SIGTERM. После 30 секунд контейнеры получают сигнал SIGKILL. Значение по умолчанию для terminationGracePeriodSeconds составляет 30 с, так что в большинстве случаев этот параметр можно пропустить. Дополнительную информацию о безопасном прекращении рабочих задач Kubernetes можно найти в документе Google «Лучшие практики Kubernetes: осторожное прекращение работы».

      Полная спецификация Fluentd должна выглядеть примерно так:

      fluentd.yaml

      apiVersion: v1
      kind: ServiceAccount
      metadata:
        name: fluentd
        namespace: kube-logging
        labels:
          app: fluentd
      ---
      apiVersion: rbac.authorization.k8s.io/v1
      kind: ClusterRole
      metadata:
        name: fluentd
        labels:
          app: fluentd
      rules:
      - apiGroups:
        - ""
        resources:
        - pods
        - namespaces
        verbs:
        - get
        - list
        - watch
      ---
      kind: ClusterRoleBinding
      apiVersion: rbac.authorization.k8s.io/v1
      metadata:
        name: fluentd
      roleRef:
        kind: ClusterRole
        name: fluentd
        apiGroup: rbac.authorization.k8s.io
      subjects:
      - kind: ServiceAccount
        name: fluentd
        namespace: kube-logging
      ---
      apiVersion: apps/v1
      kind: DaemonSet
      metadata:
        name: fluentd
        namespace: kube-logging
        labels:
          app: fluentd
      spec:
        selector:
          matchLabels:
            app: fluentd
        template:
          metadata:
            labels:
              app: fluentd
          spec:
            serviceAccount: fluentd
            serviceAccountName: fluentd
            tolerations:
            - key: node-role.kubernetes.io/master
              effect: NoSchedule
            containers:
            - name: fluentd
              image: fluent/fluentd-kubernetes-daemonset:v1.4.2-debian-elasticsearch-1.1
              env:
                - name:  FLUENT_ELASTICSEARCH_HOST
                  value: "elasticsearch.kube-logging.svc.cluster.local"
                - name:  FLUENT_ELASTICSEARCH_PORT
                  value: "9200"
                - name: FLUENT_ELASTICSEARCH_SCHEME
                  value: "http"
                - name: FLUENTD_SYSTEMD_CONF
                  value: disable
              resources:
                limits:
                  memory: 512Mi
                requests:
                  cpu: 100m
                  memory: 200Mi
              volumeMounts:
              - name: varlog
                mountPath: /var/log
              - name: varlibdockercontainers
                mountPath: /var/lib/docker/containers
                readOnly: true
            terminationGracePeriodSeconds: 30
            volumes:
            - name: varlog
              hostPath:
                path: /var/log
            - name: varlibdockercontainers
              hostPath:
                path: /var/lib/docker/containers
      

      После завершения настройки набора демонов Fluentd сохраните и закройте файл.

      Теперь выгрузите набор демонов с помощью команды kubectl:

      • kubectl create -f fluentd.yaml

      Вы должны увидеть следующий результат:

      Output

      serviceaccount/fluentd created clusterrole.rbac.authorization.k8s.io/fluentd created clusterrolebinding.rbac.authorization.k8s.io/fluentd created daemonset.extensions/fluentd created

      Убедитесь, что набор демонов успешно развернут, с помощью команды kubectl:

      • kubectl get ds --namespace=kube-logging

      Вы должны увидеть следующее состояние:

      Output

      NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE fluentd 3 3 3 3 3 <none> 58s

      Такой результат показывает, что работает 3 пода fluentd, что соответствует количеству узлов в нашем кластере Kubernetes.

      Теперь мы можем проверить Kibana и убедиться, что данные журнала собираются надлежащим образом и отправляются в Elasticsearch.

      При активном перенаправлении kubectl port-forward перейдите на адрес http://localhost:5601.

      Нажмите Discover в левом меню навигации:

      Kibana Discover

      Вы увидите следующее окно конфигурации:

      Конфигурация шаблона индексов Kibana

      Эта конфигурация позволяет определить индексы Elasticsearch, которые вы хотите просматривать в Kibana. Дополнительную информацию можно найти в документе «Определение шаблонов индексов» в официальной документации по Kibana. Сейчас мы будем использовать шаблон с подстановочным символом logstash-* для сбора всех данных журнала в нашем кластере Elasticsearch. Введите logstash-* в текстовое поле и нажмите «Следующий шаг».

      Откроется следующая страница:

      Настройки шаблона индексов Kibana

      Эти настройки позволяют указать, какое поле будет использовать Kibana для фильтрации данных по времени. Выберите в выпадающем списке поле @timestamp и нажмите «Создать шаблон индекса».

      Теперь нажмите Discover в левом меню навигации.

      Вы увидите гистограмму и несколько последних записей в журнале:

      Входящие журналы Kibana

      Вы успешно настроили и развернули комплекс EFK в своем кластере Kubernetes. Чтобы научиться использовать Kibana для анализа данных журнала, используйте «Руководство пользователя Kibana».

      В следующем необязательном разделе мы развернем простой под счетчика, который распечатывает числа в stdout, и найдем его журналы в Kibana.

      Шаг 5 (необязательный) — Тестирование регистрации данных контейнеров

      Для демонстрации простого примера использования Kibana для просмотра последних журналов пода мы развернем простой под счетчика, распечатывающий последовательности чисел в stdout.

      Для начала создадим под. Откройте файл с именем counter.yaml в своем любимом редакторе:

      Вставьте в него следующую спецификацию пода:

      counter.yaml

      apiVersion: v1
      kind: Pod
      metadata:
        name: counter
      spec:
        containers:
        - name: count
          image: busybox
          args: [/bin/sh, -c,
                  'i=0; while true; do echo "$i: $(date)"; i=$((i+1)); sleep 1; done']
      

      Сохраните и закройте файл.

      Это простой под с именем counter, который запускает цикл while и печатает последовательности чисел.

      Разверните под counter с помощью kubectl:

      • kubectl create -f counter.yaml

      Когда под будет создан и запущен, вернитесь в информационную панель Kibana.

      В панели поиска на странице Discover введите kubernetes.pod_name:counter. Этот запрос отфильтрует данные журнала для пода с именем counter.

      Вы увидите список записей в журнале для пода counter:

      Журналы счетчика в Kibana

      Вы можете нажать на любую запись в журнале, чтобы посмотреть дополнительные метаданные, в том числе имя контейнера, узел Kubernetes, пространство имен и т. д.

      Заключение

      В этом обучающем модуле мы продемонстрировали процессы установки и настройки Elasticsearch, Fluentd и Kibana в кластере Kubernetes. Мы использовали минимальную архитектуру журнала, состоящую из простого пода агента ведения журнала на каждом рабочем узле Kubernetes.

      Прежде чем развернуть комплекс ведения журнала в рабочем кластере Kubernetes, лучше всего настроить требования к ресурсам и ограничения в соответствии с указаниями этого обучающего модуля. Также вы можете настроить X-Pack для поддержки встроенных функций мониторинга и безопасности.

      Использованная нами архитектура ведения журналов включает 3 пода Elasticsearch, один под Kibana (без балансировки нагрузки), а также набор подов Fluentd, развернутый в форме набора демонов. При желании вы можете масштабировать эти настройки в зависимости от конкретной реализации решения. Дополнительную информацию о масштабировании комплекса Elasticsearch и Kibana можно найти в документе «Масштабирование Elasticsearch».

      Kubernetes также позволяет использовать более сложны архитектуры агентов регистрации данных, которые могут лучше подойти для определенных решений. Дополнительную информацию можно найти в документе «Архитектура регистрации данных» в документации по Kubernetes.



      Source link