Q&A по Kubernetes

Kubernetes

( * Відповідь на питання розгорніть за допомого трикутного значка |> )

  • Чим відрізняється Kubernetes від Openshift?

Відповідь

https://www.redhat.com/cms/managed-files/cl-openshift-and-kubernetes-ebook-f25170wg-202010-en.pdf

  • Openshift має більш строгі політики безпеки та моделі аутентифікації.
  • Openshift підтримує повну інтеграцію CI/CD Jenkins.
  • Openshift має веб-консоль за замовчуванням. В Kubernetes консоль необхідно додатково встановлювати консоль.
  • В Kubernetes можливо встановлювати сторонні мережеві плагіни. В Openshift використовується власне мережеве рішення Open vSwitch, яке надає 3 різних плагіни.
  • Kubernetes може бути встановлений практично на будь-який дистрибутив Linux. Openshift має обмеження на встановлювані дистрибутиви, переважно використовуються RH-дистрибутиви.
  • Kubernets доступний в більшості хмарних платформ – GCP, AWS, Azure, Yandex.Cloud. Openshift доступний на хмарній платформі Azure та хмарі від IBM.
  • За замовчуванням, в Openshift поди в кластері можуть бути запущені тільки під звичайним користувачем, щоб запустити під під користувачем root необхідно видати права для сервісного акаунту. В Kubernetes за замовчуванням поди можуть бути запущені під користувачем root.

  • *Чим відрізняються ReplicationController від ReplicaSet?*

Відповідь

ReplicationController гарантує, що вказана кількість реплік подів будуть працювати одночасно. Іншими словами, ReplicationController гарантує, що под або набір подів завжди активний і доступний.

ReplicaSet – це наступне покоління Replication Controller. Єдина різниця між ReplicaSet та Replication Controller – це підтримка селектора. ReplicaSet підтримує множинний вибір в селекторі, тоді як ReplicationController підтримує в селекторі тільки вибір на основі рівності.

  • Якщо на кожній ноді Kubernetes кластера потрібно запустити контейнер, то який ресурс Kubernetes вам підійде?

Відповідь

DaemonSet є контролером, основним призначенням якого є запуск подів на всіх нодах кластера. Якщо нода додається/видаляється — DaemonSet автоматично додасть/видалить под на цій ноді.

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

  • Як поди рознести на різні ноди?

Відповідь

Необхідно налаштувати podAntiAffinity. Дане вказівка визначає, що для певних подів слід використовувати їх розміщення на різних нодах.

  • В хмарі є 3 зони доступності. Як зробити так, щоб поди додатку розподілилися по цим зонам доступності рівномірно?

Відповідь

Необхідно налаштувати podAntiAffinity. Або, більш новий варіант для даної задачі, налаштувати topologySpreadConstraints з вказанням ключа лейбла зон.

  • Як контейнери одного пода рознести на різні ноди?

Відповідь

Ніяк. Под – мінімальна і неподільна сутність, Kubernetes оперує подами, а не окремими контейнерами.

  • Як забезпечити, щоб поди ніколи не перейшли в стан Evicted на ноді?

Відповідь

Коли вузлу (node) кластера не вистачає пам’яті або дискового простору, він активує прапор, що сигналізує про дану проблему. Дана дія блокує будь-яке нове виділення ресурсів на ноді і запускає процес “виселення” (evicted) пода з ноди.

В цей момент kubelet починає відновлювати ресурси, видаляючи контейнери і оголошуючи поди, як Failed, поки використання ресурсів знову не стане нижче порогу “виселення”.

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

  • Best Effort.
  • Burstable поди, що використовують більше ресурсів, ніж запит вичерпаного ресурсу.
  • Burstable поди, що використовують менше ресурсів, ніж запит вичерпаного ресурсу.

Щоб под не був видалений при “виселенні”, необхідно налаштувати політики QoS для пода як Guaranteed.

Докладніше в документації Kubernetes: Create a Pod that gets assigned a QoS class of Guaranteed

Крім того, можна використовувати сутність кубернетиса PodDisruptionBudget, яка дозволить регулювати кількість витісняємих подів і забезпечувати гарантовану доступність для конкретного мікросервісу https://kubernetes.io/docs/tasks/run-application/configure-pdb/

  • За що відповідає kube-proxy?

