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

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

Завдання

Цей розділ документації Kubernetes містить сторінки, які показують, як виконувати окремі завдання. Сторінка завдання показує, як виконати одну дію, зазвичай за допомогою короткої послідовності кроків.

Якщо ви хочете написати сторінку завдання, дивіться Створення запиту на злиття для документації.

1 - Встановлення інструментів

Налаштування інструментів Kubernetes на вашому компʼютері.

Примітка:

Щоб налаштувати середовище для практики, дивіться сторінку Навчальне середовище.

kubectl

Інструмент командного рядка Kubernetes, kubectl, дозволяє виконувати команди в кластерах Kubernetes. За допомогою kubectl можна розгортати застосунки, оглядати ресурси кластера й керувати ними, а також переглядати логи. Докладніше, зокрема повний перелік операцій kubectl, дивіться в довідковій документації kubectl.

kubectl можна встановити на різних платформах Linux, macOS і Windows. Виберіть свою операційну систему нижче.

kind

kind дозволяє запускати Kubernetes на вашому локальному компʼютері. Для цього інструмента потрібно встановити Docker або Podman.

На сторінці kind Quick Start показано, що потрібно зробити, щоб почати працювати з kind.

Переглянути посібник kind Quick Start

minikube

Подібно до kind, minikube — це інструмент, який дозволяє запускати Kubernetes локально. minikube запускає локальний кластер Kubernetes «все в одному» або багатовузловий кластер на вашому персональному компʼютері (зокрема на ПК з Windows, macOS і Linux), щоб ви могли випробувати Kubernetes або використовувати його для щоденної розробки.

Якщо ваша мета — встановити інструмент, скористайтеся офіційним посібником Get Started!.

Переглянути посібник minikube Get Started!

Коли minikube запрацює, ви зможете використовувати його для запуску застосунку-прикладу.

kubeadm

Ви можете використовувати інструмент kubeadm для створення кластерів Kubernetes і керування ними. Він виконує дії, потрібні для зручного запуску мінімально життєздатного захищеного кластера.

На сторінці Встановлення kubeadm показано, як встановити kubeadm. Після встановлення ви можете використовувати його для створення кластера.

Переглянути посібник зі встановлення kubeadm

1.1 - Встановлення Minikube

Ця сторінка описує, як встановити Minikube - інструмент, який дозволяє запустити Kubernetes кластер з однієї ноди у віртуальній машині на вашому персональному комп'ютері.

Перш ніж ви розпочнете

Для перевірки, чи підтримується віртуалізація на Linux, запустіть наступну команду і впевніться що її вивід не пустий:

grep -E --color 'vmx|svm' /proc/cpuinfo

Для перевірки, чи підтримується віртуалізація на macOS, запустіть наступну команду в терміналі.

sysctl -a | grep -E --color 'machdep.cpu.features|VMX'

Якщо ви бачите VMX у виводі (має бути кольоровий), то VT-x опція включена на вашому хості.

Для перевірки, чи підтримується віртуалізація на Windows 8 та версіях вище, запустіть наступну команду в терміналі вашого або через command prompt.

systeminfo

Якщо ви бачите наступне, віртуалізація підтримується на Windows.

Hyper-V Requirements:     VM Monitor Mode Extensions: Yes
                          Virtualization Enabled In Firmware: Yes
                          Second Level Address Translation: Yes
                          Data Execution Prevention Available: Yes

Якщо ви бачите наступнний вивід, на вашій системі вже встановлен гіпервізор і ви можете пропустити наступний крок.

Hyper-V Requirements:     A hypervisor has been detected. Features required for Hyper-V will not be displayed.

Встановлення Minikube

Встановлення kubectl

Впевніться що kubectl встановлений. Ви можете встановити kubectl згідно інструкції Встановлення та налаштування kubectl.

Встановлення Hypervisor

Якщо у вас немає встановленого гіпервізора, то встановіть один з наступних:

• KVM, який також використовує QEMU

• VirtualBox

Minikube також пітримує опцію --driver=none яка дозволяє запускати компоненти Kubernetes на хост системі, ні в віртуальній машині. Використання цього драйвера вимагає Docker та Linux оточення але не гіпервізор.

Якщо ви використувуєте none драйвер у Debian або похідних дістрибутивах, використовуйте .deb пакети для Docker замість встановлення snap пакетів, які не працюють з Minikube. Ви можете скачати .deb пакети звідси Docker.

Увага:

none VM драйвер може привести до проблем з безпекою та втрати даних. Перед тим, як використовувати --driver=none, ознайомтесь з цієй документацієй для отримання додаткової інформації.

Minikube також підтримує vm-driver=podman схожий на Docker драйвер. Podman запущений як суперюзер (root user) це найкрайщий шлях забезпечити повний доступ ваших контейнерів до будь-якої функції, наявної у вашій системі.

Увага:

podman драйвер вимагає запущені контейнери з під root користувача оскільки звичайні облікові записи користувачів не мають повного доступу до всіх функцій операційної системи, які, можливо, потребуватимуть їх роботи.

Встановлення Minikube як Linux пакет

Доступні experimental пакети для Minikube; ви можете знайти Linux (AMD64) пакети для Minikube's releases на сторінці GitHub.

Використовувайте ваш Linux інсталер пакетів для того, шоб поставити відповідний пакет.

Встановлення Minikube за допомогою прямого завантаження

Якщо ви не можете встановити Minikube за допомогою пакета, ви можете скачати автономний бінарний файл, та використати його.

curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64 \
  && chmod +x minikube

Ось простий спосіб додати виконуваний файл Minikube до вашого шляху:

sudo mkdir -p /usr/local/bin/
sudo install minikube /usr/local/bin/

Встановлення Minikube використовуючи Homebrew

Як альтернативний варіант, ви можете установити Minikube використовуючи Linux Homebrew:

brew install minikube

Встановлення kubectl

Впевніться шо kubectl встановлен. Ви можете встановити kubectl згідно інструкції Установка та налаштування kubectl.

Встановлення Hypervisor

Якщо у вас немає встановленого гіпервізора, то встановіть один з наступних:

• HyperKit

• VirtualBox

• VMware Fusion

Встановлення Minikube

Найпростіший спосіб встановити Minikube на macOS це використати Homebrew:

brew install minikube

Ви також можете встановити Minikube за допомогою автономного бінарного файла:

curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-darwin-amd64 \
  && chmod +x minikube

Ось простий спосіб додати виконуваний файл Minikube до вашого шляху:

sudo mv minikube /usr/local/bin

Встановлення kubectl

