티스토리 뷰

반응형

쿠버네티스 실습: Redis 배포와 NestJS 애플리케이션 연동

앞선 글에서는 StatefulSet으로 PostgreSQL을 배포하고 PVC를 연결하여 데이터 영속성을 확보했습니다.
이번 글에서는 Redis를 쿠버네티스 환경에 배포하고, 이후 NestJS 애플리케이션에서 캐시 레이어로 연동하는 실습을 진행합니다.


1) Redis를 쿠버네티스에 배포하는 이유

  • 메모리 기반 데이터 저장소: 빠른 읽기/쓰기 성능.
  • 캐싱: DB 조회 부담을 줄이고 성능을 높임.
  • 세션 저장소: 로그인 세션, 토큰 관리.
  • Pub/Sub: 실시간 메시징.

NestJS 같은 백엔드 서버에서 Redis를 붙이면 응답 속도 개선과 확장성에 큰 도움이 됩니다.


2) Redis Deployment 작성

redis-deployment.yaml 작성:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis
spec:
  replicas: 1
  selector:
    matchLabels:
      app: redis
  template:
    metadata:
      labels:
        app: redis
    spec:
      containers:
      - name: redis
        image: redis:7
        ports:
        - containerPort: 6379
        resources:
          requests:
            memory: "256Mi"
            cpu: "250m"
          limits:
            memory: "512Mi"
            cpu: "500m"

적용:

kubectl apply -f redis-deployment.yaml

확인:

kubectl get pods -l app=redis

3) Redis Service 작성

redis-service.yaml 작성:

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

적용:

kubectl apply -f redis-service.yaml
kubectl get svc redis

출력 예시:

NAME    TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
redis   ClusterIP   10.96.128.200    <none>        6379/TCP   10s

4) Redis Pod 내부 테스트

반응형

Pod 안에 들어가서 Redis CLI 실행:

kubectl exec -it $(kubectl get pod -l app=redis -o jsonpath='{.items[0].metadata.name}') -- redis-cli

테스트:

set hello "kubernetes redis"
get hello

예상 출력:

"kubernetes redis"

5) NestJS 애플리케이션에서 Redis 연결

NestJS 프로젝트에 Redis 모듈을 설치합니다.

npm install cache-manager ioredis @nestjs/cache-manager

app.module.ts 예시:

import { Module } from '@nestjs/common';
import { CacheModule } from '@nestjs/cache-manager';
import * as redisStore from 'cache-manager-ioredis';

@Module({
  imports: [
    CacheModule.registerAsync({
      useFactory: async () => ({
        store: redisStore,
        host: 'redis',   // 쿠버네티스 서비스 이름
        port: 6379,
        ttl: 60,         // 캐시 유효시간(초)
      }),
    }),
  ],
})
export class AppModule {}

6) NestJS Pod 배포 시 Redis 연결 확인

NestJS 컨테이너가 올라간 뒤, 캐싱 로직을 추가합니다.
예시 컨트롤러(app.controller.ts):

import { Controller, Get, Inject } from '@nestjs/common';
import { CACHE_MANAGER } from '@nestjs/cache-manager';
import { Cache } from 'cache-manager';

@Controller()
export class AppController {
  constructor(@Inject(CACHE_MANAGER) private cacheManager: Cache) {}

  @Get('cache-test')
  async getCache(): Promise<string> {
    const cached = await this.cacheManager.get('greeting');
    if (cached) {
      return `From Cache: ${cached}`;
    }
    await this.cacheManager.set('greeting', 'Hello Redis in Kubernetes', { ttl: 60 });
    return 'Cache Miss, Stored new value!';
  }
}

쿠버네티스에 NestJS Pod를 띄우고 /cache-test 엔드포인트를 호출하면:

  • 첫 호출 → "Cache Miss, Stored new value!"
  • 두 번째 호출 → "From Cache: Hello Redis in Kubernetes"

즉, Redis가 정상적으로 연결된 것을 확인할 수 있습니다.


