본문 바로가기
BackEnd

도커와 쿠버네티스 -K8S(환경 변수)

by mizuiro 2024. 11. 17.

1. 환경 변수

0. 환경 변수 설정 방법

  1. 컨테이너 내부에 직접 설정
  2. configMap
  3. secret

환경 변수는 컨테이너 단위로 정의가 되기 때문에 공통으로 사용될 환경 변수도 중복 해서 컨테이너에 정의될 수 있다

또한 비밀번호, API KEY 등은 공개가 되면 공개가 되면 안되기 때문에 이러한 부분들을 해결하기 위한 ConfigMqp, Secret 객체가 존재

ConfigMap, Secret 는 K8S에서 설정값을 저장하는 객체이다

ConfigMap : 외부에 공개되어도 문제가 되지 않는 값을 저장 (Database Host Name, Database User)

Secret : 외부에 공개가 되면 안되는 값을 저장 (Database Password)

컨테이너 입장에서의 K8S 환경 변수의 장점

K8S 입장에서의 환경 변수는 컨테이너 내부에 어떠한 값을 전달 할 때 값을 전달하기 쉬운 방법 중에 하나이다 그러므로 빌드가 왼료된 이미지라고 하더라도 컨테이너로 실행되는 타이밍에 필요한 정보를 더 주입할 수 있다

또한 환경 변수가 pod 레벨에 정의되어 모든 컨테이너에게 전파되어지는 형태가 아니라 컨테이너 독립적인 속성으로 정의가 되어 사용되어 진다

1. 컨테이너 내부에 직접 환경 변수 설정

pod 환경 변수 설정 추가

apiVersion: v1
kind : Pod
metadata:
  name: env-test-pod
spec:
  containers:
    - name: my-container
      image: nginx
      env:
        - name: SAMPLE_ENV
          value: "Sample Variable"
        - name: POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
  • spec.containers.env :

    • 첫번째 name : 환경 변수 첫 번째 설정

      • SAMPLE_ENV : 환경 변수 명
    • 두번째 name : 환경 변수 두 번째 설정

      • POD_NAME : pod의 이름(env-test-pod)을 컨테이너 내부에 설정

      • valueFrom : 참조해서 사용할 수 있도록 value 대신 valueFrom 으로 정의

      • fieldPath : 참조 하는 위치

        ⇒ 참조를 위한 field를 지정하는 것을 K8S에서는 donward api 라고 한다

  • 실행
kubectl apply -f .\ex5-1_env.yaml
kubectl get pod
kubectl exec env-test-pod -- printenv
  • kubectl exec : pod 내부에 있는 컨테이너에 임의의 명령어를 실행하는 형태로 사용
  • printenv : 컨테이너 내부에 설정된 환경변수 목록을 출력하는 명령어

node환경 변수 설정 추가

apiVersion: v1
kind: Pod
metadata:
    name: env-test-pod
spec:
    containers:
        - name: my-container
          image: nginx
          env:
              - name: SAMPLE_ENV
                value: "Sample Variable"
              - name: POD_NAME
                valueFrom:
                    fieldRef:
                        fieldPath: metadata.name
              - name: NODE_NAME
                valueFrom:
                    fieldRef:
                        fieldPath: spec.nodeName
  • 실행
kubectl apply -f .\ex5-2_env.yaml
kubectl get pod
kubectl exec env-test-pod -- printenv

2. ConfigMap

configMap은 환경 변수의 재사용 및 통합 관리 목적 용

apiVersion: v1
kind: ConfigMap
metadata:
    name: my-config
data:
    profile: "dev"
    db_host: "10.20.30.40"
    welcom-script: |
        echo Hello!
        echo Db is $ db_host
  • data : 관리할 환경 변수를 설정 key, value 형태로 설정

  • ‘|’ : multi line 작성을 위해 사용

  • 실행

 kubectl apply -f .\ex6_configMap.yaml
 kubectl get configmap 
 kubectl describe configmap my-config

3. Secret

명령어 방법 (CLI)

