• Час читання ~9 хв
  • 14.11.2023

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

Але це може мати свою ціну. Ефемерність подів Kubernetes і те, як вони масштабуються, ускладнює керування сесіями в Laravel. Використання драйвера файлової сесії за замовчуванням може призвести до втрати даних, якщо под перезавантажиться або буде замінений, тому розробники повинні перейти на інший механізм.

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

Ця стаття спонсорується Scout APM.

Переваги використання Kubernetes з Laravel

Почнемо з того, чому ви можете це зробити. Ви можете розгортати програми Laravel безліччю різних способів, тож навіщо вибирати той, який одразу завдасть вам головного болю під час цієї сесії? Що ж, основними перевагами розгортання програми Laravel у Kubernetes є:Однак

  1. Stateless horizontal scaling. Laravel is inherently designed to be stateless for most of its components (excluding sessions and cache if stored locally). This design complements Kubernetes' scaling capabilities. When traffic to your Laravel application increases, Kubernetes can quickly spawn more replicas of your Laravel application to handle the load, and vice-versa when traffic decreases.
  2. Background processing. Laravel's job and queue system, built around tools like Laravel Horizon, can benefit from Kubernetes' deployment strategies. For instance, worker containers can be scaled independently of the main application, allowing for effective processing of queued jobs.
  3. Configuration management. Laravel's configuration system relies heavily on environment variables. Kubernetes' ConfigMaps and Secrets make it easy to manage and inject these environment variables consistently and securely across different environments (development, staging, production).
  4. Storage flexibility. If your Laravel application requires file storage (for example, for user uploads), Kubernetes offers Persistent Volume Claims (PVCs) that abstract the underlying storage backend. This means your Laravel application can seamlessly store files whether you're on cloud object storage, a block storage device, or a network file system.
  5. Service mesh integration. If you adopt a service mesh like Istio with your Laravel application on Kubernetes, you gain enhanced observability, traffic management, and security features without modifying the Laravel application itself.

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

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

Виклики управління сесіями за допомогою Laravel та Kubernetes Отже, проблема управління сесіями пов'язана з трьома факторами, невід'ємними від того, як працює Kubernetes

.

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

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

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

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

Щоб протистояти цим викликам, розробники Laravel, які розгортають Kubernetes, мають два варіанти:

  1. Leverage Kubernetes' session affinity feature to ensure requests from a user consistently land on the same replica.
  2. Store sessions in distributed systems like Redis or databases, ensuring that session data is centralized and accessible to all replicas.

Давайте розглянемо кожен варіант і те, як вони працюють з Laravel.

Спорідненість із сеансами липких сеансів

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

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

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

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

Коли ви налаштовуєте спорідненість до сесії на основі IP-адреси клієнта, Kubernetes перевіряє вихідну IP-адресу вхідного запиту та спрямовує її до того ж блоку, що й попередні запити з цієї IP-адреси. Якщо спорідненість із сеансом базується на файлах cookie, Kubernetes гарантує, що всі запити з певним файлом cookie спрямовуються в один і той самий блок

.У визначенні YAML вашого сервісу ви повинні вказати тип спорідненості сеансу. Наприклад:

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: my-app
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9376
  sessionAffinity: ClientIP

У наведеній вище конфігурації поле встановлено на ClientIP, що означає, що сервіс Kubernetes використовуватиме IP-адресу клієнта, щоб гарантувати, sessionAffinity що всі запити з цієї IP-адреси будуть спрямовані на один і той самий под.

Якщо вам потрібен більший контроль над спорідненістю сеансу, ви можете скористатися пунктом sessionAffinityConfigменю . Наприклад, щоб встановити тайм-аут для спорідненості сеансу:

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: my-app
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9376
  sessionAffinity: ClientIP
  sessionAffinityConfig:
    clientIP:
      timeoutSeconds: 3600

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

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

Розподілені сховища сеансів за допомогою Redis Розподілене сховище сеансів, як-от Redis

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

Redis є ідеальним вибором, тому що:

  1. Performance. Redis is an in-memory data structure store offering rapid data access. This makes it exceptionally well-suited for session management, where fast read and write operations are crucial for maintaining a seamless user experience.
  2. Scalability. Redis supports horizontal partitioning or sharding, making it scalable across multiple machines. In high-traffic scenarios where a single Redis instance might become a bottleneck, you can distribute your data across multiple Redis instances.
  3. Persistence. While primarily an in-memory store, Redis provides mechanisms to persist data on disk without compromising much on performance. This ensures that session data isn't lost if the Redis service restarts.
  4. Data structures. Redis isn't just a simple key-value store. It supports a variety of data structures like strings, hashes, lists, and sets. This flexibility can be beneficial for more complex session-related operations.

