Today I Learned

[쿠버네티스 인 액션] 7. 컨피그맵과 시크릿 : 애플리케이션 설정 (2) 본문

쿠버네티스

[쿠버네티스 인 액션] 7. 컨피그맵과 시크릿 : 애플리케이션 설정 (2)

하이라이터 2022. 11. 7. 20:44
728x90

7.4 컨피그맵으로 설정 분리

  • 애플리케이션 구성의 요점은 환경에 따라 다르거나 자주 변경되는 설정 옵션을 애플리케이션 소스 코드와 별도로 유지하는 것이다.

7.4.1 컨피그맵 소개

  • 컨피그맵은 짧은 문자열에 전체 설정 파일에 이르는 값을 가지는 키/값 쌍으로 구성된 맵이다.
  • 맵의 내용은 컨테이너의 환경변수 또는 볼륨 파일로 전달된다.
  • 또한 환경변수는 $(ENV_VAR) 구문을 사용해 명령줄 인자에서 참조할 수 있기 때문에, 컨피그맵 항목을 프로세스의 명령줄 인자로 전달할 수도 있다.

  • REST API 엔드포인트를 통해 애플리케이션에서 컨피그맵의 내용을 직접 읽을 수 있지만, 반드시 필요한 경우가 아니라면 애플리케이션은 쿠버네티스와 무관하도록 유지해야 한다.
  • 별도의 독립적인 오브젝트에 설정을 포함하면 각각 다른 환경에 관해 동일한 이름으로 컨피그맵에 관한 여러 매니페스를 유지할 수 있다.


7.4.2 컨피그맵 생성

kubectl create configmap 명령 사용

  • 위 명령을 통해 sleep-interval=25라는 단일 항목을 가진 fortune-config 컨피그맵을 생성한다.

  • 컨피그맵은 일반적으로 두 개 이상의 항목을 포함한다. 여러 개의 --from-literal 인자로 여러 문자열 항목을 추가할 수 있다.

  • 앞서 생성한 컨피그맵의 YAML 정의를 출력해 살펴보자

  • 그리고 이 파일을 쿠버네티스 API에 게시한다.

 

파일 내용으로 컨피그맵 생성

  • 전체 설정 파일 데이터를 통째로 저장하는 것도 가능하다.

  • 위 명령을 실행하면, kubectl을 실행한 디렉터리에서 config-file.conf 파일을 찾고 파일 내용을 컨피그맵의 config-file.conf 키 값으로 지정한다.

  • 위와 같이 키값을 직접 지정할 수도 있다.

 

디렉터리에 있는 파일로 컨피그맵 설정

  • 각 파일을 개별적으로 추가하는 대신, 디렉터리 안에 있는 모든 파일을 가져올 수도 있다.

  • 이 명령에서 kubectl은 지정한 디렉터리 안에 있는 각 파일을 개별 항목으로 작성한다. 이때 파일 이름이 컨피그맵 키로 사용하기에 유효한 파일만 추가한다.

다양한 옵션 결합

  • 컨피그맵을 생성할 때 여기에서 언급한 모든 옵션을 조합해 사용할 수 있다.


7.4.3 컨피그맵 항목을 환경변수로 컨테이너에 전달

  • 이렇게 생성한 맵의 값을 파드 안에 컨테이너로 전달하기 위해 세 가지 옵션을 사용할 수 있다.
  • 가장 간단한 방법은 환경변수를 설정하는 것이다.

  • INTERVAL 환경변수를 선언하고 fortune-config 컨피그맵의 안에 있는 sleep-interval 키를 이용해 가져온 값으로 설정했다.
  • html-generator 컨테이너 안에서 실행 중인 프로세느는 INTERVAL 환경변수를 읽을 때 25를 가져온다.

 

파드에 존재하지 않는 컨피그맵 참조

  • 컨테이너가 존재하지 않는 컨피그맵을 참조하려고 하면 컨테이너는 시작하는 데 실패한다.
  • 하지만 참조하지 않는 다른 컨테이너는 정상적으로 시작되고, 누락된 컨피그맵을 생성하면 실패했던 컨테이너는 파드를 다시 만들지 않아도 시작된다.


7.4.4 컨피그맵의 모든 항목을 한 번에 환경변수로 전달

  • 컨피그맵에 여러 항목이 포함되어 있을 경우 env 속성 대신 envFrom 속을 사용해 환경변수로 모두 노출할 수 있다.

  • 컨피그맵이 FOO, BAR, FOO-BAR 세 개의 키를 갖고 있다고 가정하면, 이 컨테이에는 CONFIG_FOO와 CONFIG_BAR 환경변수가 존재하게 된다.
  • CONFIG_FOO-BAR가 생성되지 않는 이유는 올바른 환경변수 이름이 아니기 때문이다. 컨피그맵의 키가 올바른 형식이 아닐 경우 항목을 건너뛴다(건너뛰었다는 것을 알려주는 이벤트는 기록된다).

