(6) Configmap, Secret 이해하기

2025. 6. 8. 14:01·🌱 인프런/⚓ 쿠버네티스 어나더 클래스 (지상편)

⚓ 쿠버네티스 어나더 클래스 (지상편) - Spring 1, 2 을 듣고 작성하는 복습 블로그 입니다.

 

1. Configmap, Secret 기본 개념

  • Configmap 과 Secret 은 Pod 에 바로 연결
  • 기본적으로 둘 다 데이터를 담을 수 있다.

 

Configmap

Pod 의 환경변수 설정
  • Pod 의 containers > envFrom 과 연결
  • envFrom 은 ConfigMap의 데이터를 Pod 내부의 환경변수로 주입 하는 속성
  • Pod 가 생성되면, env 명령어로 해당 환경변수가 잘 주입되었는지 확인 가능
spring_profiles_active: "dev"
application_role: "ALL"
postgresql_filepath: "/usr/src/myapp/datasource/postgresql-info.yaml"
  • key: value 형식으로 구성
  • 각각의 역할 ⬇️
Key 설명
spring_profiles_active Spring의 환경 설정 값 지정 (예: dev, prod)
application_role 애플리케이션의 역할 지정 (기능 제어용)
postgresql_filepath 외부 환경 설정 파일의 경로 (Secret 연동 등)

 

  • postgresql_filepath는 Secret 데이터로 연결될 파일 경로이며, 이 경로는 Pod의 mountPath 설정에 따라 결정
  • 만약 mountPath 경로를 변경하고 싶다면, 애플리케이션을 다시 빌드하지 않고 ConfigMap만 수정해서 간단하게 처리 가능

 

 

Pod 가 생성 시 동작 흐름

  1. Configmap 의 모든 데이터가 환경변수로 주입
  2. 컨테이너 실행시, 환경변수 값이 명령어에 매핑
  3. App 기동
java -Dspring.profiles.active=${spring_profiles_active} \
     -D... \
     -jar /usr/src/myapp/app.jar

Secret

  • Secret 은 Pod의 volumes 와 연결
  • Volume 은 Pod 와 외부 저장소를 연결하는 속성
  • Secret 을 연결하고 Pod 내부에 접속하면,
    마운트된 경로 안에 Secret 의 stringData 값이 파일로 저장되어 있음을 확인 가능

 

Secret 정의 예시

 # stringData 
 postgresql-info.yaml: |
    driver-class-name: "org.postgresql.Driver"
    url: "jdbc:postgresql://postgresql:5431"
    username: "dev"
    password: "dev123"
    
 # data
 postgresql-info.yaml: >-    
 	ZHJpdmVyLWNsYXNzL.....kZXYiCnBhc3N3b3JkOiAiZGtmaTNuZmFrK2RmajMiCg==
  • postgresql-info.yaml 파일이 만들어지고, 아래 내용들이 저장
  • stringData 는 쓰기 전용 속성
  • 저장되는 값은 Base64 인코딩 값으로 저장되지만, 보안 측면에서 완전한 보호는 아니다 (쉽게 디코딩 가능)

 

Secret 동작 흐름

 

  1. Pod에 mountPath 설정
    • 지정된 경로에 Secret이 마운트됨
  2. Pod 실행 시 Volume이 Secret과 연결됨
    • Secret에 있는 postgresql-info.yaml 파일이 컨테이너 안에 생성됨
  3. 컨테이너 내부에서 파일 접근 가능
    • 생성된 파일 내용은 Base64 디코딩된 원래 입력값
  4. 애플리케이션은 해당 파일을 읽어 DB 설정에 사용
    • 예: DB 연결 정보 (driver, url, username, password) 등

 


동작 확인

1. 입력값 확인 : Configmap 과 Secret 의 data 확인

     1-1. 대시보드