Відповідь

Kube-proxy відповідає за взаємодію між сервісами на різних нодах кластера.

  • Що знаходиться на master ноді?

Відповідь

  • Kube-apiserver відповідає за оркестрацію всіх операцій кластера.
  • Controller-manager (Node controller + Replication Controller) Controller відповідає за функції контролю за нодами, репліками.
  • ETCD cluster (розподілене сховище ключ-значення) ETCD зберігає інформацію про кластер і його конфігурацію.
  • Kube-sheduler відповідає за планування додатків і контейнерів на нодах.

За замовчуванням на master ноді не розміщуються контейнери додатків, але даний функціонал можливо налаштувати.

  • Що знаходиться на worker ноді?

Відповідь

  • Kubelet слухає інструкції від kube-apiserver і розгортає або видаляє контейнери на нодах.
  • Kube-proxy відповідає за взаємодію між сервісами на різних нодах кластера.

На worker нодах за замовчуванням розміщуються контейнери додатків. На кожній ноді кластера встановлюється Docker або інша платформа контейнеризації (наприклад RKT або containterd). На Master ноді також встановлюється Docker, якщо необхідно використовувати компоненти Kubernetes в контейнерах.

  • Як встановити Kubernetes?

Відповідь

  • *Чим відрізняється StatefulSet від Deployment?*

Відповідь

Deployment – ресурс Kubernetes призначений для розгортання додатку без збереження стану. При використанні PVC всі репліки будуть використовувати один і той же том, і жоден з них не буде мати власного стану.

StatefulSet – підтримують стан додатків за межами життєвого циклу окремих модулів pod, наприклад для сховища. Використовується для додатків з відстеженням стану, кожна репліка модуля буде мати власний стан і буде використовувати свій власний том.

  • *Що таке оператори в поняттях Kubernetes?*

Відповідь

Оператори — це програмні розширення Kubernetes, покликані автоматизувати виконання рутинних дій над об’єктами кластера при певних подіях.

Оператор працює по підписці на події до API Kubernetes.

  • *Чому DaemonSet не потрібен scheduler?*

Відповідь

DaemonSet гарантує, що певний под буде запущений на всіх нодах кластера. При наявності DaemonSet в кластері на будь-якій з існуючих і майбутніх нод в кластері зарезервовані ресурси для пода на ноді.

Тут варто зробити застереження щодо того, що DaemonSet може працювати не на всіх нодах кластера, а на деяких, вибраних, наприклад, по nodeSelector. До прикладу, у нас є GPU ноди і нам потрібно на всі ці ноди задеплоїти мікросервіс що виконує обчислення на GPU.

  • В яких випадках не спрацює перенесення пода на іншу ноду?

Відповідь

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

  • *Що робить ControllerManager?*

Відповідь

Controller виконує постійний процес моніторингу стану кластера і різних компонент.

Controller-manager (Node controller + Replication Controller) – Controller відповідає за функції контролю за нодами, репліками.

  • Адміністратор виконує команду kubectl apply -f deployment.yaml. Опишіть по порядку що відбувається в кожному з вузлів Kubernetes і в якому порядку.

Відповідь

Клієнт kubectl звертається до мастер-сервера kube-apiserver (стандартно на порт 6443), адреса мастер сервер заданий в .config файлі. В запиті передається інформація, яку потрібно застосувати в кластері звернення. API-сервер звертається до etcd сховища, перевіряє наявність конфігурації запитуваного ресурсу. Якщо конфігурація в сховищі etcd є, то API-сервер порівнює нову конфігурацію з конфігурацією в базі даних: якщо конфігурація однакова, то змін в кластері не відбувається, клієнту віддається відповідь про успішність запитуваної дії, якщо конфігурації немає в etcd, то якщо потрібна дія стосується створення сутностей, які потребують ресурсів кластера (створення подів, сховища pv/pvc і т.д.), scheduler перевіряє можливість розміщення подів на нодах і після чого відбувається створення подів, при цьому controll-manager контролює створення потрібної кількості реплік сутності. Після створення потрібної сутності, відбувається запис в etcd, controll-manager продовжує відстежувати стан сутностей протягом всього циклу його життя.

  • Як виконати оновлення Kubernetes в контурі де немає інтернету?

Відповідь

