[DevOps] ConfigMap, Secret

·2025년 2월 17일

쿠버네티스

목록 보기
7/7
post-thumbnail

기존에 사용했던 백엔드(Spring) 서버에서 환경변수를 등록해서 사용하는 법을 알아보자.

1. API 작성

@RestController
public class AppController {
    @Value("${MY_ACCOUNT:default}")
    private String myAccount;

    @Value("${MY_PASSWORD:default}")
    private String myPassword;

    @GetMapping("/env")
    public String env() {
        return "MY_ACCOUNT: " + myAccount + ", MY_PASSWORD: " + myPassword;
    }
}

2. 매니페스트 파일 작성

  • spring-deployment.yaml
apiVersion: apps/v1
kind: Deployment

# Deployment 기본 정보
metadata:
  name: spring-deployment # Deployment 이름

# Deployment 세부 정보
spec:
  replicas: 3 # 생성할 Pod 개수
  selector:
    matchLabels:
      app: backend-app # 아래에서 정의한 Pod 중 'app: backend-app' 라벨을 가진 Pod'

  # 배포할 Pod 정의
  template:
    metadata:
      labels: # 레이블
        app: backend-app
    spec:
      containers:
        - name: spring-container # 컨테이너 이름
          image: spring-server # 컨테이너 이미지
          imagePullPolicy: IfNotPresent # 로컬에서 이미지를 먼저 가져온다. 이미지가 없을 때만 pull
          ports:
            - containerPort: 8080 # 컨테이너에서 사용할 포트를 명시적으로 작성
          env:
            - name: MY_ACCOUNT
              value: "user"
            - name: MY_PASSWORD
              value: "password"
  • spring-service.yaml
apiVersion: v1
kind: Service

# Service 기본 정보
metadata:
    name: spring-service # Service 이름

# Service 세부 정보
spec:
  type: NodePort # Service의 종류
  selector:
    app: backend-app # 실행되고 있는 Pod 중 'app: backend-app' 라벨을 가진 Pod와 연결
  ports:
    - protocol: TCP # TCP 프로토콜 사용
      port: 8080 # 쿠버네티스 내부에서 Service에 접속하기 위한 포트 번호
      targetPort: 8080 # 매핑하기 위한 Pod 포트 번호
      nodePort: 30000 # 외부에서 접근할 포트 (30000~32767 사이) - 쿠버네티스가 예약한 포트 범위

3. Docker 빌드 후 매니페스트 파일 실행

./gradlew clean build # 프로젝트 빌드

docker build -t spring-server .

kubectl apply -f spring-deployment.yaml

kubectl apply -f spring-service.yaml

4. 환경변수 적용 확인

localhost:30000/env 접속

5. 파드 내부에서 확인하는 방법

kubectl get pods # 파드명 확인하기
kubectl exec -it [파드명] -- bash # 파드 내부로 접속하기
env # 환경변수 조회


컨피그맵(ConfigMap)

✅ 컨피그맵(ConfigMap) 이란?

Spring Boot에서는 설정값을 application.yml으로 분리해서 관리하고, Next.js에서도 설정값을 .env 파일로 분리해서 관리한다.
별도의 파일로 분리함으로써 유지보수가 편리해지고, 개발, 테스트, 프로덕션과 같은 환경 분리가 편해진다.
쿠버네티스도 환경 변수를 관리하는 오브젝트가 따로 존재한다. 그것이 바로 컨피그맵(ConfigMap)이다.

기존 문제점

위에서 디플로이먼트 내용과 환경변수 내용이 같은파일에 작성했다.
이렇게 환경변수를 디플로이먼트 내부에 작성하면 다른 환경에서 서버를 실행할 때 유연하게 설정변경이 안된다.

✅ 컨피그맵(ConfigMap)으로 환경변수 분리

1. ConfigMap 매니페스트 파일 생성

  • spring-config.yaml
apiVersion: v1
kind: ConfigMap

# ConfigMap 기본 정보
metadata:
    name: spring-config # ConfigMap 이름

# ConfigMap 세부 정보 (key-value 형태로 데이터를 저장)
data:
  my-account: "configmap-user" # ConfigMap 적용 확인을 위해 다르게 작성
  my-password: "configmap-password"

2. Deployment 매니페스트 파일 수정