Configmap  Secret
{
     "application_role": "ALL",
     "postgresql_filepath": "/usr/src/myapp/datasource/postgresql-info.yaml",
     "spring_profiles_active": "dev"
}
driver-class-name: "org.postgresql.Driver"
url: "jdbc:postgresql://postgresql:5431"
username: "dev"
password: "dev123"

 

 

     1-2. 명령어로 확인

Configmap Secret
kubectl describe -n anotherclass-123 configmaps api-tester-1231-properties kubectl get -n anotherclass-123 secret api-tester-1231-postgresql -o yaml
Data ====
application_role:
----
ALL
postgresql_filepath:
----
/usr/src/myapp/datasource/postgresql-info.yaml spring_profiles_active:
---- dev
apiVersion: v1
data:
     postgresql-info.yaml: ZHJpdmVyLWNsYXNzLW5hbWU6ICJvcmcucG9zdGdyZXNxbC5Ecml2ZXIiCnVybDogImpkYmM6cG9zdGdyZXNxbDovL3Bvc3RncmVzcWw6NTQzMSIKdXNlcm5hbWU6ICJkZXYiCnBhc3N3b3JkOiAiZGV2MTIzIgo=
     kind: Secret
     metadata:
         creationTimestamp: "2025-05-30T02:40:38Z"
         labels:
             component: backend-server
             instance: api-tester-1231
             managed-by: dashboard
             name: api-tester
             part-of: k8s-anotherclass
             version: 1.0.0
         name: api-tester-1231-postgresql
         namespace: anotherclass-123
         resourceVersion: "82533"
         uid: 54b27805-51a3-48ec-9657-1a4336d4f6d0
     type: Opaque

 

2. 컨테이너 내부에 환경변수로 잘 주입이 됐는지 확인

     2-1. App 이 기동할 때 환경변수가 사용된 명령어 조회 (env)

더보기
API_TESTER_1231_SERVICE_PORT=80
API_TESTER_1231_SERVICE_HOST=10.106.210.22
postgresql_filepath=/usr/src/myapp/datasource/postgresql-info.yaml
LANG=C.UTF-8
API_TESTER_1231_PORT_80_TCP_ADDR=10.106.210.22
HOSTNAME=api-tester-1231-755676484f-gmn88
JAVA_HOME=/usr/java/openjdk-17
API_TESTER_1231_PORT=tcp://10.106.210.22:80
KUBERNETES_PORT_443_TCP_PROTO=tcp
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
JAVA_VERSION=17.0.2
API_TESTER_1231_PORT_80_TCP=tcp://10.106.210.22:80
KUBERNETES_PORT=tcp://10.96.0.1:443
PWD=/usr/src/myapp
HOME=/root
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_PORT_443_TCP_PORT=443
API_TESTER_1231_PORT_80_TCP_PROTO=tcp
spring_profiles_active=dev
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
TERM=xterm
API_TESTER_1231_PORT_80_TCP_PORT=80
application_role=ALL
SHLVL=1
KUBERNETES_SERVICE_PORT=443
PATH=/usr/java/openjdk-17/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
KUBERNETES_SERVICE_HOST=10.96.0.1
_=/usr/bin/env

 

     2-2. Secret 으로 마운팅한 값 확인

# Secret 파일 확인
(1) ls /usr/src/myapp/datasource 
(2) cat /usr/src/myapp/datasource/postgresql-info.yaml
# java 실행 인자 확인
(3) jps -v
(1)postgresql-info.yaml
(2) driver-class-name: "org.postgresql.Driver"
		url: "jdbc:postgresql://postgresql:5431"
		username: "dev"
		password: "dev123"
(3) 1 app.jar -Dspring.profiles.active=${spring_profiles_active} -Dapplication.role=${application_role} -Dpostgresql.filepath=${postgresql_filepath}
42 Jps -Dapplication.home=/usr/java/openjdk-17 -Xms8m -Djdk.module.main=jdk.jcmd

 

3. API 를 날려서 환경변수가 잘 반영됐는지 확인

     3-1. http://192.168.56.30:31231/info → Application 정보 확인 

