• Czas czytania ~10 min
  • 14.11.2023

Kubernetes to doskonała opcja do skalowania aplikacji Laravel. Kubernetes oferuje skalowalność, wysoką dostępność, odnajdywanie usług i równoważenie obciążenia. W szczególności w przypadku wdrożeń Laravel, Kubernetes może pomóc w bezstanowym skalowaniu poziomym, łatwym zarządzaniu przetwarzaniem w tle i elastyczności pamięci masowej.

Ale może to mieć swoją cenę. Efemeryczność zasobników Kubernetes i sposób ich skalowania utrudnia zarządzanie sesjami w Laravel. Użycie domyślnego sterownika sesji plików może prowadzić do utraty danych, jeśli zasobnik zostanie ponownie uruchomiony lub zastąpiony, więc deweloperzy muszą przejść na inny mechanizm.

W tym miejscu chcemy przeprowadzić Cię przez niektóre z problemów związanych z zarządzaniem sesjami Laravel, których doświadczysz podczas przechodzenia do wdrożenia Kubernetes. Dobrą wiadomością jest to, że wszystkie można naprawić dzięki zrozumieniu wewnętrznego działania konteneryzacji.

Ten artykuł jest sponsorowany przez Scout APM.

Korzyści z używania Kubernetesa z Laravelem

Zacznijmy od tego, dlaczego warto to zrobić. Aplikacje Laravel można wdrażać na wiele różnych sposobów, więc po co wybierać taką, która od razu przyprawi Cię o ból głowy podczas sesji? Cóż, podstawowe korzyści płynące z wdrożenia aplikacji Laravel na Kubernetes to:

  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.

Jednak chociaż Kubernetes oferuje te korzyści, wprowadza również złożoność, a zarządzanie sesjami jest ofiarą tej złożoności. Jedną z powyższych korzyści jest główny winowajca powodujący problemy z zarządzaniem sesjami — bezstanowe skalowanie poziome. Powoduje to problemy z zarządzaniem sesjami poprzez wprowadzenie wielu replik aplikacji Laravel, które mogą z natury nie współdzielić stanu sesji.

W tradycyjnych konfiguracjach z jednym serwerem dane sesji użytkownika są zwykle przechowywane lokalnie, dzięki czemu są natychmiast dostępne dla kolejnych żądań od tego użytkownika. Na platformie Kubernetes, gdy wiele replik obsługuje żądania, użytkownik może być obsługiwany przez inną replikę z każdym żądaniem.

Wyzwania związane z zarządzaniem sesjami związane z Laravelem i Kubernetesem Tak więc wyzwanie związane z zarządzaniem sesjami wynika z trzech czynników integralnych dla działania Kubernetesa

.

Po pierwsze, istnieje potrzeba trwałości sesji. Gdy sesje są przechowywane lokalnie w zasobniku, żądanie, które przechodzi do innej repliki, nie będzie miało dostępu do danych poprzedniej sesji, co prowadzi do przerwania środowiska użytkownika. Ta niespójność może prowadzić do problemów, takich jak losowe wylogowywanie użytkowników lub potrzeba pomocy w zachowaniu stanu aplikacji.

Drugim jest efemeryczna natura strąków. Zasobniki na platformie Kubernetes można zakończyć i wymienić w dowolnym momencie, zwłaszcza jeśli staną się w złej kondycji lub podczas aktualizacji. Jeśli sesja jest przechowywana lokalnie w zasobniku, a ten zasobnik zostanie zakończony, dane sesji zostaną utracone, co wpłynie na środowisko użytkownika.

Po trzecie, chociaż platforma Kubernetes zapewnia równoważenie obciążenia między zasobnikami, bez konfiguracji koligacji sesji kolejne żądania od tego samego użytkownika mogą trafić do różnych replik. Bez scentralizowanego magazynu sesji może to prowadzić do nieprzewidywalnego zachowania.

Wszystko to prowadzi do obciążenia związanego z synchronizacją danych i zwiększonego opóźnienia, ponieważ próba zarządzania sesjami za pomocą synchronizacji lub innych metod innych niż centralne może wprowadzić opóźnienie w żądaniach. Pogarsza to wrażenia użytkownika, zwłaszcza w aplikacjach, w których czas reakcji ma kluczowe znaczenie.

