Skip to main content Link Menu Expand (external link) Document Search Copy Copied

Spring Cloud Gateway

SSL 인증서 적용 방법

  • sudo openssl pkcs12 -export -in fullchain.pem -inkey privkey.pem -out keystore.p12 -name ttp -CAfile chain.pem -caname root

fastAPI def 와 async def 차이

  • def 로 api 요청 받을 시, fastAPI 는 새로운 스레드를 생성 및 실행
  • async def 로 api 요청 받을 시, fastAPI 는 워커 스레드 풀 내에서 실행

저는 왜 JWT 와 Redis Session Cluster 을 같이 썼을까요?

  • 첫번째 문제점
    • Session 인증의 문제점은 동일 서버 스케일 아웃 시, 로그인한 사용자가 다른 서버로 요청을 보낼 경우, 로그인이 풀리는 문제가 발생합니다.
    • RDB CP를 계속 소모합니다. 동시접속자가 많을 수록 더 많은 RDB 연결을 소모합니다.
  • 해결책 - 토큰 기반 인증
    • 토큰은 서버에 저장하지 않고, 클라이언트에 저장합니다. 이러면 DB Connection 을 줄일 수 있습니다.
    • 서버 스케일 아웃 시, 동일 서버에 로그인한 사용자가 다른 서버로 요청을 보내도 로그인이 풀리지 않도록 할 수 있습니다.
  • 두번째 문제점
    • 토큰은 클라이언트에 저장되기 때문에, 클라이언트가 토큰을 탈취당하면, 토큰을 사용하여 인증이 가능합니다.
    • 유저가 중복으로 로그인이 가능합니다.
  • 해결책 - Redis Session Cluster
    • Key 로 유저고유 식별번호를 설정한다면 중복 유저 로그인을 방지할 수 있습니다.
    • 비정상 유저 강제 로그아웃이 가능합니다.
  • 이런 질문이 있을 수 있습니다
    • JWT 없이도 Redis Session Cluster 만 사용하면 되지 않나? 왜 JWT 를 굳이 추가했나요?
  • JWT 를 사용하는 이유는 다음과 같습니다
    • accessToken, refreshToken 을 사용하여 refreshToken 을 Redis 에 저장한다면 accessToken 만료기간전까지는 Redis 에 접속하지 않아도 된다(하지만, accessToken 만료기간이 지나면, Redis 에 접속하여 refreshToken 을 확인해야한다).

즉, Redis Session Cluster 의 R/W 를 줄일 수 있습니다.

  • JWT 와 Redis Session Cluster 을 함께 사용하면 얻는 이점
    • [Redis Session Cluster 이점]
      • 중복 유저 로그인 방지(만약 유저 고유넘버를 key 로 저장한다면 가능)
      • 특정 유저 강제 로그아웃 가능(유저가 비정상적인 행동 수행 시, 서버 측에서 퇴실시킬 수 있습니다)
    • [JWT 이점]
      • Redis Session Cluster 의 R/W 를 줄일 수 있습니다. 네트워크도 그만큼 작게 타겠죠?

쿠버네티스 환경에서 Kafka 와 Spring-boot, Java version 호환성

  • Kubernetes 환경에서 호환불가능
    • spring-boot:3.0.5
    • kafka-clients:3.3.2
    • openjdk:17-alpine
  • Kubernetes 환경에서 가능
    • spring-boot:3.0.5
    • kafka-clients:3.3.2
    • amazoncorretto:17-alpine3.16-jdk

      쿠버네티스 환경에서 Java 내장 OpenTelemetry 버전 호환성 문제가 존재했습니다.

K8S RollOut

  • revision 확인

kubectl rollout history deployment/chatting-server-deployment

deployment.apps/chatting-server-deployment 
REVISION  CHANGE-CAUSE
2         <none>
3         <none>
  • revision 상세 체크