더보기
[Version] : Api Tester v1.0.0
[Profile] : dev
[Role] : ALL (option: ALL, GET, POST, PUT, DELETE)
[Database]
driver-class-name : org.postgresql.Driver
url : jdbc:postgresql://postgresql:5431
username : dev
password : dev123

 

     3-2. http://192.168.56.30:31231/properties → Application Properties 파일 구성 확인

더보기
[Application profile] : dev
Volume path :/usr/src/myapp/files/dev/

application.yaml : Common properties
---
datasource:
  driver-class-name:
  url:
  username:
  password:
application:
  role: "ALL"
  version: "Api Tester v1.0.0"

postgresql:
  filepath:


application-dev.yaml : Dev properties
---
volume-path:
  persistent-volume-data: "/usr/src/myapp/files/dev/"
  pod-volume-data: "/usr/src/myapp/tmp/"


application-qa.yaml : QA properties
---
volume-path:
  persistent-volume-data: "/usr/src/myapp/files/qa/"
  pod-volume-data: "/usr/src/myapp/tmp/"


application-prod.yaml : Prod properties
---
volume-path:
  persistent-volume-data: "/usr/src/myapp/files/prod/"
  pod-volume-data: "/usr/src/myapp/tmp/"

 

4. 데이터 수정

(Configmap) application_role 을 ALL → GET 으로 변경

(Secret) username 을 dev → test 로 변경

 

5. 환경변수가 잘 반영됐는지 확인

(Configmap)

  • 파드 Exec 에 들어가서 env 명령어 입력
  • 하지만, application_role=ALL 로 환경변수 값이 변경되지 않음

→ 환경변수는 Pod 가 생성될 때 한번만 주입되기 때문에, ConfigMap 의 값을 바꾼다고 변경되지 않음

→ Pod 를 삭제 후 다시 만들어지면 환경변수가 변경된다.

 

 

(Secret)

  • 파드 Exec 에 들어가서 cat /usr/src/myapp/datasource/postgresql-info.yaml 입력
driver-class-name: "org.postgresql.Driver"
url: "jdbc:postgresql://postgresql:5431"
username: "test"
password: "dev123"
  • 값이 변경됨

→ Secret 은 볼륨 마운팅으로 연결해놓았기 때문에

→ App 에서는 이 파일을 5초 간격으로 조회한다.


2. 영역 파괴의 주범 Configmap

출처URL : https://inf.run/k7mF

VM (Kubernetes 전 환경) Kubernetes
[인프라 환경]
  1. 인프라 담당자가 환경별로 서버를 세팅
  2. 환경 별로 JDK 설치
  3. 필요할 때마다 값을 변경하기 위해서 환경변수로 관리 (java_home, volume_path, log_path)
[인프라 환경]
  1. 각 환경마다 (dev, qa, prod) Pod 가 만들어지고, dockerHub에서 같은 이미지를 다운받는다.
  2. 환경마다 다른 값을 주기 위해서 각각 Configmap
  3. 이미지 안에 변수 값을 받아서 실행하는 명령이 존재
[개발 환경 & CI/CD 환경]
  1. JAR package 파일을 VM 환경에 복사
  2. 실행 명령을 직접 날린다
  3. 데브옵스 담당자는 App 에 환경이나 목적에 맞는 변수 넣는다.
  4. 개발자도 환경별로 Properties 파일들을 관리
[개발 환경 & CI/CD 환경]
  1. 스프링으로 개발
  2. Github 로 소스를 커밋
  3. Jenkins 에서 소스를 받아서 파이프라인이 돌아간다.
  4. 소스 빌드와 컨테이너 빌드 과정에서 컨테이너 이미지가 dockerHub 로 올라간다
  5. 컨테이너 빌드 후 개발 환경이 이어서 배포
  6. QA / 운영은 필요할 때 배포 버튼을 눌러서 배포

 

→ VM 에서 각자 담당자들이 관리하는 환경변수들을

→ ConfigMap 으로 이 모든 역할들을 한 번에 처리 가능

 

