세션 정보
웹 서비스를 개발할 때 세션 정보를 활용하는 방식은 다음과 같다.
- 로그인 유지: 서버 접근시 로그인 반복을 방지하기 위해 app을 개발할 때 로그인 유지기능을 구현해야 한다. 로그인을 한 이후에 사용자에 대한 인증정보를 세션에 넣어 사용자에게 보내주면 해당 세션 정보로 서버에 접근한다. 서버는 이를 확인하여 로그인 없이 바로 서비스를 사용 가능하게 한다.
- 환경 설정 유지: 언어, 테마, 시간 설정
- 임시 저장 기능: 사용자 데이터를 자동으로 저장. 예시) 작성 중인 글
여기서 app이 이중화 되어있는 시스템에서는 어떻게 세션을 관리하는 서비스를 만들까?
사용자가 처음 로그인 하면 APP-1에 트래픽이 전달되어 인증을 받고 세션 정보가 만들어진다.
로그인 이후 포탈 정보를 조회할 때 APP-2로 트래픽이 전달될 수 있다. 이 때 APP-2에서 로그인을 요구하면 서비스 이용이 불편하다. 이 때 세션 정보를 다음과 같은 방식들로 관리할 수 있다.
- 쿠키 사용: 브라우저에 세션 정보 보관. BUT 보안상 좋지 않다.
- 스티키 세션: 사용자 별로 같은 서버로 트래픽을 전송한다. 로그인할 때 APP-1에서 했다면 로그아웃 전까지 계속 APP-1로 트래픽을 전달한다. BUT 서버 장애시 문제 발생, 트래픽 분배가 비효율적이다.
- 세션 복제: 세션 변경시 내용 공유. BUT 주기적인 동기화로 인해 서버, 네트워크에 부하가 발생한다.
- 세션 저장소: Redis 같은 메모리 캐시 시스템에 저장. 많이 사용되는 방식이다. MSA 아키텍처에서 보안 처리 강화가 가능하고 app 장애에 영향이 없다. 성능이 좋고 app 확장에도 용이하다.
세션 어피니티 (Session Affinity)
sessionAffinity: ClientIP
sessionAffinityConfig:
clientIP:
timeoutSeconds: 600
쿠버네티스 서비스에 sessionAffinity 설정할 수 있다. ClientIP를 추가하면 스티키 세션이 적용된다.
동일한 client ip에 대해 같은 pod를 호출하고, timeout을 두어 10분동안 동일한 파드로 트래픽 유지가 가능하다.
트래픽 폴리쉬(Traffic Policy)
type: ClusterIP
internalTrafficPolicy: Local | Cluster
ClusterIP 서비스의 경우 internalTrafficPolicy 를 사용하고 설정값은 Local, Cluster 2가지가 존재한다.
Cluster인 경우 대상 파드가 어느 노드에 있건 상관없이 클러스터 내에 있다면 호출이 잘 된다.
Local인 폴리시에 호출하면 같은 워커 노드에서만 통신을 할 수 있다.
굳이 폴리쉬를 Local로 해야하나요? → portal과 core를 항상 같은 워커노드에 올라가게 설정할 수 있음(PodAffinity). 워커노드간 트래픽 감소 효과. 전체적인 네트워크 성능 향상할 수 있음.
실무에서는 실제로 포탈 하나에 10개 이상의 파드가 연결되어 있기 때문에 특정 관계에 있는 어플리케이션 끼리 같은 워커노드에 넣는게 불가능할 수 있음. 스케일링도 고려해야 한다. 따라서 노드 스케쥴링에 불리, 워커노드 자원을 골고루 사용 못할 수 있음.
type: NodePort, LoadBalancer
externalTrafficPolicy: Local | Cluster
노드포트나 로드밸런서를 쓸 때는 externalTrafficPolicy를 써야한다. 외부에서 들어오는 통신과 내부 통신은 트래픽 라우팅에 대한 방식이 다르기 때문이다. 설정값은 클러스터와 로컬로 동일하다.
로드밸런서는 워커노드의 모든 노드 포트로 골고루 트래픽을 분산시키는 중.
externalTrafficPolicy가 Cluster일 때는 어떤 노드로 트래픽이 들어오던간에 실제 파드가 있는 워커노드로 트래픽이 이동한 다음 포탈 파드로 호출이 된다.
하지만 local인 경우 트래픽이 워커노드 2로 들어왔을 때는 서비스를 찾을 수 없다는 에러가 발생한다. 워커 노드 2에는 portal 파드가 존재하지 않기 때문이다.
이렇게 local로 설정하는 경우가 별로 없을 것 같다.
하지만 nginx의 경우 서비스 설정 후 파드 설치 시 Daemonset이라는 컨트롤러를 사용한다. 이 컨트롤러는 모든 워커노드의 파드를 딱 하나씩 만들어주는 역할. nginx가 설치되기 때문에 로드밸런서에서 어떤 워커노드로 트래픽이 들어오건 에러는 발생하지 않음. helm 설치 시 deployment, daemonset 선택 옵션이 존재한다.
deployment로 설치하면 트래픽이 nginx 파드가 존재하지 않는 워커 노드로 들어오면 다른 워커노드로 트래픽을 보내고, 또 없으면 다른 노드로 이동한다. 따라서 워커 노드간 트래픽 이동이 많은 문제가 있음.
이런 케이스를 위해 서비스를 local로 externalTrafficPolicy를 설정하고 daemonset으로 설치하기도 한다.
결론은 로드 밸런서를 쓸 경우에는 externalTrafficPolicy를 local로, daemonset으로 설치하면 트래픽 효율이 좋아짐.