Моніторинг, логування та налагодження
Налаштуйте моніторинг та логування для розвʼязання проблем кластера або налагодження контейнеризованих застосунків.
Іноді трапляються неприємності. Цей посібник допоможе вам зібрати необхідну інформацію та вирішити проблеми. Він складається з чотирьох розділів:
- Налагодження вашого застосунку — корисно для користувачів, які розгортають код у Kubernetes та цікавляться причиною його непрацездатності.
- Налагодження вашого кластера — корисно для адміністраторів та операторів кластерів, які усувають несправності у самому кластері Kubernetes.
- Логи в Kubernetes — корисно для адміністраторів кластерів, які хочуть налаштувати та керувати логами у Kubernetes.
- Моніторинг в Kubernetes — корисно для адміністраторів кластерів, які хочуть увімкнути моніторинг у кластері Kubernetes.
Вам також слід перевірити відомі проблеми для випуску, який ви використовуєте.
Отримання допомоги
Якщо жоден із наведених вище посібників не відповідає на ваше питання, є різні способи отримати допомогу від спільноти Kubernetes.
Питання
Документацію на цьому сайті структуровано так, щоб відповідати на широке коло питань. Концепції пояснюють архітектуру Kubernetes і роботу кожного компонента, а Налаштування містить практичні інструкції для початку роботи. Завдання показують, як виконувати поширені завдання, а Навчальні матеріали — це докладніші покрокові розбори реальних, галузевих або наскрізних сценаріїв розробки. Розділ Довідник містить докладну документацію з API Kubernetes та інтерфейсів командного рядка (CLI), таких як kubectl.
Допоможіть! Моє питання не розглянуто! Мені потрібна допомога зараз!
Stack Exchange, Stack Overflow або Server Fault
Якщо у вас є питання, повʼязане з розробкою програмного забезпечення для вашого контейнеризованого застосунку, ви можете задати його на Stack Overflow.
Якщо у вас є питання про Kubernetes, повʼязані з керуванням кластером або конфігурацією, ви можете поставити їх на Server Fault.
Також існують кілька більш конкретних сайтів мережі Stack Exchange, які можуть бути відповідним місцем для питань про Kubernetes в таких областях, як DevOps, Software Engineering або InfoSec.
Можливо, хтось зі спільноти вже ставив схоже питання або може допомогти з вашою проблемою.
Команда Kubernetes також слідкуватиме за постами з теґом Kubernetes. Якщо немає наявних питань, які можуть допомогти, будь ласка, переконайтеся, що ваше питання відповідає правилам Stack Overflow, Server Fault або сайту мережі Stack Exchange, на якому ви його ставите, і ознайомтеся з інструкцією як поставити нове питання, перед тим як задавати нове!
Slack
Багато людей зі спільноти Kubernetes спілкуються у Kubernetes Slack в каналі #kubernetes-users. Slack потребує реєстрації; ви можете надіслати запит на запрошення, реєстрація відкрита для всіх. Запрошуємо приходити й ставити будь-які питання. Після реєстрації відкрийте організацію Kubernetes у Slack у браузері або у власному застосунку Slack.
Після реєстрації переглядайте список каналів для різних тем. Наприклад, люди, які тільки вчаться Kubernetes, також можуть приєднатися до каналу #kubernetes-novice. Як ще один приклад, розробникам корисно приєднатися до каналу #kubernetes-contributors.
Також існують багато каналів, специфічних для країн / мов. Запрошуємо приєднатися до цих каналів для локалізованої підтримки та інформації:
Форум
Вас раді бачити на офіційному форумі Kubernetes: discuss.kubernetes.io.
Помилки та запити на нові можливості
Якщо ви натрапили на щось схоже на помилку або хочете запросити нову можливість, скористайтеся системою відстеження issue на GitHub.
Перш ніж створювати issue, пошукайте серед наявних issue, чи вашу проблему вже описано.
Якщо ви повідомляєте про помилку, додайте докладну інформацію про те, як відтворити проблему, наприклад:
- Версія Kubernetes:
kubectl version - Хмарний провайдер, дистрибутив ОС, конфігурація мережі та версія середовища виконання контейнерів
- Кроки для відтворення проблеми
1 - Логи в Kubernetes
Архітектура логування та системні логи.
На цій сторінці наведено ресурси про логування в Kubernetes. Ви можете дізнатися, як збирати, переглядати й аналізувати логи за допомогою вбудованих інструментів і популярних стеків логування:
2 - Моніторинг в Kubernetes
Моніторинг системних компонентів Kubernetes.
На цій сторінці наведено ресурси про моніторинг у Kubernetes. Ви можете дізнатися, як збирати системні метрики й трасування для системних компонентів Kubernetes:
3 - Усунення несправностей застосунків
Налагодження поширених проблем контейнеризованих застосунків.
Цей розділ містить набір ресурсів для виправлення проблем із контейнеризованими застосунками. Він охоплює поширені проблеми з ресурсами Kubernetes (як-от Pods, Services або StatefulSets), поради щодо розуміння повідомлень про завершення контейнерів і способи налагодження запущених контейнерів.
3.1 - Налагодження Podʼів
Цей посібник допоможе користувачам налагодити застосунки, які розгорнуті в Kubernetes і поводяться некоректно. Це не посібник для тих, хто хоче налагодити свій кластер. Для цього ознайомтеся з цим посібником.
Діагностика проблеми
Перший крок в усуненні несправностей — первинна оцінка. У чому проблема? У ваших Podʼах, ReplicationController чи Service?
Налагодження Podʼів
Перший крок у налагодженні Podʼа — переглянути його. Перевірте поточний стан Podʼа й останні події такою командою:
kubectl describe pods ${POD_NAME}
Перегляньте стан контейнерів у Podʼі. Чи всі вони в стані Running? Чи були нещодавні перезапуски?
Продовжуйте налагодження залежно від стану Podʼів.
Мій Pod залишається в стані Pending
Якщо Pod застряг у стані Pending, це означає, що його не можна призначити на вузол. Зазвичай це стається через нестачу ресурсів того чи іншого типу, яка заважає плануванню. Перегляньте вивід команди kubectl describe ... вище. Там мають бути повідомлення від планувальника про те, чому він не може запланувати ваш Pod. Можливі причини:
У вас недостатньо ресурсів: можливо, ви вичерпали запас CPU або памʼяті в кластері; у такому разі потрібно видалити Podʼи, скоригувати запити ресурсів або додати нові вузли до кластера. Докладніше дивіться документ про обчислювальні ресурси.
Ви використовуєте hostPort: коли ви привʼязуєте Pod до hostPort, кількість місць, де можна запланувати цей Pod, обмежена. У більшості випадків hostPort не потрібен, спробуйте використати обʼєкт Service, щоб відкрити доступ до вашого Podʼа. Якщо hostPort вам усе ж потрібен, ви зможете запланувати лише стільки Podʼів, скільки вузлів у вашому кластері Kubernetes.
Мій Pod залишається у стані Waiting
Якщо Pod застряг у стані Waiting, його вже призначено на робочий вузол, але він не може працювати на цій машині. Знову ж таки, корисну інформацію має дати вивід kubectl describe .... Найпоширеніша причина Podʼів у стані Waiting — помилка завантаження образу. Перевірте три речі:
- Переконайтеся, що ви правильно вказали імʼя образу.
- Чи надіслали ви образ до реєстру?
- Спробуйте вручну завантажити образ, щоб перевірити, чи його можна завантажити. Наприклад, якщо ви використовуєте Docker на своєму ПК, виконайте
docker pull <image>.
Мій Pod залишається у стані Terminating
Якщо Pod застряг у стані Terminating, це означає, що для Podʼа надіслано запит на видалення, але панель управління не може видалити обʼєкт Pod.
Зазвичай таке стається, якщо Pod має завершувач, а в кластері встановлено вебхук допуску, який не дає панелі управління вилучити завершувач.
Щоб виявити такий сценарій, перевірте, чи є у вашому кластері ValidatingWebhookConfiguration або MutatingWebhookConfiguration, спрямовані на операції UPDATE для ресурсів pods.
Якщо вебхук надає третя сторона:
- Переконайтеся, що ви використовуєте найновішу версію.
- Вимкніть вебхук для операцій
UPDATE. - Повідомте про проблему відповідному постачальнику.
Якщо ви автор вебхука:
- Для змінювального вебхука переконайтеся, що він ніколи не змінює незмінні поля під час операцій
UPDATE. Наприклад, зміни контейнерів зазвичай не дозволені. - Для валідаційного вебхука переконайтеся, що ваші політики валідації застосовуються лише до нових змін. Іншими словами, слід пропускати Podʼи з наявними порушеннями. Це дозволяє Podʼам, створеним до встановлення валідаційного вебхука, і далі працювати.
Мій Pod виходить з ладу або несправний іншим чином
Щойно ваш Pod заплановано, для налагодження можна використовувати методи, описані в Налагодження запущених Podʼів.
Мій Pod працює, але не робить того, що я йому вказав
Якщо ваш Pod поводиться не так, як ви очікували, можливо, в описі Podʼа (наприклад, у файлі mypod.yaml на вашому локальному компʼютері) була помилка, яку мовчки проігнорували під час створення Podʼа. Часто якийсь розділ опису Podʼа вкладено неправильно або імʼя ключа написано з помилкою, тож ключ ігнорується. Наприклад, якщо ви написали command як commnd, Pod буде створено, але він не використовуватиме командний рядок, який ви задумали.
Насамперед видаліть свій Pod і спробуйте створити його знову з параметром --validate. Наприклад, виконайте kubectl apply --validate -f mypod.yaml. Якщо ви написали command як commnd, ви отримаєте помилку на кшталт такої:
I0805 10:43:25.129850 46757 schema.go:126] unknown field: commnd
I0805 10:43:25.129973 46757 schema.go:129] this may be a false alarm, see https://github.com/kubernetes/kubernetes/issues/6842
pods/mypod
Далі перевірте, чи збігається Pod на API-сервері з Podʼом, який ви хотіли створити (наприклад, з YAML-файлом на вашому локальному компʼютері). Наприклад, виконайте kubectl get pods/mypod -o yaml > mypod-on-apiserver.yaml, а потім вручну порівняйте початковий опис Podʼа, mypod.yaml, з тим, що ви отримали від API-сервера, mypod-on-apiserver.yaml. Зазвичай у версії з API-сервера будуть рядки, яких немає в початковій версії. Це очікувано. Однак якщо в початковому описі є рядки, яких немає у версії з API-сервера, це може свідчити про проблему зі специфікацією вашого Podʼа.
Налагодження ReplicationController
ReplicationController досить прості. Вони або можуть створювати Podʼи, або не можуть. Якщо вони не можуть створювати Podʼи, скористайтеся інструкціями вище, щоб налагодити свої Podʼи.
Також можна використати kubectl describe rc ${CONTROLLER_NAME}, щоб переглянути події, повʼязані з ReplicationController.
Налагодження Service
Service забезпечують балансування навантаження між набором Podʼів. Є кілька поширених проблем, через які Service можуть працювати неправильно. Наведені нижче інструкції допоможуть налагодити проблеми з Service.
Спершу переконайтеся, що для Service є точки доступу. Для кожного обʼєкта Service API-сервер робить доступними один або кілька ресурсів EndpointSlice.
Переглянути ці ресурси можна так:
kubectl get endpointslices -l kubernetes.io/service-name=${SERVICE_NAME}
Переконайтеся, що точки доступу в EndpointSlice відповідають кількості Podʼів, які мають входити до вашого Service. Наприклад, якщо ваш Service призначено для контейнера nginx з 3 репліками, ви маєте побачити три різні IP-адреси в EndpointSlice цього Service.
У моєму Service бракує точок доступу
Якщо точок доступу бракує, спробуйте вивести перелік Podʼів за мітками із селектора Service. Наприклад, у вас є Service з таким селектором:
...
spec:
selector:
name: nginx
type: frontend
Можна використати:
kubectl get pods --selector=name=nginx,type=frontend
щоб вивести перелік Podʼів, які відповідають цьому селектору. Перевірте, чи список збігається з Podʼами, які мають обслуговувати ваш Service. Перевірте, чи containerPort Podʼа збігається з targetPort Service.
Мережевий трафік не пересилається
Докладніше дивіться налагодження Service.
Що далі
Якщо жоден із наведених вище кроків не розвʼязав вашої проблеми, виконайте інструкції з документа про налагодження Service, щоб переконатися, що ваш Service працює, має Endpoints, а ваші Podʼи справді обслуговують запити; що DNS працює, правила iptables встановлено, а kube-proxy поводиться правильно.
Докладніше також дивіться документ про усунення несправностей.
3.2 - Налагодження StatefulSet
Це завдання показує, як налагоджувати StatefulSet.
Перш ніж ви розпочнете
- Вам потрібен кластер Kubernetes, та інструмент командного рядка kubectl повинен бути налаштований на звʼязок з вашим кластером.
- У вас має бути запущений StatefulSet, який ви хочете дослідити.
Налагодження StatefulSet
Щоб вивести список усіх Podʼів, які належать до StatefulSet і мають мітку app.kubernetes.io/name=MyApp, можна використати таку команду:
kubectl get pods -l app.kubernetes.io/name=MyApp
Якщо ви бачите, що якісь із перелічених Podʼів тривалий час перебувають у стані Unknown або Terminating, зверніться до завдання Видалення Podʼів StatefulSet за інструкціями, що з ними робити. Налагоджувати окремі Podʼи у StatefulSet можна за допомогою посібника Налагодження Podʼів.
Що далі
Дізнайтеся більше про налагодження init-контейнера.
4 - Усунення несправностей кластерів
Налагодження поширених проблем кластера.
Цей документ присвячено усуненню несправностей кластера; ми припускаємо, що ви вже виключили свій застосунок як першопричину проблеми, з якою стикаєтеся. Поради щодо налагодження застосунків дивіться в посібнику з усунення несправностей застосунків. Докладніше також дивіться загальний документ з усунення несправностей.
Про усунення несправностей kubectl дивіться Усунення несправностей kubectl.
Виведення інформації про кластер
Перше, що слід перевірити під час налагодження кластера, — чи всі ваші вузли зареєстровано правильно.
Виконайте таку команду:
І переконайтеся, що всі очікувані вузли присутні й перебувають у стані Ready.
Щоб отримати детальну інформацію про загальний стан вашого кластера, ви можете виконати:
kubectl cluster-info dump
Приклад: налагодження вимкненого/недоступного вузла
Іноді під час налагодження корисно переглянути стан вузла — наприклад, тому що ви помітили дивну поведінку Podʼа, який працює на вузлі, або щоб зʼясувати, чому Pod не призначається на вузол. Як і для Podʼів, для отримання детальної інформації про вузли можна використовувати kubectl describe node і kubectl get node -o yaml. Наприклад, ось що ви побачите, якщо вузол не працює (відʼєднаний від мережі, або kubelet завершився й не перезапускається тощо). Зверніть увагу на події, які показують, що вузол у стані NotReady, а також на те, що Podʼи більше не працюють (їх буде виселено після пʼяти хвилин у стані NotReady).
NAME STATUS ROLES AGE VERSION
kube-worker-1 NotReady <none> 1h v1.23.3
kubernetes-node-bols Ready <none> 1h v1.23.3
kubernetes-node-st6x Ready <none> 1h v1.23.3
kubernetes-node-unaj Ready <none> 1h v1.23.3
kubectl describe node kube-worker-1
Name: kube-worker-1
Roles: <none>
Labels: beta.kubernetes.io/arch=amd64
beta.kubernetes.io/os=linux
kubernetes.io/arch=amd64
kubernetes.io/hostname=kube-worker-1
kubernetes.io/os=linux
node.alpha.kubernetes.io/ttl: 0
volumes.kubernetes.io/controller-managed-attach-detach: true
CreationTimestamp: Thu, 17 Feb 2022 16:46:30 -0500
Taints: node.kubernetes.io/unreachable:NoExecute
node.kubernetes.io/unreachable:NoSchedule
Unschedulable: false
Lease:
HolderIdentity: kube-worker-1
AcquireTime: <unset>
RenewTime: Thu, 17 Feb 2022 17:13:09 -0500
Conditions:
Type Status LastHeartbeatTime LastTransitionTime Reason Message
---- ------ ----------------- ------------------ ------ -------
NetworkUnavailable False Thu, 17 Feb 2022 17:09:13 -0500 Thu, 17 Feb 2022 17:09:13 -0500 WeaveIsUp Weave pod has set this
MemoryPressure Unknown Thu, 17 Feb 2022 17:12:40 -0500 Thu, 17 Feb 2022 17:13:52 -0500 NodeStatusUnknown Kubelet stopped posting node status.
DiskPressure Unknown Thu, 17 Feb 2022 17:12:40 -0500 Thu, 17 Feb 2022 17:13:52 -0500 NodeStatusUnknown Kubelet stopped posting node status.
PIDPressure Unknown Thu, 17 Feb 2022 17:12:40 -0500 Thu, 17 Feb 2022 17:13:52 -0500 NodeStatusUnknown Kubelet stopped posting node status.
Ready Unknown Thu, 17 Feb 2022 17:12:40 -0500 Thu, 17 Feb 2022 17:13:52 -0500 NodeStatusUnknown Kubelet stopped posting node status.
Addresses:
InternalIP: 192.168.0.113
Hostname: kube-worker-1
Capacity:
cpu: 2
ephemeral-storage: 15372232Ki
hugepages-2Mi: 0
memory: 2025188Ki
pods: 110
Allocatable:
cpu: 2
ephemeral-storage: 14167048988
hugepages-2Mi: 0
memory: 1922788Ki
pods: 110
System Info:
Machine ID: 9384e2927f544209b5d7b67474bbf92b
System UUID: aa829ca9-73d7-064d-9019-df07404ad448
Boot ID: 5a295a03-aaca-4340-af20-1327fa5dab5c
Kernel Version: 5.13.0-28-generic
OS Image: Ubuntu 21.10
Operating System: linux
Architecture: amd64
Container Runtime Version: containerd://1.5.9
Kubelet Version: v1.23.3
Kube-Proxy Version: v1.23.3
Non-terminated Pods: (4 in total)
Namespace Name CPU Requests CPU Limits Memory Requests Memory Limits Age
--------- ---- ------------ ---------- --------------- ------------- ---
default nginx-deployment-67d4bdd6f5-cx2nz 500m (25%) 500m (25%) 128Mi (6%) 128Mi (6%) 23m
default nginx-deployment-67d4bdd6f5-w6kd7 500m (25%) 500m (25%) 128Mi (6%) 128Mi (6%) 23m
kube-system kube-proxy-dnxbz 0 (0%) 0 (0%) 0 (0%) 0 (0%) 28m
kube-system weave-net-gjxxp 100m (5%) 0 (0%) 200Mi (10%) 0 (0%) 28m
Allocated resources:
(Total limits may be over 100 percent, i.e., overcommitted.)
Resource Requests Limits
-------- -------- ------
cpu 1100m (55%) 1 (50%)
memory 456Mi (24%) 256Mi (13%)
ephemeral-storage 0 (0%) 0 (0%)
hugepages-2Mi 0 (0%) 0 (0%)
Events:
...
kubectl get node kube-worker-1 -o yaml
apiVersion: v1
kind: Node
metadata:
annotations:
node.alpha.kubernetes.io/ttl: "0"
volumes.kubernetes.io/controller-managed-attach-detach: "true"
creationTimestamp: "2022-02-17T21:46:30Z"
labels:
beta.kubernetes.io/arch: amd64
beta.kubernetes.io/os: linux
kubernetes.io/arch: amd64
kubernetes.io/hostname: kube-worker-1
kubernetes.io/os: linux
name: kube-worker-1
resourceVersion: "4026"
uid: 98efe7cb-2978-4a0b-842a-1a7bf12c05f8
spec: {}
status:
addresses:
- address: 192.168.0.113
type: InternalIP
- address: kube-worker-1
type: Hostname
allocatable:
cpu: "2"
ephemeral-storage: "14167048988"
hugepages-2Mi: "0"
memory: 1922788Ki
pods: "110"
capacity:
cpu: "2"
ephemeral-storage: 15372232Ki
hugepages-2Mi: "0"
memory: 2025188Ki
pods: "110"
conditions:
- lastHeartbeatTime: "2022-02-17T22:20:32Z"
lastTransitionTime: "2022-02-17T22:20:32Z"
message: Weave pod has set this
reason: WeaveIsUp
status: "False"
type: NetworkUnavailable
- lastHeartbeatTime: "2022-02-17T22:20:15Z"
lastTransitionTime: "2022-02-17T22:13:25Z"
message: kubelet has sufficient memory available
reason: KubeletHasSufficientMemory
status: "False"
type: MemoryPressure
- lastHeartbeatTime: "2022-02-17T22:20:15Z"
lastTransitionTime: "2022-02-17T22:13:25Z"
message: kubelet has no disk pressure
reason: KubeletHasNoDiskPressure
status: "False"
type: DiskPressure
- lastHeartbeatTime: "2022-02-17T22:20:15Z"
lastTransitionTime: "2022-02-17T22:13:25Z"
message: kubelet has sufficient PID available
reason: KubeletHasSufficientPID
status: "False"
type: PIDPressure
- lastHeartbeatTime: "2022-02-17T22:20:15Z"
lastTransitionTime: "2022-02-17T22:15:15Z"
message: kubelet is posting ready status
reason: KubeletReady
status: "True"
type: Ready
daemonEndpoints:
kubeletEndpoint:
Port: 10250
nodeInfo:
architecture: amd64
bootID: 22333234-7a6b-44d4-9ce1-67e31dc7e369
containerRuntimeVersion: containerd://1.5.9
kernelVersion: 5.13.0-28-generic
kubeProxyVersion: v1.23.3
kubeletVersion: v1.23.3
machineID: 9384e2927f544209b5d7b67474bbf92b
operatingSystem: linux
osImage: Ubuntu 21.10
systemUUID: aa829ca9-73d7-064d-9019-df07404ad448
Аналіз логів
Наразі для глибшого дослідження кластера потрібно входити на відповідні машини. Ось розташування відповідних файлів логів. У системах на основі systemd замість перегляду файлів логів може знадобитися journalctl.
Вузли панелі управління
/var/log/kube-apiserver.log — API-сервер, відповідальний за обслуговування API/var/log/kube-scheduler.log — планувальник, відповідальний за ухвалення рішень щодо планування/var/log/kube-controller-manager.log — компонент, який запускає більшість вбудованих контролерів Kubernetes, за помітним винятком планування (плануванням займається kube-scheduler).
Робочі вузли
/var/log/kubelet.log — логи kubelet, відповідального за запуск контейнерів на вузлі/var/log/kube-proxy.log — логи kube-proxy, відповідального за спрямування трафіку до точок доступу Service
Режими відмови кластера
Це неповний перелік того, що може піти не так, і того, як змінити налаштування кластера, щоб помʼякшити проблеми.
Причини відмов
- Вимкнення віртуальних машин
- Розділення мережі всередині кластера або між кластером і користувачами
- Збої програмного забезпечення Kubernetes
- Втрата даних або недоступність постійного сховища (наприклад, томів GCE PD або AWS EBS)
- Помилка оператора, наприклад, неправильно налаштоване програмне забезпечення Kubernetes або застосунків
Конкретні сценарії
- Вимкнення віртуальної машини API-сервера або збій apiserver
- Результати
- не вдається зупинити, оновити чи запустити нові Podʼи, Service, ReplicationController
- наявні Podʼи та Service мають і далі працювати нормально, якщо вони не залежать від API Kubernetes
- Втрата сховища, що лежить в основі API-сервера
- Результати
- компонент kube-apiserver не може успішно запуститися й стати справним
- kubelet не зможуть звʼязатися з ним, але й далі запускатимуть ті самі Podʼи та забезпечуватимуть те саме проксіювання Service
- перед перезапуском apiserver необхідно вручну відновити або відтворити його стан
- Вимкнення віртуальних машин або збої допоміжних сервісів (контролер вузлів, менеджер контролерів реплікації, планувальник тощо)
- наразі вони розміщені разом з apiserver, і їхня недоступність має схожі наслідки, як і недоступність apiserver
- у майбутньому вони також будуть репліковані й можуть розміщуватися окремо
- вони не мають власного постійного стану
- Вимкнення окремого вузла (віртуальної або фізичної машини)
- Результати
- Podʼи на цьому вузлі припиняють роботу
- Розділення мережі
- Результати
- розділ A вважає, що вузли в розділі B не працюють; розділ B вважає, що не працює apiserver. (За умови, що master VM опиниться в розділі A.)
- Збій програмного забезпечення kubelet
- Результати
- kubelet, що аварійно завершився, не може запускати нові Podʼи на вузлі
- kubelet може видаляти Podʼи або ні
- вузол позначається як несправний
- ReplicationController запускають нові Podʼи в інших місцях
- Помилка оператора кластера
- Результати
- втрата Podʼів, Service тощо
- втрата сховища, що лежить в основі apiserver
- користувачі не можуть читати API
- тощо
Помʼякшення
Дія: використовуйте можливість автоматичного перезапуску віртуальних машин IaaS-провайдера для віртуальних машин IaaS
- Помʼякшує: вимкнення віртуальної машини apiserver або збій apiserver
- Помʼякшує: вимкнення віртуальних машин або збої допоміжних сервісів
Дія: використовуйте надійне сховище IaaS-провайдера (наприклад, томи GCE PD або AWS EBS) для віртуальних машин з apiserver+etcd
- Помʼякшує: втрату сховища, що лежить в основі apiserver
Дія: використовуйте конфігурацію з високою доступністю
- Помʼякшує: вимкнення вузла панелі управління або збої компонентів панелі управління (планувальник, API-сервер, controller-manager)
- Витримує одну або кілька одночасних відмов вузлів чи компонентів
- Помʼякшує: втрату сховища, що лежить в основі API-сервера (тобто теки даних etcd)
- Передбачає конфігурацію etcd з високою доступністю (HA)
Дія: регулярно створюйте знімки томів PD/EBS apiserver
- Помʼякшує: втрату сховища, що лежить в основі apiserver
- Помʼякшує: деякі випадки помилок оператора
- Помʼякшує: деякі випадки збоїв програмного забезпечення Kubernetes
Дія: використовуйте ReplicationController і Service перед Podʼами
- Помʼякшує: вимкнення вузла
- Помʼякшує: збій програмного забезпечення kubelet
Дія: застосунки (контейнери), спроєктовані так, щоб витримувати неочікувані перезапуски
- Помʼякшує: вимкнення вузла
- Помʼякшує: збій програмного забезпечення kubelet
Що далі
4.1 - Конвеєр метрик ресурсів
Для Kubernetes Metrics API пропонує базовий набір метрик для підтримки автоматичного масштабування та подібних випадків використання. Це API робить доступною інформацію про використання ресурсів вузлами й Podʼами, зокрема метрики CPU та памʼяті. Якщо ви розгорнете Metrics API у своєму кластері, клієнти API Kubernetes зможуть запитувати цю інформацію, а ви зможете використовувати механізми контролю доступу Kubernetes для керування дозволами на це.
HorizontalPodAutoscaler (HPA) і VerticalPodAutoscaler (VPA) використовують дані з Metrics API, щоб коригувати кількість реплік і ресурси робочих навантажень відповідно до попиту користувачів.
Ви також можете переглядати метрики ресурсів, використовуючи команду kubectl top.
Примітка:
Metrics API та конвеєр метрик, який воно уможливлює, надають лише мінімальний набір метрик CPU та памʼяті для автоматичного масштабування за допомогою HPA та / або VPA. Якщо ви хочете надати повніший набір метрик, ви можете доповнити простіший Metrics API, розгорнувши другий
конвеєр метрик, який використовує
Custom Metrics API.
Схема 1 ілюструє архітектуру конвеєра метрик ресурсів.
flowchart RL
subgraph cluster[Кластер]
direction RL
S[
]
A[Сервер-
метрик]
subgraph B[Вузли]
direction TB
D[cAdvisor] --> C[kubelet]
E[Середовище
виконання
контейнерів] --> D
E1[Середовище
виконання
контейнерів] --> D
P[Дані Podʼа] -.- C
end
L[API-сервер]
W[HPA]
C ---->|метрики ресурсів
на рівні вузла| A -->|Metrics
API| L --> W
end
L ---> K[kubectl
top]
classDef box fill:#fff,stroke:#000,stroke-width:1px,color:#000;
class W,B,P,K,cluster,D,E,E1 box
classDef spacewhite fill:#ffffff,stroke:#fff,stroke-width:0px,color:#000
class S spacewhite
classDef k8s fill:#326ce5,stroke:#fff,stroke-width:1px,color:#fff;
class A,L,C k8s
Схема 1. Конвеєр метрик ресурсів
Компоненти архітектури, справа наліво на схемі, такі:
cAdvisor: демон, вбудований у kubelet, для збирання, агрегування та надання метрик контейнерів.
kubelet: агент вузла для керування ресурсами контейнерів. Метрики ресурсів доступні через точки доступу API kubelet /metrics/resource і /stats.
метрики ресурсів на рівні вузла: API, який надає kubelet для виявлення й отримання підсумкової статистики по вузлу, доступної через точку доступу /metrics/resource.
metrics-server: компонент-надбудова кластера, який збирає й агрегує метрики ресурсів, отримані від кожного kubelet. API-сервер обслуговує Metrics API для HPA, VPA і команди kubectl top. Metrics Server — це еталонна реалізація Metrics API.
Metrics API: API Kubernetes, що надає доступ до даних про CPU та памʼять, які використовуються для автомасштабування робочих навантажень. Щоб це працювало у вашому кластері, потрібен API-сервер розширення, який надає Metrics API.
Примітка:
cAdvisor підтримує читання метрик з cgroups, що працює зі звичайними середовищами виконання контейнерів у Linux. Якщо ви використовуєте середовище виконання контейнерів з іншим механізмом ізоляції ресурсів, наприклад віртуалізацією, це середовище виконання контейнерів має підтримувати
метрики контейнерів CRI, щоб метрики були доступні kubelet.
Metrics API
СТАН ФУНКЦІОНАЛУ:
GA since Kubernetes v1.37
Metrics-server реалізує Metrics API. Це API дає змогу отримати дані про використання CPU та памʼяті вузлами й Podʼами вашого кластера. Його основна роль — передавати метрики використання ресурсів компонентам автомасштабування K8s.
Ось приклад запиту до Metrics API для вузла minikube, обробленого через jq для зручного перегляду:
kubectl get --raw "/apis/metrics.k8s.io/v1/nodes/minikube" | jq '.'
Той самий виклик API за допомогою curl:
curl http://localhost:8080/apis/metrics.k8s.io/v1/nodes/minikube
Приклад відповіді:
{
"kind": "NodeMetrics",
"apiVersion": "metrics.k8s.io/v1",
"metadata": {
"name": "minikube",
"selfLink": "/apis/metrics.k8s.io/v1/nodes/minikube",
"creationTimestamp": "2022-01-27T18:48:43Z"
},
"timestamp": "2022-01-27T18:48:33Z",
"window": "30s",
"usage": {
"cpu": "487558164n",
"memory": "732212Ki"
}
}
Ось приклад запиту до Metrics API для Podʼа kube-scheduler-minikube у просторі імен kube-system, обробленого через jq для зручного перегляду:
kubectl get --raw "/apis/metrics.k8s.io/v1/namespaces/kube-system/pods/kube-scheduler-minikube" | jq '.'
Той самий виклик API за допомогою curl:
curl http://localhost:8080/apis/metrics.k8s.io/v1/namespaces/kube-system/pods/kube-scheduler-minikube
Приклад відповіді:
{
"kind": "PodMetrics",
"apiVersion": "metrics.k8s.io/v1",
"metadata": {
"name": "kube-scheduler-minikube",
"namespace": "kube-system",
"selfLink": "/apis/metrics.k8s.io/v1/namespaces/kube-system/pods/kube-scheduler-minikube",
"creationTimestamp": "2022-01-27T19:25:00Z"
},
"timestamp": "2022-01-27T19:24:31Z",
"window": "30s",
"containers": [
{
"name": "kube-scheduler",
"usage": {
"cpu": "9559630n",
"memory": "22244Ki"
}
}
]
}
Metrics API визначено в репозиторії k8s.io/metrics. Вам потрібно увімкнути шар агрегації API та зареєструвати APIService для API metrics.k8s.io.
Щоб дізнатися більше про Metrics API, дивіться дизайн API метрик ресурсів, репозиторій metrics-server і API метрик ресурсів.
Примітка:
Щоб отримати доступ до Metrics API, потрібно розгорнути metrics-server або інший адаптер, який його надає.Вимірювання використання ресурсів
CPU
CPU відображається як середнє використання ядер, виміряне в одиницях CPU. Один CPU у Kubernetes еквівалентний 1 vCPU/ядру в хмарних провайдерів і 1 гіперпотоку на процесорах Intel на bare-metal.
Це значення отримують, обчислюючи швидкість зміни накопичувального лічильника CPU, який надає ядро (і в Linux, і в Windows). Часове вікно, використане для обчислення CPU, показано в полі window у Metrics API.
Щоб дізнатися більше про те, як Kubernetes розподіляє та вимірює ресурси CPU, дивіться значення CPU.
Памʼять
Памʼять відображається як робочий набір, виміряний у байтах, у момент збору метрики.
В ідеальному світі "робочий набір" — це обсяг памʼяті, що використовується й не може бути звільнений за умов тиску на памʼять. Однак обчислення робочого набору залежить від ОС хоста й, як правило, значною мірою покладається на евристики для отримання оцінки.
Модель Kubernetes для робочого набору контейнера очікує, що середовище виконання контейнерів враховує анонімну памʼять, повʼязану з відповідним контейнером. Метрика робочого набору зазвичай також включає деяку кешовану памʼять (file-backed), оскільки ОС хоста не завжди може звільнити сторінки.
Щоб дізнатися більше про те, як Kubernetes розподіляє та вимірює ресурси памʼяті, дивіться значення памʼяті.
Metrics Server
Metrics-server отримує метрики ресурсів від kubelet і надає їх через Metrics API на API-сервері Kubernetes для використання HPA та VPA. Ці метрики також можна переглядати командою kubectl top.
Metrics-server використовує API Kubernetes для відстеження вузлів і Podʼів у вашому кластері. Metrics-server запитує кожен вузол через HTTP, щоб отримати метрики. Metrics-server також будує внутрішнє подання метаданих Podʼів і зберігає кеш стану справності Podʼів. Ця кешована інформація про стан справності Podʼів доступна через API розширення, яке надає metrics-server.
Наприклад, для запиту HPA metrics-server має визначити, які Podʼи відповідають селекторам міток у Deployment.
Metrics-server викликає API kubelet для збору метрик з кожного вузла. Залежно від версії metrics-server використовується:
- Точка доступу ресурсів метрик
/metrics/resource у версії v0.6.0+ або - Точка доступу Summary API
/stats/summary у старіших версіях
Що далі
Щоб дізнатися більше про metrics-server, перегляньте репозиторій metrics-server.
Також можна переглянути таке:
Щоб дізнатися про те, як kubelet надає метрики вузла, і як ви можете отримати до них доступ через API Kubernetes, прочитайте Дані метрик вузлів.
4.2 - Налагодження вузлів Kubernetes за допомогою crictl
СТАН ФУНКЦІОНАЛУ:
GA since Kubernetes v1.11
crictl — це інтерфейс командного рядка для середовищ виконання контейнерів, сумісних з CRI. За його допомогою можна оглядати й налагоджувати середовища виконання контейнерів і застосунки на вузлі Kubernetes. crictl і його вихідний код розміщено в репозиторії cri-tools.
Перш ніж ви розпочнете
Для роботи crictl потрібна операційна система Linux із середовищем виконання CRI.
Встановлення crictl
Стиснений архів crictl для кількох різних архітектур можна завантажити зі сторінки релізів cri-tools. Завантажте версію, яка відповідає вашій версії Kubernetes. Розпакуйте архів і перемістіть crictl у теку з вашого системного шляху, наприклад /usr/local/bin/.
Загальне використання
Команда crictl має кілька підкоманд і прапорців середовища виконання. Докладніше дивіться crictl help або crictl <subcommand> help.
Точку доступу для crictl можна встановити одним із таких способів:
- Встановіть прапорці
--runtime-endpoint та --image-endpoint. - Встановіть змінні середовища
CONTAINER_RUNTIME_ENDPOINT та IMAGE_SERVICE_ENDPOINT. - Встановіть точку доступу у файлі конфігурації
/etc/crictl.yaml. Щоб вказати інший файл, використовуйте прапорець --config=PATH_TO_FILE під час запуску crictl.
Примітка:
Якщо ви не встановите точку доступу, crictl намагатиметься підʼєднатися до відомих точок доступу зі списку, що може вплинути на продуктивність.Також можна вказати тайм-аут підʼєднання до сервера й увімкнути або вимкнути налагодження, задавши значення timeout або debug у файлі конфігурації або використавши прапорці командного рядка --timeout і --debug.
Щоб переглянути або змінити поточну конфігурацію, перегляньте або відредагуйте вміст /etc/crictl.yaml. Наприклад, з середовищем виконання контейнерів containerd конфігурація буде схожа на таку:
runtime-endpoint: unix:///var/run/containerd/containerd.sock
image-endpoint: unix:///var/run/containerd/containerd.sock
timeout: 10
debug: true
Щоб дізнатися більше про crictl, зверніться до документації crictl.
Приклади команд crictl
Наведені нижче приклади показують деякі команди crictl і приклади їхнього виводу.
Отримання переліку Podʼів
Вивести всі Podʼи:
Вивід подібний до такого:
POD ID CREATED STATE NAME NAMESPACE ATTEMPT
926f1b5a1d33a About a minute ago Ready sh-84d7dcf559-4r2gq default 0
4dccb216c4adb About a minute ago Ready nginx-65899c769f-wv2gp default 0
a86316e96fa89 17 hours ago Ready kube-proxy-gblk4 kube-system 0
919630b8f81f1 17 hours ago Ready nvidia-device-plugin-zgbbv kube-system 0
Вивести Podʼи за назвою:
crictl pods --name nginx-65899c769f-wv2gp
Вивід подібний до такого:
POD ID CREATED STATE NAME NAMESPACE ATTEMPT
4dccb216c4adb 2 minutes ago Ready nginx-65899c769f-wv2gp default 0
Вивести Podʼи за міткою:
crictl pods --label run=nginx
Вивід подібний до такого:
POD ID CREATED STATE NAME NAMESPACE ATTEMPT
4dccb216c4adb 2 minutes ago Ready nginx-65899c769f-wv2gp default 0
Отримання переліку образів
Вивести всі образи:
Вивід подібний до такого:
IMAGE TAG IMAGE ID SIZE
busybox latest 8c811b4aec35f 1.15MB
k8s-gcrio.azureedge.net/hyperkube-amd64 v1.10.3 e179bbfe5d238 665MB
k8s-gcrio.azureedge.net/pause-amd64 3.1 da86e6ba6ca19 742kB
nginx latest cd5239a0906a6 109MB
Вивести образи за репозиторієм:
Вивід подібний до такого:
IMAGE TAG IMAGE ID SIZE
nginx latest cd5239a0906a6 109MB
Вивести лише ідентифікатори образів:
Вивід подібний до такого:
sha256:8c811b4aec35f259572d0f79207bc0678df4c736eeec50bc9fec37ed936a472a
sha256:e179bbfe5d238de6069f3b03fccbecc3fb4f2019af741bfff1233c4d7b2970c5
sha256:da86e6ba6ca197bf6bc5e9d900febd906b133eaa4750e6bed647b0fbe50ed43e
sha256:cd5239a0906a6ccf0562354852fae04bc5b52d72a2aff9a871ddb6bd57553569
Отримання переліку контейнерів
Вивести всі контейнери:
Вивід подібний до такого:
CONTAINER ID IMAGE CREATED STATE NAME ATTEMPT
1f73f2d81bf98 busybox@sha256:141c253bc4c3fd0a201d32dc1f493bcf3fff003b6df416dea4f41046e0f37d47 7 minutes ago Running sh 1
9c5951df22c78 busybox@sha256:141c253bc4c3fd0a201d32dc1f493bcf3fff003b6df416dea4f41046e0f37d47 8 minutes ago Exited sh 0
87d3992f84f74 nginx@sha256:d0a8828cccb73397acb0073bf34f4d7d8aa315263f1e7806bf8c55d8ac139d5f 8 minutes ago Running nginx 0
1941fb4da154f k8s-gcrio.azureedge.net/hyperkube-amd64@sha256:00d814b1f7763f4ab5be80c58e98140dfc69df107f253d7fdd714b30a714260a 18 hours ago Running kube-proxy 0
Вивести запущені контейнери:
Вивід подібний до такого:
CONTAINER ID IMAGE CREATED STATE NAME ATTEMPT
1f73f2d81bf98 busybox@sha256:141c253bc4c3fd0a201d32dc1f493bcf3fff003b6df416dea4f41046e0f37d47 6 minutes ago Running sh 1
87d3992f84f74 nginx@sha256:d0a8828cccb73397acb0073bf34f4d7d8aa315263f1e7806bf8c55d8ac139d5f 7 minutes ago Running nginx 0
1941fb4da154f k8s-gcrio.azureedge.net/hyperkube-amd64@sha256:00d814b1f7763f4ab5be80c58e98140dfc69df107f253d7fdd714b30a714260a 17 hours ago Running kube-proxy 0
Виконання команди в запущеному контейнері
crictl exec -i -t 1f73f2d81bf98 ls
Вивід подібний до такого:
bin dev etc home proc root sys tmp usr var
Отримання логів контейнера
Отримати всі логи контейнера:
crictl logs 87d3992f84f74
Вивід подібний до такого:
10.240.0.96 - - [06/Jun/2018:02:45:49 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.47.0" "-"
10.240.0.96 - - [06/Jun/2018:02:45:50 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.47.0" "-"
10.240.0.96 - - [06/Jun/2018:02:45:51 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.47.0" "-"
Отримати лише останні N рядків логів:
crictl logs --tail=1 87d3992f84f74
Вивід подібний до такого:
10.240.0.96 - - [06/Jun/2018:02:45:51 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.47.0" "-"
Що далі
4.3 - Аудит
Аудит Kubernetes надає важливий для безпеки хронологічний набір записів, що документують послідовність дій у кластері. Кластер проводить аудит дій, ініційованих користувачами, застосунками, які використовують API Kubernetes, і самою панеллю управління.
Аудит дає змогу адміністраторам кластера відповісти на такі запитання:
- що сталося?
- коли це сталося?
- хто це ініціював?
- з чим це сталося?
- де це було помічено?
- звідки це було ініційовано?
- куди це прямувало?
Записи аудиту починають свій життєвий цикл у компоненті kube-apiserver. Кожен запит на кожному етапі виконання генерує подію аудиту, яку потім попередньо обробляють відповідно до певної політики й записують у бекенд. Політика визначає, що записується, а бекенди зберігають записи. Поточні реалізації бекендів — файли логів і вебхуки.
Кожен запит можна записати з відповідним етапом (stage). Визначено такі етапи:
RequestReceived — етап для подій, що генеруються, щойно обробник аудиту отримує запит, і до того, як запит передано далі ланцюжком обробників.ResponseStarted — після надсилання заголовків відповіді, але до надсилання тіла відповіді. Цей етап генерується лише для тривалих запитів (наприклад, watch).ResponseComplete — тіло відповіді завершено, і більше жодних байтів не буде надіслано.Panic — події, що генеруються, коли сталася паніка.
Можливість логування аудиту збільшує споживання памʼяті API-сервером, оскільки для кожного запиту зберігається певний контекст, потрібний для аудиту. Споживання памʼяті залежить від конфігурації логування аудиту.
Політика аудиту
Політика аудиту визначає правила щодо того, які події слід записувати і які дані вони мають містити. Структуру обʼєкта політики аудиту визначено в групі API audit.k8s.io. Під час обробки подію по черзі порівнюють зі списком правил. Перше правило, що збіглося, встановлює рівень аудиту події. Визначено такі рівні аудиту:
None — не записувати події, які відповідають цьому правилу.Metadata — записувати події з метаданими (користувач, що надіслав запит, часова мітка, ресурс, дієслово тощо), але без тіла запиту чи відповіді.Request — записувати події з метаданими й тілом запиту, але без тіла відповіді. Це не стосується запитів, не повʼязаних з ресурсами.RequestResponse — записувати події з метаданими запиту, тілом запиту й тілом відповіді. Це не стосується запитів, не повʼязаних з ресурсами.
Файл з політикою можна передати kube-apiserver за допомогою прапорця --audit-policy-file. Якщо прапорець пропущено, жодні події не записуються. Зверніть увагу, що поле rules обовʼязково має бути у файлі політики аудиту. Політика без правил (0) вважається неприпустимою.
Нижче наведено приклад файлу політики аудиту:
apiVersion: audit.k8s.io/v1 # Це обовʼязково.
kind: Policy
# Не генерувати події аудиту для всіх запитів на етапі RequestReceived.
omitStages:
- "RequestReceived"
rules:
# Логувати зміни Podʼів на рівні RequestResponse
- level: RequestResponse
resources:
- group: ""
# Ресурс "pods" не охоплює запити до будь-якого субресурсу Podʼів,
# що узгоджується з політикою RBAC.
resources: ["pods"]
# Логувати "pods/log", "pods/status" на рівні Metadata
- level: Metadata
resources:
- group: ""
resources: ["pods/log", "pods/status"]
# Не логувати запити до ConfigMap з назвою "controller-leader"
- level: None
resources:
- group: ""
resources: ["configmaps"]
resourceNames: ["controller-leader"]
# Не логувати watch-запити від "system:kube-proxy" до endpoints або services
- level: None
users: ["system:kube-proxy"]
verbs: ["watch"]
resources:
- group: "" # основна група API
resources: ["endpoints", "services"]
# Не логувати автентифіковані запити до певних URL-шляхів, що не є ресурсами.
- level: None
userGroups: ["system:authenticated"]
nonResourceURLs:
- "/api*" # Зіставлення за шаблоном.
- "/version"
# Логувати тіло запитів на зміну ConfigMap у kube-system.
- level: Request
resources:
- group: "" # основна група API
resources: ["configmaps"]
# Це правило застосовується тільки до ресурсів в просторі імен "kube-system".
# Порожній рядок "" можна використовувати для вибору ресурсів без простору імен.
namespaces: ["kube-system"]
# Логувати зміни ConfigMap і Secret у всіх інших просторах імен на рівні Metadata.
- level: Metadata
resources:
- group: "" # основна група API
resources: ["secrets", "configmaps"]
# Логувати всі інші ресурси в групах core та extensions на рівні Request.
- level: Request
resources:
- group: "" # основна група API
- group: "extensions" # Версію групи НЕ слід вказувати.
# Загальне правило для логування всіх інших запитів на рівні Metadata.
- level: Metadata
# Тривалі запити, як-от watch, що підпадають під це правило,
# не генерують подію аудиту на етапі RequestReceived.
omitStages:
- "RequestReceived"
Можна використати мінімальний файл політики аудиту, щоб записувати всі запити на рівні Metadata:
# Записувати всі запити на рівні Metadata.
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
- level: Metadata
Якщо ви створюєте власний профіль аудиту, за відправну точку можна взяти профіль аудиту для Google Container-Optimized OS. Перегляньте скрипт configure-helper.sh, який генерує файл політики аудиту. Більшу частину файлу політики аудиту можна побачити безпосередньо в скрипті.
Докладніше про визначені поля дивіться в довіднику конфігурації Policy.
Бекенди аудиту
Бекенди аудиту зберігають події аудиту в зовнішньому сховищі. Без додаткових налаштувань kube-apiserver надає два бекенди:
- бекенд логів, який записує події у файлову систему
- бекенд webhook, який надсилає події до зовнішнього HTTP API
У всіх випадках події аудиту мають структуру, визначену API Kubernetes у групі API audit.k8s.io.
Примітка:
У разі патчів тіло запиту — це масив JSON з операціями патча, а не обʼєкт JSON з відповідним обʼєктом API Kubernetes. Наприклад, наведене нижче тіло запиту є коректним запитом на патч до /apis/batch/v1/namespaces/some-namespace/jobs/some-job-name:
[
{
"op": "replace",
"path": "/spec/parallelism",
"value": 0
},
{
"op": "remove",
"path": "/spec/template/spec/containers/0/terminationMessagePolicy"
}
]
Бекенд логів
Бекенд логів записує події аудиту у файл у форматі JSONlines. Бекенд аудиту логів можна налаштувати за допомогою таких прапорців kube-apiserver:
--audit-log-path вказує шлях до файлу логу, який бекенд логів використовує для запису подій аудиту. Якщо цей прапорець не вказано, бекенд логів вимкнено. - означає стандартний вивід--audit-log-maxage визначає максимальну кількість днів для зберігання старих файлів логів аудиту--audit-log-maxbackup визначає максимальну кількість файлів логів аудиту для зберігання--audit-log-maxsize визначає максимальний розмір файлу логу аудиту в мегабайтах, після якого виконується його ротація
Якщо панель управління вашого кластера запускає kube-apiserver як Pod, не забудьте змонтувати hostPath у розташування файлу політики й файлу логів, щоб записи аудиту зберігалися. Наприклад:
- --audit-policy-file=/etc/kubernetes/audit-policy.yaml
- --audit-log-path=/var/log/kubernetes/audit/audit.log
потім змонтуйте томи:
...
volumeMounts:
- mountPath: /etc/kubernetes/audit-policy.yaml
name: audit
readOnly: true
- mountPath: /var/log/kubernetes/audit/
name: audit-log
readOnly: false
і нарешті налаштуйте hostPath:
...
volumes:
- name: audit
hostPath:
path: /etc/kubernetes/audit-policy.yaml
type: File
- name: audit-log
hostPath:
path: /var/log/kubernetes/audit/
type: DirectoryOrCreate
Бекенд Webhook
Бекенд аудиту webhook надсилає події аудиту до віддаленого веб-API, яке вважається різновидом API Kubernetes, зокрема щодо засобів автентифікації. Бекенд аудиту webhook можна налаштувати за допомогою таких прапорців kube-apiserver:
--audit-webhook-config-file вказує шлях до файлу з конфігурацією webhook. Конфігурація webhook фактично є спеціалізованим kubeconfig.--audit-webhook-initial-backoff вказує час очікування після першого невдалого запиту перед повторною спробою. Подальші запити повторюються з експоненційною затримкою.
Файл конфігурації webhook використовує формат kubeconfig, щоб вказати віддалену адресу сервісу й облікові дані для підʼєднання до нього.
Пакетна обробка подій
Обидва бекенди, log і webhook, підтримують пакетну обробку. Нижче наведено перелік доступних прапорців для кожного бекенду. Стандартно пакетну обробку й тротлінг увімкнено для бекенду webhook і вимкнено для бекенду log.
--audit-webhook-mode визначає стратегію буферизації. Можливі значення:batch — буферизувати події й асинхронно обробляти їх пакетами. Це стандартний режим для бекенду webhook.blocking — блокувати відповіді API-сервера під час обробки кожної окремої події.blocking-strict — те саме, що й blocking, але якщо під час логування аудиту на етапі RequestReceived стається збій, увесь запит до kube-apiserver завершується невдачею.
Такі прапорці використовуються лише в режимі batch:
--audit-webhook-batch-buffer-size визначає кількість подій для буферизації перед пакетною обробкою. Якщо швидкість надходження подій переповнює буфер, події відкидаються. Стандартне значення — 10000.--audit-webhook-batch-max-size визначає максимальну кількість подій в одному пакеті. Стандартне значення — 400.--audit-webhook-batch-max-wait визначає максимальний час очікування перед безумовною пакетною обробкою подій у черзі. Стандартне значення — 30 секунд.--audit-webhook-batch-throttle-enable визначає, чи увімкнено тротлінг пакетів. Стандартно тротлінг увімкнено.--audit-webhook-batch-throttle-qps визначає максимальну середню кількість пакетів, що генеруються за секунду. Стандартне значення — 10.--audit-webhook-batch-throttle-burst визначає максимальну кількість пакетів, згенерованих у той самий момент, якщо дозволений QPS раніше використовувався не повністю. Стандартне значення — 15.
--audit-log-mode визначає стратегію буферизації. Можливі значення:batch — буферизувати події й асинхронно обробляти їх пакетами. Пакетна обробка не рекомендується для бекенду log.blocking — блокувати відповіді API-сервера під час обробки кожної окремої події. Це стандартний режим для бекенду log.blocking-strict — те саме, що й blocking, але якщо під час логування аудиту на етапі RequestReceived стається збій, увесь запит до kube-apiserver завершується невдачею.
Такі прапорці використовуються лише в режимі batch (стандартно для бекенду log пакетну обробку вимкнено, і коли її вимкнено, усі прапорці, повʼязані з пакетною обробкою, ігноруються):
--audit-log-batch-buffer-size визначає кількість подій для буферизації перед пакетною обробкою. Якщо швидкість надходження подій переповнює буфер, події відкидаються.--audit-log-batch-max-size визначає максимальну кількість подій в одному пакеті.--audit-log-batch-max-wait визначає максимальний час очікування перед безумовною пакетною обробкою подій у черзі.--audit-log-batch-throttle-enable визначає, чи увімкнено тротлінг пакетної обробки.--audit-log-batch-throttle-qps визначає максимальну середню кількість пакетів, що генеруються за секунду.--audit-log-batch-throttle-burst визначає максимальну кількість пакетів, згенерованих у той самий момент, якщо дозволений QPS раніше використовувався не повністю.
Налаштування параметрів
Параметри слід задавати з урахуванням навантаження на API-сервер.
Наприклад, якщо kube-apiserver отримує 100 запитів щосекунди і кожен запит проходить аудит лише на етапах ResponseStarted і ResponseComplete, слід розраховувати на ≅200 подій аудиту щосекунди. Якщо в пакеті до 100 подій, рівень тротлінгу слід встановити щонайменше 2 запити на секунду. Якщо бекенду може знадобитися до 5 секунд для запису подій, розмір буфера слід встановити так, щоб він вміщував події за 5 секунд, тобто 10 пакетів або 1000 подій.
Однак у більшості випадків стандартних параметрів має бути достатньо, і вам не потрібно задавати їх вручну. Щоб відстежувати стан підсистеми аудиту, можна переглядати такі метрики Prometheus, які надає kube-apiserver, а також логи.
- Метрика
apiserver_audit_event_total містить загальну кількість експортованих подій аудиту. - Метрика
apiserver_audit_error_total містить загальну кількість подій, відкинутих через помилку під час експорту.
Обрізання записів логу
Обидва бекенди, логів і webhook, підтримують обмеження розміру подій, що записуються. Наприклад, ось перелік прапорців, доступних для бекенду логів:
audit-log-truncate-enabled — чи ввімкнено обрізання подій і пакетів.audit-log-truncate-max-batch-size — максимальний розмір у байтах пакета, що надсилається до базового бекенду.audit-log-truncate-max-event-size — максимальний розмір у байтах події аудиту, що надсилається до базового бекенду.
Стандартно обрізання вимкнено і для webhook, і для log; щоб увімкнути цю можливість, адміністратор кластера має встановити audit-log-truncate-enabled або audit-webhook-truncate-enabled.
Що далі
4.4 - Розробка та налагодження сервісів локально за допомогою telepresence
Примітка: Цей розділ містить посилання на проєкти сторонніх розробників, які надають функціонал, необхідний для Kubernetes. Автори проєкту Kubernetes не несуть відповідальності за ці проєкти. Проєкти вказано в алфавітному порядку. Щоб додати проєкт до цього списку, ознайомтеся з
посібником з контенту перед надсиланням змін.
Докладніше. Застосунки Kubernetes зазвичай складаються з кількох окремих сервісів, кожен з яких працює у власному контейнері. Розробляти й налагоджувати ці сервіси у віддаленому кластері Kubernetes може бути незручно, бо для запуску інструментів налагодження потрібно отримати доступ до оболонки запущеного контейнера.
telepresence — це інструмент, що спрощує локальну розробку й налагодження сервісів, проксіюючи сервіс до віддаленого кластера Kubernetes. telepresence дає змогу використовувати для локального сервісу власні інструменти, як-от налагоджувач та IDE, і надає сервісу повний доступ до ConfigMap, Secrets і сервісів, що працюють у віддаленому кластері.
У цьому документі описано, як використовувати telepresence для локальної розробки й налагодження сервісів, що працюють у віддаленому кластері.
Перш ніж ви розпочнете
- Кластер Kubernetes встановлено
kubectl налаштовано для звʼязку з кластером- Telepresence встановлено
Підʼєднання вашого локального компʼютера до віддаленого кластера Kubernetes
Після встановлення telepresence виконайте telepresence connect, щоб запустити його демон і підʼєднати вашу локальну робочу станцію до кластера.
$ telepresence connect
Launching Telepresence Daemon
...
Connected to context default (https://<cluster public IP>)
Ви можете звертатися до сервісів командою curl, використовуючи синтаксис Kubernetes, наприклад curl -ik https://kubernetes.default
Розробка або налагодження наявного сервісу
Під час розробки застосунку в Kubernetes ви зазвичай програмуєте або налагоджуєте один сервіс. Цьому сервісу може знадобитися доступ до інших сервісів для тестування й налагодження. Один із варіантів — використовувати конвеєр безперервного розгортання, але навіть найшвидший конвеєр розгортання додає затримку в цикл програмування чи налагодження.
Використовуйте команду telepresence intercept $SERVICE_NAME --port $LOCAL_PORT:$REMOTE_PORT, щоб створити «перехоплення» (intercept) для перенаправлення трафіку віддаленого сервісу.
Де:
$SERVICE_NAME — це назва вашого локального сервісу$LOCAL_PORT — це порт, на якому ваш сервіс працює на вашій локальній робочій станції$REMOTE_PORT — це порт, який ваш сервіс слухає в кластері
Ця команда вказує Telepresence надсилати віддалений трафік на ваш локальний сервіс замість сервісу у віддаленому кластері Kubernetes. Вносьте зміни у вихідний код сервісу локально, зберігайте їх, і відповідні зміни одразу набиратимуть чинності під час доступу до віддаленого застосунку. Ви також можете запускати локальний сервіс за допомогою налагоджувача чи будь-якого іншого локального інструмента розробки.
Як працює Telepresence?
Telepresence встановлює sidecar traffic-agent поруч із контейнером вашого наявного застосунку, що працює у віддаленому кластері. Потім він перехоплює всі запити трафіку, що надходять до Podʼа, і замість того, щоб пересилати їх застосунку у віддаленому кластері, спрямовує весь трафік (коли ви створюєте глобальне перехоплення) або його частину (коли ви створюєте персональне перехоплення) до вашого локального середовища розробки.
Що далі
Якщо вас цікавить практичний навчальний матеріал, перегляньте цей навчальний матеріал, у якому покроково описано локальну розробку застосунку Guestbook на Google Kubernetes Engine.
Докладніше дивіться на вебсайті Telepresence.
4.5 - Усунення несправностей керування топологією
Kubernetes приховує від користувача багато аспектів того, як Podʼи виконуються на вузлах. Це зроблено навмисно. Однак деяким робочим навантаженням для прийнятної роботи потрібні сильніші гарантії щодо затримки та/або продуктивності. kubelet надає методи для складніших політик розміщення робочих навантажень і водночас зберігає абстракцію вільною від явних директив розміщення.
Ви можете керувати топологією всередині вузлів. Це означає, що ви допомагаєте kubelet налаштувати операційну систему хоста так, щоб Podʼи й контейнери розміщувалися з правильного боку внутрішніх меж, таких як домени NUMA. (NUMA — абревіатура від non-uniform memory access (нерівномірний доступ до памʼяті); вона відображає ідею, що CPU можуть бути топологічно ближчими до певних ділянок памʼяті через фізичне розташування апаратних компонентів і спосіб їх зʼєднання.)
Щоб зʼясувати, чому Pod не вдалося розгорнути або чому його відхилено на вузлі в контексті керування топологією, можна скористатися такими засобами:
- Статус Podʼа — показує помилки спорідненості топології
- Системні логи — містять цінну інформацію для налагодження, наприклад, про згенеровані підказки
- Файл стану kubelet — дамп внутрішнього стану менеджера памʼяті (включно з мапою вузлів і мапами памʼяті)
- Ви можете використовувати API ресурсів втулка пристрою для отримання інформації про памʼять, зарезервовану для контейнерів
Усунення несправностей TopologyAffinityError
Ця помилка зазвичай виникає в таких ситуаціях:
- вузол не має достатньо доступних ресурсів, щоб задовольнити запит Podʼа
- запит Podʼа відхилено через обмеження певної політики менеджера топології
Помилка зʼявляється в статусі Podʼа:
NAME READY STATUS RESTARTS AGE
guaranteed 0/1 TopologyAffinityError 0 113s
Використовуйте kubectl describe pod <id> або kubectl events, щоб отримати детальне повідомлення про помилку:
Warning TopologyAffinityError 10m kubelet, dell8 Resources cannot be allocated with Topology locality
Перегляньте системні логи
Шукайте в системних логах записи щодо конкретного Podʼа.
Набір підказок, згенерованих менеджером CPU, має бути в логах. Також у логах можна знайти набір підказок, які менеджер памʼяті згенерував для Podʼа.
Менеджер топології обʼєднує ці підказки, щоб обчислити одну найкращу підказку. Найкраща підказка також має бути в логах.
Найкраща підказка вказує, де виділити всі ресурси. Менеджер топології перевіряє цю підказку на відповідність своїй поточній політиці й, залежно від результату, або допускає Pod на вузол, або відхиляє його.
Також шукайте в логах записи, повʼязані з менеджером памʼяті, наприклад, щоб знайти інформацію про оновлення cgroups і cpuset.mems.
Приклади
Перевірка стану менеджера памʼяті на вузлі
Спочатку розгорнімо зразковий Pod Guaranteed з такою специфікацією:
apiVersion: v1
kind: Pod
metadata:
name: guaranteed
spec:
containers:
- name: guaranteed
image: consumer
imagePullPolicy: Never
resources:
limits:
cpu: "2"
memory: 150Gi
requests:
cpu: "2"
memory: 150Gi
command: ["sleep","infinity"]
Далі увійдіть на вузол, де його розгорнуто, і перегляньте файл стану в /var/lib/kubelet/memory_manager_state:
{
"policyName":"Static",
"machineState":{
"0":{
"numberOfAssignments":1,
"memoryMap":{
"hugepages-1Gi":{
"total":0,
"systemReserved":0,
"allocatable":0,
"reserved":0,
"free":0
},
"memory":{
"total":134987354112,
"systemReserved":3221225472,
"allocatable":131766128640,
"reserved":131766128640,
"free":0
}
},
"nodes":[
0,
1
]
},
"1":{
"numberOfAssignments":1,
"memoryMap":{
"hugepages-1Gi":{
"total":0,
"systemReserved":0,
"allocatable":0,
"reserved":0,
"free":0
},
"memory":{
"total":135286722560,
"systemReserved":2252341248,
"allocatable":133034381312,
"reserved":29295144960,
"free":103739236352
}
},
"nodes":[
0,
1
]
}
},
"entries":{
"fa9bdd38-6df9-4cf9-aa67-8c4814da37a8":{
"guaranteed":[
{
"numaAffinity":[
0,
1
],
"type":"memory",
"size":161061273600
}
]
}
},
"checksum":4142013182
}
З файлу стану можна зробити висновок, що Pod закріплено за обома вузлами NUMA, тобто:
Термін «закріплений» означає, що споживання памʼяті Podʼом обмежено (через конфігурацію cgroups) цими вузлами NUMA.
Це автоматично означає, що менеджер памʼяті створив нову групу з цих двох вузлів NUMA, тобто вузлів NUMA з індексами 0 і 1.
Щоб проаналізувати ресурси памʼяті, доступні в групі, потрібно підсумувати відповідні записи з вузлів NUMA, що належать до групи.
Наприклад, загальний обсяг вільної «звичайної» памʼяті в групі можна обчислити, додавши вільну памʼять, доступну на кожному вузлі NUMA групи, тобто в розділі "memory" вузла NUMA 0 ("free":0) і вузла NUMA 1 ("free":103739236352). Отже, загальний обсяг вільної «звичайної» памʼяті в цій групі дорівнює 0 + 103739236352 байтів.
Рядок "systemReserved":3221225472 показує, що адміністратор цього вузла зарезервував 3221225472 байти (тобто 3Gi) для kubelet і системних процесів на вузлі NUMA 0 за допомогою прапорця --reserved-memory.
Перевірка API ресурсів втулка пристрою
kubelet надає gRPC-сервіс PodResourceLister, щоб уможливити виявлення ресурсів і повʼязаних з ними метаданих. Через його точку доступу gRPC List можна отримати інформацію про зарезервовану памʼять для кожного контейнера, яка міститься в повідомленні protobuf ContainerMemory.
Цю інформацію можна отримати лише для Podʼів класу QoS Guaranteed.