영역 파괴?

  • 큰 프로젝트로 가면 갈수록 각 분야의 담당자들이 존재
  • 그리고 모두가 쿠버네티스를 다 다룰 줄 아는게 아니다
  • 모든 인프라가 쿠버네티스 위에서 돌아가지도 않는다.

Configmap 이 목적만 보면 간단하지만, 프로젝트 상황에 따라 영역을 넘나들고 정답이 없다. (⇒ 영역파괴의 주범)


3. 이름 때문에 기대가 너무 컸던 Secret

type

✅ type: Opaque (기본값)

  • 의미: '불투명'이라는 뜻이지만 Kubernetes에서는 일반적인 Key-Value 저장용으로 사용됨
  • ConfigMap과 거의 동일한 방식으로 동작
  • 차이점은 민감 정보를 다루기 때문에 **Base64 인코딩된 data**로 저장된다는 점

 

🐳 type: kubernetes.io/dockerconfigjson (구: docker-registry)

  • 사설 이미지 저장소(Private Docker Registry)를 사용할 때 사용
  • data 항목에 docker-username, docker-password, docker-email 등의 정보를 포함시킴
  • Secret을 생성한 후, imagePullSecrets 속성으로 Pod에 연결

 

🔐 type: kubernetes.io/tls

  • TLS 인증서를 저장할 때 사용
  • data에 다음과 같은 키를 포함해야 함:
    • tls.crt: 인증서 파일 내용
    • tls.key: 개인키 내용
  • 주로 Ingress, HTTPS 통신, Pod 개별 인증서 설정 등에 사용

 

-> 이 외에도 3~4개의 타입들이 더있다. 

-> type 중에서 데이터 암호화를 제공해주는 건 없음


중요 데이터 관리 방안

  1. Cluster 내에서 직접 생성/관리
    1. Secret 에 대한 오브젝트 생성을 파이프라인을 태워서 만들지 안기
    2. Cluster 내에서 직접 만들고 관리
    3. 쿠버네티스 관리 권한을 확실하게 설정하면, 아무나 Pod 내부의 데이터를 볼 수 없다
    4. 접근 제어를 통한 보안 관리 방법
  2. 자체 암호화
    1. 문자를 자체적으로 암호화
    2. 특정 key 를 가지고 문자를 암호화하고
    3. Secret 을 통해서 관리
  3. 서브파티 사용
    1. HashiCorp 의 Valut 가 대표 예
    2. App 기동 시 요청

 

4. 응용 과제

https://soyeon-devlog.tistory.com/44

'🌱 인프런 > ⚓ 쿠버네티스 어나더 클래스 (지상편)' 카테고리의 다른 글

(8) Component 동작으로 이해하기  (0) 2025.06.08
(7) PV/PVC, Deployment, Service, HPA  (1) 2025.06.08
(5) Probe 이해하기  (1) 2025.06.02
(4) Object 그려보며 이해하기  (0) 2025.05.30
(3) 실무에서 느껴 본 쿠버네티스가 정말 편한 이유  (0) 2025.05.29
'🌱 인프런/⚓ 쿠버네티스 어나더 클래스 (지상편)' 카테고리의 다른 글
  • (8) Component 동작으로 이해하기
  • (7) PV/PVC, Deployment, Service, HPA
  • (5) Probe 이해하기
  • (4) Object 그려보며 이해하기
말린
말린
  • 말린
    개발새발
    말린
  • 전체
    오늘
    어제
    • 분류 전체보기 (58)
      • 👩🏻‍💻 알고리즘 (17)
        • 백준 (17)
      • ✒️ 글또 10기 (6)
      • 🗃️ 데이터베이스 (5)
      • ☕️ 자바 (1)
      • 🌱 인프런 (28)
        • ⚓ 쿠버네티스 어나더 클래스 (지상편) (22)
        • ☕️ 김영한의 실전 자바 - 중급 1편 (6)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.6
말린
(6) Configmap, Secret 이해하기
상단으로

티스토리툴바