Application 기능으로 이해하기 - Configmap, Secret

appti·2024년 4월 6일
0

쿠버네티스 인강

목록 보기
6/15

서론

해당 글은 일프로 님의 인프런 강의 쿠버네티스 어나더 클래스 (지상편) - Sprint 1, 2의 내용을 정리한 글입니다.

해당 글에 사용된 내용, 사진 및 그림은 모두 강의와 강의 자료에 포함된 내용입니다.

Configmap & Secret

Configmap 기본 개념

  • Cofigmap
    • 파드 환경 변수 주입
    • 파드의 template.spec.containers.envFrom을 통해 연결될 Configmap 명시
    • key-value 형태로 환경 변수 세팅
      • spring_profiles_active : 애플리케이션 실행 환경 속성
      • application_role : 해당 애플리케이션의 동작 역할 속성
      • postgresql_filepath : Secret에 존재하는 파일 경로
    • 주로 다음과 같은 종류의 환경 변수 세팅
      • 인프라 환경에 따른 속성
      • 애플리케이션 기능을 제어하기 위한 속성
      • 외부 환경을 애플리케이션으로 주입하기 위한 속성
  • 파드 생성 시 Configmap 동작 과정
    1. Configmap에 세팅된 모든 데이터를 컨테이너 내부 환경 변수로 주입
    2. 애플리케이션 실행 명령어 수행 시 지정된 환경 변수 값에 주입된 Configmap의 값 매칭
      2-1. 애플리케이션 실행 명령어 수행 시 존재하지 않는 환경 변수 key라면 null 세팅
      2-2. 스프링 애플리케이션을 사용하고 있기 때문에 profiles에 맞는 설정 파일 적용

Secret 기본 개념

  • Secret
    • 파드와 연결되는 일종의 볼륨
    • 마운팅된 경로(= mountPath)를 통해 볼륨 접근 가능
    • 쓰기 전용 속성인 StringData를 통해 파일 생성
      • 실제 값을 data 속성을 통해 저장
      • key는 그대로이지만 value는 Base64로 인코딩한 값으로 세팅
        • Secret이지만 보안 요소는 없음(Base64로 인코딩하기 때문)
  • 파드 생성 시 Secret 동작 과정
    1. mountPath 속성으로 컨테이너 내부에 지정된 경로 생성
    2. 컨테이너 내부 경로와 볼륨을 마운트해 Secret과 연결
    3. 컨테이너 내부 경로에 파일 생성
      3-1. 파일 생성 시 Base64로 인코딩된 값을 디코딩해 파일로 저장
    4. 스프링 애플리케이션 기동 시 컨테이너 내부 경로에 저장된 파일을 읽어 DB 연결 처리

특징

  • ConfigMap
    • 다양한 암호화 방식을 통해 중요한 데이터 관리 가능
  • Secret
    • 보안 목적 외에 다양한 활용 케이스 존재
  • 데이터 암호화 방식은 ConfigMap, Secret Object와 별도로 고려해야 함
  • Secret을 통해 envFrom으로 환경 변수 주입 가능
    • 기능적으로는 가능하지만 불편하므로 잘 사용되지 않는 방식
      • 의도하지 않은 상황에서 중요한 데이터를 볼 수 있는 소지 발생하므로 지양

실습

  1. ConfigMap, Secret 설정 값 확인
  2. 컨테이너 내부에서 ConfigMap으로 설정한 환경 변수 값이 정상적으로 주입되었는지 확인
    Secret과 마운트된 값 확인
  3. API를 통해 애플리케이션에 환경 변수가 정상적으로 적용되었는지 확인
  4. ConfigMap 에서 환경 변수 수정
  5. API를 통해 애플리케이션에 변경된 환경 변수가 적용되었는지 확인

ConfigMap & Secret 확인

  • 대시보드로 ConfigMap & Secret 확인
# ConfigMap 확인
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}'

# Secret 확인
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}'

# Secret data에서 postgresql-info가 Key인 Value값만 조회 하기
kubectl get -n anotherclass-123 secret api-tester-1231-postgresql -o jsonpath='{.data.postgresql-info\.yaml}'

# Secret data에서 postgresql-info가 Key인 Value값을 Base64 디코딩해서 보기
kubectl get -n anotherclass-123 secret api-tester-1231-postgresql -o jsonpath='{.data.postgresql-info\.yaml}' | base64 -d
  • 명령어로 ConfigMap & Secret 확인

  • env 명령어를 통해 ConfigMap에 세팅한 환경 변수가 정상적으로 주입된 것을 확인할 수 있음

  • ls 및 cat 명령어를 통해 실제 postgresql-info.yaml이 생성되었으며 파일의 내용도 정상적으로 적용됨을 확인할 수 있음

API 확인

  • 스프링 애플리케이션 실행 커맨드 확인

  • /info로 애플리케이션 정보 확인

  • /properties로 application.yml 조회

ConfigMap 수정

  • ConfigMap의 data.application_role을 ALL -> GET으로 변경

  • ConfigMap의 값은 파드가 생성될 때 최초 한 번만 주입되므로 ConfigMap을 변경하더라도 값이 변경되지 않음