kubectl rollout history deployment/chatting-server-deployment --revision=2 -o yaml

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  annotations:
    deployment.kubernetes.io/desired-replicas: "1"
    deployment.kubernetes.io/max-replicas: "2"
    deployment.kubernetes.io/revision: "2"
  creationTimestamp: "2023-12-07T05:48:50Z" # 확인하기 좋음
  generation: 2
  labels:
    app: chatting-server-service
    pod-template-hash: 5c4d8f6b68
  name: chatting-server-deployment-5c4d8f6b68
  namespace: default
  ownerReferences:
  - apiVersion: apps/v1
    blockOwnerDeletion: true
    controller: true
    kind: Deployment
    name: chatting-server-deployment
    uid: cb6f9f6a-c269-465b-b1b2-58968c61cbe8
  resourceVersion: "847982"
  uid: b6390071-ae86-406d-b79e-da372ee615ae
spec: # 여기서 imagePull 시 태그 확인가능
  ...
status:
  observedGeneration: 2
  replicas: 0
  • revision rollout 되돌리기
    gyuminhwangbo@Gyuminui-MacBookPro onlychat % kubectl rollout undo deployment/chatting-server-deployment      
    deployment.apps/chatting-server-deployment rolled back
    

EC2 Public IP vs Elastic IP

  • Public IP:
    • 임시적: Public IP는 EC2 인스턴스가 시작될 때 할당되고, 인스턴스가 중지되거나 종료될 때 해제됩니다. 인스턴스를 다시 시작하면 새로운 Public IP가 할당됩니다.
    • 유동적: 인스턴스 재시작 시마다 변경되므로, 고정 IP 주소가 필요한 용도에는 적합하지 않습니다.
  • Elastic IP (탄력적 IP):
    • 고정적: Elastic IP는 사용자가 할당 및 해제할 수 있는 AWS의 고정 IPv4 주소입니다. 한 번 할당하면, 사용자가 명시적으로 해제하기 전까지 그 주소가 유지됩니다.
    • 재사용 가능: 인스턴스에 연결해제 후 다른 인스턴스에 연결할 수 있습니다.

K8S Grafana

  • Helm K8S configuration Repo 설치
curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash -s -- --version v3.2.2
  • monitoring 에 프로메테우스 및 grafana 추가
kubectl create namespace monitoring
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
helm install prometheus prometheus-community/kube-prometheus-stack --namespace monitoring -f prometheus-config.yaml
helm update prometheus prometheus-community/kube-prometheus-stack --namespace monitoring -f prometheus-config.yaml

Grafana IngressController 연결

K8S cert-manager

  1. 설치 kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.13.2/cert-manager.yaml
  2. 확인 kubectl get pods --namespace cert-manager
  gyuminhwangbo@Gyuminui-MacBookPro onlychat % kubectl get pods --namespace cert-manager
  NAME                                      READY   STATUS    RESTARTS   AGE
  cert-manager-7d75f47cc5-8twbg             1/1     Running   0          19s
  cert-manager-cainjector-c778d44d8-5hzf9   1/1     Running   0          19s
  cert-manager-webhook-55d76f97bb-fpk6b     1/1     Running   0          19s

Git Actions

  • github.event.pull_request.titleon.pull_request 에서만 유효합니다. 현재는 workflow 가 push 에 의해 트리거되고 있기때문에 PR_TITLE 을 사용할 수 없었습니다.

etc

  • 현재 Auto-scaling group 으로 평균 cpu 사용량이 70% 가 넘어가면, 새로운 인스턴스를 생성하고, 기존 인스턴스를 제거하는 방식으로 스케일 아웃을 쉽게 구현하였습니다.
    • 이 부분이 EKS 노드 그룹과 연동되어 최소/최대 크기를 설정할 수 있습니다.
  • 보안 정책때문에 Ingress 는 같은 네임스페이스 내부 서비스만 호출할 수 있음
    • 우회하려면 CNAME 사용

Git 이슈 정리

EC2 쿠버네티스 External IP 노출