7.4.5 컨피그맵 항목을 명령줄 인자로 전달

  • 컨피그 값을 컨테이너 안에서 실행되는 프로세스의 인자로 전달하는 방법을 살펴보자.
  • 컨피그맵 항목을 환경변수로 먼저 초기화하고 이 변수를 인자로 참조하도록 지정할 수 있다.


7.4.6 컨피그맵 볼륨을 사용해 컨피그맵 항목을 파일로 노출

  • 컨피그맵 볼륨은 파일로 컨피그맵의 각 항목을 노출한다. 컨테이너에서 실행 중인 프로세스는 이 파일 내용을 읽어 각 항목의 값을 얻을 수 있다.

컨피그맵 생성

  • Nginx 서버가 클라이언트로 응답을 압축해서 보내려고 한다고 가정해보자. 압축을 사용하도록 설정하려면 Nginx 설정 파일에 다음과 같은 내용이 포함돼야 한다.

  • 이제 kubectl delete configmap fortune-config 명령으로 기존 fortune-config 컨피그맵을 삭제하고 Nginx 설정 파일을 포함하는 새로운 컨피그맵으로 교체할 수 있다.
  • configmap-files라는 새 디렉터리를 생성하고 앞 예제 Ngnix 설정 파일을 configmap-files/my-ngnix-config.conf 파일로 저장한다.
  • 컨피그맵에 sleep-interval 항목도 포함시키려면, 동일한 디렉터리에 sleep-interval 텍스트 파일을 생성하고 25를 저장한다.

  • 이 컨피그맵의 YAML 정의는 다음과 같다.

 

볼륨 안에 있는 컨피그맵 항목 사용

  • 컨피그맵 항목에서 생성된 파일로 볼륨을 초기화할 수 있다.
  • Ngnix는 /etc/nginx/ngnix.conf 파일의 설정을 읽는다. 기본 설정 파일은 /etc/ngnix/conf.d/ 디렉터리 안에 있는 모든 파일을 포함하기 때문에 원하는 설정 파일을 해당 디렉터리에 추가하면, 기본 설정 옵션 파일의 옵션을 무시하지 않으면서 추가할 수 있다.

  • 이 파드 정의에는 fortune-config 컨피그맵을 참조하는 볼륨이 포함되어 있다. 해당 볼륨을 Ngnix에서 사용할 수 있도록 /etc/nginx/config.d 디렉터리로 마운트한다.

Ngnix 서버가 마운트한 설정 파일을 사용하는지 확인

  • 웹 서버가 응답을 압축해서 보내주도록 설정되어 있는지 검증하기 위해 localhost:8080을 파드의 80번 포트로 전달하도록 연결하고, curl 명령을 이용해 응답을 확인할 수 있다.

 

마운트된 컨피그맵 볼륨 내용 살펴보기

  • conf.d 디렉터리에 컨피그맵의 두 항목이 파일로 추가되어 있다.
  • 서로 다른 두 개의 컨피그맵을 작성해 각각의 컨테이너에 사용하도록 할 수 있지만, 여러 컨피그맵을 동일한 파드의 컨테이너들을 구성하는데 사용하는 것은 이상하다.
  • 결국 동일한 파드에 있는 컨테이너들은 밀접한 관계를 가지고있어 하나의 유닛으로 설정되어야 함을 의미한다.

 

볼륨에 특정 컨피그맵 항목 노출

  • 컨피그맵 볼륨을 컨피그맵 항목의 일부만으로 채울 수 있다.

  • my-ngnix-config.conf 항목한 사용하고 sleep-interval 항목은 볼륨이 아닌 환경변수로 전달해 fortuneloop 컨테이너에 영향을 주지 않는다.
  • 개별 항목을 지정할 때 항목 키와 함께 각 개별 항목의 파일 이름을 설정하는 것이 필요하다.

 

