Схема коллекции контейнеров K8S

Kubernetes
Схема коллекции контейнеров K8S

Во-первых, развертывание агента ведения журнала на узле, файл журнала будет перенаправлен во внутреннее хранилище в сохраненном виде.

Рисунок 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 записывается следующим образом:
    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: {}
    
    *Поскольку объем разделяется между sidecar и основным контейнером, вторичная потеря производительности решения sidecar здесь невелика, и оно занимает немного больше ресурсов процессора и памяти. Однако в это время на хост-компьютере будет два идентичных лог-файла: один записывается самим приложением, а другой — файл json, соответствующий stdout и dtderr сайдкара. Это огромная трата диска. Поэтому, если это не крайняя мера или контейнер приложения вообще не может быть изменен, рекомендуется напрямую использовать вариант 1 или вариант 3.

Вариант 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, что также официально рекомендуется.