One place for hosting & domains

      Как

      Как добавить пространство подкачки на Ubuntu 18.04


      Предыдущая версия данного обучающего руководства была написана Джастином Эллингвудом

      Введение

      Один из наиболее простых способов предотвратить ошибки нехватки памяти в приложениях — добавить пространство подкачки на сервер. В этом руководстве мы расскажем, как добавить файл подкачки на сервер Ubuntu 18.04.

      Предупреждение: Хотя подкачка в целом рекомендуется для систем с использованием традиционных жестких дисков, ее использование с SSD-накопителями может со временем вызывать ухудшение аппаратного обеспечения. В связи с этим мы не рекомендуем использовать подкачку с DigitalOcean или с любым другим провайдером, использующим SSD-накопители. Использование подкачки может повлиять на надежность соответствующего аппаратного обеспечения у вас и ваших соседей. Настоящее руководство предоставляет справочные данные для пользователей, у которых в других местах имеются системы вращающихся дисков.

      Если вам нужно повысить производительность сервера на DigitalOcean, рекомендуем обновить Droplet. Это приведет к лучшим результатам в целом и снизит вероятность создания проблем с аппаратным обеспечением, способных повлиять на ваши работы.

      Что такое подкачка?

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

      Чтение и запись информации с диска намного медленнее, чем из оперативной памяти. Операционная система будет по-прежнему предпочитать работать с данными приложений в памяти, а подкачку использовать для более старых данных. Как правило, полезно перестраховываться и иметь область подкачки в качестве резерва на случай нехватки оперативной памяти, чтобы исключить ошибки памяти в системах без SSD.

      Шаг 1 — Проверка информации о подкачке в системе

      Сначала мы можем посмотреть, есть ли уже в системе область подкачки. Можно иметь несколько файлов или разделов подкачки, но обычно одного достаточно.

      Можно узнать, сконфигурирована ли в системе подкачка, введя:

      Если после этой команды ничего не появляется, в системе сейчас нет области подкачки.

      Можно убедиться в отсутствии активной подкачки при помощи утилиты free:

      Output

      total used free shared buff/cache available Mem: 985M 84M 222M 680K 678M 721M Swap: 0B 0B 0B

      В строке ​​​Swap видно​​​, что в системе отсутствует активная подкачка.

      Шаг 2 — Проверка свободного пространства в разделе жесткого диска

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

      Output

      Filesystem Size Used Avail Use% Mounted on udev 481M 0 481M 0% /dev tmpfs 99M 656K 98M 1% /run /dev/vda1 25G 1.4G 23G 6% / tmpfs 493M 0 493M 0% /dev/shm tmpfs 5.0M 0 5.0M 0% /run/lock tmpfs 493M 0 493M 0% /sys/fs/cgroup /dev/vda15 105M 3.4M 102M 4% /boot/efi tmpfs 99M 0 99M 0% /run/user/1000

      В данном случае устройство с / в столбце ​​​​​​Mounted on​​​ — наш диск. В данном примере у нас достаточно места (использовано только 1,4 Гбайт). Ваше использование, вероятно, будет другим.

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

      Шаг 3 — Создание файла подкачки

      Теперь, когда известно свободное место на жестком диске, можно создать файл подкачки в нашей файловой системе. Поместим файл под названием swapfile с необходимым для подкачки размером в корневую (/) директорию.

      Лучше всего создавать файл подкачки при помощи программы fallocate. Эта команда мгновенно создает файл указанного размера.

      Поскольку на сервере в нашем случае 1 Гбайт оперативной памяти, в этом руководстве создадим файл размером 1 Гбайт. Скорректируйте с учетом необходимости на вашем сервере:

      • sudo fallocate -l 1G /swapfile

      Чтобы проверить правильность выделенного объема памяти, введите:

      • -rw-r--r-- 1 root root 1.0G Apr 25 11:14 /swapfile

      Файл создан с правильным выделенным объемом памяти.

      Шаг 4 — Активация файла подкачки

      Теперь, когда у нас есть файл правильного размера, нам нужно превратить его в пространство подкачки.

      Сначала нужно изменить права доступа к файлу, чтобы только пользователи с правами root могли читать его содержимое. Это предотвращает доступ обычных пользователей к файлу — такой доступ может существенно влиять на безопасность.

      Чтобы передать все права доступа пользователям root, введите:

      Проверьте изменение прав доступа, введя следующее:

      Output

      -rw------- 1 root root 1.0G Apr 25 11:14 /swapfile

      Теперь только у пользователя root отмечены флажки чтения и записи.

      Теперь можем отметить файл как пространство подкачки, введя следующее:

      Output

      Setting up swapspace version 1, size = 1024 MiB (1073737728 bytes) no label, UUID=6e965805-2ab9-450f-aed6-577e74089dbf

      После этого можем активировать файл подкачки, чтобы система начала использовать его:

      Убедитесь, что пространство подкачки активировано, введя следующее:

      Output

      NAME TYPE SIZE USED PRIO /swapfile file 1024M 0B -2

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

      Output

      total used free shared buff/cache available Mem: 985M 84M 220M 680K 680M 722M Swap: 1.0G 0B 1.0G

      Подкачка успешно настроена, и операционная система начнет использовать ее по мере необходимости.

      Шаг 5 — Сделать файл подкачки постоянным

      В результате внесенных нами изменений файл подкачки активирован для текущей сессии. После перезагрузки сервер не сохранит настройки подкачки автоматически. Мы можем изменить это, добавив файл подкачки к файлу /etc/fstab.

      Сделайте резервную копию файла /etc/fstab на случай если что-то пойдет не так:

      • sudo cp /etc/fstab /etc/fstab.bak

      Добавьте информацию о файле подкачки в конец файла /etc/fstab, введя следующее:

      • echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

      Далее рассмотрим некоторые настройки, которые мы сможем обновить, чтобы настроить пространство подкачки.

      Шаг 6 — Изменение настроек подкачки

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

      Настройка параметра Swappiness

      Параметр swappiness определяет, как часто система выгружает данные из оперативной памяти в пространство подкачки. Его значение выражается числом от 0 до 100 процентов.

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

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

      Можем увидеть текущее значение фактора swappiness, введя следующее:

      • cat /proc/sys/vm/swappiness

      Output

      60

      Для настольного компьютера неплохое значение swappiness — 60. Для сервера, возможно, вы захотите приблизить его к 0.

      Можно задать другое значение swappiness при помощи команды sysctl.

      Например, чтобы установить значение swappiness 10, можно ввести следующее:

      • sudo sysctl vm.swappiness=10

      Output

      vm.swappiness = 10

      Эта настройка будет сохраняться до следующей перезагрузки. Можно автоматически задать это значение при перезагрузке, добавив строку в файл /etc/sysctl.conf:

      • sudo nano /etc/sysctl.conf

      Внизу можно ввести следующее:

      /etc/sysctl.conf

      vm.swappiness=10
      

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

      Изменение настроек нагрузки кэш-памяти

      Еще одно связанное значение, которое вы, возможно, захотите изменить — vfs_cache_pressure. Эта настройка определяет, насколько система будет кэшировать данные inode и dentry по сравнению с другими данными.

      По сути, это данные доступа к файловой системе. Как правило, искать их довольно сложно, а запрашиваются они часто, так что кэш-память в этом случае весьма полезна. Чтобы узнать текущее значение этого параметра, можно еще раз запросить файловую систему proc:

      • cat /proc/sys/vm/vfs_cache_pressure

      Output

      100

      Согласно текущим настройкам, система удаляет данные инодов из кэша слишком быстро. Можно задать более консервативное значение — например, 50 — введя следующее:

      • sudo sysctl vm.vfs_cache_pressure=50

      Output

      vm.vfs_cache_pressure = 50

      Опять-таки, это значение действительно только для текущей сессии. Чтобы сделать его постоянным, нужно (как и в случае со swappiness) изменить файл конфигурации:

      • sudo nano /etc/sysctl.conf

      Внизу добавьте строку с новым значением:

      /etc/sysctl.conf

      vm.vfs_cache_pressure=50
      

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

      Заключение

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

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



      Source link

      Как создать кластер Kubernetes с помощью Kubeadm в Ubuntu 18.04


      Автор выбрал фонд Free and Open Source Fund для получения пожертвования в рамках программы Write for DOnations.

      Введение

      Kubernetes — это система оркестровки контейнеров, обеспечивающая управление контейнерами в масштабе. Система Kubernetes была первоначально разработана Google на основе опыта компании в использовании контейнеров в рабочей среде. Это решение с открытым исходным кодом, и в его разработке активно участвуют представители сообщества разработчиков со всего мира.

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

      Kubeadm автоматизирует установку и настройку компонентов Kubernetes, в том числе сервера API, Controller Manager и Kube DNS. Однако данное средство не создает пользователей и не выполняет установку зависимостей уровня операционной системы и их конфигурации. Для предварительных задач существует возможность использования инструментов управления конфигурацией, таких как Ansible и SaltStack. Использование этих инструментов упрощает создание дополнительных кластеров или воссоздание существующих кластеров, а также снижает вероятность ошибок.

      В этом обучающем модуле вы научитесь создавать кластер Kubernetes с помощью Ansible и Kubeadm, а затем развертывать в нем приложение Nginx в контейнерах.

      Цели

      Ваш кластер будет включать следующие физические ресурсы:

      • Один главный узел

      Главный узел (под узлом в Kubernetes подразумевается сервер), отвечающиой за управление состоянием кластера. На нем работает система Etcd, которая хранит данные кластера среди компонентов, распределяющих рабочие задачи по рабочим узлам.

      • Два рабочих узла

      Рабочие узлы — это серверы, где выполняются рабочие задачи (т. е. приложения и службы в контейнерах). Рабочий узел продолжает выполнять назначенную задачу, даже если главный узел отключается после распределения задач. Добавление рабочих узлов позволяет увеличить объем кластера.

      После прохождения данного обучающего модуля вы получите кластер, готовый к запуску приложений в контейнерах, при условии, что серверы кластера имеют достаточные ресурсы процессорной мощности и оперативной памяти для выполнения этих приложений. Практически любые традиционные приложения Unix, в том числе веб-приложения, базы данных, демоны и инструменты командной строки, можно поместить в контейнеры и запускать в кластере. Сам кластер потребляет примерно 300-500 МБ оперативной памяти и 10% ресурсов процессора на каждом узле.

      После настройки кластера вы развернете веб-сервер Nginx для проверки правильного выполнения рабочих задач.

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

      Шаг 1 — Настройка каталога рабочего пространства и файла инвентаризации Ansible

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

      Из трех ваших серверов один сервер будет главным сервером, и его IP-адрес будет отображаться как master_ip. Другие два сервера будут рабочими узлами и будут иметь IP-адреса worker_1_ip и worker_2_ip.

      Создайте каталог ~/kube-cluster в домашнем каталоге локального компьютера и перейдите в него с помощью команды cd:

      • mkdir ~/kube-cluster
      • cd ~/kube-cluster

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

      Создайте файл с именем ~/kube-cluster/hosts с помощью nano или своего любимого текстового редактора:

      • nano ~/kube-cluster/hosts

      Добавьте в файл следующий текст с информацией о логической структуре вашего кластера:

      ~/kube-cluster/hosts

      [masters]
      master ansible_host=master_ip ansible_user=root
      
      [workers]
      worker1 ansible_host=worker_1_ip ansible_user=root
      worker2 ansible_host=worker_2_ip ansible_user=root
      
      [all:vars]
      ansible_python_interpreter=/usr/bin/python3
      

      Возможно вы помните, что файлы инвентаризации в Ansible используются для указания данных серверов, в том числе IP-адресов, удаленных пользователей и группировок серверов как единый объем для целей выполнения команд. Файл ~/kube-cluster/hosts будет вашим файлом инвентаризации, и вы добавили в него две группы Ansible (masters и workers) для определения логической структуры вашего кластера.

      В группе masters имеется запись сервера master, в которой указан IP-адрес главного узла (master_ip) и указывается, что система Ansible должна запускать удаленные команды от имени пользователя root.

      В группе workers также есть две записи для серверов рабочих узлов (worker_1_ip и worker_2_ip), где пользователь ansible_user также задается как пользователь root.

      В последней строке файла Ansible предписывается использовать для операций управления интерпретаторы Python 3 удаленных серверов.

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

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

      Шаг 2 — Создание пользователя без привилегий root на всех удаленных серверах

      В этом разделе вы создадите пользователя без привилегий root с привилегиями sudo на всех серверах, чтобы вы могли вручную подключаться к ним через SSH как пользователь без привилегий. Это полезно на случай, если вы захотите посмотреть информацию о системе с помощью таких команд как top/htop, просмотреть список работающих контейнеров или изменить файлы конфигурации, принадлежащие пользователю root. Данные операции обычно выполняются во время технического обслуживания кластера, и использование пользователя без привилегий root для выполнения таких задач минимизирует риск изменения или удаления важных файлов или случайного выполнения других опасных операций.

      Создайте в рабочем пространстве файл с именем ~/kube-cluster/initial.yml:

      • nano ~/kube-cluster/initial.yml

      Добавьте в файл следующую строку сценария play для создания пользователя без привилегий root с привилегиями sudo на всех серверах. Сценарий в Ansible — это набор выполняемых шагов, нацеленных на определенные серверы и группы. Следующий сценарий создаст пользователя без привилегий root с привилегиями sudo:

      ~/kube-cluster/initial.yml

      - hosts: all
        become: yes
        tasks:
          - name: create the 'ubuntu' user
            user: name=ubuntu append=yes state=present createhome=yes shell=/bin/bash
      
          - name: allow 'ubuntu' to have passwordless sudo
            lineinfile:
              dest: /etc/sudoers
              line: 'ubuntu ALL=(ALL) NOPASSWD: ALL'
              validate: 'visudo -cf %s'
      
          - name: set up authorized keys for the ubuntu user
            authorized_key: user=ubuntu key="{{item}}"
            with_file:
              - ~/.ssh/id_rsa.pub
      

      Далее приведено детальное описание операций, выполняемых этим плейбуком:

      • Создает пользователя без привилегий root с именем ubuntu.

      • Настраивает файл sudoers, чтобы пользователь ubuntu мог запускать команды sudo без ввода пароля.

      • Добавляет на локальный компьютер открытый ключ (обычно ~/.ssh/id_rsa.pub) в список авторизованных ключей удаленного пользователя ubuntu. Это позволит вам подключаться к каждому серверу через SSH под именем пользователя ubuntu.

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

      Затем запустите плейбук на локальном компьютере:

      • ansible-playbook -i hosts ~/kube-cluster/initial.yml

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

      Output

      PLAY [all] **** TASK [Gathering Facts] **** ok: [master] ok: [worker1] ok: [worker2] TASK [create the 'ubuntu' user] **** changed: [master] changed: [worker1] changed: [worker2] TASK [allow 'ubuntu' user to have passwordless sudo] **** changed: [master] changed: [worker1] changed: [worker2] TASK [set up authorized keys for the ubuntu user] **** changed: [worker1] => (item=ssh-rsa AAAAB3...) changed: [worker2] => (item=ssh-rsa AAAAB3...) changed: [master] => (item=ssh-rsa AAAAB3...) PLAY RECAP **** master : ok=5 changed=4 unreachable=0 failed=0 worker1 : ok=5 changed=4 unreachable=0 failed=0 worker2 : ok=5 changed=4 unreachable=0 failed=0

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

      Шаг 3 — Установка зависимостей Kubernetetes

      В этом разделе вы научитесь устанавливать требующиеся Kubernetes пакеты уровня операционной системы с помощью диспетчера пакетов Ubuntu. Вот эти пакеты:

      • Docker — среда исполнения контейнеров. Это компонент, который запускает ваши контейнеры. В настоящее время для Kubernetes активно разрабатывается поддержка других сред исполнения, в том числе rkt.

      • kubeadm — инструмент командной строки, который устанавливает и настраивает различные компоненты кластера стандартным образом.

      • kubelet — системная служба / программа, которая работает на всех узлах и обрабатывает операции на уровне узлов.

      • kubectl — инструмент командной строки, используемый для отправки команд на кластер через сервер API.

      Создайте в рабочем пространстве файл с именем ~/kube-cluster/kube-dependencies.yml:

      • nano ~/kube-cluster/kube-dependencies.yml

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

      ~/kube-cluster/kube-dependencies.yml

      - hosts: all
        become: yes
        tasks:
         - name: install Docker
           apt:
             name: docker.io
             state: present
             update_cache: true
      
         - name: install APT Transport HTTPS
           apt:
             name: apt-transport-https
             state: present
      
         - name: add Kubernetes apt-key
           apt_key:
             url: https://packages.cloud.google.com/apt/doc/apt-key.gpg
             state: present
      
         - name: add Kubernetes' APT repository
           apt_repository:
            repo: deb http://apt.kubernetes.io/ kubernetes-xenial main
            state: present
            filename: 'kubernetes'
      
         - name: install kubelet
           apt:
             name: kubelet=1.14.0-00
             state: present
             update_cache: true
      
         - name: install kubeadm
           apt:
             name: kubeadm=1.14.0-00
             state: present
      
      - hosts: master
        become: yes
        tasks:
         - name: install kubectl
           apt:
             name: kubectl=1.14.0-00
             state: present
             force: yes
      

      Первый сценарий в плейбуке выполняет следующие операции:

      • Устанавливает среду исполнения контейнеров Docker.

      • Устанавливает apt-transport-https, позволяя добавлять внешние источники HTTPS в список источников APT.

      • Добавляет ключ apt-key репозитория Kubernetes APT для проверки ключей.

      • Добавляет репозиторий Kubernetes APT в список источников APT ваших удаленных серверов.

      • Устанавливает kubelet и kubeadm.

      Второй сценарий состоит из одной задачи, которая устанавливает kubectl на главном узле.

      Примечание. Хотя документация по Kubernetes рекомендует использовать для вашей среды последнюю стабильную версию Kubernetes, в данном обучающем модуле используется конкретная версия. Это обеспечит успешное следование процедуре, поскольку Kubernetes быстро изменяется и последняя версия может не соответствовать этому обучающему модулю.

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

      Затем запустите плейбук на локальном компьютере:

      • ansible-playbook -i hosts ~/kube-cluster/kube-dependencies.yml

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

      Output

      PLAY [all] **** TASK [Gathering Facts] **** ok: [worker1] ok: [worker2] ok: [master] TASK [install Docker] **** changed: [master] changed: [worker1] changed: [worker2] TASK [install APT Transport HTTPS] ***** ok: [master] ok: [worker1] changed: [worker2] TASK [add Kubernetes apt-key] ***** changed: [master] changed: [worker1] changed: [worker2] TASK [add Kubernetes' APT repository] ***** changed: [master] changed: [worker1] changed: [worker2] TASK [install kubelet] ***** changed: [master] changed: [worker1] changed: [worker2] TASK [install kubeadm] ***** changed: [master] changed: [worker1] changed: [worker2] PLAY [master] ***** TASK [Gathering Facts] ***** ok: [master] TASK [install kubectl] ****** ok: [master] PLAY RECAP **** master : ok=9 changed=5 unreachable=0 failed=0 worker1 : ok=7 changed=5 unreachable=0 failed=0 worker2 : ok=7 changed=5 unreachable=0 failed=0

      После выполнения на всех удаленных серверах будут установлены Docker, kubeadm и kubelet. kubectl не является обязательным компонентом и требуется только для выполнения команд кластера. В этом контексте имеет смысл производить установку только на главный узел, поскольку вы будете запускать команды kubectl только на главном узле. Однако следует отметить, что команды kubectl можно запускать с любых рабочих узлов и на любом компьютере, где их можно установить и настроить для указания на кластер.

      Теперь все системные зависимости установлены. Далее мы настроим главный узел и проведем инициализацию кластера.

      Шаг 4 — Настройка главного узла

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

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

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

      Эту функцию обеспечивают плагины сети подов. Для этого кластера мы используем стабильный и производительный плагин Flannel.

      Создайте на локальном компьютере плейбук Ansible с именем master.yml:

      • nano ~/kube-cluster/master.yml

      Добавьте в файл следующий сценарий для инициализации кластера и установки Flannel:

      ~/kube-cluster/master.yml

      - hosts: master
        become: yes
        tasks:
          - name: initialize the cluster
            shell: kubeadm init --pod-network-cidr=10.244.0.0/16 >> cluster_initialized.txt
            args:
              chdir: $HOME
              creates: cluster_initialized.txt
      
          - name: create .kube directory
            become: yes
            become_user: ubuntu
            file:
              path: $HOME/.kube
              state: directory
              mode: 0755
      
          - name: copy admin.conf to user's kube config
            copy:
              src: /etc/kubernetes/admin.conf
              dest: /home/ubuntu/.kube/config
              remote_src: yes
              owner: ubuntu
      
          - name: install Pod network
            become: yes
            become_user: ubuntu
            shell: kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/a70459be0084506e4ec919aa1c114638878db11b/Documentation/kube-flannel.yml >> pod_network_setup.txt
            args:
              chdir: $HOME
              creates: pod_network_setup.txt
      

      Далее приведена детализация этого сценария:

      • Первая задача инициализирует кластер посредством запуска kubeadm init. При передаче аргумента --pod-network-cidr=10.244.0.0/16 задается частная подсеть, из которой назначаются IP-адреса подов. Flannel использует вышеуказанную подсеть по умолчанию, и мы предпишем kubeadm использовать ту же подсеть.

      • Вторая задача создает каталог .kube по адресу /home/ubuntu. В это каталоге будут храниться данные конфигурации, в том числе файлы ключа администратора, необходимые для подключения к кластеру, и адрес API кластера.

      • Третья задача копирует файл /etc/kubernetes/admin.conf, сгенерированный kubeadm init в домашнем каталоге пользователя без привилегий root. Это позволит вам использовать kubectl для доступа к новому кластеру.

      • Последняя задача запускает kubectl apply для установки Flannel. Синтаксис kubectl apply -f descriptor.[yml|json] предписывает kubectl создать объекты, описанные в файле descriptor.[yml|json]. Файл kube-flannel.yml содержит описания объектов, требуемых для настроки Flannel в кластере.

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

      Запустите плейбук на локальной системе с помощью команды:

      • ansible-playbook -i hosts ~/kube-cluster/master.yml

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

      Output

      PLAY [master] **** TASK [Gathering Facts] **** ok: [master] TASK [initialize the cluster] **** changed: [master] TASK [create .kube directory] **** changed: [master] TASK [copy admin.conf to user's kube config] ***** changed: [master] TASK [install Pod network] ***** changed: [master] PLAY RECAP **** master : ok=5 changed=4 unreachable=0 failed=0

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

      Запустите на главном узле следующую команду:

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

      Output

      NAME STATUS ROLES AGE VERSION master Ready master 1d v1.14.0

      В результатах показано, что главный узел master завершил выполнение всех задач инициализации и находится в состоянии готовности Ready, из которого он может принимать подключения от рабочих узлов и выполнять задачи, отправленные на сервер API. Теперь вы можете добавить рабочие узлы с локального компьютера.

      Шаг 5 — Настройка рабочих узлов

      Для добавления рабочих узлов в кластер нужно запустить на каждом из них отдельную команду. Эта команда предоставляет всю необходимую информацию о кластере, включая IP-адрес, порт сервера API главного узла и защищенный токен. К кластеру могут подключаться только те узлы, которые проходят проверку с защищенным токеном.

      Вернитесь в рабочее пространство и создайте плейбук с именем workers.yml:

      • nano ~/kube-cluster/workers.yml

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

      ~/kube-cluster/workers.yml

      - hosts: master
        become: yes
        gather_facts: false
        tasks:
          - name: get join command
            shell: kubeadm token create --print-join-command
            register: join_command_raw
      
          - name: set join command
            set_fact:
              join_command: "{{ join_command_raw.stdout_lines[0] }}"
      
      
      - hosts: workers
        become: yes
        tasks:
          - name: join cluster
            shell: "{{ hostvars['master'].join_command }} >> node_joined.txt"
            args:
              chdir: $HOME
              creates: node_joined.txt
      

      Вот что делает этот плейбук:

      • Первый сценарий получает команду join, которую нужно запустить на рабочих узлах. Эта команда имеет следующий форматt: kubeadm join --token <token> <master-ip>:<master-port> --discovery-token-ca-cert-hash sha256:<hash>. После получения фактической команды с правильными значениями token и hash задача задает их как фактические, чтобы следующий сценарий имел доступ к этой информации.

      • Второй сценарий содержит одну задачу, которая запускает команду join на всех рабочих узлах. После завершения этой задачи два рабочих узла становятся частью кластера.

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

      Запустите плейбук на локальном компьютере:

      • ansible-playbook -i hosts ~/kube-cluster/workers.yml

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

      Output

      PLAY [master] **** TASK [get join command] **** changed: [master] TASK [set join command] ***** ok: [master] PLAY [workers] ***** TASK [Gathering Facts] ***** ok: [worker1] ok: [worker2] TASK [join cluster] ***** changed: [worker1] changed: [worker2] PLAY RECAP ***** master : ok=2 changed=1 unreachable=0 failed=0 worker1 : ok=2 changed=1 unreachable=0 failed=0 worker2 : ok=2 changed=1 unreachable=0 failed=0

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

      Шаг 6 — Проверка кластера

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

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

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

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

      Output

      NAME STATUS ROLES AGE VERSION master Ready master 1d v1.14.0 worker1 Ready <none> 1d v1.14.0 worker2 Ready <none> 1d v1.14.0

      Если на всех ваших узлах отображается значение Ready для параметра STATUS, это означает, что они являются частью кластера и готовы к выполнению рабочих задач.

      Если же на некоторых узлах отображается значение NotReady для параметра STATUS, это может означать, что настройка рабочих узлов еще не завершена. Подождите от пяти до десяти минут, а затем снова запустите команду kubectl get nodes и проверьте полученные результаты. Если для некоторых узлов еще отображается статус NotReady, вам нужно проверить и заново запустить команды, которые выполнялись на предыдущих шагах.

      Теперь кластер успешно проверен, и мы запланируем запуск на кластере образца приложения Nginx.

      Шаг 7 — Запуск приложения на кластере

      Теперь вы можете развернуть на кластере любое приложение в контейнере. Для удобства мы развернем Nginx с помощью Deployments и Services и посмотрим, как можно развернуть это приложение на кластере. Вы можете использовать приведенные ниже команды для других приложений в контейнерах, если вы измените имя образа Docker и дополнительные параметры (такие как ports и volumes).

      Запустите на главном узле следующую команду для создания развертывания с именем nginx:

      • kubectl create deployment nginx --image=nginx

      Развертывание — это тип объекта Kubernetes, обеспечивающий постоянную работу определенного количества подов на основе заданного шаблона, даже в случае неисправности пода в течение срока службы кластера. Вышеуказанное развертывание создаст под с одним контейнером из образа Nginx Docker в реестре Docker.

      Запустите следующую команду, чтобы создать службу nginx, которая сделает приложение общедоступным. Для этого используется схема NodePort, которая делает под доступным на произвольном порту, который открывается на каждом узле кластера:

      • kubectl expose deploy nginx --port 80 --target-port 80 --type NodePort

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

      Запустите следующую команду:

      Будет выведен текст следующего вида:

      Output

      NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 1d nginx NodePort 10.109.228.209 <none> 80:nginx_port/TCP 40m

      В третьей сроке результатов указан номер порта, на котором запущен Nginx. Kubernetes автоматически назначает случайный порт с номером выше 30000 и при этом проверяет, не занят ли этот порт другой службой.

      Чтобы убедиться в работе всех элементов, откройте адрес http://worker_1_ip:nginx_port или http://worker_2_ip:nginx_port в браузере на локальном компьютере. Вы увидите знакомую начальную страницу Nginx.

      Если вы захотите удалить приложение Nginx, предварительно удалите службу nginx с главного узла:

      • kubectl delete service nginx

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

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

      Output

      NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 1d

      Затем удалите развертывание:

      • kubectl delete deployment nginx

      Запустите следующую команду для проверки успешности выполнения:

      Output

      No resources found.

      Заключение

      В этом обучающем модуле вы научились успешно настраивать кластер Kubernetes в Ubuntu 18.04, используя для автоматизации Kubeadm и Ansible.

      Если вы не знаете, что дальше делать с настроенным кластером, попробуйте развернуть на нем собственные приложения и службы. Далее приведен список ссылок с дополнительной информацией, которая будет вам полезна:

      • Докеризация приложений — детальные примеры контейнеризации приложений с помощью Docker.

      • Обзор подов — детальное описание принципов работы подов и их отношений с другими объектами Kubernetes. Поды используются в Kubernetes повсеместно, так что понимание этой концепции упростит вашу работу.

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

      • Обзор служб — рассказывает о службах, еще одном часто используемом объекте кластеров Kubernetes. Понимание типов служб и доступных для них опций важно для использования приложений с сохранением состояния и без сохранения состояния.

      Другие важные концепции, полезные при развертывании рабочих приложений: тома, входы и секреты.

      В Kubernetes имеется множество функций и возможностей. Официальная документация Kubernetes — лучший источник информации о концепциях, руководств по конкретным задачам и ссылок API для различных объектов.



      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