1. 사용 이유

예를 들어 데이터베이스를 쿠버네티스 파드에 컨테이너로 띄운다면, 데이터베이스 사용자 아이디와 패스워드 같은 기밀 정보가 컨테이너에 주입되어야 한다. 이를 위한 몇가지 방법을 생각해볼 수 있다.(Docker 기준)

  • 이미지를 정의하는 Dockerfile 에 직접 아이디와 패스워드를 기재하는 방법
  • 이미지를 정의하는 Dockerfile 에 ARG 지시자로 수신하고, ENV 지시자로 런타임 변수로 저장하도록 작성하고 이미지 빌드시 --build-arg 로 빌드 인수로 아이디와 패스워드를 전달하는 방법
  • 컨테이너 실행시에만 -e 로 인수로 아이디와 패스워드를 전달하는 방법
  • Pod나 Deployment의 매니페스트 파일에 직접 아이디와 패스워드를 기재하는 방법

그러나, 이미지 정의 파일에 기재하거나 이미지 빌드시 인수로 넘기는 방법은 이미지 자체에 기밀 정보가 포함되기 때문에 보안상 바람직하지 않다. 이미지 레지스트리 서버에 올라가기 때문이다. 더구나 기밀 정보 내용을 변경할 때 마다 이미지를 재빌드 하여야 한다는 번거로움이 있다.(빌드시 DOCKER_BUILDKIT 을 사용하여 secret 을 이미지에 저장되지 않도록 할 수 있기는 하다.)

Pod나 Deployment 매니페스트에 기밀 정보를 기재하는 것도 해당 매니페스트를 github 같은 소스 저장소에 올리기 때문에 보안상 바람직하지 않다. 또한 해당 기밀 정보를 여러 애플리케이션에서 필요로 할 경우 애플리케이션 마다 기밀 정보를 중복되게 기재해야 하기 때문에 관리가 어려워진다.

이러한 문제점들을 해결하기 위해서 Secret 리소스를 사용할 수 있다. 기밀 정보를 별도의 리소스에 단일 저장해두고 여러 파드에서 읽어들이는 것이다.

2. 시크릿의 데이터 처리 구조

시크릿 데이터는 마스터 노드의 etcd 라는 데이터베이스에 저장된다. etcd 는 분산 KVS(Key-Value Store)이다. 분산 KVS란 한대의 머신에서 모두 관리하지 않고 여러대의 머신에 분산되어 관리된다는 뜻이다. 즉, 마스터 노드가 여러대인 경우 여러대에 etcd 가 분산되어 저장된다는 것이다. 시크릿의 실제 저장 위치는 /registry/secrets/<namespace>/<name> 이다. 기본적으로 시크릿 데이터는 Base64 인코딩만 되어있고 암호화 되어있지는 않다.

이렇게 저장된 시크릿은 항상 각 노드에 전송되지 않고, 실제 시크릿을 사용하는 파드가 노드에 존재하는 경우에만 해당 워커노드의 kubelet 이 마스터 노드의 API Server를 호출하여 시크릿 데이터를 가져온다. 가져온 데이터는 민감한 기밀 데이터이기 때문에 워커 노드에 영구적으로 남지 않아야 한다. 따라서 하드디스크가 아닌 RAM 기반의 가상 파일 시스템에 저장하게 되는데, 이 영역을 tmpfs 라고 한다. 위치는 /var/lib/kubelet/pods/<pod-id>/volumes/kubernetes.io~secret/ 경로 아래에 생성된다. 노드가 재부팅되거나 접근중인 Pod 가 삭제되면 메모리에서 사라지는 영역이다.

시크릿은 데이터는 기본적으로는 암호화되어있지 않기 때문에, 시크릿 매니페스트같은 파일을 소스 형상관리 서버에 직접 업로드하면 안되고, 시크릿을 암호화하는 OSS, Vault 등의 솔루션을 사용하여야 한다.

3. 시크릿 리소스의 종류(타입)

종류 용도
Opaque 범용
kubernetes.io/tls TLS 인증서용
kubernetes.io/basic-auth 기본 인증용
kubernetes.io/dockerconfigjson 도커 레지스트리 인증 정보용
kubernetes.io/ssh-auth SSH 인증 정보용
kubernetes.io/service-account-token 서비스 어카운트 토큰용
bootstrap.kubernetes.io/token Bootstrap 토큰용

 

블로그 이미지

망원동똑똑이

프로그래밍 지식을 자유롭게 모아두는 곳입니다.

,