Во-первых, развертывание агента ведения журнала на узле, файл журнала будет перенаправлен во внутреннее хранилище в сохраненном виде.
Рисунок 1.1
- Здесь нетрудно заметить, что основной агент ведения журнала, обычно это путь к DaemonSet, работающему на узле, затем каталог журнала контейнера на хосте для монтирования в него, и, наконец, агент ведения журнала пересылает журналы.
- Например, мы можем использовать проект +Fluentd+ в качестве +агента ведения журнала на хосте, а затем пересылать журналы на удаленный +ElasticSearch+ и сохранять их для последующего извлечения. конкретный рабочий процессОфициальный сайтВо многих развертываниях kubernetes функция logrotate будет автоматически включена для вас, и файл журнала будет автоматически маршрутизироваться, когда файл журнала превысит 10 МБ.
- Вы можете увидеть развертывание самых больших преимуществ агента ведения журнала на узле, что нужно только развернуть агент, и не будет вторжения в приложение и модуль. Так что эта схема в этом районе самая распространенная.
- Тем не менее, субсидирование этой схемы заключается в том, что она требует, чтобы журналы, выводимые приложением, выводились непосредственно на стандартный вывод и стандартный вывод контейнера.
Второе, обработка особых случаев
- Когда контейнер может загрузить только выход в определенный файл, мы можем поставить эти файлы журнала повторной экспортировки контейнера через Sidecar Sidecar на STDOUT и STDERR, показанную на рисунке 1.2
- Теперь мой модуль приложения имеет только один контейнер, и он будет выводить журналы в два файла /var/log/1.log и 2.log в контейнере. Файл 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)" >> /var/log/1.log; echo "$(date) INFO $i" >> /var/log/2.log; i=$((i+1)); sleep 1; done volumeMounts: - name: varlog mountPath: /var/log volumes: - name: varlog emptyDir: {}
- В этом случае вы не увидите никаких логов приложения с командой kubect. И одно из наиболее часто используемых решений также недоступно. В настоящее время мы можем добавить два контейнера sidecar в этот модуль и вывести содержимое двух вышеупомянутых файлов журнала как stout и stderr соответственно.Файл YAML записывается следующим образом:
*Поскольку объем разделяется между sidecar и основным контейнером, вторичная потеря производительности решения sidecar здесь невелика, и оно занимает немного больше ресурсов процессора и памяти. Однако в это время на хост-компьютере будет два идентичных лог-файла: один записывается самим приложением, а другой — файл json, соответствующий stdout и dtderr сайдкара. Это огромная трата диска. Поэтому, если это не крайняя мера или контейнер приложения вообще не может быть изменен, рекомендуется напрямую использовать вариант 1 или вариант 3.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)" >> /var/log/1.log; echo "$(date) INFO $i" >> /var/log/2.log; i=$((i+1)); sleep 1; done volumeMounts: - name: varlog mountPath: /var/log - name: count-log-1 image: busybox args: [/bin/sh, -c, 'tail -n+1 -f /var/log/1.log'] volumeMounts: - name: varlog mountPath: /var/log - name: count-log-2 image: busybox args: [/bin/sh, -c, 'tail -n+1 -f /var/log/2.log'] volumeMounts: - name: varlog mountPath: /var/log volumes: - name: varlog emptyDir: {}
Вариант 3. Отправка файлов журналов напрямую в удаленное хранилище через дополнительный контейнер.
- Это эквивалентно размещению агента ведения журнала в решении 1 в модуле приложения. Рисунок 1.3:
- В этом решении ваше приложение может напрямую выводить журналы в фиксированный файл вместо стандартного вывода, ваш агент ведения журналов также может использовать fluentd, а серверное хранилище также может быть ElasticSearch. Однако источником ввода fluentd становится файл журнала приложения. Вообще говоря, мы сохраним конфигурацию источника ввода fluentd в ConfigMap следующим образом:
apiVersion: v1 kind: ConfigMap metadata: name: fluentd-config data: fluentd.conf: | <source> type tail format none path /var/log/1.log pos_file /var/log/1.log.pos tag count.format1 </source> <source> type tail format none path /var/log/2.log pos_file /var/log/2.log.pos tag count.format2 </source> <match **> type google_cloud </match>
- В определении модуля приложения мы можем создать контейнер Fluentd в качестве sidecar, который отвечает за пересылку 1.log и 2.log, сгенерированных приложением, в ElasticSearch.Эта конфигурация выглядит следующим образом:
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)" >> /var/log/1.log; echo "$(date) INFO $i" >> /var/log/2.log; i=$((i+1)); sleep 1; done volumeMounts: - name: varlog mountPath: /var/log - name: count-agent image: k8s.gcr.io/fluentd-gcp:1.30 env: - name: FLUENTD_ARGS value: -c /etc/fluentd-config/fluentd.conf volumeMounts: - name: varlog mountPath: /var/log - name: config-volume mountPath: /etc/fluentd-config volumes: - name: varlog emptyDir: {} - name: config-volume configMap: name: fluentd-config
- Как показано выше, источник ввода, используемый этим контейнером Fluentd, указывается ссылкой на ConfigMap, который мы написали ранее. Projected Volume используется здесь, чтобы повесить ConfigMap в Pod.
- Это решение является самым простым в развертывании и наиболее удобным для хоста, но этот дополнительный контейнер, вероятно, будет потреблять больше ресурсов и даже перетаскивать контейнер приложения вниз. Поскольку журнал не выводится на стандартный вывод, вы не можете просмотреть информацию журнала через журналы kubectl.
Суммировать
Выше приведены три наиболее часто используемых метода сбора логов в k8s.Сравнивая приведенные выше решения, рекомендуется выводить логи приложений на stdout и stderr, а затем централизованно обрабатывать логи, развернув log-agent в Su Shushu.Решение такое можно использовать не только простые журналы, но и журналы kubectl, что также официально рекомендуется.