서론
해당 글은 일프로 님의 인프런 강의 쿠버네티스 어나더 클래스 (지상편) - Sprint 1, 2의 내용을 정리한 글입니다.
해당 글에 사용된 내용, 사진 및 그림은 모두 강의와 강의 자료에 포함된 내용입니다.
Configmap & Secret
![](https://velog.velcdn.com/images/appti/post/309b8401-e0ca-4c75-925f-d1112d279460/image.png)
Configmap 기본 개념
- Cofigmap
- 파드 환경 변수 주입
- 파드의 template.spec.containers.envFrom을 통해 연결될 Configmap 명시
- key-value 형태로 환경 변수 세팅
- spring_profiles_active : 애플리케이션 실행 환경 속성
- application_role : 해당 애플리케이션의 동작 역할 속성
- postgresql_filepath : Secret에 존재하는 파일 경로
- 주로 다음과 같은 종류의 환경 변수 세팅
- 인프라 환경에 따른 속성
- 애플리케이션 기능을 제어하기 위한 속성
- 외부 환경을 애플리케이션으로 주입하기 위한 속성
- 파드 생성 시 Configmap 동작 과정
- Configmap에 세팅된 모든 데이터를 컨테이너 내부 환경 변수로 주입
- 애플리케이션 실행 명령어 수행 시 지정된 환경 변수 값에 주입된 Configmap의 값 매칭
2-1. 애플리케이션 실행 명령어 수행 시 존재하지 않는 환경 변수 key라면 null 세팅
2-2. 스프링 애플리케이션을 사용하고 있기 때문에 profiles에 맞는 설정 파일 적용
Secret 기본 개념
- Secret
- 파드와 연결되는 일종의 볼륨
- 마운팅된 경로(= mountPath)를 통해 볼륨 접근 가능
- 쓰기 전용 속성인 StringData를 통해 파일 생성
- 실제 값을 data 속성을 통해 저장
- key는 그대로이지만 value는 Base64로 인코딩한 값으로 세팅
- Secret이지만 보안 요소는 없음(Base64로 인코딩하기 때문)
- 파드 생성 시 Secret 동작 과정
- mountPath 속성으로 컨테이너 내부에 지정된 경로 생성
- 컨테이너 내부 경로와 볼륨을 마운트해 Secret과 연결
- 컨테이너 내부 경로에 파일 생성
3-1. 파일 생성 시 Base64로 인코딩된 값을 디코딩해 파일로 저장
- 스프링 애플리케이션 기동 시 컨테이너 내부 경로에 저장된 파일을 읽어 DB 연결 처리
특징
- ConfigMap
- 다양한 암호화 방식을 통해 중요한 데이터 관리 가능
- Secret
- 데이터 암호화 방식은 ConfigMap, Secret Object와 별도로 고려해야 함
- Secret을 통해 envFrom으로 환경 변수 주입 가능
- 기능적으로는 가능하지만 불편하므로 잘 사용되지 않는 방식
- 의도하지 않은 상황에서 중요한 데이터를 볼 수 있는 소지 발생하므로 지양
실습
![](https://velog.velcdn.com/images/appti/post/de43ff53-c99c-4bb8-9b35-151fc949eb63/image.png)
- ConfigMap, Secret 설정 값 확인
- 컨테이너 내부에서 ConfigMap으로 설정한 환경 변수 값이 정상적으로 주입되었는지 확인
Secret과 마운트된 값 확인
- API를 통해 애플리케이션에 환경 변수가 정상적으로 적용되었는지 확인
- ConfigMap 에서 환경 변수 수정
- API를 통해 애플리케이션에 변경된 환경 변수가 적용되었는지 확인
ConfigMap & Secret 확인
![](https://velog.velcdn.com/images/appti/post/dc3cfa6c-26ae-498a-98c1-01bf99f61325/image.png)
![](https://velog.velcdn.com/images/appti/post/4819fd2d-716f-4c78-aa72-d2537e75630f/image.png)
- 대시보드로 ConfigMap & Secret 확인
kubectl describe -n anotherclass-123 configmaps api-tester-1231-properties
kubectl get -n anotherclass-123 configmaps api-tester-1231-properties -o yaml
kubectl get -n anotherclass-123 configmaps api-tester-1231-properties -o jsonpath='{.data}'
kubectl get -n anotherclass-123 secret api-tester-1231-postgresql -o yaml
kubectl get -n anotherclass-123 secret api-tester-1231-postgresql -o jsonpath='{.data}'
kubectl get -n anotherclass-123 secret api-tester-1231-postgresql -o jsonpath='{.data.postgresql-info\.yaml}'
kubectl get -n anotherclass-123 secret api-tester-1231-postgresql -o jsonpath='{.data.postgresql-info\.yaml}' | base64 -d
- 명령어로 ConfigMap & Secret 확인
![](https://velog.velcdn.com/images/appti/post/88bbe7c7-2c7c-49cf-ac0c-7cd2016cfaa7/image.png)
- env 명령어를 통해 ConfigMap에 세팅한 환경 변수가 정상적으로 주입된 것을 확인할 수 있음
![](https://velog.velcdn.com/images/appti/post/21d22609-ae6d-41d9-9fff-c2a3dcdf8521/image.png)
- ls 및 cat 명령어를 통해 실제 postgresql-info.yaml이 생성되었으며 파일의 내용도 정상적으로 적용됨을 확인할 수 있음
API 확인
![](https://velog.velcdn.com/images/appti/post/53bc2d0e-4a1a-4f39-85cd-f2c000fbd11d/image.png)
![](https://velog.velcdn.com/images/appti/post/df42d6c7-7f42-4c86-8288-3ff9d16b122f/image.png)
![](https://velog.velcdn.com/images/appti/post/9565a52e-46bf-41de-b678-20321f2a9385/image.png)
/properties
로 application.yml 조회
ConfigMap 수정
![](https://velog.velcdn.com/images/appti/post/20fce1c8-338e-4bde-b46c-2cd62541846a/image.png)
- ConfigMap의 data.application_role을 ALL -> GET으로 변경
![](https://velog.velcdn.com/images/appti/post/a46330c5-55d2-4d71-aa93-e419873b3bd6/image.png)
- ConfigMap의 값은 파드가 생성될 때 최초 한 번만 주입되므로 ConfigMap을 변경하더라도 값이 변경되지 않음
export application_role=GET
![](https://velog.velcdn.com/images/appti/post/8aaa5757-269f-4fb2-a3fa-a50704c8634a/image.png)
![](https://velog.velcdn.com/images/appti/post/2cbec9ef-3075-4061-bdec-9315b3c25f4e/image.png)
- 애플리케이션 실행 시점의 환경 변수가 적용되므로 환경 변수를 변경했다고 하더라도 애플리케이션에 적용되지 않음
![](https://velog.velcdn.com/images/appti/post/3357f6f7-1c55-4784-8cde-5bfe229072c9/image.png)
![](https://velog.velcdn.com/images/appti/post/d2996a38-c825-4a60-b567-3ace953c35f9/image.png)
![](https://velog.velcdn.com/images/appti/post/c9e7b7e7-ce7a-4911-9091-12921b25c841/image.png)
- 애플리케이션에서도 변경된 Secret 값이 제대로 반영됨
![](https://velog.velcdn.com/images/appti/post/37d1c0aa-e973-43f0-b536-8b496f744a94/image.png)
![](https://velog.velcdn.com/images/appti/post/15ec25d1-356a-490b-a60e-7d93a793c26a/image.png)
![](https://velog.velcdn.com/images/appti/post/7dca048b-4818-48f1-bb67-311434812498/image.png)
결론
- ConfigMap / Secret에 따라 실시간으로 애플리케이션에 값을 반영할 수 있는지 여부 결정
영역 파괴의 주범 ConfigMap
배포 흐름 & 상황
![](https://velog.velcdn.com/images/appti/post/ff1d2fe7-e971-438b-b7ab-3b56bc094cbe/image.png)
쿠버네티스 적용 이후
- 각 환경(dev, qa, prod)마다 파드 생성
- 파드에서 실행되는 컨테이너 이미지는 DockerHub에서 다운
- 해당 이미지는 애플리케이션 실행 시 환경 변수를 통해 profiles 적용
- jenkins에서 dev는 Web Hook이 트리거되면 즉시 파드 생성
- qa, prod는 jenkins에서 별도의 작업을 수행해야 파드 생성
쿠버네티스 적용 이전
- VM 관리자가 각 환경에 환경 변수를 직접 세팅
- 데브옵스 관리자가 jenkins에서 실행 스크립트를 구성하면서 필요한 환경 변수 세팅
- 웹 개발자가 application.properties로 각 환경에 따른 설정 추가
주의 사항
- ConfigMap에 데이터를 넣을 때 어떤 값을 넣어야 할지, 넣을 때 기존 구성이 어떤 식으로 변경될지, 추후 조작은 어떤 식으로 할지 확실하게 인지해야 함
- 그렇지 않은 경우 ConfigMap이 다른 영역을 침범해 관리 포인트가 증가할 수 있음
이름 때문에 기대가 너무 컸던 Secret
![](https://velog.velcdn.com/images/appti/post/a963c0e2-cd1b-48ec-985e-80fbe0d1995e/image.png)
- type
- 여러 종류의 기밀 데이터를 프로그래밍 방식으로 용이하게 처리하기 위해 사용
- 쿠버네티스에서 사용자 편의에 따라 커스터마이징할 수 있는 요소 제공
- 종류
- opaque
- 임의의 사용자 정의 데이터
- 기본 값
- ConfigMap을 사용해도 되지만 조금 중요한 데이터일 경우 해당 type 사용
- docker-registry
- 컨테이너 생성 시 Public Docker Registry가 아닌 Private Docker Registry의 이미지를 가져오고자 할 경우 사용
- docker-username / docker-password / docker-email key가 반드시 포함되어야 함
- 파드와 연결될 때 imagePullSecrets로 매핑됨
- tls
- 이 외에 다양한 종류가 있음
- Secret 보안 관리
- Cluster 내에서 관련 데이터를 직접 생성 / 관리
1-1. 쿠버네티스 관리 권한을 철저히 관리하면 다른 파드나 Secret을 조회하는 것을 방지할 수 있음
1-2. Object를 yaml 파일로 배포하는 것이 일반적이므로 비밀번호와 같은 매우 중요한 데이터만을 내부적으로 관리
- 문자를 자체적으로 암호화
2-1. 특정 key를 통해 암호화한 문자열을 Secret에 관리
2-2. 애플리케이션에서 암호화한 문자열을 복호화해야 함
2-3. 이 경우 Secret이 아닌 ConfigMap에서도 관리할 수 있음
- 암호화를 관리해주는 third-party 라이브러리 사용
3-1. 그림에서는 예시로 Vault 사용
3-2. 애플리케이션 기동 시 해당 애플리케이션이 접근이 허용된 파드라면 Vault가 데이터 전달
응용 과제
응용 1
Configmap의 환경변수들을 Secret을 사용해서 작성하고, App에서는 같은 결과가 나오도록 확인해 보세요.
![](https://velog.velcdn.com/images/appti/post/b45863c5-3419-40eb-b060-342b0ffa8fc9/image.png)
- Secret yaml 작성
1-1. stringdata와 같이 별도로 파일을 생성하는 기능이 아닌 data 속성에 일반적인 key-value 형식으로 작성
- 파드 설정에 envFrom으로 환경 변수를 주입할 대상으로 Secret 설정
2-1. 파드 생성 데이터는 Deployment의 spec.template에서 관리
2-2. 사용 옵션은 secretRef
apiVersion: v1
kind: Secret
metadata:
namespace: anotherclass-123
name: api-tester-1231-properties
labels:
part-of: k8s-anotherclass
component: backend-server
name: api-tester
instance: api-tester-1231
version: 1.0.0
managed-by: dashboard
stringData:
spring_profiles_active: "dev"
application_role: "ALL"
postgresql_filepath: "/usr/src/myapp/datasource/dev/postgresql-info.yaml"
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: anotherclass-123
name: api-tester-1231
spec:
template:
spec:
nodeSelector:
kubernetes.io/hostname: k8s-master
containers:
- name: api-tester-1231
image: 1pro/api-tester:v1.0.0
envFrom:
- secretRef:
name: api-tester-1231-properties
응용 2
반대로 Secret의 DB정보를 Configmap으로 만들어보고 App을 동작시켜 보세요.
![](https://velog.velcdn.com/images/appti/post/09416b94-72d8-4143-bb1f-9e6fc6a548bb/image.png)
- ConfigMap을 통해 파일을 생성하고, 애플리케이션이 읽을 수 있도록 읽기 전용 볼륨에 파일을 추가할 수 있다는 내용
![](https://velog.velcdn.com/images/appti/post/28f782ec-2710-45af-81bf-482bace9508c/image.png)
- 파드 spec에 볼륨 마운트와 볼륨을 선택해 ConfigMap을 통해 생성하는 파일을 볼륨과 연동하는 내용
apiVersion: v1
kind: ConfigMap
metadata:
namespace: anotherclass-123
name: api-tester-1231-postgresql
labels:
part-of: k8s-anotherclass
component: backend-server
name: api-tester
instance: api-tester-1231
version: 1.0.0
managed-by: dashboard
data:
postgresql-info.yaml: |
driver-class-name: "org.postgresql.Driver"
url: "jdbc:postgresql://postgresql:5431"
username: "dev"
password: "dev123"
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: anotherclass-123
name: api-tester-1231
spec:
template:
spec:
nodeSelector:
kubernetes.io/hostname: k8s-master
containers:
- name: api-tester-1231
image: 1pro/api-tester:v1.0.0
volumeMounts:
- name: configmap-datasource
mountPath: /usr/src/myapp/datasource/dev
volumes:
- name: configmap-datasource
configMap:
name: api-tester-1231-postgresql