Впевніться шо kubectl встановлен. Ви можете встановити kubectl згідно інструкції Установка та налаштування kubectl.

Встановлення Hypervisor

Якщо у вас немає встановленого гіпервізора, то встановіть один з наступних:

• Hyper-V

• VirtualBox

Примітка:

Hyper-V може бути запущен на трьох версіях Windows 10: Windows 10 Enterprise, Windows 10 Professional, and Windows 10 Education.

Встановлення Minikube за допомогою Chocolatey

Найпростіший спосіб встановити Minikube на Windows за допомогою Chocolatey (run as an administrator):

choco install minikube

Коли Minikube закінчив установку, закрийте поточну CLI сесію та перезавантажтесь. Minikube має бути додан до вашого шляху автоматично.

Встановлення Minikube за допомогою програми встановлення

Для встановлення Minikube вручну на Windows за допомогою Windows Installer, скачайте minikube-installer.exe та виконайте програму.

Встановлення Minikube за допомогою прямого завантаження

Для встановлення Minikube вручну на Windows, скачайте minikube-windows-amd64, перейменуйте в minikube.exe, та додайте до вашего шляху.

Що далі

Підтвердження встановлення

Щоб підтвердити успішну установку як гіпервізора, так і Minikube, ви можете запустити таку команду, щоб запустити локальний кластер Kubernetes:

Примітка:

Щоб встановити --driver за допомогою minikube start, введіть ім'я гіпервізора, який ви встановили, малими літерами, де <driver_name> згадано нижче. Повний список значень --driver доступний у вказуванні документації на драйвер VM.
minikube start --driver=<driver_name>

Після того як minikube start закінчився, запустіть команду нижче, щоб перевірити стан кластера:

minikube status

Якщо ваш кластер працює, вивід із "minikube status" має бути аналогічним:

host: Running
kubelet: Running
apiserver: Running
kubeconfig: Configured

Після того, як ви підтвердили, чи Minikube працює з обраним вами гіпервізором, ви можете продовжувати використовувати Minikube або ви можете зупинити кластер. Щоб зупинити кластер, запустіть:

minikube stop

Очистити локальний стан

Якщо ви раніше встановили Minikube та запустили:

minikube start

але minikube start повертає помилку:

machine does not exist

тоді вам треба очистити локальний стан minikube:

minikube delete

2 - Налагодження 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 - Конвеєр метрик ресурсів

Для 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 - Налагодження вузлів 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" "-"

Що далі

5 - Аудит

Аудит 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 # This is required.
kind: Policy
# Don't generate audit events for all requests in RequestReceived stage.
omitStages:
  - "RequestReceived"
rules:
  # Log pod changes at RequestResponse level
  - level: RequestResponse
    resources:
    - group: ""
      # Resource "pods" doesn't match requests to any subresource of pods,
      # which is consistent with the RBAC policy.
      resources: ["pods"]
  # Log "pods/log", "pods/status" at Metadata level
  - level: Metadata
    resources:
    - group: ""
      resources: ["pods/log", "pods/status"]

  # Don't log requests to a configmap called "controller-leader"
  - level: None
    resources:
    - group: ""
      resources: ["configmaps"]
      resourceNames: ["controller-leader"]

  # Don't log watch requests by the "system:kube-proxy" on endpoints or services
  - level: None
    users: ["system:kube-proxy"]
    verbs: ["watch"]
    resources:
    - group: "" # core API group
      resources: ["endpoints", "services"]

  # Don't log authenticated requests to certain non-resource URL paths.
  - level: None
    userGroups: ["system:authenticated"]
    nonResourceURLs:
    - "/api*" # Wildcard matching.
    - "/version"

  # Log the request body of configmap changes in kube-system.
  - level: Request
    resources:
    - group: "" # core API group
      resources: ["configmaps"]
    # This rule only applies to resources in the "kube-system" namespace.
    # The empty string "" can be used to select non-namespaced resources.
    namespaces: ["kube-system"]

  # Log configmap and secret changes in all other namespaces at the Metadata level.
  - level: Metadata
    resources:
    - group: "" # core API group
      resources: ["secrets", "configmaps"]

  # Log all other resources in core and extensions at the Request level.
  - level: Request
    resources:
    - group: "" # core API group
    - group: "extensions" # Version of group should NOT be included.

  # A catch-all rule to log all other requests at the Metadata level.
  - level: Metadata
    # Long-running requests like watches that fall under this rule will not
    # generate an audit event in 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.

Що далі

6 - Усунення несправностей керування топологією

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.

7 - Керування демонами кластера

Виконуйте поширені завдання керування DaemonSet, наприклад поетапне оновлення.

7.1 - Створення базового DaemonSet

На цій сторінці показано, як створити базовий DaemonSet, який запускає Pod на кожному вузлі кластера Kubernetes. Вона охоплює простий сценарій монтування файлу з хоста, логування його вмісту за допомогою init-контейнера і використання контейнера pause.

Перш ніж ви розпочнете

Вам треба мати кластер Kubernetes, а також інструмент командного рядка kubectl має бути налаштований для роботи з вашим кластером. Рекомендується виконувати ці настанови у кластері, що має щонайменше два вузли, які не виконують роль вузлів управління. Якщо у вас немає кластера, ви можете створити його, за допомогою minikube або використовувати одну з цих пісочниць:

Кластер Kubernetes щонайменше з двома вузлами (один вузол панелі управління та один робочий вузол), щоб продемонструвати поведінку DaemonSets.

Визначення DaemonSet

У цьому завданні створюється базовий DaemonSet, який гарантує, що копія Podʼа планується на кожен вузол. Pod використовуватиме init-контейнер для читання й логування вмісту /etc/machine-id з хоста, а основним контейнером буде контейнер pause, який підтримує роботу Podʼа.

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: example-daemonset
spec:
  selector:
    matchLabels:
      app.kubernetes.io/name: example
  template:
    metadata:
      labels:
        app.kubernetes.io/name: example
    spec:
      containers:
      - name: pause
        image: registry.k8s.io/pause
      initContainers:
      - name: log-machine-id
        image: busybox:1.37
        command: ['sh', '-c', 'cat /etc/machine-id > /var/log/machine-id.log']
        volumeMounts:
        - name: machine-id
          mountPath: /etc/machine-id
          readOnly: true
        - name: log-dir
          mountPath: /var/log
      volumes:
      - name: machine-id
        hostPath:
          path: /etc/machine-id
          type: File
      - name: log-dir
        hostPath:
          path: /var/log
  1. Створіть DaemonSet на основі маніфесту (YAML):

    kubectl apply -f https://k8s.io/examples/application/basic-daemonset.yaml
    
  2. Після застосування ви можете перевірити, що DaemonSet запускає Pod на кожному вузлі кластера:

    kubectl get pods -o wide
    

    Вивід міститиме по одному Podʼу на вузол, наприклад:

    NAME                                READY   STATUS    RESTARTS   AGE    IP       NODE
    example-daemonset-xxxxx             1/1     Running   0          5m     x.x.x.x  node-1
    example-daemonset-yyyyy             1/1     Running   0          5m     x.x.x.x  node-2
    
  3. Ви можете переглянути вміст залогованого файлу /etc/machine-id, перевіривши теку логів, змонтовану з хоста:

    kubectl exec <pod-name> -- cat /var/log/machine-id.log
    

    Де <pod-name> — назва одного з ваших Podʼів.

