Це багатосторінковий друкований вигляд цього розділу. Натисність щоб друкувати.

Повернутися до звичайного перегляду сторінки.

Моніторинг, логування та налагодження

Налаштуйте моніторинг та логування для розвʼязання проблем кластера або налагодження контейнеризованих застосунків.

Іноді трапляються неприємності. Цей посібник допоможе вам зібрати необхідну інформацію та вирішити проблеми. Він складається з чотирьох розділів:

  • Налагодження вашого застосунку — корисно для користувачів, які розгортають код у 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.

Також існують багато каналів, специфічних для країн / мов. Запрошуємо приєднатися до цих каналів для локалізованої підтримки та інформації:

Канали Slack для окремих країн і мов
КраїнаКанали
Китай#cn-users, #cn-events
Фінляндія#fi-users
Франція#fr-users, #fr-events
Німеччина#de-users, #de-events
Індія#in-users, #in-events
Італія#it-users, #it-events
Японія#jp-users, #jp-events
Корея#kr-users
Нідерланди#nl-users
Норвегія#norw-users
Польща#pl-users
Росія#ru-users
Іспанія#es-users
Швеція#se-users
Туреччина#tr-users, #tr-events

Форум

Вас раді бачити на офіційному форумі 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.

Виведення інформації про кластер

Перше, що слід перевірити під час налагодження кластера, — чи всі ваші вузли зареєстровано правильно.

Виконайте таку команду:

kubectl get nodes

І переконайтеся, що всі очікувані вузли присутні й перебувають у стані Ready.

Щоб отримати детальну інформацію про загальний стан вашого кластера, ви можете виконати:

kubectl cluster-info dump

Приклад: налагодження вимкненого/недоступного вузла

Іноді під час налагодження корисно переглянути стан вузла — наприклад, тому що ви помітили дивну поведінку Podʼа, який працює на вузлі, або щоб зʼясувати, чому Pod не призначається на вузол. Як і для Podʼів, для отримання детальної інформації про вузли можна використовувати kubectl describe node і kubectl get node -o yaml. Наприклад, ось що ви побачите, якщо вузол не працює (відʼєднаний від мережі, або kubelet завершився й не перезапускається тощо). Зверніть увагу на події, які показують, що вузол у стані NotReady, а також на те, що Podʼи більше не працюють (їх буде виселено після пʼяти хвилин у стані NotReady).

kubectl get nodes
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ʼи:

crictl pods

Вивід подібний до такого:

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

Отримання переліку образів

Вивести всі образи:

crictl images

Вивід подібний до такого:

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

Вивести образи за репозиторієм:

crictl images nginx

Вивід подібний до такого:

IMAGE               TAG                 IMAGE ID            SIZE
nginx               latest              cd5239a0906a6       109MB

Вивести лише ідентифікатори образів:

crictl images -q

Вивід подібний до такого:

sha256:8c811b4aec35f259572d0f79207bc0678df4c736eeec50bc9fec37ed936a472a
sha256:e179bbfe5d238de6069f3b03fccbecc3fb4f2019af741bfff1233c4d7b2970c5
sha256:da86e6ba6ca197bf6bc5e9d900febd906b133eaa4750e6bed647b0fbe50ed43e
sha256:cd5239a0906a6ccf0562354852fae04bc5b52d72a2aff9a871ddb6bd57553569

Отримання переліку контейнерів

Вивести всі контейнери:

crictl ps -a

Вивід подібний до такого:

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

Вивести запущені контейнери:

crictl ps

Вивід подібний до такого:

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 Event.

Можливість логування аудиту збільшує споживання памʼяті 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ʼа:

kubectl get pods
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, тобто:

"numaAffinity":[
   0,
   1
],

Термін «закріплений» означає, що споживання памʼяті 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.