Redis також має деякі переваги перед липкими сесіями. Оскільки будь-який інстанс може обробляти запити, трафік більш рівномірно розподіляється по всіх подах. Якщо под не працює, сеанси користувача не втрачаються. Інший под може прийняти запит і отримати дані сесії від Redis. У міру зростання трафіку ви можете масштабувати свою програму та екземпляри Redis незалежно залежно від потреби.

Давайте розглянемо кроки для налаштування Redis як драйвера сеансу в Laravel. По-перше, вам потрібно встановити необхідний пакунок:

composer require predis/predis

Потім ви можете оновити файл Laravel .env, щоб він вказував на Redis для керування сеансами:У Laravel вам потрібно оновити свою конфігурацію/сесію.php щоб використовувати драйвер сесії з файлу .env:Потім переконайтеся, що конфігурація Redis у config/database.php виглядає так:

SESSION_DRIVER=redis
REDIS_HOST=your_redis_server
REDIS_PASSWORD=your_redis_password
REDIS_PORT=6379

'driver' => env('SESSION_DRIVER', 'file'),

'redis' => [
    'client' => 'predis',
    'default' => [
        'host'     => env('REDIS_HOST', '127.0.0.1'),
        'password' => env('REDIS_PASSWORD', null),
        'port'     => env('REDIS_PORT', 6379),
        'database' => env('REDIS_DB', 0),
    ],
],

Далі вам знадобиться таблиця для зберігання сесій. Laravel надає команду для створення цієї таблиці:

php artisan session:table

Це створить файл міграції. Запустіть міграцію, щоб зробити таблицю сесій:

php artisan migrate

Після вищевказаних конфігурацій Laravel автоматично оброблятиме сесії за допомогою Redis, не вимагаючи будь-якого спеціального коду у вашому додатку. Наприклад, коли ви встановлюєте змінну сеансу:

session(['key' => 'value']);

Це значення буде зберігатися в Redis. Щоб отримати його:

$value = session('key');

Коли ви викликаєте такі функції, Laravel автоматично використовує Redis як сервер для керування даними сесії.

Щоб розгорнути Redis у Kubernetes, вам потрібно використовувати Helm для розгортання екземпляра Redis у вашому кластері Kubernetes:

# Add the Bitnami repository which has the Redis chart
helm repo add bitnami <https://charts.bitnami.com/bitnami>
# Install Redis using Helm
helm install my-redis bitnami/redis

Обов'язково запишіть пароль для екземпляра Redis, наданий Helm під час встановлення. Потім створіть маніфест сервісу Kubernetes. Назвемо його redis-service.yaml:Ви можете застосувати маніфест сервісу Kubernetes для створення сервісу:Потім переконайтеся, що сервіс запущений:Нарешті, вкажіть Laravel на сервіс Kubernetes Redis, оновивши файл Laravel .env або конфігурацію для використання сервісу Redis, створеного в Kubernetes:

apiVersion: v1
kind: Service
metadata:
  name: redis-service
spec:
  selector:
    app: redis
  ports:
    - protocol: TCP
      port: 6379
      targetPort: 6379

kubectl apply -f redis-service.yaml

kubectl get svc redis-service

REDIS_HOST=redis-service
REDIS_PORT=6379

redis-service є хостом, оскільки це ім'я сервісу Kubernetes, і внутрішній DNS Kubernetes перетворить це ім'я на відповідну IP-адресу для сервісу.

Вітаємо, ви інтегрували Redis з Laravel і забезпечили зв'язок програми Laravel з екземпляром Redis, розгорнутим у Kubernetes. Це забезпечує ефективне зберігання та управління даними сеансу в розподіленому середовищі.

Масштабовані сеанси за допомогою Laravel та Kubernetes

Використовуючи спорідненість сеансів та розподілене сховище сеансів, ваш додаток Laravel може зберігати та зберігати дані сесії, до яких мають доступ усі екземпляри вашого застосунку. Потім ви можете масштабувати свою програму, гарантуючи, що всі користувачі зберігають дані про свої сеанси незалежно від того, який екземпляр вашого додатка обробляє їхній запит. У середовищі Kubernetes, де поди можуть бути ефемерними, а запити користувачів можуть бути спрямовані на будь-який под, ці опції є важливими для підтримки узгодженості сесій користувача.

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

Спробуйте Scout APM вже сьогодні!

Comments

No comments yet
Yurij Finiv

Yurij Finiv

Full stack

Про мене

Professional Fullstack Developer with extensive experience in website and desktop application development. Proficient in a wide range of tools and technologies, including Bootstrap, Tailwind, HTML5, CSS3, PUG, JavaScript, Alpine.js, jQuery, PHP, MODX, and Node.js. Skilled in website development using Symfony, MODX, and Laravel. Experience: Contributed to the development and translation of MODX3 i...

Про автора CrazyBoy49z
WORK EXPERIENCE
Контакти
Ukraine, Lutsk
+380979856297