Всем привет, меня зовут Чжан Цзиньтао.
я написал«Более элегантная схема измерения событий кластера Kubernetes», и используйте Jaeger для использования трассировки для сбора событий в кластере Kubernetes и их отображения. Окончательный эффект выглядит следующим образом:
Когда я писал ту статью, я поставил флажок, чтобы подробно представить принцип.Я был голубем в течение долгого времени, и теперь это конец года, пришло время отправить его.
Обзор объектов
Давайте начнем с простого примера, чтобы увидеть, какие события происходят в кластере Kubernetes.
Создайте новое пространство имен с именем moelove и создайте в нем развертывание с именем redis. Затем просмотрите все события в этом пространстве имен.
(MoeLove) ➜ kubectl create ns moelove
namespace/moelove created
(MoeLove) ➜ kubectl -n moelove create deployment redis --image=ghcr.io/moelove/redis:alpine
deployment.apps/redis created
(MoeLove) ➜ kubectl -n moelove get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
redis 1/1 1 1 11s
(MoeLove) ➜ kubectl -n moelove get events
LAST SEEN TYPE REASON OBJECT MESSAGE
21s Normal Scheduled pod/redis-687967dbc5-27vmr Successfully assigned moelove/redis-687967dbc5-27vmr to kind-worker3
21s Normal Pulling pod/redis-687967dbc5-27vmr Pulling image "ghcr.io/moelove/redis:alpine"
15s Normal Pulled pod/redis-687967dbc5-27vmr Successfully pulled image "ghcr.io/moelove/redis:alpine" in 6.814310968s
14s Normal Created pod/redis-687967dbc5-27vmr Created container redis
14s Normal Started pod/redis-687967dbc5-27vmr Started container redis
22s Normal SuccessfulCreate replicaset/redis-687967dbc5 Created pod: redis-687967dbc5-27vmr
22s Normal ScalingReplicaSet deployment/redis Scaled up replica set redis-687967dbc5 to 1
Но мы обнаружим, что по умолчаниюkubectl get events
Он расположен не в том порядке, в котором происходят события, поэтому нам часто нужно добавить к нему--sort-by='{.metadata.creationTimestamp}'
параметр, позволяющий организовать его вывод во времени.
Вот почему версия Kubernetes v1.23 добавитkubectl alpha events
Причина заказа. я был раньшеСтатья «K8S Ecological Weekly | Официальный выпуск Kubernetes v1.23.0, список новых функций»Подробно он был представлен в , и здесь не будет останавливаться.
После сортировки по времени можно увидеть следующие результаты:
(MoeLove) ➜ kubectl -n moelove get events --sort-by='{.metadata.creationTimestamp}'
LAST SEEN TYPE REASON OBJECT MESSAGE
2m12s Normal Scheduled pod/redis-687967dbc5-27vmr Successfully assigned moelove/redis-687967dbc5-27vmr to kind-worker3
2m13s Normal SuccessfulCreate replicaset/redis-687967dbc5 Created pod: redis-687967dbc5-27vmr
2m13s Normal ScalingReplicaSet deployment/redis Scaled up replica set redis-687967dbc5 to 1
2m12s Normal Pulling pod/redis-687967dbc5-27vmr Pulling image "ghcr.io/moelove/redis:alpine"
2m6s Normal Pulled pod/redis-687967dbc5-27vmr Successfully pulled image "ghcr.io/moelove/redis:alpine" in 6.814310968s
2m5s Normal Created pod/redis-687967dbc5-27vmr Created container redis
2m5s Normal Started pod/redis-687967dbc5-27vmr Started container redis
С помощью вышеуказанных операций мы можем найти, чтоСобытия на самом деле являются ресурсом в кластере Kubernetes. При изменении состояния ресурсов в кластере Kubernetes могут генерироваться новые события..
Погрузитесь в события
один объект события
Поскольку события являются ресурсом в кластере Kubernetes, обычно оно должно содержать свое имя в своем metadata.name для отдельных операций. Таким образом, мы можем вывести его имя с помощью следующей команды:
(MoeLove) ➜ kubectl -n moelove get events --sort-by='{.metadata.creationTimestamp}' -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}'
redis-687967dbc5-27vmr.16c4fb7bde8c69d2
redis-687967dbc5.16c4fb7bde6b54c4
redis.16c4fb7bde1bf769
redis-687967dbc5-27vmr.16c4fb7bf8a0ab35
redis-687967dbc5-27vmr.16c4fb7d8ecaeff8
redis-687967dbc5-27vmr.16c4fb7d99709da9
redis-687967dbc5-27vmr.16c4fb7d9be30c06
Выберите любую из записей событий и выведите ее в формате YAML для просмотра:
(MoeLove) ➜ kubectl -n moelove get events redis-687967dbc5-27vmr.16c4fb7bde8c69d2 -o yaml
action: Binding
apiVersion: v1
eventTime: "2021-12-28T19:31:13.702987Z"
firstTimestamp: null
involvedObject:
apiVersion: v1
kind: Pod
name: redis-687967dbc5-27vmr
namespace: moelove
resourceVersion: "330230"
uid: 71b97182-5593-47b2-88cc-b3f59618c7aa
kind: Event
lastTimestamp: null
message: Successfully assigned moelove/redis-687967dbc5-27vmr to kind-worker3
metadata:
creationTimestamp: "2021-12-28T19:31:13Z"
name: redis-687967dbc5-27vmr.16c4fb7bde8c69d2
namespace: moelove
resourceVersion: "330235"
uid: e5c03126-33b9-4559-9585-5e82adcd96b0
reason: Scheduled
reportingComponent: default-scheduler
reportingInstance: default-scheduler-kind-control-plane
source: {}
type: Normal
Вы видите, что он содержит много информации, мы не будем ее здесь раскрывать. Давайте посмотрим на другой пример.
kubectl describe
События в
Мы можем выполнять объект Deployment и объект Pod отдельно.describe
операции можно получить следующие результаты (опуская промежуточный вывод):
- Операции с развертываниями
(MoeLove) ➜ kubectl -n moelove describe deploy/redis
Name: redis
Namespace: moelove
...
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 15m deployment-controller Scaled up replica set redis-687967dbc5 to 1
- Операции над модулями
(MoeLove) ➜ kubectl -n moelove describe pods redis-687967dbc5-27vmr
Name: redis-687967dbc5-27vmr
Namespace: moelove
Priority: 0
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 18m default-scheduler Successfully assigned moelove/redis-687967dbc5-27vmr to kind-worker3
Normal Pulling 18m kubelet Pulling image "ghcr.io/moelove/redis:alpine"
Normal Pulled 17m kubelet Successfully pulled image "ghcr.io/moelove/redis:alpine" in 6.814310968s
Normal Created 17m kubelet Created container redis
Normal Started 17m kubelet Started container redis
мы можем узнатьПри описании различных объектов ресурсов содержание событий, которые вы видите, напрямую связано с вами. При описании развертывания я не вижу событий, связанных с подом.
это означает,Объект Event содержит информацию об объекте ресурса, который он описывает., они имеют прямое отношение.
Объединив один объект Event, который мы видели ранее, мы находим, чтоinvolvedObject
Содержимое поля представляет собой информацию об объекте ресурса, связанном с событием..
Узнать больше о событиях
Давайте рассмотрим следующий пример, в котором создается Deployment, но используется несуществующий образ:
(MoeLove) ➜ kubectl -n moelove create deployment non-exist --image=ghcr.io/moelove/non-exist
deployment.apps/non-exist created
(MoeLove) ➜ kubectl -n moelove get pods
NAME READY STATUS RESTARTS AGE
non-exist-d9ddbdd84-tnrhd 0/1 ErrImagePull 0 11s
redis-687967dbc5-27vmr 1/1 Running 0 26m
Мы видим, что текущий Pod находится вErrImagePull
статус. Просмотр событий в текущем пространстве имен (предыдущие записи deploy/redis я пропустил)
(MoeLove) ➜ kubectl -n moelove get events --sort-by='{.metadata.creationTimestamp}'
LAST SEEN TYPE REASON OBJECT MESSAGE
35s Normal SuccessfulCreate replicaset/non-exist-d9ddbdd84 Created pod: non-exist-d9ddbdd84-tnrhd
35s Normal ScalingReplicaSet deployment/non-exist Scaled up replica set non-exist-d9ddbdd84 to 1
35s Normal Scheduled pod/non-exist-d9ddbdd84-tnrhd Successfully assigned moelove/non-exist-d9ddbdd84-tnrhd to kind-worker3
17s Warning Failed pod/non-exist-d9ddbdd84-tnrhd Error: ErrImagePull
17s Warning Failed pod/non-exist-d9ddbdd84-tnrhd Failed to pull image "ghcr.io/moelove/non-exist": rpc error: code = Unknown desc = failed to pull and unpack image "ghcr.io/moelove/non-exist:latest": failed to resolve reference "ghcr.io/moelove/non-exist:latest": failed to authorize: failed to fetch anonymous token: unexpected status: 403 Forbidden
18s Normal Pulling pod/non-exist-d9ddbdd84-tnrhd Pulling image "ghcr.io/moelove/non-exist"
4s Warning Failed pod/non-exist-d9ddbdd84-tnrhd Error: ImagePullBackOff
4s Normal BackOff pod/non-exist-d9ddbdd84-tnrhd Back-off pulling image "ghcr.io/moelove/non-exist"
Выполнить на этом подеdescribe
работать:
(MoeLove) ➜ kubectl -n moelove describe pods non-exist-d9ddbdd84-tnrhd
...
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 4m default-scheduler Successfully assigned moelove/non-exist-d9ddbdd84-tnrhd to kind-worker3
Normal Pulling 2m22s (x4 over 3m59s) kubelet Pulling image "ghcr.io/moelove/non-exist"
Warning Failed 2m21s (x4 over 3m59s) kubelet Failed to pull image "ghcr.io/moelove/non-exist": rpc error: code = Unknown desc = failed to pull and unpack image "ghcr.io/moelove/non-exist:latest": failed to resolve reference "ghcr.io/moelove/non-exist:latest": failed to authorize: failed to fetch anonymous token: unexpected status: 403 Forbidden
Warning Failed 2m21s (x4 over 3m59s) kubelet Error: ErrImagePull
Warning Failed 2m9s (x6 over 3m58s) kubelet Error: ImagePullBackOff
Normal BackOff 115s (x7 over 3m58s) kubelet Back-off pulling image "ghcr.io/moelove/non-exist"
Мы видим, что вывод здесь не такой, как когда модуль работал правильно раньше. Основное отличие сAge
Список. Здесь мы видим что-то вроде115s (x7 over 3m58s)
такой выход.
Его значение означает:Событие такого типа произошло 7 раз за 3 минуты 58 секунд, последнее произошло до 115 секунд.
Но когда мы идем прямоkubectl get events
, мы не видим событие с 7 повторениями. это означаетKubernetes автоматически объединяет повторяющиеся события.
Выбираем последние Events (метод уже описан ранее) и выводим его содержимое в формате YAML:
(MoeLove) ➜ kubectl -n moelove get events non-exist-d9ddbdd84-tnrhd.16c4fce570cfba46 -o yaml
apiVersion: v1
count: 43
eventTime: null
firstTimestamp: "2021-12-28T19:57:06Z"
involvedObject:
apiVersion: v1
fieldPath: spec.containers{non-exist}
kind: Pod
name: non-exist-d9ddbdd84-tnrhd
namespace: moelove
resourceVersion: "333366"
uid: 33045163-146e-4282-b559-fec19a189a10
kind: Event
lastTimestamp: "2021-12-28T18:07:14Z"
message: Back-off pulling image "ghcr.io/moelove/non-exist"
metadata:
creationTimestamp: "2021-12-28T19:57:06Z"
name: non-exist-d9ddbdd84-tnrhd.16c4fce570cfba46
namespace: moelove
resourceVersion: "334638"
uid: 60708be0-23b9-481b-a290-dd208fed6d47
reason: BackOff
reportingComponent: ""
reportingInstance: ""
source:
component: kubelet
host: kind-worker3
type: Normal
Здесь мы видим, что его поля включаютcount
Поле, указывающее, сколько раз происходит одно и то же событие. а такжеfirstTimestamp
иlastTimestamp
Соответственно представляют время, когда событие впервые появилось в последний раз. Это также объясняет продолжительность событий в предыдущем выводе.
Полностью понимать События
Ниже приведен случайный выбор из Events, и мы можем увидеть некоторую информацию о полях, которую он содержит:
apiVersion: v1
count: 1
eventTime: null
firstTimestamp: "2021-12-28T19:31:13Z"
involvedObject:
apiVersion: apps/v1
kind: ReplicaSet
name: redis-687967dbc5
namespace: moelove
resourceVersion: "330227"
uid: 11e98a9d-9062-4ccb-92cb-f51cc74d4c1d
kind: Event
lastTimestamp: "2021-12-28T19:31:13Z"
message: 'Created pod: redis-687967dbc5-27vmr'
metadata:
creationTimestamp: "2021-12-28T19:31:13Z"
name: redis-687967dbc5.16c4fb7bde6b54c4
namespace: moelove
resourceVersion: "330231"
uid: 8e37ec1e-b3a1-420c-96d4-3b3b2995c300
reason: SuccessfulCreate
reportingComponent: ""
reportingInstance: ""
source:
component: replicaset-controller
type: Normal
Значения основных полей следующие:
- count: Указывает, сколько раз произошло текущее событие того же типа (описано ранее)
- вовлеченный объект: объект ресурса, непосредственно связанный с этим событием (представленным ранее), имеет следующую структуру:
type ObjectReference struct {
Kind string
Namespace string
Name string
UID types.UID
APIVersion string
ResourceVersion string
FieldPath string
}
- источник: Непосредственно связанные компоненты, структура следующая:
type EventSource struct {
Component string
Host string
}
- причина: простая сводка (или фиксированный код), которая больше подходит для условий фильтрации, в основном для того, чтобы сделать ее читаемой машинами, таких кодов на данный момент более 50;
- сообщение: дайте более удобочитаемое подробное описание
- тип: пока только
Normal
иWarning
Есть два типа, и их значения также прописаны в исходном коде:
// staging/src/k8s.io/api/core/v1/types.go
const (
// Information only and will not cause any problems
EventTypeNormal string = "Normal"
// These events are to warn that something might go wrong
EventTypeWarning string = "Warning"
)
Поэтому, когда мы собираем эти события как диапазоны трассировки, мы можем следить за ихsource
Сортировать поinvolvedObject
Сопоставьте и отсортируйте по времени.
Суммировать
В этой статье я в основном представляю фактическую роль объекта Events и значение его различных полей с помощью двух примеров: развертывание, развернутое правильно, и развертывание, развернутое с использованием несуществующего образа.
Для Kubernetes события содержат много полезной информации, но эта информация не оказывает никакого влияния на Kubernetes, и они не являются реальными журналами Kubernetes. По умолчанию журналы в Kubernetes очищаются через 1 час, чтобы освободить ресурсы etcd.
Поэтому, чтобы лучше сообщить администратору кластера о том, что произошло, в производственной среде мы обычно также собираем события кластера Kubernetes. Лично я рекомендую следующие инструменты:GitHub.com/op с IE/crying…
Конечно, вы также можете следить за моей предыдущей статьей«Более элегантная схема измерения событий кластера Kubernetes», и используйте Jaeger для использования трассировки для сбора событий в кластере Kubernetes и их отображения.
Добро пожаловать, чтобы подписаться на мой публичный аккаунт статьи [MoeLove]