Коли Linux conntrack вам більше не товариш

Коли Linux conntrack вам більше не товариш

Відстеження з'єднань (“conntrack”) є основною функцією стека ядра Linux. Вона дозволяє ядру відстежувати всі логічні мережеві з'єднання чи потоки і цим ідентифікувати всі пакети, які становлять кожен потік, щоб їх можна було послідовно обробляти разом.

Conntrack - це важлива функція ядра, яка використовується в деяких основних випадках:

  • NAT спирається на інформацію від сonntrack, тому він може однаково обробляти всі пакети з одного потоку. Наприклад, коли pod звертається до service Kubernetes, балансувальник навантаження kube-proxy використовує NAT для направлення трафіку на конкретний pod всередині кластера. Conntrack записує, що для певного з'єднання всі пакети до IP service повинні відправлятися в один і той же pod, і що пакети, що повертаються pod'ом бекенда, повинні бути направлені NAT назад в pod з якого прийшов запит.
  • Firewall'и з відстеженням стану, такі як Calico, спираються на інформацію від сonntrack, щоб додавати "трафік у відповідь" в білий список. Це дозволяє вам написати мережеву політику, яка каже: «дозволити моєму pod'у підключатися до будь-якої віддаленої IP-адреси» без необхідності писати політику для явного дозволу трафіку у відповідь. (Без цього вам довелося б додати набагато менш безпечне правило "дозволяти пакети в мій pod з будь-якого IP".)

Крім того, conntrack зазвичай підвищує продуктивність системи (знижуючи споживання процесорного часу та час затримок пакетів), оскільки тільки перший пакет у потоці
повинен пройти повну обробку стека мережі, щоб визначити, що з нею робити. Дивіться пост «Порівняння режимів kube-proxy», щоб побачити приклад того, як це працює.

Тим не менш, у conntrack є свої обмеження.

Тож де все пішло не так?

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

  • Найбільш очевидний випадок, якщо ваш сервер обробляє надзвичайно велику кількість одночасно активних з'єднань. Наприклад, якщо ваша таблиця conntrack налаштована на 128k записів, але у вас є > 128k одночасних підключень, ви, напевно, зіштовхнетеся з проблемою!
  • Трохи менш очевидний випадок: якщо ваш сервер обробляє дуже багато з'єднань за секунду. Навіть якщо короткочасні з'єднання, вони продовжують відстежуватися Linux протягом деякого періоду часу (за замовчуванням 120с). Наприклад, якщо ваша таблиця conntrack налаштована на 128 тис. записів і ви намагаєтеся обробити 1100 підключень за секунду, вони будуть перевищувати розмір таблиці conntrack, навіть якщо з'єднання дуже недовговічні (128k / 120с = 1092 з'єднань / с).

Є кілька нішевих типів додатків, які у ці категорії. Крім того, якщо у вас багато недоброзичливців, заповнення таблиці conntrack вашого сервера безліччю напіввідкритих з'єднань може використовуватися в рамках атаки типу «відмова в обслуговуванні» (DOS). В обох випадках conntrack може стати вузьким місцем, що обмежує, у вашій системі. У деяких випадках налаштування параметрів таблиці conntrack може бути достатньо для задоволення ваших потреб шляхом збільшення розміру або скорочення тайм-аутів conntrack (але якщо ви зробите це неправильно, то зіткнетеся з великими труднощами). Для інших випадків необхідно буде обійти conntrack для агресивного трафіку.

реальний приклад

Наведемо конкретний приклад: один великий SaaS провайдер з яким ми працювали мав ряд memcached-серверів на хостах (не віртуальних машинах), кожен з яких обробляв 50К+ короткочасних з'єднань за секунду.

Вони експериментували з конфігурацією conntrack, збільшували розміри таблиць і скорочували час відстеження, але конфігурація була ненадійною, значно збільшилося споживання ОЗП, що було проблемою (порядку ГБайтів!), а з'єднання були настільки короткими, що conntrack не створював свого звичайного виграшу у продуктивності (зменшення) ЦП чи затримок пакетів).