Очищення

Щоб видалити DaemonSet, виконайте цю команду:

kubectl delete --cascade=foreground --ignore-not-found --now daemonsets/example-daemonset

Цей простий приклад DaemonSet знайомить із ключовими компонентами, такими як init-контейнери й томи hostPath, які можна розширювати для складніших сценаріїв. Докладніше дивіться DaemonSet.

Що далі

7.2 - Виконання поетапного оновлення DaemonSet

На цій сторінці показано, як виконати поетапне оновлення DaemonSet.

Перш ніж ви розпочнете

Вам треба мати кластер Kubernetes, а також інструмент командного рядка kubectl має бути налаштований для роботи з вашим кластером. Рекомендується виконувати ці настанови у кластері, що має щонайменше два вузли, які не виконують роль вузлів управління. Якщо у вас немає кластера, ви можете створити його, за допомогою minikube або використовувати одну з цих пісочниць:

Стратегія оновлення DaemonSet

DaemonSet має два типи стратегій оновлення:

  • OnDelete: Зі стратегією оновлення OnDelete після оновлення шаблону DaemonSet нові Podʼи DaemonSet створюватимуться лише тоді, коли ви вручну видалите старі Podʼи DaemonSet. Така сама поведінка була в DaemonSet у Kubernetes версії 1.5 або раніше.
  • RollingUpdate: Це стандартна стратегія оновлення. Зі стратегією оновлення RollingUpdate після оновлення шаблону DaemonSet старі Podʼи DaemonSet буде завершено, а нові Podʼи DaemonSet буде автоматично створено контрольованим чином. Протягом усього процесу оновлення на кожному вузлі працюватиме щонайбільше один Pod DaemonSet.

Виконання поетапного оновлення

Щоб увімкнути поетапне оновлення DaemonSet, потрібно встановити .spec.updateStrategy.type у RollingUpdate.

Ви також можете встановити .spec.updateStrategy.rollingUpdate.maxUnavailable (стандартно 1), .spec.minReadySeconds (стандартно 0) та .spec.updateStrategy.rollingUpdate.maxSurge (стандартно 0).

Створення DaemonSet зі стратегією оновлення RollingUpdate

Цей файл YAML визначає DaemonSet зі стратегією оновлення RollingUpdate:

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: fluentd-elasticsearch
  namespace: kube-system
  labels:
    k8s-app: fluentd-logging
spec:
  selector:
    matchLabels:
      name: fluentd-elasticsearch
  updateStrategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1
  template:
    metadata:
      labels:
        name: fluentd-elasticsearch
    spec:
      tolerations:
      # these tolerations are to have the daemonset runnable on control plane nodes
      # remove them if your control plane nodes should not run pods
      - key: node-role.kubernetes.io/control-plane
        operator: Exists
        effect: NoSchedule
      - key: node-role.kubernetes.io/master
        operator: Exists
        effect: NoSchedule
      containers:
      - name: fluentd-elasticsearch
        image: quay.io/fluentd_elasticsearch/fluentd:v5.0.1
        volumeMounts:
        - name: varlog
          mountPath: /var/log
        - name: varlibdockercontainers
          mountPath: /var/lib/docker/containers
          readOnly: true
      terminationGracePeriodSeconds: 30
      volumes:
      - name: varlog
        hostPath:
          path: /var/log
      - name: varlibdockercontainers
        hostPath:
          path: /var/lib/docker/containers

Перевіривши стратегію оновлення в маніфесті DaemonSet, створіть DaemonSet:

kubectl create -f https://k8s.io/examples/controllers/fluentd-daemonset.yaml

Або скористайтесь командою kubectl apply, щоб створити той самий DaemonSet, якщо ви плануєте оновлювати DaemonSet за допомогою kubectl apply.

kubectl apply -f https://k8s.io/examples/controllers/fluentd-daemonset.yaml

Перевірка стратегії оновлення RollingUpdate у DaemonSet

Перевірте стратегію оновлення вашого DaemonSet і переконайтеся, що вона встановлена в RollingUpdate:

kubectl get ds/fluentd-elasticsearch -o go-template='{{.spec.updateStrategy.type}}{{"\n"}}' -n kube-system

Якщо ви ще не створили DaemonSet у системі, натомість перевірте маніфест DaemonSet такою командою:

kubectl apply -f https://k8s.io/examples/controllers/fluentd-daemonset.yaml --dry-run=client -o go-template='{{.spec.updateStrategy.type}}{{"\n"}}'

Вивід обох команд має бути таким:

RollingUpdate

Якщо вивід не RollingUpdate, поверніться й відповідно змініть обʼєкт DaemonSet або маніфест.

Оновлення шаблону DaemonSet

Будь-які оновлення .spec.template у DaemonSet зі стратегією RollingUpdate запускають поетапне оновлення. Оновімо DaemonSet, застосувавши новий файл YAML. Це можна зробити кількома різними командами kubectl.

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: fluentd-elasticsearch
  namespace: kube-system
  labels:
    k8s-app: fluentd-logging
spec:
  selector:
    matchLabels:
      name: fluentd-elasticsearch
  updateStrategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1
  template:
    metadata:
      labels:
        name: fluentd-elasticsearch
    spec:
      tolerations:
      # these tolerations are to have the daemonset runnable on control plane nodes
      # remove them if your control plane nodes should not run pods
      - key: node-role.kubernetes.io/control-plane
        operator: Exists
        effect: NoSchedule
      - key: node-role.kubernetes.io/master
        operator: Exists
        effect: NoSchedule
      containers:
      - name: fluentd-elasticsearch
        image: quay.io/fluentd_elasticsearch/fluentd:v5.0.1
        resources:
          limits:
            memory: 200Mi
          requests:
            cpu: 100m
            memory: 200Mi
        volumeMounts:
        - name: varlog
          mountPath: /var/log
        - name: varlibdockercontainers
          mountPath: /var/lib/docker/containers
          readOnly: true
      terminationGracePeriodSeconds: 30
      volumes:
      - name: varlog
        hostPath:
          path: /var/log
      - name: varlibdockercontainers
        hostPath:
          path: /var/lib/docker/containers

