쿠버네티스에서 ConfigMap📑
과 Secret📜
은 환경 설정 값과 민감한 데이터를 이미지 외부에서 관리하는 방법이다.
객체 지향 프로그래밍에 대해서 들어본 적이 있다면, 인터페이스라는 말을 들어보았을 것이다.
이들은 이러한 인터페이스와 유사한데 즉, 생성되는 이미지에 동적으로 구성 데이터를 주입하게 된다.
ConfigMap📑
은 주로 애플리케이션 설정, 환경 변수, 구성 파일 등을 저장하는 데 사용되며, Secret📜
은 비밀번호, 토큰, 키와 같은 민감한 정보를 안전하게 저장하는 데 사용된다.
핵심은 개발환경과 운영환경 간의 차이를 보다 단순하게 관리하기 위해서이다.
개발과 운영 환경은 대체로 서로 다른 구성을 필요로 하는데, 만약 이러한 ConfigMap과 Secret이 없다면 개발용과 운영용의 컨테이너 이미지가 각각 별도로 필요할 것이다.
즉, 이는 단지 몇 가지 설정 값이 다를 뿐인 상황에서 전체 이미지를 별도로 보관해야 하는 비효율적인 상황이 발생하게 된다.
이를 ConfigMap과 Secret을 사용함으로써, 하나의 이미지를 여러 환경에서 재사용할 수 있게 되고, 이미지 관리의 효율성을 향상시킬 수 있다.
ConfigMap의 데이터는 일반적으로 쿠버네티스의 etcd 데이터베이스에 저장된다.
etcd는 쿠버네티스 클러스터의 모든 구성 데이터와 상태 정보를 저장하는 분산 키-값 저장소이다.
ConfigMap 배포 후 확인하는 명령어는 다음과 같다.
k get cm
k describe configmaps sleepy-config
로그를 확인해보면 echo
명령어를 통해서 출력하도록 한 두 환경변수의 내용이 각각 잘 출력되는 것을 확인할 수 있다.
디플로이먼트로 배포된 파드의 로그를 확인해보면 sleepy WAKE UP
이 잘 출력되어 있는 것을 확인할 수 있다.
파드 내부로 접속해서 보자.
ConfigMap의 data
필드에 정의 되었던 값을 마운트 된 볼륨의 위치에서 확인할 수 있다.
수정된 ConfigMap 새롭게 배포해 보도록 하자.
기존 ConfigMap과 이름이 동일하므로 배포를 하게되면 덮어씌워지게 된다.
이후 파드를 재생성해야 로그가 새롭게 찍히므로 파드를 재생성하고 로그를 확인하면?
새로운 ConfigMap의 data
를 반영한 결과를 확인할 수 있다.
현재 보이는 명령을 실행해서 다음과 같은 base64로 된 파일이 만들어진다.
쿠버네티스에서 Secret 오브젝트의 데이터는 기본적으로 etcd에 영구적으로 저장된다.
한편, 파드가 Secret을 사용할 때 (예를 들어, 볼륨으로 마운트하거나 환경 변수로 주입할 때) Secret 데이터는 해당 파드가 실행 중인 노드의 메모리에 저장된다.
먼저 사용자 이름과 비밀번호가 data
로 담긴 Secret을 생성한다.
kubectl create secret generic mysql-cred --from-literal=username='db-user' --from-literal=password='hoon
이제 생성된 mysql-cred
Secret을 사용하는 Mysql 이미지의 파드를 배포해보자.
이 때, Mysql은 볼륨의 연결이 필수적이므로 PVC를 통해 볼륨에 마운트한다.
(스토리지 클래스를 통해 PVC를 배포하면서 PVC는 PV와 이미 바인드된 상태이다.)
배포를 하게되면 다음과 pods
, pv
, pvc
모두 정상적으로 잘 배포되어 동작하는 것을 확인할 수 있다.
만일 이러한 Secret을 임으로 수정하는 경우, 오류가 발생하게 된다. 아래쪽 annotations
까지 수정해주면 오류는 나지 않는다.
Secret의 데이터가 저장되는 Base64 인코딩은 암호화 방법이 아니며, 보안 목적으로 사용되지 않는다. 단지, 문자의 호환성을 위해서 사용할 뿐이다.
따라서, Secret 데이터를 실제로 보호하려면 쿠버네티스 클러스터에서 RBAC 등의 접근 제어를 통해 Secret으로의 접근을 제한하거나,
HashiCorp Vault
와 같은 외부 Secret 관리 시스템을 사용하여, 쿠버네티스 외부에서 Secret을 관리하도록 해야한다.
ConfigMap과 Secret은 immutable: true
설정을 통해서 즉, 변경하지 못하도록 하는 것이 좋다.
그 이유는, 크게 2가지가 있다.
애플리케이션 중단을 유발할 수 있는 우발적(또는 원하지 않는) 업데이트로부터 보호할 수 있다.
kube-apiserver가 immutable: true
로 표시된 시크릿에 대한 감시를 중단하여 부하를 크게 줄임으로써 클러스터의 성능을 향상시킬 수 있다.