Aby sprostać tym wyzwaniom, programiści Laravel wdrażający Kubernetes mają dwie opcje:

  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.

Przyjrzyjmy się każdej opcji i temu, jak współpracują z Laravel.

Sesje lepkie

Koligacja sesji, znana również jako "sesje trwałe", może mieć kluczowe znaczenie w scenariuszach, w których wdrażane są aplikacje stanowe lub obciążenia, a wszystkie żądania od określonego klienta mają zawsze trafiać do tego samego zasobnika. Na platformie Kubernetes można to osiągnąć przy użyciu koligacji sesji usługi.

W tradycyjnych architekturach monolitycznych aplikacje są zwykle uruchamiane na jednym serwerze, na którym dane sesji są przechowywane lokalnie. Ten model zapewnia, że wszystkie kolejne żądania od określonego użytkownika zawsze mają dostęp do danych sesji tego użytkownika. Jednak w środowisku orkiestracji kontenerów, takim jak Kubernetes, aplikacja może działać w wielu zasobnikach rozmieszczonych w różnych węzłach. W tym przypadku nie ma nieodłącznej gwarancji, że kolejne żądania użytkownika trafią za każdym razem do tego samego zasobnika.

W tym miejscu do gry wchodzą lepkie sesje. W przypadku określonych aplikacji żądania użytkownika muszą zawsze znajdować się w tym samym zasobniku, aby zachować stan aplikacji, zapewnić spójne środowisko użytkownika lub efektywnie wykorzystać lokalne buforowanie.

Platforma Kubernetes udostępnia koncepcję koligacji sesji, umożliwiając określenie, że wszystkie żądania od określonego klienta powinny być kierowane do tego samego zasobnika. Osiąga się to za pomocą plików cookie lub IP.

Po skonfigurowaniu koligacji sesji na podstawie adresu IP klienta platforma Kubernetes sprawdza źródłowy adres IP żądania przychodzącego i kieruje go do tego samego zasobnika, co poprzednie żądania z tego adresu IP. Jeśli koligacja sesji jest oparta na plikach cookie, Kubernetes zapewni, że wszystkie żądania z określonym plikiem cookie są kierowane do tego samego zasobnika.

W definicji YAML usługi należy określić typ koligacji sesji. Na przykład:

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

W powyższej konfiguracji pole jest ustawione sessionAffinity na ClientIP, co oznacza, że usługa Kubernetes użyje adresu IP klienta, aby zapewnić, że wszystkie żądania z tego adresu IP będą kierowane do tego samego zasobnika.

Jeśli chcesz mieć większą kontrolę nad koligacją sesji, możesz użyć sessionAffinityConfig. Na przykład, aby ustawić limit czasu dla koligacji sesji:

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

Chociaż sesje przyklejone mogą rozwiązać niektóre problemy, tylko czasami są odpowiednim dopasowaniem. Jeśli zasobnik obsługujący sesję przytrzymania przeciąży lub przestanie działać, użytkownik może napotkać problemy z wydajnością lub zakłócenia.

Poleganie wyłącznie na sesjach sticky może również prowadzić do nierównomiernego rozkładu ruchu między zasobnikami, zwłaszcza jeśli niektórzy klienci wysyłają częstsze lub intensywniejsze żądania wymagające dużej ilości zasobów. W wielu przypadkach użycia scentralizowany magazyn sesji, taki jak Redis, może być bardziej skalowalny i odporny na uszkodzenia niż sesje trwałe. Przyjrzyjmy się więc tej opcji.

Rozproszone magazyny sesji z Redis Rozproszony magazyn sesji, taki jak Redis

w Laravel, umożliwia współdzielenie danych sesji w wielu instancjach aplikacji. Jest to szczególnie przydatne w skalowalnych środowiskach, takich jak Kubernetes, gdzie aplikacja może działać w wielu zasobnikach, a każdy z tych zasobników może obsługiwać żądania użytkowników.