Декларативні команди

Якщо ви оновлюєте DaemonSets за допомогою файлів конфігурації, використовуйте kubectl apply:

kubectl apply -f https://k8s.io/examples/controllers/fluentd-daemonset-update.yaml

Імперативні команди

Якщо ви оновлюєте DaemonSets за допомогою імперативних команд, використовуйте kubectl edit :

kubectl edit ds/fluentd-elasticsearch -n kube-system
Оновлення лише образу контейнера

Якщо вам потрібно оновити лише образ контейнера у шаблоні DaemonSet, тобто .spec.template.spec.containers[*].image, використовуйте kubectl set image:

kubectl set image ds/fluentd-elasticsearch fluentd-elasticsearch=quay.io/fluentd_elasticsearch/fluentd:v2.6.0 -n kube-system

Спостереження за станом поетапного оновлення

Нарешті, спостерігайте за станом розгортання останнього поетапного оновлення DaemonSet:

kubectl rollout status ds/fluentd-elasticsearch -n kube-system

Коли розгортання завершиться, вивід буде подібний до такого:

daemonset "fluentd-elasticsearch" successfully rolled out

Усунення несправностей

Поетапне оновлення DaemonSet застрягло

Іноді поетапне оновлення DaemonSet може застрягнути. Ось деякі можливі причини:

На деяких вузлах вичерпуються ресурси

Розгортання застрягло, оскільки нові Podʼи DaemonSet не можна запланувати щонайменше на один вузол. Таке можливо, коли на вузлі вичерпуються ресурси.

Коли це трапляється, знайдіть вузли, на яких не заплановано Podʼи DaemonSet, порівнявши вивід kubectl get nodes з виводом:

kubectl get pods -l name=fluentd-elasticsearch -o wide -n kube-system

Знайшовши ці вузли, видаліть із них деякі Podʼи, що не належать до DaemonSet, щоб звільнити місце для нових Podʼів DaemonSet.

Примітка:

Це спричинить порушення роботи сервісу, якщо видалені Podʼи не контролюються жодним контролером або не мають реплік. Це також не враховує PodDisruptionBudget.

Невдале розгортання

Якщо останнє оновлення шаблону DaemonSet невдале, наприклад контейнер постійно аварійно завершується (crash looping) або образу контейнера не існує (часто через одруківку), розгортання DaemonSet не просуватиметься.

Щоб виправити це, ще раз оновіть шаблон DaemonSet. Нове розгортання не блокуватиметься попередніми несправними розгортаннями.

Невідповідність годинників

Якщо в DaemonSet задано .spec.minReadySeconds, невідповідність годинників між панеллю управління та вузлами не дасть DaemonSet правильно визначати перебіг розгортання.

Очищення

Видаліть DaemonSet із простору імен:

kubectl delete ds fluentd-elasticsearch -n kube-system

Що далі

7.3 - Виконання відкочування DaemonSet

На цій сторінці показано, як виконати відкочування DaemonSet.

Перш ніж ви розпочнете

Вам треба мати кластер Kubernetes, а також інструмент командного рядка kubectl має бути налаштований для роботи з вашим кластером. Рекомендується виконувати ці настанови у кластері, що має щонайменше два вузли, які не виконують роль вузлів управління. Якщо у вас немає кластера, ви можете створити його, за допомогою minikube або використовувати одну з цих пісочниць:

Версія вашого Kubernetes сервера має бути не старішою ніж 1.7.

Для перевірки версії введіть kubectl version.

Ви вже маєте знати, як виконати поетапне оновлення DaemonSet.

Виконання відкочування DaemonSet

Крок 1: Знайдіть ревізію DaemonSet, до якої потрібно відкотитися

Цей крок можна пропустити, якщо ви хочете лише відкотитися до останньої ревізії.

Виведіть усі ревізії DaemonSet:

kubectl rollout history daemonset <daemonset-name>

Це поверне список ревізій DaemonSet:

daemonsets "<daemonset-name>"
REVISION        CHANGE-CAUSE
1               ...
2               ...
...
  • Причина зміни копіюється з анотації DaemonSet kubernetes.io/change-cause до його ревізій під час їх створення. Ви можете вказати --record=true у kubectl, щоб записати виконану команду в анотацію причини зміни.

Щоб переглянути подробиці конкретної ревізії:

kubectl rollout history daemonset <daemonset-name> --revision=1

Це поверне подробиці цієї ревізії:

daemonsets "<daemonset-name>" with revision #1
Pod Template:
Labels:       foo=bar
Containers:
app:
 Image:        ...
 Port:         ...
 Environment:  ...
 Mounts:       ...
Volumes:      ...

Крок 2: Відкотіться до конкретної ревізії

# Вкажіть номер ревізії, отриманий на кроці 1, у --to-revision
kubectl rollout undo daemonset <daemonset-name> --to-revision=<revision>

Якщо команда виконається успішно, вона поверне:

daemonset "<daemonset-name>" rolled back

Примітка:

Якщо прапорець --to-revision не вказано, kubectl обирає найновішу ревізію.

Крок 3: Спостерігайте за перебігом відкочування DaemonSet

kubectl rollout undo daemonset наказує серверу почати відкочування DaemonSet. Фактичне відкочування виконується асинхронно всередині панелі управління кластера.

Щоб спостерігати за перебігом відкочування:

kubectl rollout status ds/<daemonset-name>

Коли відкочування завершиться, вивід буде подібний до такого:

daemonset "<daemonset-name>" successfully rolled out

Розуміння ревізій DaemonSet

На попередньому кроці kubectl rollout history ви отримали список ревізій DaemonSet. Кожна ревізія зберігається в ресурсі під назвою ControllerRevision.

Щоб побачити, що зберігається в кожній ревізії, знайдіть необроблені ресурси ревізій DaemonSet:

kubectl get controllerrevision -l <daemonset-selector-key>=<daemonset-selector-value>

Це поверне список ControllerRevisions:

NAME                               CONTROLLER                     REVISION   AGE
<daemonset-name>-<revision-hash>   DaemonSet/<daemonset-name>     1          1h
<daemonset-name>-<revision-hash>   DaemonSet/<daemonset-name>     2          1h

Кожен ControllerRevision зберігає анотації та шаблон ревізії DaemonSet.