7) 정리

  • Redis를 Deployment + Service로 쿠버네티스에 배포.
  • Pod 내부에서 redis-cli로 데이터 저장/조회 확인.
  • NestJS 애플리케이션에서 Redis를 캐시 레이어로 붙여 성능 개선.

다음 글에서는 Nginx Ingress Controller와 Nginx Proxy Manager를 붙여 외부에서 도메인으로 접근 가능한 구조를 만들어 보겠습니다. (SSL 적용까지 포함)


 

쿠버네티스,Redis,StatefulApp,캐시서버,NestJS연동,DevOps,Minikube,컨테이너,K8s실습,쿠버네티스서비스

 

 

주요 보완 제안

1. Redis는 단순 Deployment보다는 StatefulSet + PVC 또는 Helm/Operator 활용 추천

  • 배포 방식 참고: 많은 실제 Redis 클러스터 구성은 StatefulSet과 PersistentVolume을 함께 사용하여 각 인스턴스의 데이터 지속성과 고유성을 보장합니다.
  • “All the examples available are showing Redis cluster being deployed as a combination of Kubernetes’ StatefulSets and PersistentVolumes.”
    (Medium, Stack Overflow)
  • StatefulSet의 장점:
    • 안정적인 네트워크 ID와 저장소 연계
    • 순차적인 Pod 생성/스케일링 보장
      (Kubernetes)
  • 실습 대안:
    • 간단한 단일 인스턴스 Redis라면 현재 구성으로도 충분하지만,
    • 고가용성 HA 또는 확장성 연습을 위해 Helm(예: Bitnami Redis)이나 Redis Operator를 활용하는 방법도 안내하면 더욱 완성도 높아집니다.
      (Dragonfly)

2. NestJS와 Redis 연동 시 도입 및 타입 이슈 처리

  • 캐시 연결 방식:
    • @nestjs/cache-manager와 cache-manager-ioredis를 함께 사용하는 경우가 안정적입니다.
      (GitHub)
  • TypeScript 타입 문제:
    • cacheManager.store.getClient() 호출 시 타입 오류 발생 가능. 이를 해결하려면 아래처럼 타입을 정의해 사용하세요:(Stack Overflow)
    • interface RedisCache extends Cache { store: { getClient: () => any; }; } // 사용 예 const redisCache = await this.cacheManager.store.getClient();
  • 사용자 경험 인사이트:
  • “You can try another library. It’s called ‘cache-manager-ioredis-yet’.”
    (Reddit)

3. Redis 기반 캐싱에 TTL (Time-To-Live) 적용 중요성 강조

  • TTL을 지정하지 않으면 캐시 데이터가 무한히 유지되어, 데이터 신선도가 떨어질 수 있습니다.
  • TTL 없이 캐싱할 경우의 문제점과 함께 TTL 설정 방식을 설명하는 것이 좋습니다.
    (JavaScript in Plain English, Medium)
  • 예:
  • await this.cacheManager.set('key', 'value', { ttl: 60 });

보완 정리 (표)

보완 항목 설명

Redis 구성 방식 추천 단순 Deployment 대신 StatefulSet+PVC 또는 Helm/Operator 사용 권장
NestJS Redis 연동 시 타입 문제 cache-manager-ioredis 사용 및 타입 정의 필요
캐시 TTL 설정 강조 TTL을 지정하지 않으면 stale cache 위험

예시 추가 제안

  • StatefulSet 기반 Redis + PVC 예제 추가
  • Helm 설치 명령:(Dragonfly)
  • helm repo add bitnami https://charts.bitnami.com/bitnami helm install my-redis bitnami/redis
  • NestJS 코드에 TTL 설정 예시
  • await this.cacheManager.set('greeting', 'Hello...', { ttl: 30 });
  • TypeScript 타입 처리 예시
  • const client = (this.cacheManager as RedisCache).store.getClient();

 

※ 이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2026/04   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30
글 보관함
반응형