디렉터리를 마운트할 때 디렉터리의 기존 파일을 숨기는 것 이해

  • 위 예제와 이전 예제에서 볼륨을 디렉터리에 마운트했다. 이는 컨테이너 이미지 자체에 있던 /etc/ngnix/conf.d 디렉터리 안에 저장된 파일을 숨겼음을 의미한다.
  • 이는 일반적으로 리눅스에서 파일시스템을 비어 있지 않은 디렉터리에 마운트할 때 발생한다.
  • 해당 디렉터리는 마운트한 파일 시스템에 있는 파일만 포함하고, 원래 있던 파일은 해당 파일 시스템이 마운트돼 있는 동안 접근할 수 없게 된다.
  • 중요한 파일을 포함하는 /etc 티렉터리에 볼륨을 마운트 한다면, /etc 디렉터리에 있어야 하는 모든 원본 파일이 더 이상 존재하지 않기 때문에 전체 컨테이너가 손상될 수 있다.

디렉터리 안에 다른 파일을 숨기지 않고 개별 컨피그맵 항목을 파일로 마운트

  • 전체 볼륨을 마운트하는 대신 volumeMount에 subPath 속성으로 파일이나 디렉터리 하나를 볼륨에 마운트할 수 있다.

  • myconfig.conf 파일을 포함하는 컨피그맵 볼륨을 갖고 있고, 이 파일을 /etc 디렉터리에 someconfig.conf 파일로 추가하려 한다.
  • subPath 속성으로 디렉터리에 있는 다른 파일에 영향을 주지 않고 마운트할 수 있다.

  • 하지만 개별 파일을 마운트하는 이 방법은 파일 업데이트와 관련해 상대적으로 큰 결함을 가지고 있다. 이는 다음 절에서 살펴보자.

 

컨피그맵 볼륨 안에 있는 파일 권한 설정

  • 기본적으로 컨피그맵 볼륨의 모든 파일 권한은 644(-rw-r-r--)로 설정되지만, 볼륨 정의 안에 있는 defaultMode 속성을 설정해 변경할 수 있다.


7.4.7 애플리케이션을 재시작하지 않고 애플리케이션 설정 업데이트

  • 환경변수 또는 명령줄 인수를 설정 소스로 사용할 때의 단점은 프로세스가 실행되고 있는 동안에 업데이트할 수 없다는 것이다.
  • 컨피그맵을 사용해 볼륨으로 노출하면 파드를 다시 만들거나 컨테이너를 재시작할 필요 없이 설정을 업데이트할 수 있다.

 

컨피그맵 편집

  • 컨피그맵을 변경하고 파드 안에서 실행 중인 프로세스가 컨피그맵 볼륨에 노출된 파일을 다시 노출하는 방법을 살펴보자.

  • fortune-config에서 gzip on을 gzip off로 변경해서 gzip 압축을 해제하고 파일 내용을 출력해 확인해보자.

 

설정을 다시 로드하기 위해 Ngnix에 신호 전달

 

파일이 한꺼번에 업데이트되는 방법 이해하기

  • 모든 파일은 동시에 업데이트되기 때문에 컨피그맵 볼륨에 있는 모든 파일에 업데이트되기 전에 애플리케이션이 설정파일의 변경사항을 자체적으로 감지하고 다시 로드되는 경우는 없다.

  • 마운트된 컨피그맵의 볼륨의 모든 파일을 조회해보면 ..data 디렉터리의 파일을 가리키는 심볼릭 링크를 볼 수 있으며, ..data 디렉터리 또한 ..49894_09_04_somthig 디렉터리를 가리키는 심볼릭 링크이다.
  • 컨피그맵이 업데이트되면 이와 같은 새 디렉토리를 생성하고, 모든 파일을 여기에 쓴 다음 ..data 심볼릭 링크가 새 디렉토리를 가리키도록 해서 모든 파일을 한 번에 변경한다.

이미 존재하는 디렉터리에 파일만 마운트했을 때 업데이트가 되지 않는 것 이해하기

  • 만약 전체 볼륨 대신 단일 파일을 컨테이너에 마운트한 경우 파일이 업데이트되지 않는다.
  • 개별 파일을 추가하고 원본 컨피그맵을 업데이트할 때 파일을 업데이트해야 하는 경우 한 가지 해결 방법은 전체 볼륨을 다른 디렉터리에 마운트한 다음 해달 파일을 가리키는 심볼릭 링크를 생성하는 것이다.

 

컨피그맵 업데이트의 결과 이해하기

  • 컨테이너의 가장 중요한 기능은 불변성이다. 동일한 이미지에서 생성된 여러 실행 컨테이너 간에 차이가 없는지 확인할 수 있지만 컨피그맵을 수정하면 이 불변성을 우회하게 된다.
  • 따라서 애플리케이션이 설정을 다시 읽는 기능을 지원하지 않는 경우, 서로 다른 설정을 가진 인스턴스가 실행되는 결과를 초래할 수 있다.

 

728x90
Comments