kubectl rollout undo бере конкретний ControllerRevision і замінює шаблон DaemonSet шаблоном, збереженим у ControllerRevision. kubectl rollout undo рівнозначний оновленню шаблону DaemonSet до попередньої ревізії іншими командами, такими як kubectl edit або kubectl apply.

Примітка:

Ревізії DaemonSet рухаються лише вперед. Тобто після завершення відкочування номер ревізії (поле .revision) ControllerRevision, до якого відбулося відкочування, збільшується. Наприклад, якщо в системі є ревізії 1 і 2 і ви відкочуєтеся з ревізії 2 до ревізії 1, ControllerRevision із .revision: 1 стане .revision: 3.

Усунення несправностей

7.4 - Запуск Podʼів лише на деяких вузлах

На цій сторінці показано, як запускати Podʼи лише на деяких вузлах у складі DaemonSet

Перш ніж ви розпочнете

Вам треба мати кластер Kubernetes, а також інструмент командного рядка kubectl має бути налаштований для роботи з вашим кластером. Рекомендується виконувати ці настанови у кластері, що має щонайменше два вузли, які не виконують роль вузлів управління. Якщо у вас немає кластера, ви можете створити його, за допомогою minikube або використовувати одну з цих пісочниць:

Запуск Podʼів лише на деяких вузлах

Уявімо, що ви хочете запустити DaemonSet, але ці Podʼи демонів потрібно запускати лише на вузлах із локальним твердотільним сховищем (SSD). Наприклад, Pod може надавати вузлу сервіс кешування, а кеш корисний лише тоді, коли доступне локальне сховище з низькою затримкою.

Крок 1: Додайте мітки до вузлів

Додайте мітку ssd=true до вузлів, які мають SSD.

kubectl label nodes example-node-1 example-node-2 ssd=true

Крок 2: Створіть маніфест

Створімо DaemonSet, який розгортатиме Podʼи демонів лише на вузлах з міткою SSD.

Далі використайте nodeSelector, щоб DaemonSet запускав Podʼи лише на вузлах, де мітка ssd має значення "true".

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: ssd-driver
  labels:
    app: nginx
spec:
  selector:
    matchLabels:
      app: ssd-driver-pod
  template:
    metadata:
      labels:
        app: ssd-driver-pod
    spec:
      nodeSelector:
        ssd: "true"
      containers:
        - name: example-container
          image: example-image

Крок 3: Створіть DaemonSet

Створіть DaemonSet з маніфесту, використовуючи kubectl create або kubectl apply.

Додамо мітку ssd=true ще одному вузлу.

kubectl label nodes example-node-3 ssd=true

Додавання мітки вузлу автоматично спонукає панель управління (а саме контролер DaemonSet) запустити новий Pod демона на цьому вузлі.

kubectl get pods -o wide

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

NAME                              READY     STATUS    RESTARTS   AGE    IP      NODE
<daemonset-name><some-hash-01>    1/1       Running   0          13s    .....   example-node-1
<daemonset-name><some-hash-02>    1/1       Running   0          13s    .....   example-node-2
<daemonset-name><some-hash-03>    1/1       Running   0          5s     .....   example-node-3

8 - Розширення kubectl за допомогою втулків

Розширюйте kubectl, створюючи та встановлюючи втулки kubectl.

Цей посібник показує, як встановлювати й створювати розширення для kubectl. Розглядаючи основні команди kubectl як базові будівельні блоки для взаємодії з кластером Kubernetes, адміністратор кластера може вважати втулки засобом використання цих блоків для створення складнішої поведінки. Втулки розширюють kubectl новими підкомандами, додаючи нові й власні можливості, яких немає в основному дистрибутиві kubectl.

Перш ніж ви розпочнете

Вам потрібен встановлений робочий бінарний файл kubectl.

Встановлення втулків для kubectl

Втулок — це окремий виконуваний файл, назва якого починається з kubectl-. Щоб установити втулок, перемістіть його виконуваний файл у будь-яке місце у вашому PATH.

Ви також можете шукати й встановлювати втулки kubectl із відкритим кодом за допомогою Krew. Krew — це менеджер втулків, який підтримує спільнота Kubernetes SIG CLI.

Увага:

Втулки kubectl, доступні через індекс втулків Krew, не проходять перевірки безпеки. Сторонні втулки ви встановлюєте й запускаєте на власний ризик, оскільки це довільні програми, що виконуються на вашому компʼютері.

Пошук втулків

kubectl надає команду kubectl plugin list, яка шукає у вашому PATH дійсні виконувані файли втулків. Виконання цієї команди спричиняє обхід усіх файлів у вашому PATH. Усі файли, які є виконуваними й починаються з kubectl-, зʼявляться у виводі цієї команди у тому порядку, в якому вони розташовані у вашому PATH. Для всіх файлів, що починаються з kubectl- і не є виконуваними, буде показано попередження. Також буде показано попередження для всіх дійсних файлів втулків, назви яких перекривають одна одну.

Ви можете використовувати Krew, щоб шукати й встановлювати втулки kubectl з індексу втулків, який підтримує спільнота.

Створення втулків

kubectl дозволяє втулкам додавати власні команди створення вигляду kubectl create something: для цього в PATH має бути виконуваний файл kubectl-create-something.

Обмеження

Наразі неможливо створити втулки, які перезаписують наявні команди kubectl або розширюють інші команди, крім create. Наприклад, якщо створити втулок kubectl-version, він ніколи не виконуватиметься, оскільки наявна команда kubectl version завжди матиме пріоритет. Через це обмеження також не можна використовувати втулки для додавання нових підкоманд до наявних команд kubectl. Наприклад, якщо додати підкоманду kubectl attach vm, назвавши втулок kubectl-attach-vm, цей втулок буде проігноровано.

kubectl plugin list показує попередження для всіх дійсних втулків, які намагаються це зробити.

Написання втулків для kubectl

Ви можете написати втулок будь-якою мовою програмування або скриптом, що дозволяє створювати команди командного рядка.

Втулки не потребують встановлення чи попереднього завантаження. Виконувані файли втулків успадковують середовище від бінарного файлу kubectl. Втулок визначає шлях команди, який він реалізує, за своєю назвою. Наприклад, втулок із назвою kubectl-foo надає команду kubectl foo. Виконуваний файл втулка потрібно встановити десь у вашому PATH.

Приклад втулка

#!/bin/bash

# необовʼязкова обробка аргументів
if [[ "$1" == "version" ]]
then
    echo "1.0.0"
    exit 0
fi

# необовʼязкова обробка аргументів
if [[ "$1" == "config" ]]
then
    echo "$KUBECONFIG"
    exit 0
fi