kubectl create secret generic db-info --from-literal=DB_PW=mypasword
  • —from-literal : 문자열 형태로 secret 에서 key, value 형태로 저장

    • DB_PW ; 환경 변수의 key
    • mypassword : DB_PW 환경 변수의 value
  • 실행 결과

kubectl get secret
kubectl describe secret db-info
  • DB_PW key 의 value를 볼 수 없고 참조 해서 사용만 가능

선언형 방법 (yaml)

secret 객체는 yaml 파일로 사용하지 않는 경우도 많이 있음

만약 yaml 로 관리를 하면 모든 정보들이 노출이 될 가능성이 있기에 yaml은 잘 사용하지 않음

apiVersion: v1
kind: Secret
metadata:
  name: my-secret
type: Opaque
data:
  DB_PW : bXlwYXNzd29yZA==
stringData:
  API_KEY1: afdf-sdkl-jsfs-563
  API_KEY1: bXlwYXNzd29yZA==
  • data: 내부에 들어가는 value 의 값들은 base64로 인코딩된 문자열이어야 한다

  • 실행

kubectl apply -f .\ex7_secret.yaml
kubectl describe secret my-secret

결과를 보면 value값이 보이지 않는 것을 알 수 있다

이렇게 보이지 않게 되면 사용할 때 참조하면 내부에서 자동으로 디코딩을 해서 사용하게 된다

그러나 이렇게 보이지 않더라도 강제로 볼 수 있게 하는 방법이 있다

kubectl get secret my-secret -o yaml
  • -o : 출력 형식 지정 (yaml or json)

my-db secret 내부에 base64로 인코딩된 mypassword 값을 가지고 잇다

이때 pod에서 DB_PW 값을 참조하게 되면, 복호화된 mypassword값을 사용하게 된다

(pod DB_PW 참조 ) → (secret 복호화)

하지만, base64 인코딩은 실제 암호화가 아니고, 그냥 문자열을 인코딩하는 수준이라서 정확하게 말하면 평문에 가깝다 그래서 kubectl, kubectl describe 같은 기본적인 명령어로 간단히 인코딩된 값을 보여주지만, 실제 값(디코딩된)은 보여주지 않는다

보안을 더 강화하고 싶다면, secret 에 접근할 수 있는 사용자와 프로세스를 제한하는 기능을 사용해야 하고 secret 에 저장되는 값에 실제 암호화를 할 수 있는 옵션을 가지고 암호화를 진행해야 한다

4. ConfigMap, Secret 함께 사용

단, configMap, secret이 생성된 후 설정해야 한다

apiVersion: v1
kind: Pod
metadata:
    name: my-config-secret-pod
spec:
    containers:
        - name: my-container
          image: nginx
          env:
              - name: DB_HOST
                valueFrom:
                    configMapKeyRef:
                        name: my-config
                        key: db_host
              - name: DB_PASSWORD
                valueFrom:
                    secretKeyRef:
                        name: my-secret
                        key: DB_PW
  • env : 환경 변수 설정 정보 , 현재 2개의 환경 변수 설정

    • 첫번째 환경 변수 : configMap을 참조 해서 환경 변수를 초기화 한다
      • configMap으로 생성한 my-config를 참조하고 그 안에 설정한 key 값을 가져온다
      • db_host의 value를 참조하여 DB_HOST를 초기화 한다
    • 두번째 환경 변수 : secret을 참조 해서 환경 변수를 초기화 한다
      • secret으로 생성한 my-secret을 참조하고 그 안에 설정한 key 값을 가져온다
      • DB_PW 의 value를 참조하여 DB_PASSWORD를 초기화 한다
  • 실행

kubectl apply -f .\ex8_configSecret_pod.yaml
kubectl get pod    
kubectl describe pod my-config-secret-pod
kubectl exec my-config-secret-pod -- printenv

⇒ describe 결과를 보면 Containers 속성 안에 Environment로 configMap, secret에서 참조한 값이 저장이 되어 있는 것을 확인 할 수 있다

⇒ 파일 상세 설정에 보면 디코딩 된 결과로 볼 수 가 있다