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 을 같이 썼을까요?
저는 왜 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 를 줄일 수 있습니다. 네트워크도 그만큼 작게 타겠죠?
- [Redis Session Cluster 이점]
쿠버네티스 환경에서 Kafka 와 Spring-boot, Java version 호환성
쿠버네티스 환경에서 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
EC2 Public IP vs Elastic IP
- Public IP:
- 임시적: Public IP는 EC2 인스턴스가 시작될 때 할당되고, 인스턴스가 중지되거나 종료될 때 해제됩니다. 인스턴스를 다시 시작하면 새로운 Public IP가 할당됩니다.
- 유동적: 인스턴스 재시작 시마다 변경되므로, 고정 IP 주소가 필요한 용도에는 적합하지 않습니다.
- Elastic IP (탄력적 IP):
- 고정적: Elastic IP는 사용자가 할당 및 해제할 수 있는 AWS의 고정 IPv4 주소입니다. 한 번 할당하면, 사용자가 명시적으로 해제하기 전까지 그 주소가 유지됩니다.
- 재사용 가능: 인스턴스에 연결해제 후 다른 인스턴스에 연결할 수 있습니다.
K8S Grafana
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.19
- Reference : https://cert-manager.io/docs/installation/kubectl/
- 설치
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.13.2/cert-manager.yaml
- 확인
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.title
은on.pull_request
에서만 유효합니다. 현재는 workflow 가 push 에 의해 트리거되고 있기때문에 PR_TITLE 을 사용할 수 없었습니다.
etc
- 현재 Auto-scaling group 으로 평균 cpu 사용량이 70% 가 넘어가면, 새로운 인스턴스를 생성하고, 기존 인스턴스를 제거하는 방식으로 스케일 아웃을 쉽게 구현하였습니다.
- 이 부분이 EKS 노드 그룹과 연동되어 최소/최대 크기를 설정할 수 있습니다.
- 보안 정책때문에 Ingress 는 같은 네임스페이스 내부 서비스만 호출할 수 있음
- 우회하려면 CNAME 사용
Git 이슈 정리
- 쿠버네티스 파드 리소스 모니터링과 OOMKiled
- Git Actions Job 간 변수 공유방법
- Git Actions 슬랙 알람
- ECR 토큰 리프레시 필요성
- 현재 구현된 기존 싱글머신 배포방식 설명 및 한계점