echo "I am a plugin named kubectl-foo"

Використання втулка

Щоб використовувати втулок, зробіть його виконуваним:

sudo chmod +x ./kubectl-foo

і помістіть його в будь-яке місце у вашому PATH:

sudo mv ./kubectl-foo /usr/local/bin

Тепер ви можете викликати втулок як команду kubectl:

kubectl foo
I am a plugin named kubectl-foo

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

kubectl foo version
1.0.0

Усі змінні середовища також передаються виконуваному файлу без змін:

export KUBECONFIG=~/.kube/config
kubectl foo config
/home/<user>/.kube/config
KUBECONFIG=/etc/kube/config kubectl foo config
/etc/kube/config

Крім того, першим аргументом, який передається втулку, завжди буде повний шлях до місця, де його викликано ($0 дорівнюватиме /usr/local/bin/kubectl-foo у наведеному вище прикладі).

Іменування втулків

Як видно з наведеного вище прикладу, втулок визначає шлях команди, яку він реалізує, за назвою свого файлу. Усі підкоманди в шляху команди, на яку націлений втулок, розділені дефісом (-). Наприклад, втулок, який має викликатися щоразу, коли користувач виконує команду kubectl foo bar baz, матиме назву файлу kubectl-foo-bar-baz.

Обробка прапорців та аргументів

Примітка:

Механізм втулків не створює жодних власних, специфічних для втулка значень або змінних середовища для процесу втулка.

Старіший механізм втулків kubectl надавав змінні середовища, такі як KUBECTL_PLUGINS_CURRENT_NAMESPACE; тепер такого немає.

Втулки kubectl мають самостійно розбирати та перевіряти всі передані їм аргументи. Докладніше про бібліотеку Go для авторів втулків дивіться в розділі використання пакунка command line runtime.

Нижче наведено кілька додаткових випадків, коли користувачі викликають ваш втулок із додатковими прапорцями та аргументами. Вони ґрунтуються на втулку kubectl-foo-bar-baz із наведеного вище сценарію.

Якщо ви виконаєте kubectl foo bar baz arg1 --flag=value arg2, механізм втулків kubectl спочатку спробує знайти втулок із найдовшою можливою назвою, у цьому випадку kubectl-foo-bar-baz-arg1. Не знайшовши такого втулка, kubectl вважатиме останнє значення, відокремлене дефісом, аргументом (тут arg1) і спробує знайти наступну найдовшу можливу назву, kubectl-foo-bar-baz. Знайшовши втулок із такою назвою, kubectl викличе його, передаючи всі аргументи й прапорці після назви втулка як аргументи процесу втулка.

Приклад:

# створимо втулок
echo -e '#!/bin/bash\n\necho "My first command-line argument was $1"' > kubectl-foo-bar-baz
sudo chmod +x ./kubectl-foo-bar-baz

# встановимо ваш втулок, перемістивши його у теку з $PATH
sudo mv ./kubectl-foo-bar-baz /usr/local/bin

# перевіримо, що kubectl розпізнав ваш втулок
kubectl plugin list
The following kubectl-compatible plugins are available:

/usr/local/bin/kubectl-foo-bar-baz
# перевірте, що виклик вашого втулка через команду "kubectl" працює
# навіть тоді, коли користувач передає додаткові аргументи та прапорці
# до виконуваного файлу вашого втулка.
kubectl foo bar baz arg1 --meaningless-flag=true
My first command-line argument was arg1

Як бачите, ваш втулок було знайдено за командою kubectl, вказаною користувачем, а всі додаткові аргументи та прапорці після цього передано виконуваному файлу втулка без змін.

Назви з дефісами та підкреслюваннями

Хоча механізм втулків kubectl використовує дефіс (-) у назвах файлів втулків для розділення послідовності підкоманд, які обробляє втулок, усе ж можна створити команду втулка з дефісами у виклику з командного рядка, використовуючи підкреслення (_) у назві файлу.

Приклад:

# створимо втулок, що містить підкреслення в назві файлу
echo -e '#!/bin/bash\n\necho "I am a plugin with a dash in my name"' > ./kubectl-foo_bar
sudo chmod +x ./kubectl-foo_bar

# перемістимо втулок у теку з $PATH
sudo mv ./kubectl-foo_bar /usr/local/bin

# тепер ви можете викликати свій втулок через kubectl:
kubectl foo-bar
I am a plugin with a dash in my name

Зверніть увагу, що підкреслення в назві файлу втулка не заважає використовувати команди на кшталт kubectl foo_bar. Команду з наведеного вище прикладу можна викликати і з дефісом (-), і з підкресленням (_):

# Ви можете викликати вашу власну команду з дефісом
kubectl foo-bar
I am a plugin with a dash in my name
# Ви також можете викликати свою власну команду з підкресленнями
kubectl foo_bar
I am a plugin with a dash in my name

Конфлікти назв і перекриття

У вашому PATH може бути кілька втулків з однаковою назвою файлу в різних розташуваннях. Наприклад, якщо PATH має значення PATH=/usr/local/bin/plugins:/usr/local/bin/moreplugins, копія втулка kubectl-foo може існувати в /usr/local/bin/plugins і /usr/local/bin/moreplugins, і тоді вивід команди kubectl plugin list буде таким:

PATH=/usr/local/bin/plugins:/usr/local/bin/moreplugins kubectl plugin list
The following kubectl-compatible plugins are available:

/usr/local/bin/plugins/kubectl-foo
/usr/local/bin/moreplugins/kubectl-foo
  - warning: /usr/local/bin/moreplugins/kubectl-foo is overshadowed by a similarly named plugin: /usr/local/bin/plugins/kubectl-foo

error: one plugin warning was found

У цьому сценарії попередження під /usr/local/bin/moreplugins/kubectl-foo повідомляє, що цей втулок ніколи не буде виконано. Натомість механізм втулків kubectl завжди спершу знайде й виконає файл, який першим трапляється у вашому PATH, тобто /usr/local/bin/plugins/kubectl-foo.

Щоб розвʼязати цю проблему, переконайтеся, що розташування втулка, який ви хочете використовувати з kubectl, завжди стоїть першим у вашому PATH. Наприклад, якщо ви хочете завжди використовувати /usr/local/bin/moreplugins/kubectl-foo під час виклику команди kubectl foo, змініть значення PATH на /usr/local/bin/moreplugins:/usr/local/bin/plugins.

Виклик за найдовшою назвою виконуваного файлу

Існує ще один вид перекриття, який може виникнути з назвами файлів втулків. Якщо в PATH користувача є два втулки, kubectl-foo-bar і kubectl-foo-bar-baz, механізм втулків kubectl завжди вибиратиме найдовшу можливу назву втулка для заданої команди користувача. Наведені нижче приклади це пояснюють:

