Логи в Kubernetes
Приложения и системы, регистрирующие выходные данные в каком-то волшебном месте, которое мы в конечном итоге находим в операционной системе или по системному пути, были спасителями каждого системного администратора и разработчика с момента появления компьютеров.
В Kubernetes все по-другому.
Без надлежащего ведения журналов и общего потребления журналов вы никогда не сможете устранять неполадки, происходящие в вашей среде Kubernetes.
В этом посте вы узнаете, что такое ведение журнала, различные методологии ведения журнала в Kubernetes и как их можно реализовать в рабочей среде.
Что такое ведение журнала
Вы когда-нибудь видели всплывающую ошибку на экране, когда вы пытались что-то установить или использовать определенный инструмент/платформу?
Вам когда-нибудь приходилось садиться за компьютер и смотреть на вывод определенного приложения? Это журналы.
Журналы содержат информацию о системе, операционной системе, приложении и многих других аспектах, при условии, что везде, где вы просматриваете журналы, поддерживается ведение журнала. Это означает, что каждое приложение имеет возможность отправлять журналы, но иногда они этого не делают. Разработчик должен реализовать функциональность для сохранения/вывода журналов для приложения.
Ведение журнала было спасением почти для всех в технологическом пространстве. Независимо от того, являетесь ли вы системным администратором, облачным инженером, разработчиком или кем-то еще, почти гарантировано, что в какой-то момент вы просматривали журналы для решения конкретной проблемы.
Короче говоря, журналы — это события, которые происходят на компьютере или в приложении.
Типы журналов логов в Kubernetes
В Kubernetes вы будете заботиться о двух разных типах журналов:
- Журналы кластера
- Журналы ресурсов/объектов Kubernetes
Журналы кластера относятся к тому, как работает кластер. Исправна ли плоскость управления, исправны ли рабочие узлы, и в зависимости от того, как они установлены, как работают компоненты Kubernetes (и т. д., планировщик, сервер API и т. д.). Например, в стандартных развертываниях Kubeadm Etcd будет работать как Pod, поэтому он будет считаться «журналом ресурсов/объектов Kubernetes». Однако, если Etcd настроен для кластеров, работающих на собственном сервере, он может не загружаться как под и, следовательно, будет считаться «кластерным журналом».
Журналы ресурсов/объектов Kubernetes — это любой запущенный ресурс Kubernetes. Вы можете получать журналы и события для различных ресурсов Kubernetes, но основная часть того, на что обычно обращают внимание инженеры, — это журналы Pod и контейнеров, поскольку это основное место, где вы можете получить информацию о запущенном приложении.
Самый быстрый способ проверить журналы для модулей — с помощью kubectl logs pod_name
команды. Однако kubectl logs
работайте только над проверкой журналов для модулей и никаких других ресурсов Kubernetes.
Различные типы методов ведения журнала в Kubernetes
Когда вы думаете о своей стратегии ведения журналов для среды Kubernetes, существует несколько различных способов вывода журналов:
- Переадресация приложений
- Коляска
- Агент узла вперед
Давайте сломаем их.
Переадресация приложений выполняется внутри кода приложения. Например, предположим, вы пишете фронтальное приложение. Внутри приложения вы можете указать логику, которая говорит «отправлять журналы отсюда в эту систему». Хотя это может показаться простым, возможно, это худший способ управления журналами. Почему?
Потому что вы ставите зависимость от кода и системы ведения журнала. Что делать, если система ведения журналов изменится? Собираетесь ли вы реализовать это для каждого приложения и части каждого приложения? Этого метода следует избегать всегда, если только у вас нет какой-то смехотворно убедительной причины для вас.
Например, веская причина сделать это — если у вас есть устаревшее приложение, в которое уже встроены функции ведения журнала (хотя вы должны планировать, как изменить эту функциональность в будущем).
Метод sidecar будет, если вы внедрите агрегатор журналов в модуль Kubernetes. В итоге у вас есть два контейнера в одном поде. Один из контейнеров — это само приложение, а другой — используемая вами система ведения журналов. Это «хороший» метод, и его определенно следует использовать вместо перенаправления приложений, но есть и лучший метод — перенаправление агента узла.
Метод Node Agent Forwarding — это Pod, который запускается на каждом рабочем узле Kubernetes. Работа Pod заключается в чтении файлов журналов контейнерного приложения и отправке их на любой инструмент/платформу ведения журнала, которую вы используете. Это лучший метод по нескольким причинам. 1) Вы не реализуете sidecar, который удаляет дополнительные функции для Pod, которые технически должны выполнять одну работу. 2) Разделяет процессы рабочей нагрузки и наличие зависимостей, и, в свою очередь, у вас есть один ресурс Kubernetes (Pod), который выполняет одну работу (отправляет журналы).
Журналы аудита Kubernetes
Дело в том, что журналы могут рассматриваться практически как любые выходные данные.
События, журналы приложений, вывод терминала, события выхода и многое другое. Из-за этого мы не можем охватить все без того, чтобы этот пост в блоге не превратился в технический документ, поэтому давайте остановимся на самом важном.
Чтобы начать практическую часть этой записи в блоге, вы начнете с журналов аудита Kubernetes.
Журналы аудита Kubernetes дают вам возможность собирать и просматривать любые выходные данные, которые создает ресурс Kubernetes. Например, когда вы создаете развертывание Kubernetes, происходит много всего.
- Образ контейнера извлекается из реестра.
- Поды планируются на рабочих узлах.
- Модули либо запускаются, либо выходят из строя, и если они выходят из строя, на это есть причина.
- Масштабирование на модулях выполнено.
Из-за этой детали вы можете захотеть собрать определенные журналы или, может быть, вы хотите их все.
Например, ниже Policy
ресурс Kubernetes используется для создания политики аудита, которая буквально собирает все, что возможно, из каждого отдельного ресурса Kubernetes.
apiVersion: audit.k8s.io/v1 kind: Policy rules: - level: Metadata
Во-первых, давайте посмотрим, как это делается в локальном кластере Kubernetes. Например, загрузился с помощью Kubeadm, так как он сильно отличается от облачных сервисов. Затем вы увидите, как настраивается аудит для облачных служб.
Kubeadm
Сначала создайте новый YAML для политики, которую вы хотите создать.
sudo vim /etc/kubernetes/kubeadmpolicy.yaml
Далее укажите политику. Например, вы можете использовать приведенную ниже политику, которая собирает журналы аудита для модулей и всех, кто проходит аутентификацию в API.
apiVersion: audit.k8s.io/v1 kind: Policy omitStages: - "RequestReceived" rules: - level: RequestResponse resources: - group: "" resources: ["pods"] - level: Metadata resources: - group: "" resources: ["pods/log", "pods/status"] - level: None userGroups: ["system:authenticated"] nonResourceURLs: - "/api*" - "/version"
После сохранения вам необходимо обновить сервер API. При начальной загрузке кластера Kubernetes с помощью Kubeadm все манифесты для модулей, составляющих плоскость управления, находятся в разделе /etc/kubernetes/manifests
.
Откройте kube-apiserver.yaml
Манифест.
sudo vim /etc/kubernetes/manifests/kube-apiserver.yaml
Сохраните следующие строки в kube-apiserver
конфигурации, которые будут указывать, куда вы хотите вести журналы, и политику, которую вы создали выше.
- --audit-log-path=/var/log/audit.log - --audit-policy-file=/etc/kubernetes/kubeadmpolicy.yaml
Далее укажите политику аудита и журнал в качестве точки монтирования.
*- mountPath: /etc/kubernetes/kubeadmpolicy.yaml* *name: audit* *readOnly: true* *- mountPath: /var/log/audit.log* *name: audit-log* *readOnly: false*
Последним шагом является указание пути хоста томов для ранее созданных путей монтирования.
*- hostPath: path: /etc/kubernetes/kubeadmpolicy.yaml type: File name: audit - hostPath: path: /var/log/audit.log type: FileOrCreate name: audit-log*
После завершения перезапустите Kubelet.
sudo systemctl restart kubelet
Теперь вы должны увидеть журналы в следующем месте.
tail -f /var/log/audit.log
Служба Azure Kubernetes
По умолчанию аудит включен в AKS, и существует политика аудита для сбора всего со всех ресурсов Kubernetes.
Однако функция просмотра журналов аудита не включена по умолчанию. Чтобы включить его, сделайте следующее.
Сначала перейдите в свой кластер AKS и в разделе «Мониторинг» нажмите «Параметры диагностики» . Затем нажмите синюю кнопку + Добавить параметры диагностики .
В настройках диагностики щелкните категорию «Аудит Kubernetes» . На этом этапе у вас будет возможность выбрать, где вы хотите сохранить журналы. Для целей этого раздела вы можете выбрать параметр «Отправить в рабочую область Log Analytics» .
Теперь, когда аудит включен, вы можете открыть рабочую область аналитики и выполнить запрос для получения событий.
Например, приведенный ниже запрос будет запрашивать все журналы аудита Kubernetes.
AzureDiagnostics | where Category == "kube-audit" | project log_s
Вы можете увидеть пример вывода ниже.
Сервис AWS Elastic Kubernetes
Для AWS ведение журнала аудита по умолчанию не включено. Вы можете включить его при создании кластера Kubernetes, и тогда журналы аудита по умолчанию будут отправляться в CloudWatch.
События Kubernetes
В этом разделе вы узнаете, как получать события Kubernetes, которые сами по себе являются журналами.
Событие — это ресурс/объект Kubernetes. это происходит, когда происходит изменение с другим ресурсом/объектом Kubernetes, будь то модули, службы, узлы и т. д.…
Вы можете запустить kubectl get events
команду, чтобы увидеть, что происходит внутри кластера.
kubectl get events LAST SEEN TYPE REASON OBJECT MESSAGE 5m1s Normal NodeHasSufficientMemory node/stdkubeadmwn Node stdkubeadmwn status is now: NodeHasSufficientMemory 5m1s Normal NodeHasNoDiskPressure node/stdkubeadmwn Node stdkubeadmwn status is now: NodeHasNoDiskPressure 5m1s Normal NodeHasSufficientPID node/stdkubeadmwn Node stdkubeadmwn status is now: NodeHasSufficientPID 5m1s Normal NodeReady node/stdkubeadmwn Node stdkubeadmwn status is now: NodeReady 5m11s Normal NodeNotReady node/stdkubeadmwn Node stdkubeadmwn status is now: NodeNotReady
Однако ничего особенного не происходит, потому что kubectl get events
команда была запущена в новом кластере. Давайте бросим на него немного трафика, чтобы сгенерировать некоторые события.
Запустите следующий YAML, который развернет развертывание Nginx Kubernetes.
kubectl apply -f - <<EOF apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment spec: selector: matchLabels: app: nginxdeployment replicas: 2 template: metadata: labels: app: nginxdeployment spec: containers: - name: nginxdeployment image: nginx:latest ports: - containerPort: 80 EOF
Если вы снова запустите kubectl get events
команду, вы увидите еще несколько событий, так как были созданы модули для развертывания Nginx, а образ контейнера Nginx был извлечен для реестра Docker.
mike@stdkubeadmcp:~$ kubectl get events LAST SEEN TYPE REASON OBJECT MESSAGE 1s Normal Scheduled pod/nginx-deployment-574db6c95f-fr8qb Successfully assigned default/nginx-deployment-574db6c95f-fr8qb to stdkubeadmwn 1s Normal Pulling pod/nginx-deployment-574db6c95f-fr8qb Pulling image "nginx:latest" 1s Normal Scheduled pod/nginx-deployment-574db6c95f-llzzd Successfully assigned default/nginx-deployment-574db6c95f-llzzd to stdkubeadmwn 1s Normal Pulling pod/nginx-deployment-574db6c95f-llzzd Pulling image "nginx:latest" 1s Normal SuccessfulCreate replicaset/nginx-deployment-574db6c95f Created pod: nginx-deployment-574db6c95f-fr8qb 1s Normal SuccessfulCreate replicaset/nginx-deployment-574db6c95f Created pod: nginx-deployment-574db6c95f-llzzd 1s Normal ScalingReplicaSet deployment/nginx-deployment Scaled up replica set nginx-deployment-574db6c95f to 2 6m16s Normal NodeHasSufficientMemory node/stdkubeadmwn Node stdkubeadmwn status is now: NodeHasSufficientMemory 6m16s Normal NodeHasNoDiskPressure node/stdkubeadmwn Node stdkubeadmwn status is now: NodeHasNoDiskPressure 6m16s Normal NodeHasSufficientPID node/stdkubeadmwn Node stdkubeadmwn status is now: NodeHasSufficientPID 6m16s Normal NodeReady node/stdkubeadmwn Node stdkubeadmwn status is now: NodeReady 6m26s Normal NodeNotReady node/stdkubeadmwn Node stdkubeadmwn status is now: NodeNotReady
Как вы можете себе представить, выполнение в kubectl get events
конечном итоге приведет к извлечению тонны данных в зависимости от того, насколько новый кластер.
Чтобы получить более конкретный список событий, вы можете настроить таргетинг на конкретный ресурс Kubernetes.
В приведенном ниже примере видно, что describe
команда используется для просмотра событий (и многих других компонентов) развертывания Kubernetes.
kubectl describe deployment nginx-deployment
Если вы прокрутите вывод команды вниз describe
, вы увидите вывод, аналогичный приведенному ниже выводу, в котором показаны события для ресурса.
Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ScalingReplicaSet 38s deployment-controller Scaled up replica set nginx-deployment-574db6c95f to 2
Заключение
Ведение журнала логов в Kubernetes очень похоже на любой другой метод ведения журнала — собирайте события, просматривайте их и используйте их для устранения неполадок или понимания того, что происходит в системе и в приложении. Здесь следует помнить, что вы должны отправлять журналы в правильное место, которое может быть использовано всей командой.