Як альтернатива вони звернулися до Calico. Мережеві політики Calico дозволяють не використовувати conntrack для певного виду трафіку (використовуючи для політик опцію doNotTrack). Це забезпечило їм необхідний рівень продуктивності плюс додатковий рівень безпеки Calico.

На що доведеться піти, щоб оминути conntrack?

  • Мережеві політики do-not-track, як правило, мають бути симетричні. У випадку SaaS-провайдера: їхні програми працювали всередині зони, що захищається, і тому за допомогою мережевої політики вони могли додати в білий список трафік від інших конкретних додатків, яким дозволявся доступ до memcached.
  • Політика do-not-track не враховує напряму з'єднання. Таким чином, у разі злому memcached-сервера з нього теоретично можна спробувати підключитися до будь-якого з memcached-клієнтів, якщо він використовує правильний вихідний порт. Однак, якщо ви коректно визначили мережну політику для своїх клієнтів memcached, ці спроби підключення все одно будуть відхилені на стороні клієнта.
  • Політика do-not-track застосовується до кожного пакету, на відміну від звичайних політик, які застосовуються лише першого пакета з потоку. Це може збільшити витрати ресурсів CPU на один пакет, тому що для кожного пакета потрібно застосовувати політику. Але для короткочасних з'єднань ця витрата врівноважується скороченням витрати ресурсів на обробку conntrack. Наприклад, у випадку SaaS провайдера кількість пакетів для кожного з'єднання була дуже невеликою, тому додаткова витрата ресурсів CPU при застосуванні політик до кожного пакета була виправдана.

Приступимо до тестів

Ми проводили тест на одному pod'і з memcached-сервером і безліччю pod'ів memcached-клієнтів, запущених на віддалених нодах, так що ми могли б запускати дуже велику кількість з'єднань в секунду. Сервер з pod'ом memcached-сервера мав 8 ядер та 512k записів у conntrack таблиці (стандартно налаштований розмір таблиці для хоста).
Ми вимірювали різницю у продуктивності між: без мережевої політики; із звичайною Calico політикою; та Calico do-not-track політикою.

Для першого тесту ми задали кількість коннектів до 4.000 в секунду, тому ми могли сфокусуватися на різниці споживання CPU. Тут не було суттєвих відмінностей між відсутністю політики та звичайної політики, але do-not-track збільшила споживання CPU приблизно на 20%.

Коли Linux conntrack вам більше не товариш

У другому тесті ми запустили стільки з'єднань, скільки могли згенерувати наші клієнти та вимірювали максимальну кількість з'єднань за секунду, яку міг відпрацювати наш memcached-сервер. Як і очікувалося, у випадку “без політик” та “звичайна політика” обидва досягли ліміту conntrack у більш ніж 4,000 з'єднань за секунду (512k / 120s = 4,369 з'єднань/с). З do-not-track політикою наші клієнти відправляли 60,000 з'єднань за секунду без жодних проблем. Ми впевнені, що могли б збільшити це число, підключивши більше клієнтів, але відчуваємо, що цих цифр вже достатньо, щоб проілюструвати посилання цієї статті!

Коли Linux conntrack вам більше не товариш

Висновок

Conntrack – це важлива функція ядра. Він чудово виконує свою роботу. Найчастіше його використовують ключові компоненти системи. Однак, у деяких певних сценаріях, навантаження через conntrack переважує звичайні переваги, які він дає. У цьому сценарії мережеві політики Calico можуть бути використані, щоб вибірково відключати використання conntrack, при цьому підвищуючи рівень мережної безпеки. Для решти трафіку conntrack продовжує бути вашим товаришем!

Також читайте інші статті у нашому блозі:

Джерело: habr.com

Додати коментар або відгук