apiVersion: apps/v1
kind: Deployment

# Deployment 기본 정보
metadata:
  name: spring-deployment # Deployment 이름

# Deployment 세부 정보
spec:
  replicas: 3 # 생성할 Pod 개수
  selector:
    matchLabels:
      app: backend-app # 아래에서 정의한 Pod 중 'app: backend-app' 라벨을 가진 Pod'

  # 배포할 Pod 정의
  template:
    metadata:
      labels: # 레이블
        app: backend-app
    spec:
      containers:
        - name: spring-container # 컨테이너 이름
          image: spring-server # 컨테이너 이미지
          imagePullPolicy: IfNotPresent # 로컬에서 이미지를 먼저 가져온다. 이미지가 없을 때만 pull
          ports:
            - containerPort: 8080 # 컨테이너에서 사용할 포트를 명시적으로 작성
          env:
            - name: MY_ACCOUNT
              valueFrom:
                configMapKeyRef:
                  name: spring-config # 참조할 ConfigMap 이름
                  key: my-account # 참조할 ConfigMap key
            - name: MY_PASSWORD
              valueFrom:
                configMapKeyRef:
                  name: spring-config
                  key: my-password

3. 매니페스트 파일 반영

kubectl apply -f spring-config.yaml
kubectl apply -f spring-deployment.yaml

# kubectl rollout restart deployment [디플로이먼트명]
kubectl rollout restart deployment spring-deployment # Deployment 재시작

4. 반영 됐는지 확인


시크릿(Secret)

✅ 시크릿(Secret)이란?

  • 시크릿(Secret)은 컨피그맵(ConfigMap)과 비슷하게 환경변수를 분리해서 관리하는 오브젝트이다. 차이점은 시크릿은 비밀번호와 같이 보안적으로 민감한 값을 관리하기 위한 오브젝트이다.

✅ 시크릿(Secret)을 활용해 '민감한 값' 분리

위에서 설정한 값 중 아이디와 비밀번호중 비밀번호를 시크릿으로 분리해보겠다.

1. 매니페스트 수정 및 생성

  • 수정 (spring-config.yaml)
apiVersion: v1
kind: ConfigMap

# ConfigMap 기본 정보
metadata:
  name: spring-config # ConfigMap 이름

# ConfigMap 세부 정보 (key-value 형태로 데이터를 저장)
data:
  my-account: "configmap-user"
  # my-password: "configmap-password" # 주석처리
  • 생성 (spring-secret.yaml)
apiVersion: v1
kind: Secret

# Secret 기본 정보
metadata:
  name: spring-secret # Secret 이름

# Secret 세부 정보 (key-value 형태로 데이터를 저장)
stringData:
  my-password: "secret-password"
  • 수정 (spring-deployment.yaml)
apiVersion: apps/v1
kind: Deployment

# Deployment 기본 정보
metadata:
  name: spring-deployment # Deployment 이름

# Deployment 세부 정보
spec:
  replicas: 3 # 생성할 Pod 개수
  selector:
    matchLabels:
      app: backend-app # 아래에서 정의한 Pod 중 'app: backend-app' 라벨을 가진 Pod'

  # 배포할 Pod 정의
  template:
    metadata:
      labels: # 레이블
        app: backend-app
    spec:
      containers:
        - name: spring-container # 컨테이너 이름
          image: spring-server # 컨테이너 이미지
          imagePullPolicy: IfNotPresent # 로컬에서 이미지를 먼저 가져온다. 이미지가 없을 때만 pull
          ports:
            - containerPort: 8080 # 컨테이너에서 사용할 포트를 명시적으로 작성
          env:
            - name: MY_ACCOUNT
              valueFrom:
                configMapKeyRef:
                  name: spring-config # 참조할 ConfigMap 이름
                  key: my-account # 참조할 ConfigMap key
            - name: MY_PASSWORD # 수정
              valueFrom:
                secretKeyRef:
                  name: spring-secret # 참조할 Secret 이름
                  key: my-password # 참조할 Secret key

2. 매니페스트 파일 반영

kubectl apply -f spring-secret.yaml
kubectl apply -f spring-config.yaml
kubectl apply -f spring-deployment.yaml
kubectl rollout restart deployment spring-deployment

3. 확인

0개의 댓글