Використання sysctl в кластері Kubernetes

СТАН ФУНКЦІОНАЛУ: Kubernetes v1.21 [stable]

У цьому документі описано, як налаштовувати та використовувати параметри ядра в межах кластера Kubernetes, використовуючи інтерфейс sysctl.

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

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

Для деяких кроків вам також потрібно мати змогу змінювати параметри командного рядка для kubelet, що працюють на вашому кластері.

Перелік всіх параметрів Sysctl

У Linux інтерфейс sysctl дозволяє адміністратору змінювати параметри ядра під час виконання. Параметри доступні через віртуальну файлову систему /proc/sys/. Параметри охоплюють різні підсистеми, такі як:

  • ядро (загальний префікс: kernel.)
  • мережа (загальний префікс: net.)
  • віртуальна памʼять (загальний префікс: vm.)
  • MDADM (загальний префікс: dev.)
  • Більше підсистем описано у документації ядра.

Щоб отримати список всіх параметрів, ви можете виконати команду:

sudo sysctl -a

Безпечні та Небезпечні Sysctl

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

  • не повинно мати жодного впливу на інші Podʼи на вузлі
  • не повинно дозволяти шкодити справності вузла
  • не повинно дозволяти отримувати CPU або ресурси памʼяті поза межами обмежень ресурсів Podʼу.

Наразі більшість просторово розмежованих (по просторах імен) sysctl не обовʼязково вважаються безпечними. До набору безпечних sysctl входять наступні параметри:

  • kernel.shm_rmid_forced;
  • net.ipv4.ip_local_port_range;
  • net.ipv4.tcp_syncookies;
  • net.ipv4.ping_group_range (починаючи з Kubernetes 1.18);
  • net.ipv4.ip_unprivileged_port_start (починаючи з Kubernetes 1.22);
  • net.ipv4.ip_local_reserved_ports (починаючи з Kubernetes 1.27, потрібне ядро 3.16+);
  • net.ipv4.tcp_keepalive_time (починаючи з Kubernetes 1.29, потрібне ядро 4.5+);
  • net.ipv4.tcp_fin_timeout (починаючи з Kubernetes 1.29, потрібне ядро 4.6+);
  • net.ipv4.tcp_keepalive_intvl (починаючи з Kubernetes 1.29, потрібне ядро 4.5+);
  • net.ipv4.tcp_keepalive_probes (починаючи з Kubernetes 1.29, потрібне ядро 4.5+).

Цей список буде розширюватися у майбутніх версіях Kubernetes, коли kubelet буде підтримувати кращі механізми ізоляції.

Увімкнення небезпечних Sysctl

Всі безпечні sysctl є типово увімкненими.

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

З врахуванням попередження вище, адміністратор кластера може дозволити певні небезпечні sysctl для дуже спеціальних ситуацій, таких як налаштування високопродуктивних або застосунків реального часу. Небезпечні sysctl вмикаються на основі вузла з прапорцем kubelet; наприклад:

kubelet --allowed-unsafe-sysctls \
  'kernel.msg*,net.core.somaxconn' ...

Для Minikube, це можна зробити за допомогою прапорця extra-config:

minikube start --extra-config="kubelet.allowed-unsafe-sysctls=kernel.msg*,net.core.somaxconn"...

Таким чином можна увімкнути лише просторово розмежовані sysctl.

Налаштування Sysctl для Podʼу

Численні sysctl просторово розмежовані в сучасних ядрах Linux. Це означає, що їх можна налаштовувати незалежно для кожного Pod на вузлі. Лише просторово розмежовані sysctl можна налаштовувати через securityContext Podʼа в межах Kubernetes.

Відомо, що наступні sysctl мають просторове розмежування. Цей список може змінитися в майбутніх версіях ядра Linux.

  • kernel.shm*
  • kernel.msg*
  • kernel.sem
  • fs.mqueue.*
  • Ті net.*, які можна налаштувати в просторі імен мережі контейнера. Однак є винятки (наприклад, net.netfilter.nf_conntrack_max та net.netfilter.nf_conntrack_expect_max можуть бути налаштовані в просторі імен мережі контейнера, але не мають просторового розмежування до Linux 5.12.2).

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

Використовуйте securityContext Podʼа для налаштування просторово розмежованих sysctl. securityContext застосовується до всіх контейнерів у тому ж Podʼі.

У цьому прикладі використовується securityContext Podʼа для встановлення безпечного sysctl kernel.shm_rmid_forced та двох небезпечних sysctl net.core.somaxconn та kernel.msgmax. В специфікації немає розрізнення між безпечними та небезпечними sysctl.

apiVersion: v1
kind: Pod
metadata:
  name: sysctl-example
spec:
  securityContext:
    sysctls:
    - name: kernel.shm_rmid_forced
      value: "0"
    - name: net.core.somaxconn
      value: "1024"
    - name: kernel.msgmax
      value: "65536"
  ...

Хорошою практикою є вважати вузли з особливими налаштуваннями sysctl як позначені taint в межах кластера і планувати на них лише ті Podʼи, яким потрібні ці налаштування sysctl. Рекомендується використовувати функцію Заплямованість та Толерантність кластера Kubernetes, щоб реалізувати це.

Pod з небезпечними sysctl не вдасться запустити на будь-якому вузлі, на якому не були явно увімкнені ці два небезпечні sysctl. Як і з вузловими sysctl, рекомендується використовувати функцію Заплямованість та Толерантність або заплямованість вузлів для планування цих Podʼів на відповідні вузли.

Змінено June 20, 2024 at 12:44 PM PST: Sync changest from andygol/k8s-website (36d05bc8a1)