Попередньо з робочого кластера з новою версією Kubernetes і доступом в Інтернет необхідно скачати потрібні пакети kubeadm і образи api, controllmanager, etcd, scheduler, kubelet, docker-ce. Скачати пакети з дозволом залежностей можливо командою yumdownloader --resolve kubeadm. Образи скачуються локально в архів docker save <ім'я_образу> > <ім'я_образу>.tar.

  • Видалити додатки з кластера.

helm delete --purge all

  • Після того, як всі необхідні компоненти скачені і завантажені в контур без Інтернету, виконує команду скидання kubeadm.

kubeadm reset

  • Видаляємо CNI-плагін Kubernetes.

yum remove kubernetes-cni-plugins

  • Локально встановлюємо необхідні пакети.

yum install ./kubernetes_packages/*.rpm

  • Завантажуємо образи сервісів Kubernetes.

docker load < <ім'я_образу>.tar

  • Відключаємо SELinux.

setenforce 0 sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config

  • Визначаємо IP адресу master сервера.

IP=$(ip route get 1 | awk '{print $NF;exit}')

  • Ініціалізуємо кластер Kubernetes.

kubeadm init --apiserver-advertise-address=$IP

  • Далі необхідно встановити CNI-плагін, наприклад Weave.
  • Дозволити на master ноді запускати контейнери додатку.

kubectl taint nodes --all node-role.kubernetes.io/master-

На worker ноді виконуються аналогічні дії, крім того, що встановлюється тільки kubelet. При ініціалізації master ноди видається token для підключення worker нод, його необхідно зберегти, щоб пізніше включити woker ноду в кластер.

  • Чим Router в Openshift відрізняється від Ingress в Kubernetes?

Відповідь

Router Openshift використовує haproxy, як проксі-вебсервер. Ingress як в Kubernetes, так і OpenShift може бути різним (nginx, haproxy, caddy, etc).

  • Чому для встановлення Kubernetes потрібно відключити swap?

Відповідь

Планувальник Kubernetes визначає найкращий доступний вузол для розгортання новостворених модулів. Якщо в хост-системі дозволена підкачка пам’яті, це може призвести до проблем з продуктивністю і стабільністю в Kubernetes. З цієї причини Kubernetes вимагає, щоб ви відключили swap в хост-системі.

  • *Що таке Pod в Kubernetes?*

Відповідь

Мінімальна сутність в Kubernetes і є абстракцією над контейнерами. Pod представляє собою запит на запуск одного або більше контейнерів на одному вузлі.

  • Скільки контейнерів запускається в одному поді?

Відповідь

За замовчуванням при запуску одного контейнера в одному поді запускається ще pause контейнер. Підсумок, в одному поді може бути запущено n+1 контейнерів.

  • *Для чого потрібен pause контейнер в кожному поді?*

Відповідь

Контейнер pause запускається першим в поді і створює мережевий простір імен для пода. Потім Kubernetes виконує CNI плагін для приєднання контейнера pause до мережі. Всі контейнери пода використовують мережевий простір імен (netns) цього pause контейнера.

  • *Чим відрізняється Deployment від DeploymentConfig (Openshift)?*

Відповідь

https://docs.openshift.com/container-platform/4.1/applications/deployments/what-deployments-are.html

  • *Для чого потрібні Startup, Readiness, Liveness проби? Чим відрізняються?*

Відповідь

Kubelet використовує Liveness пробу для перевірки, коли перезапустити контейнер. Наприклад, Liveness проба повинна зловити блокування, коли додаток запущений, але не може нічого зробити. В цьому випадку перезапуск додатку може допомогти зробити додаток доступним, незважаючи на баги.

Kubelet використовує Readiness проби, щоб дізнатися, чи готовий контейнер приймати трафік. Pod вважається готовим, коли всі його контейнери готові.

Одне з застосувань такого сигналу – контроль, які Pod будуть використані в якості бекенда для сервісу. Поки Pod не в статусі ready, він буде виключений з балансувальників навантаження сервісу.

Kubelet використовує Startup пробу, щоб зрозуміти, коли додаток в контейнері було запущено. Якщо проба налаштована, він блокує Liveness та Readiness перевірки, до того як проба стає успішною, і перевіряє, що ця проба не заважає запуску додатку. Це може бути використано для перевірки працездатності повільно стартуючих контейнерів, щоб уникнути вбивства kubelet’ом перш, ніж вони будуть запущені.

  • *Чим відрізняються Taints та Tolerations від Node Afiinity?*

Відповідь

Node Affinity – це властивість подів, яка дозволяє нодам вибирати необхідний под. Node Affinity дозволяє обмежувати для яких вузлів под може бути запланований, на основі міток на ноді. Node Affinity вимагає вказання nodeSelector для пода з необхідним label ноди кластера.

Типи Node Affinity:

`<Вимога 1><Момент 1><Вимога 2><Момент 2>

requiredDuringSchedulingRequiredDuringExecution`

| Тип \ Момент | DuringScheduling | DuringExecution |

|-|-|-|

| Тип 1 | Required | Ignored |

| Тип 2 | Preferred | Ignored |

| Тип 3 | Required | Required |

Існують певні оператори nodeAffinity: In, NotIn, Exists, DoesNotExist, Gt або Lt.

Taints – це властивість нод, яка дозволяє поду вибирати необхідну ноду. Tolerations застосовуються до подів і дозволяють (але не вимагають) планувати модулі на нодах з відповідним Taints.

Встановити для ноди Taints:

kubectl taint nodes <node-name> key=value:taint-effect

Taint-effect приймає значення – NoSchedule, PreferNoSchedule, NoExecute.

Приклад:

kubectl taint nodes node1 app=blue:NoSchedule

  • NoSchedule означає, що поки в специфікації пода не буде відповідного запису tolerations, він не зможе бути розгорнутий на ноді (в даному прикладі node10).
  • PreferNoSchedule— спрощена версія NoSchedule. В цьому випадку планувальник спробує не розподіляти поди, у яких немає відповідного запису tolerations на ноду, але це не жорстке обмеження. Якщо в кластері не виявиться ресурсів, то поди почнуть розгортатися на цій ноді.
  • NoExecute — цей ефект запускає негайну евакуацію подів, у яких немає відповідного запису tolerations.

Taints та Tolerations працюють разом, щоб гарантувати, що поди не заплановані на невідповідні ноди. На ноду додається один або декілька Taints і це означає, що нода не повинна приймати ніякі поди, що не відносяться до Taints.

Taints та Tolerations не гарантує, що певний под буде розміщений на потрібній ноді. NodeAffinity – не гарантує, що на певній ноді, крім вибраних подів, не будуть розміщені інші поди.

  • *Чим відрізняються Statefulset та Deployment в плані стратегії оновлення подів Rolling Update?*

Відповідь

Стратегія оновлення Rolling Update в Deployment передбачає послідовне оновлення подів: спочатку буде створений новий под, потім буде переключений трафік на новий под і потім видалений старий под.

Стратегія оновлення Rolling Update в StatefulSet передбачає оновлення подів в зворотному порядку, тобто под спочатку буде видалений, а потім встановлений новий.

  • Для чого в Kubernetes використовуються порти 2379 та 2380?

Відповідь

2379 та 2380 – порти, які використовуються etcd.

2379 використовується для взаємодії etcd з компонентами control plane. 2380 використовується тільки для взаємодії компонентів etcd в кластері, при наявності множини master нод в кластері.

  • Заданий наступний yaml файл для створення пода Test. Як зробити так, щоб контейнери nginx та redis пода test були розміщені різних нодах кластера при умові, що існують лейбли нод disk=ssd та disk=hard?

apiVersion: v1
kind: Pod
metadata:
  name: Test
spec:
  containers:
  - name: nginx
    image: nginx
  - name: redis
    image: redis
  nodeSelector:
    disk: ssd

Відповідь

Ніяк. Контейнери одного пода можуть розміщуватися тільки на одній ноді. Под є неподільною сутністю Kubernetes.

  • Яку функцію виконують indent та nindent в Helm чартах?

Відповідь

indent робить відступ кожного рядка в заданому списку до вказаної ширини відступу.

nindent аналогічна функції indent, але додає символ нового рядка на початок кожного рядка в списку.

  • *Чим відрізняється Deployment від ReplicaSet?*

Відповідь

ReplicaSet гарантує, що певна кількість екземплярів подів (Pods) буде запущено в кластері Kubernetes.

Deployment надає можливість декларативного оновлення для об’єктів типу поди (Pods) та набори реплік (ReplicaSets).

Deployment – рівень абстракції над ReplicaSet. Deployment буде створювати об’єкт ReplicaSet, але з можливістю rolling-update та rollback.

Щоб зберегти стан при розгортанні Deployment необхідно встановити ключ --record при застосуванні маніфесту.

  • *Чим відрізняється Deployment від StatefulSet?*

Відповідь

Deployment виконує оновлення подів та RelicaSets, і є найбільш використовуваним ресурсом Kubernetes для деплою додатків, як правило – stateless додатків, але якщо підключити Persistent Volume – додаток можна використовувати як stateful, але всі поди деплойменту будуть спільно використовувати це сховище і дані з нього. Для PVC можна вказати режим доступу як ReadWriteMany, так і ReadOnlyMany.

StatefulSet використовуються для управління stateful-додатками. Створює не ReplicaSet, а Pod напряму з унікальним іменем. У зв’язку з цим – при використанні StatefulSet немає можливості виконати відкат версії, але можна його видалити або виконати скейлінг. При оновленні StatefulSet – буде виконано RollingUpdate всіх подів. StatefulSet використовує volumeClaimTemplates для опису сховища і при використанні PVC для кожного пода буде створений унікальний PVC і режимом доступу ReadWriteOnce.

  • Що таке HPA (Horizontal Pod Autoscaling)? Як він працює і що для цього потрібно?

Відповідь

HPA – механізм, який дозволяє вказати потрібну метрику(и) налаштувати автоматичний поріг масштабування Pod’ів в залежності від зміни її значень.

Щоб HPA працював необхідно, щоб в кластері був встановлений metrics-server, щоб зчитувати метрики споживання ресурсів. За замовчуванням HPA можна налаштувати для метрики споживання CPU та/або пам’яті. Можливо розширення функціоналу HPA за допомогою keda.

  • Що таке Headless сервіс?

Відповідь

При вказанні ClusterIP: None для сервісу ми створюємо “безголовий сервіс”, у даного сервісу не буде віртуального IP адреси. Headless сервіс це просто А-запис в системі DNS, таким чином ім’я сервісу перетворюється не в віртуальний IP сервісу, а відразу в IP пода. Headless сервіси корисні, коли додаток сам повинен управляти тим, до якого Pod підключатися. Наприклад, gRPC-клієнти тримають по одному з’єднанню з сервісами і самі управляють запитами, мультиплексуючи запити до одного сервера. В разі використання ClusterIP клієнт може створити одне підключення і навантажувати рівно один Pod сервера.

  • Що таке ExternalName сервіс?

Відповідь

Сервіс типу ExternalName додає запис типу CNAME у внутрішній DNS сервер Kubernetes. Наприклад:

apiVersion: v1
kind: Service
metadata:
  name: ya-ru
spec:
  type: ExternalName
  externalName: ya.ru

Для сервісу ya-ru не створюється endpoint. Тому відразу переходимо до запитів до DNS.

ya-ru.default.svc.cluster.local. 5 IN CNAME   ya.ru.

  • Що таке ExternalIP сервіс?

Відповідь

При визначенні сервісу можна додати поле externalIPs, в якому можна вказати IP адресу машини кластера. При зверненні на цей IP і вказаний в сервісі порт, запит буде перекинутий на відповідний сервіс.

Наприклад:

apiVersion: v1
kind: Service
metadata:
  name: external-svc-nginx
  labels:
    app: nginx
spec:
  ports:
    - name: http-main
      port: 8080
      protocol: TCP
      targetPort: 8090
  selector:
    app: nginx
  externalIPs:
    - 192.168.218.178

При зверненні до 192.168.218.178:8080 запит буде перекинутий до сервісу external-svc-nginx:8080

  • Що таке NodePort сервіс?

Відповідь

Сервіси типу NodePort відкривають порт на кожній ноді кластера на мережевих інтерфейсах хоста. Всі запити, що приходять на цей порт, будуть пересилатися на endpoints, пов’язані з даним сервісом.

Діапазон портів, який можна використовувати в NodePort — 30000-32767. Але його можна змінити при конфігурації кластера.

  • Що таке capabilities? Для чого потрібно їх описувати?

Відповідь

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