Redis jest idealnym wyborem ze względu na:

  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 ma również pewne zalety w porównaniu z lepkimi sesjami. Ponieważ każda instancja może obsługiwać żądania, ruch jest bardziej równomiernie rozłożony we wszystkich zasobnikach. Jeśli zasobnik zakończy się niepowodzeniem, sesje użytkowników nie zostaną utracone. Inny zasobnik może odebrać żądanie i pobrać dane sesji z usługi Redis. Wraz ze wzrostem ruchu można skalować aplikacje i wystąpienia Redis niezależnie w zależności od potrzeb.

Przejdźmy przez kroki ustawiania Redis jako sterownika sesji w Laravel. Najpierw musisz zainstalować wymagany pakiet:Następnie możesz zaktualizować plik Laravel .env, aby wskazywał na Redis do zarządzania sesjami:W Laravel, musisz zaktualizować swoją config/session.php, aby użyć sterownika sesji z pliku .env:

composer require predis/predis

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

Następnie upewnij się, że konfiguracja Redis w config/database.php wygląda tak:

'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),
    ],
],

Następnie będziesz potrzebować tabeli do przechowywania sesji. Laravel udostępnia polecenie do wygenerowania tej tabeli:

php artisan session:table

Spowoduje to utworzenie pliku migracji. Uruchom migrację, aby utworzyć tabelę sesji:

php artisan migrate

Po powyższych konfiguracjach Laravel będzie automatycznie obsługiwał sesje przy użyciu Redis bez konieczności stosowania określonego kodu w Twojej aplikacji. Na przykład, gdy ustawisz zmienną sesji:

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

Ta wartość będzie przechowywana w Redis. Aby go odzyskać:

$value = session('key');

Kiedy wywołujesz takie funkcje, Laravel automatycznie używa Redis jako zaplecza do zarządzania danymi sesji.

Aby wdrożyć usługę Redis na platformie Kubernetes, należy użyć programu Helm do wdrożenia wystąpienia usługi Redis w klastrze 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

Pamiętaj, aby zanotować hasło do wystąpienia usługi Redis dostarczonego przez program Helm podczas instalacji. Następnie utwórz manifest usługi Kubernetes. Nazwijmy go redis-service.yaml:Możesz zastosować manifest usługi Kubernetes, aby utworzyć usługę:Następnie sprawdź, czy usługa jest uruchomiona:Na koniec wskaż Laravelowi usługę Kubernetes Redis, aktualizując plik .env lub konfigurację Laravel, aby korzystać z usługi Redis utworzonej na 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 jest hostem, ponieważ jest to nazwa usługi Kubernetes, a wewnętrzny system DNS platformy Kubernetes rozpozna tę nazwę jako odpowiedni adres IP dla usługi.

Gratulacje, zintegrowałeś Redis z Laravelem i upewniłeś się, że aplikacja Laravel komunikuje się z instancją Redis wdrożoną na Kubernetes. Zapewnia to efektywne przechowywanie danych sesji i zarządzanie nimi w środowisku rozproszonym.

Skalowalne sesje z Laravelem i Kubernetesem

Korzystając z koligacji sesji i rozproszonego magazynu sesji, aplikacja Laravel może przechowywać i utrwalać dane sesji, do których mają dostęp wszystkie wystąpienia aplikacji. Następnie możesz skalować aplikację, zapewniając, że wszyscy użytkownicy zachowują dane sesji niezależnie od tego, które wystąpienie aplikacji obsługuje ich żądanie. W środowisku Kubernetes, w którym zasobniki mogą być efemeryczne, a żądania użytkowników mogą być kierowane do dowolnego zasobnika, te opcje są niezbędne do zachowania spójności sesji użytkownika.

Wraz z rozwojem technologii zapewnienie bezproblemowego środowiska użytkownika staje się najważniejsze, zwłaszcza w rozproszonych i skalowalnych środowiskach, takich jak Kubernetes. Wykorzystując nieodłączną zdolność adaptacji Laravel do niezawodności Kubernetes, programiści mogą sprostać wyzwaniom związanym z zarządzaniem sesjami. To połączenie nie tylko zwiększa odporność aplikacji, ale także toruje drogę do przyszłej skalowalności bez uszczerbku dla doświadczenia użytkownika.

Wypróbuj Scout APM już dziś!

Comments

No comments yet
Yurij Finiv

Yurij Finiv

Full stack

O

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...

O autorze CrazyBoy49z
WORK EXPERIENCE
Kontakt
Ukraine, Lutsk
+380979856297