Логи системних компонентів фіксують події, що відбуваються в кластері, і це може бути дуже корисно для налагодження. Ви можете налаштувати рівень деталізації логів, щоб бачити більше або менше подробиць. Логи можуть бути як грубозернистими, показуючи лише помилки в компоненті, так і дрібнозернистими, показуючи покрокове трасування подій (наприклад, логи доступу HTTP, зміни стану Podʼів, дії контролерів або рішення планувальника).
klog — це бібліотека логування Kubernetes. klog генерує повідомлення логів для системних компонентів Kubernetes.
Kubernetes поступово спрощує логування у своїх компонентах. Наведені нижче прапорці командного рядка klog застаріли, починаючи з Kubernetes v1.23, і вилучені в Kubernetes v1.26:
--add-dir-header--alsologtostderr--log-backtrace-at--log-dir--log-file--log-file-max-size--logtostderr--one-output--skip-headers--skip-log-headers--stderrthresholdВивід завжди записується у stderr незалежно від формату виводу. Очікується, що перенаправленням виводу займається компонент, який викликає компонент Kubernetes. Це може бути оболонка POSIX або інструмент на кшталт systemd.
У деяких випадках, наприклад у контейнері distroless або системній службі Windows, ці варіанти недоступні. Тоді можна використати бінарний файл kube-log-runner як обгортку навколо компонента Kubernetes для перенаправлення виводу. Попередньо зібраний бінарний файл входить до кількох базових образів Kubernetes під традиційною назвою /go-runner і як kube-log-runner в архівах випусків для сервера та вузлів.
Ця таблиця показує відповідність викликів kube-log-runner перенаправленню в оболонці:
| Використання | Оболонка POSIX (наприклад, bash) | kube-log-runner <options> <cmd> |
|---|---|---|
| Обʼєднати stderr і stdout, записати в stdout | 2>&1 | kube-log-runner (стандартна поведінка) |
| Перенаправити обидва у файл логу | 1>>/tmp/log 2>&1 | kube-log-runner -log-file=/tmp/log |
| Скопіювати у файл логу та в stdout | 2>&1 | tee -a /tmp/log | kube-log-runner -log-file=/tmp/log -also-stdout |
| Перенаправити лише stdout у файл логу | >/tmp/log | kube-log-runner -log-file=/tmp/log -redirect-stderr=false |
Приклад традиційного власного формату klog:
I1025 00:15:15.525108 1 httplog.go:79] GET /api/v1/namespaces/kube-system/pods/metrics-server-v0.3.1-57c75779f-9p8wg: (1.512ms) 200 [pod_nanny/v0.0.0 (linux/amd64) kubernetes/$Format 10.56.1.19:51756]
Рядок повідомлення може містити перенесення рядків:
I1025 00:15:15.525108 1 example.go:79] This is a message
which has a line break.
Міграція на структуровані повідомлення логів — поточний процес. У цій версії не всі повідомлення логів структуровані. Під час розбору файлів логів потрібно також обробляти неструктуровані повідомлення логів.
Форматування логів та серіалізація значень можуть змінюватися.
Структуроване логування додає до повідомлень логів єдину структуру, що дає змогу отримувати з них інформацію програмно. Ви можете зберігати та обробляти структуровані логи з меншими зусиллями та витратами. Код, який генерує повідомлення логу, визначає, чи використовує він традиційний неструктурований вивід klog, чи структуроване логування.
Стандартно структуровані повідомлення логів форматуються як текст у форматі, зворотно сумісному з традиційним klog:
<klog заголовок> "<повідомлення>" <ключ1>="<значення1>" <ключ2>="<значення2>" ...
Приклад:
I1025 00:15:15.525108 1 controller_utils.go:116] "Pod status updated" pod="kube-system/kubedns" status="ready"
Рядки беруться в лапки. Інші значення форматуються за допомогою %+v, через що повідомлення логів можуть продовжуватися на наступному рядку залежно від даних.
I1025 00:15:15.525108 1 example.go:116] "Example" data="This is text with a line break\nand \"quotation marks\"." someInt=1 someFloat=0.1 someStruct={StringField: First line,
second line.}
Контекстне логування побудоване на основі структурованого логування. Це переважно стосується того, як розробники використовують виклики логування: код, побудований на цій концепції, гнучкіший і підтримує додаткові сценарії використання, описані в KEP про контекстне логування.
Якщо розробники використовують у своїх компонентах додаткові функції, такі як WithValues або WithName, то записи логів міститимуть додаткову інформацію, яку передає у функції код, що їх викликає.
У Kubernetes 1.37 це керується функціональною можливістю ContextualLogging, яку стандартно ввімкнено. Інфраструктуру для цього додано у версії 1.24 без змін у компонентах. Команда component-base/logs/example показує, як використовувати нові виклики логування та як поводиться компонент, що підтримує контекстне логування.
$ cd $GOPATH/src/k8s.io/kubernetes/staging/src/k8s.io/component-base/logs/example/cmd/
$ go run . --help
...
--feature-gates mapStringBool A set of key=value pairs that describe feature gates for alpha/experimental features. Options are:
AllAlpha=true|false (ALPHA - default=false)
AllBeta=true|false (BETA - default=false)
ContextualLogging=true|false (BETA - default=true)
$ go run . --feature-gates ContextualLogging=true
...
I0222 15:13:31.645988 197901 example.go:54] "runtime" logger="example.myname" foo="bar" duration="1m0s"
I0222 15:13:31.646007 197901 example.go:55] "another runtime" logger="example" foo="bar" duration="1h0m0s" duration="1m0s"
Ключ logger та foo="bar" додано кодом, що викликає функцію, яка записує повідомлення runtime і значення duration="1m0s", без потреби змінювати цю функцію.
Коли контекстне логування вимкнено, WithValues і WithName нічого не роблять, а виклики логування проходять через глобальний логер klog. Тому цієї додаткової інформації більше немає у виводі логів:
$ go run . --feature-gates ContextualLogging=false
...
I0222 15:14:40.497333 198174 example.go:54] "runtime" duration="1m0s"
I0222 15:14:40.497346 198174 example.go:55] "another runtime" duration="1h0m0s" duration="1m0s"
Вивід у форматі JSON не підтримує багато стандартних прапорців klog. Перелік непідтримуваних прапорців klog дивіться в довідці щодо інструментів командного рядка.
Не всі логи гарантовано записуються у форматі JSON (наприклад, під час запуску процесу). Якщо ви плануєте розбирати логи, переконайтеся, що можете обробляти й рядки логів, які не є JSON.
Назви полів та серіалізація JSON можуть змінюватися.
Прапорець --logging-format=json змінює формат логів із власного формату klog на формат JSON. Приклад логу у форматі JSON (відформатований для зручності читання):
{
"ts": 1580306777.04728,
"v": 4,
"msg": "Pod status updated",
"pod":{
"name": "nginx-1",
"namespace": "default"
},
"status": "ready"
}
Ключі з особливим значенням:
ts — позначка часу у форматі Unix (обовʼязково, дійсне число)v — рівень деталізації (лише для інформаційних повідомлень, не для повідомлень про помилки, ціле число)err — рядок помилки (необовʼязково, рядок)msg — повідомлення (обовʼязково, рядок)Перелік компонентів, які наразі підтримують формат JSON:
Прапорець -v керує рівнем деталізації логів. Збільшення значення збільшує кількість подій, що логуються. Зменшення значення зменшує кількість подій, що логуються. Вищі рівні деталізації додають до логів дедалі менш важливі події. На рівні деталізації 0 логуються лише критичні події.
Є два види системних компонентів: ті, що працюють у контейнері, і ті, що не працюють у контейнері. Наприклад:
На машинах із systemd kubelet і середовище виконання контейнерів пишуть у journald. В іншому разі вони пишуть у файли .log у теці /var/log. Системні компоненти всередині контейнерів завжди пишуть у файли .log у теці /var/log, оминаючи стандартний механізм логування. Як і для логів контейнерів, вам слід виконувати ротацію логів системних компонентів у теці /var/log. У кластерах Kubernetes, створених сценарієм kube-up.sh, ротацію логів налаштовано за допомогою інструмента logrotate. Інструмент logrotate виконує ротацію логів щодня або коли розмір логу перевищує 100MB.
This is a stable feature in Kubernetes, and has been since version 1.36. It was first available in the v1.27 release.
Можливість Log Query допомагає налагоджувати проблеми на вузлах Linux і Windows. Запроваджена в Kubernetes v1.27, вона дозволяє переглядати логи сервісів, що працюють на вузлі. Щоб скористатися цією можливістю, переконайтеся, що для цільового вузла обидва параметри конфігурації kubelet enableSystemLogHandler та enableSystemLogQuery встановлено в true.
У Kubernetes v1.36 ця можливість стала стабільною, і функціональну можливість NodeLogQuery тепер зафіксовано в true, тобто її стандартно ввімкнено, а enableSystemLogHandler залишається єдиним параметром, потрібним для ввімкнення або вимкнення Log Query.
Стандартно enableSystemLogHandler має значення false, і його рекомендується залишати вимкненим, окрім випадків активного налагодження.
nodes/proxy (навіть лише дозволу get) також відкриває доступ до потужних API kubelet, які можна використовувати для виконання команд у будь-якому контейнері, що працює на вузлі, тому будьте обережні з керуванням цими дозволами. Докладніше дивіться в розділі Автентифікація/авторизація kubelet.У Linux передбачається, що логи сервісів доступні через journald. У Windows передбачається, що логи сервісів доступні через провайдера логів застосунків. В обох операційних системах логи також доступні через читання файлів у /var/log/.
Якщо у вас є дозвіл на взаємодію з обʼєктами Node, ви можете спробувати цю можливість на всіх своїх вузлах або лише на їх частині. Ось приклад отримання логів сервісу kubelet із вузла:
# Отримати логи kubelet з вузла під назвою node-1.example
kubectl get --raw "/api/v1/nodes/node-1.example/proxy/logs/?query=kubelet"
Ви також можете отримувати файли, якщо вони розташовані в теці, з якої kubelet дозволяє отримувати логи. Наприклад, можна отримати лог із /var/log на вузлі Linux:
kubectl get --raw "/api/v1/nodes/<назва-вузла>/proxy/logs/?query=/<назва-файлу-логу>"
kubelet використовує евристику для отримання логів. Це допомагає, якщо ви не знаєте, чи певний системний сервіс записує логи до власного логера операційної системи, такого як journald, чи до файлу логу в /var/log/. Евристика спочатку перевіряє власний логер, а якщо він недоступний, намагається отримати перші логи з /var/log/<назва-сервісу> або /var/log/<назва-сервісу>.log чи /var/log/<назва-сервісу>/<назва-сервісу>.log.
Повний перелік параметрів, які можна використовувати:
| Параметр | Опис |
|---|---|
boot | показує повідомлення з певного завантаження системи |
pattern | фільтрує записи логів за вказаним регулярним виразом, сумісним із PERL |
query | вказує сервіс(и) або файли, з яких потрібно повернути логи (обовʼязково) |
sinceTime | позначка часу RFC3339, починаючи з якої показувати логи (включно) |
untilTime | позначка часу RFC3339, до якої показувати логи (включно) |
tailLines | вказує, скільки рядків із кінця логу отримати; стандартно отримується весь лог |
Приклад складнішого запиту:
# Отримати логи kubelet з вузла під назвою node-1.example, у яких є слово "error"
kubectl get --raw "/api/v1/nodes/node-1.example/proxy/logs/?query=kubelet&pattern=error"