# для заданої команди kubectl завжди вибиратиметься втулок із найдовшою можливою назвою файлу
kubectl foo bar baz
Plugin kubectl-foo-bar-baz is executed
kubectl foo bar
Plugin kubectl-foo-bar is executed
kubectl foo bar baz buz
Plugin kubectl-foo-bar-baz is executed, with "buz" as its first argument
kubectl foo bar buz
Plugin kubectl-foo-bar is executed, with "buz" as its first argument

Таке проєктне рішення гарантує, що підкоманди втулка можна за потреби реалізувати в кількох файлах і вкладати їх під «батьківську» команду втулка:

ls ./plugin_command_tree
kubectl-parent
kubectl-parent-subcommand
kubectl-parent-subcommand-subsubcommand

Перевірка на наявність попереджень втулків

Ви можете скористатися згаданою вище командою kubectl plugin list, щоб переконатися, що kubectl бачить ваш втулок, і перевірити, що немає попереджень, які заважають викликати його як команду kubectl.

kubectl plugin list
The following kubectl-compatible plugins are available:

test/fixtures/pkg/kubectl/plugins/kubectl-foo
/usr/local/bin/kubectl-foo
  - warning: /usr/local/bin/kubectl-foo is overshadowed by a similarly named plugin: test/fixtures/pkg/kubectl/plugins/kubectl-foo
plugins/kubectl-invalid
  - warning: plugins/kubectl-invalid identified as a kubectl plugin, but it is not executable

error: 2 plugin warnings were found

Використання пакунка command line runtime

Якщо ви пишете втулок для kubectl мовою Go, ви можете скористатися допоміжними бібліотеками cli-runtime.

Ці бібліотеки надають допоміжні засоби для розбору чи оновлення файлу kubeconfig користувача, для виконання запитів у стилі REST до API-сервера або для привʼязування прапорців, повʼязаних із конфігурацією та виводом.

Приклад використання інструментів із репозиторію CLI Runtime дивіться в Sample CLI Plugin.

Розповсюдження втулків для kubectl

Якщо ви розробили втулок для інших користувачів, варто подумати, як ви його пакуватимете, розповсюджуватимете й доставлятимете оновлення своїм користувачам.

Krew

Krew пропонує кросплатформний спосіб пакування й розповсюдження ваших втулків. Так ви використовуєте єдиний формат пакування для всіх цільових платформ (Linux, Windows, macOS тощо) і доставляєте оновлення своїм користувачам. Krew також підтримує індекс втулків, щоб інші люди могли знайти ваш втулок і встановити його.

Нативне / платформозалежне керування пакунками

Також ви можете використовувати традиційні менеджери пакунків, такі як apt або dnf у Linux, Chocolatey у Windows і Homebrew у macOS. Підійде будь-який менеджер пакунків, який може розмістити нові виконувані файли десь у PATH користувача. Якщо ви як автор втулка обираєте цей варіант, вам також доведеться оновлювати пакунок розповсюдження вашого втулка kubectl на кількох платформах для кожного випуску.

Вихідний код

Ви можете опублікувати вихідний код, наприклад як репозиторій Git. Якщо ви обираєте цей варіант, той, хто хоче використовувати цей втулок, має отримати код, налаштувати середовище збірки (якщо потрібна компіляція) і розгорнути втулок. Якщо ви також надаєте скомпільовані пакунки або використовуєте Krew, встановлення стане простішим.

Що далі

  • Перегляньте репозиторій Sample CLI Plugin, де є докладний приклад втулка, написаного мовою Go. Якщо виникнуть запитання, звертайтеся до команди SIG CLI.
  • Прочитайте про Krew, менеджер пакунків для втулків kubectl.

9 - Керування HugePages

Налаштування та керування великими сторінками як ресурсом, придатним для планування, у кластері.

This is a stable feature in Kubernetes, and has been since the 1.14 release. You can no longer toggle this feature (the associated feature gate has been removed).

Kubernetes підтримує виділення та використання застосунками в Podʼі заздалегідь виділених великих сторінок (huge pages). На цій сторінці описано, як користувачі можуть використовувати великі сторінки.

Перш ніж ви розпочнете

Вузли Kubernetes мають заздалегідь виділити великі сторінки, щоб вузол міг повідомляти про свою місткість великих сторінок.

Вузол може заздалегідь виділяти великі сторінки кількох розмірів; наприклад, такий рядок у /etc/default/grub виділяє 2*1GiB сторінок розміром 1 GiB і 512*2 MiB сторінок розміром 2 MiB:

GRUB_CMDLINE_LINUX="hugepagesz=1G hugepages=2 hugepagesz=2M hugepages=512"

Вузли автоматично виявлять усі ресурси великих сторінок і повідомлять про них як про ресурси, придатні для планування.

Коли ви переглянете опис вузла, ви маєте побачити щось подібне до наведеного нижче в розділах Capacity та Allocatable:

Capacity:
  cpu:                ...
  ephemeral-storage:  ...
  hugepages-1Gi:      2Gi
  hugepages-2Mi:      1Gi
  memory:             ...
  pods:               ...
Allocatable:
  cpu:                ...
  ephemeral-storage:  ...
  hugepages-1Gi:      2Gi
  hugepages-2Mi:      1Gi
  memory:             ...
  pods:               ...

Примітка:

Для динамічно виділених сторінок (після завантаження системи) kubelet потрібно перезапустити, щоб нові виділення відобразилися.

API

Великі сторінки можна використовувати через вимоги до ресурсів на рівні контейнера з назвою ресурсу hugepages-<size>, де <size> — найкомпактніше двійкове позначення з цілочисельними значеннями, підтримуваними на конкретному вузлі. Наприклад, якщо вузол підтримує розміри сторінок 2048KiB і 1048576KiB, він надаватиме ресурси, придатні для планування, hugepages-2Mi та hugepages-1Gi. На відміну від CPU або памʼяті, великі сторінки не підтримують надмірне виділення (overcommit). Зверніть увагу, що під час запиту ресурсів великих сторінок також потрібно запитувати ресурси памʼяті або CPU.

Pod може використовувати кілька розмірів великих сторінок в одній специфікації Podʼа. У цьому випадку для всіх монтувань томів потрібно використовувати нотацію medium: HugePages-<hugepagesize>.

apiVersion: v1
kind: Pod
metadata:
  name: huge-pages-example
