Как установить стек журналирования Elasticsearch, Fluentd и Kibana (EFK) в Ubuntu 22.04
Мониторинг и анализ журналов являются важной частью серверной или контейнерной инфраструктуры и полезны при работе со сложными приложениями. Одним из популярных решений для ведения журналов является стек Elasticsearch, Fluentd и Kibana (EFK). Прежде чем продолжить изучение руководства, давайте узнаем о компонентах стека.
Elasticsearch — это распределенная и масштабируемая поисковая система, работающая в режиме реального времени, которая позволяет осуществлять полнотекстовый поиск и анализ. Он используется для индексации и поиска в больших объемах данных. Обычно он развертывается вместе с Kibana, мощной панелью визуализации данных для Elasticsearch. Kibana позволяет вам исследовать данные журнала Elasticsearch и создавать информационные панели и запросы, чтобы получить представление о вашем приложении. Fluentd собирает, преобразует и отправляет данные журнала в серверную часть Elasticsearch.
В этом руководстве мы установим стек EFK с помощью Docker на компьютере с Ubuntu 22.04 и отправим журналы контейнера в Kibana после их фильтрации и преобразования с помощью Fluentd.
Предварительные условия
Сервер под управлением Ubuntu 22.04 с минимум 6 ГБ ОЗУ.
Пользователь без полномочий root с привилегиями sudo.
Несложный межсетевой экран (UFW) включен и работает.
Полное доменное имя (FQDN), указывающее на сервер, например kibana.example.com
.
Все обновляется.
$ sudo apt update && sudo apt upgrade
Шаг 1. Настройка брандмауэра
Прежде чем устанавливать какие-либо пакеты, первым делом необходимо настроить брандмауэр для разрешения соединений HTTP и HTTPS.
Проверьте состояние брандмауэра.
$ sudo ufw status
Вы должны увидеть что-то вроде следующего.
Status: active
To Action From
-- ------ ----
OpenSSH ALLOW Anywhere
OpenSSH (v6) ALLOW Anywhere (v6)
Разрешите порты HTTP и HTTPs.
$ sudo ufw allow http
$ sudo ufw allow https
Проверьте статус еще раз для подтверждения.
$ sudo ufw status
Status: active
To Action From
-- ------ ----
OpenSSH ALLOW Anywhere
80/tcp ALLOW Anywhere
443 ALLOW Anywhere
OpenSSH (v6) ALLOW Anywhere (v6)
80/tcp (v6) ALLOW Anywhere (v6)
443 (v6) ALLOW Anywhere (v6)
Шаг 2. Установите Docker и Docker Compose.
Добавьте официальный ключ GPG Docker.
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker.gpg
Выполните следующую команду, чтобы добавить репозиторий Docker.
$ echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
Обновите систему, включив в нее репозиторий Docker.
$ sudo apt update
Установите Docker и плагин Docker Compose.
$ sudo apt install docker-ce docker-ce-cli containerd.io docker-compose-plugin
В этом руководстве будет использоваться плагин Docker Compose v2 вместо устаревшего двоичного файла. Поэтому команда для его запуска изменилась с docker-compose
на docker compose
и это отражено здесь.
Docker работает с повышенными привилегиями, поэтому вам придется часто использовать sudo
для запуска команд. Лучшим вариантом будет добавить свою учетную запись пользователя Linux в группу пользователей docker
.
$ sudo usermod -aG docker ${USER}
Переменная $ {USER}
выбирает текущую системную учетную запись, с которой выполнен вход. Если вы не вошли в систему под пользователем, которому хотите предоставить права, замените $ {USER}
на имя пользователя.
Чтобы подать заявку на членство в новой группе, выйдите из сервера и снова войдите в него или используйте следующую команду. Вам будет предложено ввести пароль пользователя.
$ su - ${USER}
Шаг 3. Создайте файл Docker Compose
Сначала создайте каталог для проекта EFK.
$ mkdir ~/efk
Перейдите в каталог.
$ cd ~/efk
Создайте и откройте файл docker-compose.yml
для редактирования.
$ nano docker-compose.yml
Вставьте в него следующий код.
services:
# Deploy using the custom image automatically be created during the build process.
fluentd:
build: ./fluentd
volumes:
- ./fluentd/conf:/fluentd/etc
links: # Sends incoming logs to the elasticsearch container.
- elasticsearch
depends_on:
- elasticsearch
ports: # Exposes the port 24224 on both TCP and UDP protocol for log aggregation
- 24224:24224
- 24224:24224/udp
elasticsearch:
image: elasticsearch:8.7.1
expose:
- 9200
environment:
- discovery.type=single-node # Runs as a single-node
- xpack.security.enabled=false
volumes: # Stores elasticsearch data locally on the esdata Docker volume
- esdata:/usr/share/elasticsearch/data
kibana:
image: kibana:8.7.1
links: # Links kibana service to the elasticsearch container
- elasticsearch
depends_on:
- elasticsearch
ports:
- 5601:5601
environment: # Defined host configuration
- ELASTICSEARCH_HOSTS=http://elasticsearch:9200
# Define the Docker volume named esdata for the Elasticsearch container.
volumes:
esdata:
Сохраните файл, нажав Ctrl + X и введя Y при появлении запроса. Мы настроили запуск трех сервисов, по одному на каждый: Fluentd, Elasticsearch и Kibana.
Для Fluentd вместо готового образа мы создадим контейнер. Файлы сборки для Fluentd будут настроены на следующем этапе. Мы смонтировали каталог для файлов сборки и том для файлов конфигурации, а также открыли порт 24224 как для протоколов TCP, так и для UDP для агрегирования журналов.
Следующий сервис — Elasticsearch, и мы используем последнюю версию, доступную на момент написания этого руководства. Мы открыли его через порт 9200 и настроили несколько переменных среды, чтобы мы могли запускать его как одноузловой кластер, и отключили функции безопасности. Обычно это не рекомендуется, но включение безопасности выходит за рамки данного руководства. Мы также подключили локальный том для данных Elasticsearch.
Наконец, мы настраиваем Kibana и открываем его через порт 5601, который будет использоваться для доступа к панели управления. Мы также настроили переменную для настройки хоста Elasticsearch для доступа к нему.
Шаг 4. Настройка файлов сборки Fluentd
Создайте Fluentd и каталог конфигурации.
$ mkdir fluentd/conf -p
Запустите команду tree
, чтобы проверить структуру каталогов.
$ tree
Это должно выглядеть следующим образом.
Перейдите в каталог Fluentd.
$ cd fluentd
Создайте и откройте Dockerfile
для редактирования.
$ nano Dockerfile
Вставьте в него следующий код. Этот код извлекает образ Fluentd Debian Docker и устанавливает плагин Fluentd для Elasticsearch.
# fluentd/Dockerfile
FROM fluent/fluentd:v1.16-debian-1
USER root
RUN ["gem", "install", "fluent-plugin-elasticsearch", "--no-document", "--version", "5.3.0"]
USER fluent
Сохраните файл, нажав Ctrl + X и введя Y при появлении запроса.
Перейдите в каталог конфигурации.
$ cd conf
Создайте и откройте файл fluentd.conf
для редактирования.
$ nano fluentd.conf
Вставьте в него следующий код.
# bind fluentd on IP 0.0.0.0
# port 24224
<source>
@type forward
port 24224
bind 0.0.0.0
</source>
# sendlog to the elasticsearch
# the host must match to the elasticsearch
# container service
<match *.**>
@type copy
<store>
@type elasticsearch_dynamic
hosts elasticsearch:9200
logstash_format true
logstash_prefix fluentd
logstash_dateformat %Y%m%d
include_tag_key true
tag_key @log_name
include_timestamp true
flush_interval 30s
</store>
<store>
@type stdout
</store>
</match>
Сохраните файл, нажав Ctrl + X и введя Y при появлении запроса.
Приведенная выше директива source использует плагин forward
, который превращает Fluentd в конечную точку TCP для приема TCP-пакетов.
Директива match ищет события с совпадающими тегами, что в данном случае означает, что она соответствует всем событиям. Мы будем использовать плагин elasticsearch_dynamic
для хранения, который позволяет динамически указывать значения конфигурации. Поле hosts
указывает имя хоста для приложения Elasticsearch, которое является именем службы в файле компоновки Docker. Для logstash_format
установлено значение true, что означает, что Fluentd использует традиционный формат имени logstash-%Y.%m.%dlogstash-%Y.%m.%d
. Имя префикса для записи событий установлено как fluend
. Для include_tag_key
установлено значение true, что добавляет тег Fluentd в формате JSON. tag_key
— это имя поля, которое нужно извлечь для тега. Если для переменной include_timestamp
установлено значение true, в журнал добавляется поле временной метки. flush_interval
определяет интервал между сбросами данных. Мы также используем плагин stdout
для вывода событий/журналов на стандартный вывод.
Шаг 5. Запустите Docker-контейнеры
Вернитесь в каталог EFK.
$ cd ~/efk
Запустите контейнеры с помощью следующей команды.
$ docker compose up -d
Проверьте состояние запущенных контейнеров.
$ docker ps
b3780c311154 efk-fluentd "tini -- /bin/entryp…" 9 seconds ago Up 8 seconds 5140/tcp, 0.0.0.0:24224->24224/tcp, 0.0.0.0:24224->24224/udp, :::24224->24224/tcp, :::24224->24224/udp efk-fluentd-1
5a48f0a9ade1 kibana:8.7.1 "/bin/tini -- /usr/l…" 9 seconds ago Up 7 seconds 0.0.0.0:5601->5601/tcp, :::5601->5601/tcp efk-kibana-1
dab3a0ab0312 elasticsearch:8.7.1 "/bin/tini -- /usr/l…" 9 seconds ago Up 8 seconds 9200/tcp, 9300/tcp efk-elasticsearch-1
Вы также можете использовать для этого следующую команду.
$ docker compose ps
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
efk-elasticsearch-1 elasticsearch:8.7.1 "/bin/tini -- /usr/l…" elasticsearch 37 seconds ago Up 36 seconds 9200/tcp, 9300/tcp
efk-fluentd-1 efk-fluentd "tini -- /bin/entryp…" fluentd 37 seconds ago Up 36 seconds 5140/tcp, 0.0.0.0:24224->24224/tcp, 0.0.0.0:24224->24224/udp, :::24224->24224/tcp, :::24224->24224/udp
efk-kibana-1 kibana:8.7.1 "/bin/tini -- /usr/l…" kibana 37 seconds ago Up 36 seconds 0.0.0.0:5601->5601/tcp, :::5601->5601/tcp
Выполните следующие команды, чтобы проверить журналы процесса сборки EFK.
$ docker logs efk-fluentd-1
$ docker logs efk-kibana-1
$ docker logs efk-elasticsearch-1
Осмотрите контейнер Elasticsearch. Он распечатает подробные настройки контейнера.
$ docker inspect efk-elasticsearch-1
Вы можете заметить IP-адрес, присвоенный контейнеру.
[
{
"Id": "dab3a0ab03120d3a7192045e1ea84fdd0f8fdb7819cc6d6780e05109d61e0b66",
"Created": "2023-05-04T09:58:00.256169904Z",
"Path": "/bin/tini",
"Args": [
"--",
"/usr/local/bin/docker-entrypoint.sh",
"eswrapper"
],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 23619,
"ExitCode": 0,
"Error": "",
"StartedAt": "2023-05-04T09:58:00.563700803Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
"Image": "sha256:59075530be34d3a06866f894ae9735f6d739a7a751ad45efb86dec3c9bd16836",
"ResolvConfPath": "/var/lib/docker/containers/dab3a0ab03120d3a7192045e1ea84fdd0f8fdb7819cc6d6780e05109d61e0b66/resolv.conf",
"HostnamePath": "/var/lib/docker/containers/dab3a0ab03120d3a7192045e1ea84fdd0f8fdb7819cc6d6780e05109d61e0b66/hostname",
"HostsPath": "/var/lib/docker/containers/dab3a0ab03120d3a7192045e1ea84fdd0f8fdb7819cc6d6780e05109d61e0b66/hosts",
"LogPath": "/var/lib/docker/containers/dab3a0ab03120d3a7192045e1ea84fdd0f8fdb7819cc6d6780e05109d61e0b66/dab3a0ab03120d3a7192045e1ea84fdd0f8fdb7819cc6d6780e05109d61e0b66-json.log",
"Name": "/efk-elasticsearch-1",
"RestartCount": 0,
"Driver": "overlay2",
"Platform": "linux",
"MountLabel": "",
"ProcessLabel": "",
"AppArmorProfile": "docker-default",
"ExecIDs": null,
"HostConfig": {
"Binds": null,
"ContainerIDFile": "",
"LogConfig": {
"Type": "json-file",
"Config": {}
},
"NetworkMode": "efk_default",
"PortBindings": {},
"RestartPolicy": {
"Name": "",
"MaximumRetryCount": 0
},
"AutoRemove": false,
"VolumeDriver": "",
"VolumesFrom": null,
"ConsoleSize": [
0,
0
],
"CapAdd": null,
"CapDrop": null,
"CgroupnsMode": "private",
"Dns": null,
"DnsOptions": null,
"DnsSearch": null,
"ExtraHosts": [],
"GroupAdd": null,
"IpcMode": "private",
"Cgroup": "",
"Links": null,
"OomScoreAdj": 0,
"PidMode": "",
"Privileged": false,
"PublishAllPorts": false,
"ReadonlyRootfs": false,
"SecurityOpt": null,
"UTSMode": "",
"UsernsMode": "",
"ShmSize": 67108864,
"Runtime": "runc",
"Isolation": "",
"CpuShares": 0,
"Memory": 0,
"NanoCpus": 0,
"CgroupParent": "",
"BlkioWeight": 0,
"BlkioWeightDevice": null,
"BlkioDeviceReadBps": null,
"BlkioDeviceWriteBps": null,
"BlkioDeviceReadIOps": null,
"BlkioDeviceWriteIOps": null,
"CpuPeriod": 0,
"CpuQuota": 0,
"CpuRealtimePeriod": 0,
"CpuRealtimeRuntime": 0,
"CpusetCpus": "",
"CpusetMems": "",
"Devices": null,
"DeviceCgroupRules": null,
"DeviceRequests": null,
"MemoryReservation": 0,
"MemorySwap": 0,
"MemorySwappiness": null,
"OomKillDisable": null,
"PidsLimit": null,
"Ulimits": null,
"CpuCount": 0,
"CpuPercent": 0,
"IOMaximumIOps": 0,
"IOMaximumBandwidth": 0,
"Mounts": [
{
"Type": "volume",
"Source": "efk_esdata",
"Target": "/usr/share/elasticsearch/data",
"VolumeOptions": {}
}
],
"MaskedPaths": [
"/proc/asound",
"/proc/acpi",
"/proc/kcore",
"/proc/keys",
"/proc/latency_stats",
"/proc/timer_list",
"/proc/timer_stats",
"/proc/sched_debug",
"/proc/scsi",
"/sys/firmware"
],
"ReadonlyPaths": [
"/proc/bus",
"/proc/fs",
"/proc/irq",
"/proc/sys",
"/proc/sysrq-trigger"
]
},
"GraphDriver": {
"Data": {
"LowerDir": "/var/lib/docker/overlay2/ee03648cf34e03601848b1769569b4d3bb7192db118102ca050215ba87060bbf-init/diff:/var/lib/docker/overlay2/51d6cfcb59e473a3f163e68984a1ba1325a2c816ed7925c4dffdefcf2e104d11/diff:/var/lib/docker/overlay2/b9c096454bda31f1cb2ea33f108be8b29b2e94827ebe94cc17563eb596b7cab1/diff:/var/lib/docker/overlay2/effe604c5b015ba02cf3b7a238bd3ff5dad7970a72e689ef5275fcf03fd0bcd1/diff:/var/lib/docker/overlay2/72fbf23251467ea2f6af8d9458c7fdd8fa3ef716eeafd9319ceff59d07d96788/diff:/var/lib/docker/overlay2/02094ec9e4ebb04371f782744a3a46852a00bf6fd7e8820d466a3576aeb9d5fc/diff:/var/lib/docker/overlay2/ce364cdd636b67e10c879aa152360d965d08fe456663ed8fbe78c3bd37bde6c7/diff:/var/lib/docker/overlay2/33bf44b475ea5ea249845b7eed75ded47dd9dc7877b9231fa4195b4753071945/diff:/var/lib/docker/overlay2/4f19bd8089599ef879075012c710ec464d8e0446fc0a0813850657dddd23a5dc/diff:/var/lib/docker/overlay2/a39a61b12d8565c6d5b33c17a04d47c8bd47609a787e0548fbac0d47d00eecc8/diff:/var/lib/docker/overlay2/cbd9d77eb9ed6b600511f9a676aab511d2aa2b3dbd18d5403559699558546996/diff",
"MergedDir": "/var/lib/docker/overlay2/ee03648cf34e03601848b1769569b4d3bb7192db118102ca050215ba87060bbf/merged",
"UpperDir": "/var/lib/docker/overlay2/ee03648cf34e03601848b1769569b4d3bb7192db118102ca050215ba87060bbf/diff",
"WorkDir": "/var/lib/docker/overlay2/ee03648cf34e03601848b1769569b4d3bb7192db118102ca050215ba87060bbf/work"
},
"Name": "overlay2"
},
"Mounts": [
{
"Type": "volume",
"Name": "efk_esdata",
"Source": "/var/lib/docker/volumes/efk_esdata/_data",
"Destination": "/usr/share/elasticsearch/data",
"Driver": "local",
"Mode": "z",
"RW": true,
"Propagation": ""
}
],
"Config": {
"Hostname": "dab3a0ab0312",
"Domainname": "",
"User": "elasticsearch:root",
"AttachStdin": false,
"AttachStdout": true,
"AttachStderr": true,
"ExposedPorts": {
"9200": {},
"9200/tcp": {},
"9300/tcp": {}
},
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"xpack.security.enabled=false",
"discovery.type=single-node",
"PATH=/usr/share/elasticsearch/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"ELASTIC_CONTAINER=true"
],
"Cmd": [
"eswrapper"
],
"Image": "elasticsearch:8.7.1",
"Volumes": null,
"WorkingDir": "/usr/share/elasticsearch",
"Entrypoint": [
"/bin/tini",
"--",
"/usr/local/bin/docker-entrypoint.sh"
],
"OnBuild": null,
"Labels": {
"com.docker.compose.config-hash": "51c818791aa87ea7eccc389578c76ec4d596265eba8baefb8833bf5df13777e3",
"com.docker.compose.container-number": "1",
"com.docker.compose.depends_on": "",
"com.docker.compose.image": "sha256:59075530be34d3a06866f894ae9735f6d739a7a751ad45efb86dec3c9bd16836",
"com.docker.compose.oneoff": "False",
"com.docker.compose.project": "efk",
"com.docker.compose.project.config_files": "/home/navjot/efk/docker-compose.yml",
"com.docker.compose.project.working_dir": "/home/navjot/efk",
"com.docker.compose.service": "elasticsearch",
"com.docker.compose.version": "2.17.3",
"org.label-schema.build-date": "2023-04-27T04:33:42.127815583Z",
"org.label-schema.license": "Elastic-License-2.0",
"org.label-schema.name": "Elasticsearch",
"org.label-schema.schema-version": "1.0",
"org.label-schema.url": "https://www.elastic.co/products/elasticsearch",
"org.label-schema.usage": "https://www.elastic.co/guide/en/elasticsearch/reference/index.html",
"org.label-schema.vcs-ref": "f229ed3f893a515d590d0f39b05f68913e2d9b53",
"org.label-schema.vcs-url": "https://github.com/elastic/elasticsearch",
"org.label-schema.vendor": "Elastic",
"org.label-schema.version": "8.7.1",
"org.opencontainers.image.created": "2023-04-27T04:33:42.127815583Z",
"org.opencontainers.image.documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/index.html",
"org.opencontainers.image.licenses": "Elastic-License-2.0",
"org.opencontainers.image.ref.name": "ubuntu",
"org.opencontainers.image.revision": "f229ed3f893a515d590d0f39b05f68913e2d9b53",
"org.opencontainers.image.source": "https://github.com/elastic/elasticsearch",
"org.opencontainers.image.title": "Elasticsearch",
"org.opencontainers.image.url": "https://www.elastic.co/products/elasticsearch",
"org.opencontainers.image.vendor": "Elastic",
"org.opencontainers.image.version": "8.7.1"
}
},
"NetworkSettings": {
"Bridge": "",
"SandboxID": "bf47cd7764585766349085d35100611e086cf233fc9fc655c6eb9e086f1cd59a",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": {
"9200/tcp": null,
"9300/tcp": null
},
"SandboxKey": "/var/run/docker/netns/bf47cd776458",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "",
"Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "",
"IPPrefixLen": 0,
"IPv6Gateway": "",
"MacAddress": "",
"Networks": {
"efk_default": {
"IPAMConfig": null,
"Links": null,
"Aliases": [
"efk-elasticsearch-1",
"elasticsearch",
"dab3a0ab0312"
],
"NetworkID": "1bc8ac0185982b84a24a201852f2cddc0432a3ffff1a2bd4008074875f696cac",
"EndpointID": "e1c67199e679f350d1da47f0b1e208ec6a7767eb57d60f773ba08b88a6962dcf",
"Gateway": "172.23.0.1",
"IPAddress": "172.23.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:17:00:02",
"DriverOpts": null
}
}
}
}
]
Как видите, контейнер получил IP-адрес 172.23.0.2
. Выполните следующую команду, чтобы проверить, правильно ли работает Elasticsearch.
$ curl 172.23.0.2:9200
{
"name" : "dab3a0ab0312",
"cluster_name" : "docker-cluster",
"cluster_uuid" : "gldMFBtQSxS5sL93rBAdzA",
"version" : {
"number" : "8.7.1",
"build_flavor" : "default",
"build_type" : "docker",
"build_hash" : "f229ed3f893a515d590d0f39b05f68913e2d9b53",
"build_date" : "2023-04-27T04:33:42.127815583Z",
"build_snapshot" : false,
"lucene_version" : "9.5.0",
"minimum_wire_compatibility_version" : "7.17.0",
"minimum_index_compatibility_version" : "7.0.0"
},
"tagline" : "You Know, for Search"
}
Шаг 6 — Настройка Кибаны
Теперь, когда стек EFK развернут, пришло время настроить Kibana. Откройте URL-адрес http://
в браузере.
Нажмите кнопку Исследовать самостоятельно, чтобы перейти на панель управления Kibana.
Нажмите ссылку Управление стеком, чтобы настроить представление данных Kibana. Выберите опцию Kibana >> Просмотр данных на левой боковой панели, чтобы открыть страницу просмотра данных.
Нажмите кнопку Создать представление данных, чтобы продолжить.
Введите имя представления данных и шаблон индекса в виде fluentd-*
. Убедитесь, что в поле Timestamp установлено значение @timestamp
. Поле источника будет автоматически обновлено. Нажмите кнопку Сохранить представление данных в Kibana, чтобы завершить создание представления данных.
Затем щелкните верхнее меню (многоточие) и выберите параметр Обнаружение, чтобы отобразить журналы мониторинга.
Вы получите следующую страницу, подтверждающую, что ваша установка работает отлично. Все журналы берутся из Elasticsearch и отправляются агрегатором журналов Fluentd.
Шаг 7 — Установите Nginx
Ubuntu 22.04 поставляется с более старой версией Nginx. Вам необходимо скачать официальный репозиторий Nginx, чтобы установить последнюю версию.
Импортируйте ключ подписи Nginx.
$ curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor \
| sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null
Добавьте репозиторий стабильной версии Nginx.
$ echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg arch=amd64] \
http://nginx.org/packages/ubuntu `lsb_release -cs` nginx" \
| sudo tee /etc/apt/sources.list.d/nginx.list
Обновите системные репозитории.
$ sudo apt update
Установите Нгинкс.
$ sudo apt install nginx
Проверьте установку.
$ nginx -v
nginx version: nginx/1.24.0
Запустите сервер Nginx.
$ sudo systemctl start nginx
Шаг 8 — Установите SSL
Первым шагом является установка SSL-сертификата Let's Encrypt. Нам нужно установить Certbot для создания SSL-сертификата. Вы можете либо установить Certbot, используя репозиторий Ubuntu, либо получить последнюю версию с помощью инструмента Snapd. Мы будем использовать версию Snapd.
В Ubuntu 22.04 по умолчанию установлен Snapd. Выполните следующие команды, чтобы убедиться, что ваша версия Snapd обновлена.
$ sudo snap install core && sudo snap refresh core
Установите Сертбот.
$ sudo snap install --classic certbot
Используйте следующую команду, чтобы гарантировать возможность запуска команды Certbot, создав символическую ссылку на каталог /usr/bin
.
$ sudo ln -s /snap/bin/certbot /usr/bin/certbot
Сгенерируйте SSL-сертификат для домена kibana.example.com
.
$ sudo certbot certonly --nginx --agree-tos --no-eff-email --staple-ocsp --preferred-challenges http -m [email -d kibana.example.com
Приведенная выше команда загрузит сертификат в каталог /etc/letsencrypt/live/kibana.example.com
на вашем сервере.
Создайте сертификат группы Диффи-Хеллмана.
$ sudo openssl dhparam -dsaparam -out /etc/ssl/certs/dhparam.pem 4096
Проверьте службу планировщика обновления Certbot.
$ sudo systemctl list-timers
Вы найдете snap.certbot.renew.service
как одну из запланированных к запуску служб.
NEXT LEFT LAST PASSED UNIT ACTIVATES
------------------------------------------------------------------------------------------------------------------------------------
Mon 2023-05-06 13:37:57 UTC 3h 45min left Mon 2023-05-01 07:20:42 UTC 2h 31min ago ua-timer.timer ua-timer.service
Mon 2023-05-06 14:39:29 UTC 4h 47min left Sat 2023-02-04 16:04:18 UTC 2 months ago motd-news.timer motd-news.service
Mon 2023-05-06 15:53:00 UTC 6h left n/a n/a snap.certbot.renew.timer snap.certbot.renew.service
Выполните пробный запуск процесса, чтобы проверить, работает ли продление SSL нормально.
$ sudo certbot renew --dry-run
Если вы не видите ошибок, все готово. Ваш сертификат будет продлен автоматически.
Шаг 9 — Настройка Nginx
Создайте и откройте файл конфигурации Nginx для Kibana.
$ sudo nano /etc/nginx/conf.d/kibana.conf
Вставьте в него следующий код. Замените IP-адрес частным IP-адресом вашего сервера Elasticsearch.
server {
listen 80; listen [::]:80;
server_name kibana.example.com;
return 301 https://$host$request_uri;
}
server {
server_name kibana.example.com;
charset utf-8;
listen 443 ssl http2;
listen [::]:443 ssl http2;
access_log /var/log/nginx/kibana.access.log;
error_log /var/log/nginx/kibana.error.log;
ssl_certificate /etc/letsencrypt/live/kibana.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/kibana.example.com/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/kibana.example.com/chain.pem;
ssl_session_timeout 1d;
ssl_session_cache shared:MozSSL:10m;
ssl_session_tickets off;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
resolver 8.8.8.8;
ssl_stapling on;
ssl_stapling_verify on;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
location / {
proxy_pass http://localhost:5601;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Сохраните файл, нажав Ctrl + X и введя Y при появлении запроса.
Откройте файл /etc/nginx/nginx.conf
для редактирования.
$ sudo nano /etc/nginx/nginx.conf
Добавьте следующую строку перед строкой include /etc/nginx/conf.d/*.conf;
.
server_names_hash_bucket_size 64;
Сохраните файл, нажав Ctrl + X и введя Y при появлении запроса.
Проверьте конфигурацию.
$ sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
Перезапустите службу Nginx.
$ sudo systemctl restart nginx
Требуется еще один шаг. Откройте файл компоновки Docker для редактирования.
$ nano ~/docker-compose.yml
Вставьте строку SERVER_PUBLICBASEURL=https://kibana.example.com
в раздел среды службы Kibana следующим образом.
environment: # Defined host configuration
- ELASTICSEARCH_HOSTS=http://elasticsearch:9200
- SERVER_PUBLICBASEURL=https://kibana.example.com
Сохраните файл, нажав Ctrl + X и введя Y при появлении соответствующего запроса после завершения.
Остановитесь и уберите контейнеры.
$ docker compose down --remove-orphans
Запустите контейнеры снова с обновленной конфигурацией.
$ docker compose up -d
Ваша панель управления Kibana должна быть доступна по URL-адресу https://kibana.example.com
из любого места.
Шаг 10. Запуск Docker-контейнера с драйвером журнала Fluentd
Теперь мы запустим контейнер Docker с накопителем журналов Fluentd, автоматически отправляя журналы в стек. Мы будем тестировать с использованием контейнера Nginx.
Извлеките образ Nginx из реестра Docker Hub. Мы используем версию alpine
, поскольку это самая маленькая версия изображения.
$ docker pull nginx:alpine
Выполните следующую команду, чтобы создать и запустить контейнер Nginx. Мы установили драйвер журнала Fluentd
и порт 8080, поскольку порт 80 по умолчанию уже используется сервером Nginx в режиме прокси.
$ docker run --name nginx-fluentd-test -d --log-driver=fluentd -p 8080:80 nginx:alpine
Проверьте статус контейнера.
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
038c43e4e1a3 nginx:alpine "/docker-entrypoint.…" 12 seconds ago Up 11 seconds 0.0.0.0:8080->80/tcp, :::8080->80/tcp nginx-fluentd-test
a94ca706bd0c efk-fluentd "tini -- /bin/entryp…" 8 hours ago Up 8 hours 5140/tcp, 0.0.0.0:24224->24224/tcp, 0.0.0.0:24224->24224/udp, :::24224->24224/tcp, :::24224->24224/udp efk-fluentd-1
0cf04a446425 kibana:8.7.1 "/bin/tini -- /usr/l…" 8 hours ago Up 8 hours 0.0.0.0:5601->5601/tcp, :::5601->5601/tcp efk-kibana-1
7c7ad8f9b123 elasticsearch:8.7.1 "/bin/tini -- /usr/l…" 8 hours ago Up 8 hours 9200/tcp, 9300/tcp efk-elasticsearch-1
Выполните следующую команду, чтобы получить доступ к контейнеру Nginx и создать журналы доступа.
$ curl localhost:8080
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
Альтернативно вы можете открыть URL-адрес http://
в своем браузере и открыть следующую страницу.
Откройте панель управления Kibana и нажмите ссылку Обнаружить в меню левой боковой панели. Нажмите знак + в верхнем меню, чтобы открыть всплывающее окно Добавить фильтр.
Выберите поле container_name
из раскрывающегося списка, is
в качестве оператора и введите имя контейнера ( nginx-fluentd-test
) в качестве значения поля. .
Нажмите кнопку Добавить фильтр, чтобы визуализировать данные из контейнера Nginx.
Заключение
На этом завершается наше руководство по установке стека журналирования Elasticsearch, Fluentd и Kibana (EFK) на компьютере с Ubuntu 22.04. Если у вас есть вопросы, задавайте их в комментариях ниже.