# 환경 변수 수정 명령
export application_role=GET
  • OS 레벨에서 강제로 환경 변수 수정

  • 환경 변수는 ALL -> GET으로 변경됨

  • 애플리케이션 실행 시점의 환경 변수가 적용되므로 환경 변수를 변경했다고 하더라도 애플리케이션에 적용되지 않음

  • Secret 값 dev -> test로 변경

  • 파일 내용이 정상적으로 변경됨
    • Secret을 볼륨 마운팅으로 연결했기 때문

  • 애플리케이션에서도 변경된 Secret 값이 제대로 반영됨
    • 5초 간격으로 계속 조회하기 때문

  • 파드 삭제 후 재생성

  • 환경 변수는 ALL -> GET으로 변경됨

  • 애플리케이션에도 정상적으로 적용됨

결론

  • ConfigMap / Secret에 따라 실시간으로 애플리케이션에 값을 반영할 수 있는지 여부 결정

영역 파괴의 주범 ConfigMap

배포 흐름 & 상황

쿠버네티스 적용 이후

  • 각 환경(dev, qa, prod)마다 파드 생성
    • 파드에서 실행되는 컨테이너 이미지는 DockerHub에서 다운
    • 해당 이미지는 애플리케이션 실행 시 환경 변수를 통해 profiles 적용
  • jenkins에서 dev는 Web Hook이 트리거되면 즉시 파드 생성
    • qa, prod는 jenkins에서 별도의 작업을 수행해야 파드 생성

쿠버네티스 적용 이전

  • VM 관리자가 각 환경에 환경 변수를 직접 세팅
  • 데브옵스 관리자가 jenkins에서 실행 스크립트를 구성하면서 필요한 환경 변수 세팅
  • 웹 개발자가 application.properties로 각 환경에 따른 설정 추가

주의 사항

  • ConfigMap에 데이터를 넣을 때 어떤 값을 넣어야 할지, 넣을 때 기존 구성이 어떤 식으로 변경될지, 추후 조작은 어떤 식으로 할지 확실하게 인지해야 함
    • 그렇지 않은 경우 ConfigMap이 다른 영역을 침범해 관리 포인트가 증가할 수 있음

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

  • type
    • 여러 종류의 기밀 데이터를 프로그래밍 방식으로 용이하게 처리하기 위해 사용
    • 쿠버네티스에서 사용자 편의에 따라 커스터마이징할 수 있는 요소 제공
    • 종류
      • opaque
        • 임의의 사용자 정의 데이터
        • 기본 값
        • ConfigMap을 사용해도 되지만 조금 중요한 데이터일 경우 해당 type 사용
      • docker-registry
        • 컨테이너 생성 시 Public Docker Registry가 아닌 Private Docker Registry의 이미지를 가져오고자 할 경우 사용
        • docker-username / docker-password / docker-email key가 반드시 포함되어야 함
        • 파드와 연결될 때 imagePullSecrets로 매핑됨
      • tls
        • 파드마다 각각 다른 인증서를 세팅할 때 사용
      • 이 외에 다양한 종류가 있음
        • 데이터 암호화에 대한 기능을 제공하지 않음
  • Secret 보안 관리
    1. Cluster 내에서 관련 데이터를 직접 생성 / 관리
      1-1. 쿠버네티스 관리 권한을 철저히 관리하면 다른 파드나 Secret을 조회하는 것을 방지할 수 있음
      1-2. Object를 yaml 파일로 배포하는 것이 일반적이므로 비밀번호와 같은 매우 중요한 데이터만을 내부적으로 관리
    2. 문자를 자체적으로 암호화
      2-1. 특정 key를 통해 암호화한 문자열을 Secret에 관리
      2-2. 애플리케이션에서 암호화한 문자열을 복호화해야 함
      2-3. 이 경우 Secret이 아닌 ConfigMap에서도 관리할 수 있음
    3. 암호화를 관리해주는 third-party 라이브러리 사용
      3-1. 그림에서는 예시로 Vault 사용
      3-2. 애플리케이션 기동 시 해당 애플리케이션이 접근이 허용된 파드라면 Vault가 데이터 전달

응용 과제

응용 1

Configmap의 환경변수들을 Secret을 사용해서 작성하고, App에서는 같은 결과가 나오도록 확인해 보세요.

  1. Secret yaml 작성
    1-1. stringdata와 같이 별도로 파일을 생성하는 기능이 아닌 data 속성에 일반적인 key-value 형식으로 작성
  2. 파드 설정에 envFrom으로 환경 변수를 주입할 대상으로 Secret 설정
    2-1. 파드 생성 데이터는 Deployment의 spec.template에서 관리
    2-2. 사용 옵션은 secretRef
# Secret
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"

# Deployment
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을 동작시켜 보세요.

  • ConfigMap을 통해 파일을 생성하고, 애플리케이션이 읽을 수 있도록 읽기 전용 볼륨에 파일을 추가할 수 있다는 내용

  • 파드 spec에 볼륨 마운트와 볼륨을 선택해 ConfigMap을 통해 생성하는 파일을 볼륨과 연동하는 내용
# 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"
    
# Deployment
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
profile
안녕하세요

0개의 댓글