spec:
  containers:
  - name: example
    image: fedora:latest
    command:
    - sleep
    - inf
    volumeMounts:
    - mountPath: /hugepages-2Mi
      name: hugepage-2mi
    - mountPath: /hugepages-1Gi
      name: hugepage-1gi
    resources:
      limits:
        hugepages-2Mi: 100Mi
        hugepages-1Gi: 2Gi
        memory: 100Mi
      requests:
        memory: 100Mi
  volumes:
  - name: hugepage-2mi
    emptyDir:
      medium: HugePages-2Mi
  - name: hugepage-1gi
    emptyDir:
      medium: HugePages-1Gi

Pod може використовувати medium: HugePages, лише якщо він запитує великі сторінки одного розміру.

apiVersion: v1
kind: Pod
metadata:
  name: huge-pages-example
spec:
  containers:
  - name: example
    image: fedora:latest
    command:
    - sleep
    - inf
    volumeMounts:
    - mountPath: /hugepages
      name: hugepage
    resources:
      limits:
        hugepages-2Mi: 100Mi
        memory: 100Mi
      requests:
        memory: 100Mi
  volumes:
  - name: hugepage
    emptyDir:
      medium: HugePages
  • Запити великих сторінок мають дорівнювати обмеженням. Так відбувається стандартно, якщо обмеження вказано, а запити — ні.
  • Великі сторінки ізольовані на рівні контейнера, тому кожен контейнер має власне обмеження у своїй пісочниці cgroup, як запитано в специфікації контейнера.
  • Томи EmptyDir на основі великих сторінок не можуть споживати більше памʼяті великих сторінок, ніж запитує Pod.
  • Застосунки, що використовують великі сторінки через shmget() із SHM_HUGETLB, мають працювати з допоміжною групою, яка відповідає proc/sys/vm/hugetlb_shm_group.
  • Використанням великих сторінок у просторі імен можна керувати через ResourceQuota, подібно до інших обчислювальних ресурсів, таких як cpu або memory, за допомогою токена hugepages-<size>.

10 - Планування GPU

Налаштування та планування GPU для використання як ресурсу вузлів у кластері.
СТАН ФУНКЦІОНАЛУ: GA since Kubernetes v1.26

Kubernetes містить стабільну підтримку керування GPU (графічними процесорами) AMD і NVIDIA на різних вузлах вашого кластера за допомогою втулків пристроїв.

На цій сторінці описано, як користувачі можуть використовувати GPU, і наведено деякі обмеження реалізації.

Використання втулків пристроїв

Kubernetes реалізує втулки пристроїв, щоб надати Podʼам доступ до спеціалізованих апаратних можливостей, таких як GPU.

Примітка: Цей розділ містить посилання на проєкти сторонніх розробників, які надають функціонал, необхідний для Kubernetes. Автори проєкту Kubernetes не несуть відповідальності за ці проєкти. Проєкти вказано в алфавітному порядку. Щоб додати проєкт до цього списку, ознайомтеся з посібником з контенту перед надсиланням змін. Докладніше.

Як адміністратору вам потрібно встановити на вузлах драйвери GPU від відповідного постачальника обладнання й запустити відповідний втулок пристроїв від постачальника GPU. Ось кілька посилань на інструкції постачальників:

Після встановлення втулка ваш кластер надає власний ресурс, придатний для планування, наприклад amd.com/gpu або nvidia.com/gpu.

Ви можете використовувати ці GPU у своїх контейнерах, запитуючи власний ресурс GPU так само, як ви запитуєте cpu чи memory. Однак є деякі обмеження щодо того, як вказувати вимоги до ресурсів для власних пристроїв.

GPU слід вказувати лише в розділі limits, що означає:

  • Ви можете вказати limits для GPU без requests, оскільки Kubernetes стандартно використовує обмеження як значення запиту.
  • Ви можете вказати GPU і в limits, і в requests, але ці два значення мають бути однаковими.
  • Ви не можете вказати requests для GPU без limits.

Ось приклад маніфесту для Podʼа, який запитує GPU:

apiVersion: v1
kind: Pod
metadata:
  name: example-vector-add
spec:
  restartPolicy: OnFailure
  containers:
    - name: example-vector-add
      image: "registry.example/example-vector-add:v42"
      resources:
        limits:
          gpu-vendor.example/example-gpu: 1 # запит на 1 GPU

Керування кластерами з різними типами GPU

Якщо різні вузли вашого кластера мають різні типи GPU, ви можете використовувати мітки вузлів і селектори вузлів для планування Podʼів на відповідні вузли.

Наприклад:

# Додайте вузлам мітки з типом прискорювача, який вони мають.
kubectl label nodes node1 accelerator=example-gpu-x100
kubectl label nodes node2 accelerator=other-gpu-k915

Ключ мітки accelerator — лише приклад; за бажання ви можете використовувати інший ключ мітки.

Автоматичне додавання міток вузлам

Як адміністратор ви можете автоматично виявляти всі вузли з підтримкою GPU й додавати їм мітки, розгорнувши Kubernetes Node Feature Discovery (NFD). NFD виявляє апаратні можливості, доступні на кожному вузлі кластера Kubernetes. Зазвичай NFD налаштовують оголошувати ці можливості як мітки вузлів, але NFD також може додавати розширені ресурси, анотації та taints вузлів. NFD сумісний з усіма підтримуваними версіями Kubernetes. Стандартно NFD створює мітки можливостей для виявлених можливостей. Адміністратори також можуть використовувати NFD, щоб додавати taints вузлам із певними можливостями, і тоді на цих вузлах можна буде планувати лише Podʼи, що запитують ці можливості.

Вам також потрібен втулок для NFD, який додає відповідні мітки вашим вузлам; це можуть бути загальні мітки або мітки конкретного постачальника. Ваш постачальник GPU може надавати сторонній втулок для NFD; докладніше дивіться в його документації.

apiVersion: v1
kind: Pod
metadata:
  name: example-vector-add
spec:
  restartPolicy: OnFailure
  # Ви можете використовувати спорідненість вузлів Kubernetes, щоб запланувати цей Pod на вузол,
  # який надає тип GPU, потрібний його контейнеру для роботи
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: "gpu.gpu-vendor.example/installed-memory"
            operator: Gt # (більше ніж)
            values: ["40535"]
          - key: "feature.node.kubernetes.io/pci-10.present" # мітка можливості NFD
            values: ["true"] # (необовʼязково) планувати лише на вузли з пристроєм PCI 10
  containers:
    - name: example-vector-add
      image: "registry.example/example-vector-add:v42"
      resources:
        limits:
          gpu-vendor.example/example-gpu: 1 # запит на 1 GPU

Реалізації постачальників GPU