⚓ 쿠버네티스 어나더 클래스 (지상편) - 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 가 생성 시 동작 흐름
- Configmap 의 모든 데이터가 환경변수로 주입
- 컨테이너 실행시, 환경변수 값이 명령어에 매핑
- 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 동작 흐름
- Pod에 mountPath 설정
- 지정된 경로에 Secret이 마운트됨
- Pod 실행 시 Volume이 Secret과 연결됨
- Secret에 있는 postgresql-info.yaml 파일이 컨테이너 안에 생성됨
- 컨테이너 내부에서 파일 접근 가능
- 생성된 파일 내용은 Base64 디코딩된 원래 입력값
- 애플리케이션은 해당 파일을 읽어 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

| VM (Kubernetes 전 환경) | Kubernetes |
[인프라 환경]
|
[인프라 환경]
|
[개발 환경 & CI/CD 환경]
|
[개발 환경 & CI/CD 환경]
|
→ 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 중에서 데이터 암호화를 제공해주는 건 없음
중요 데이터 관리 방안
- Cluster 내에서 직접 생성/관리
- Secret 에 대한 오브젝트 생성을 파이프라인을 태워서 만들지 안기
- Cluster 내에서 직접 만들고 관리
- 쿠버네티스 관리 권한을 확실하게 설정하면, 아무나 Pod 내부의 데이터를 볼 수 없다
- 접근 제어를 통한 보안 관리 방법
- 자체 암호화
- 문자를 자체적으로 암호화
- 특정 key 를 가지고 문자를 암호화하고
- Secret 을 통해서 관리
- 서브파티 사용
- HashiCorp 의 Valut 가 대표 예
- App 기동 시 요청
4. 응용 과제
'🌱 인프런 > ⚓ 쿠버네티스 어나더 클래스 (지상편)' 카테고리의 다른 글
| (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 |