Kubernetes는 Credentials을 Secret이라는 리소스 단위로 관리한다. 만약 당신이 ClusterAdmin 중 한 명이라면 Secret이든 ConfigMap이든 별 차이가 없어 보일 수 있다. 하지만 Secret과 RBAC를 엮으면 그 둘은 완전히 다른 용도임을 깨닫는다. 권한 제어가 필요한 데이터, 이를테면 데이터베이스 암호는 Secret에 둔다. 권한 제어가 크게 필요하지는 않은 애플리케이션 설정은 ConfigMap에 두고 가능한 많은 사람과 공유한다. 그래야 전체 인프라스트럭처의 구성을 누구라도 한눈에 알 수 있다.
Secret을 생성하고 변경하는 역할을 누군가는 해야 한다. 그들을 GoG라 부르기로 하자. 그리고 Credentials에는 접근하지 못하지만 애플리케이션을 배포하고 유지보수해야 하는 사람이 있다. 그들은 Avengers라 부른다.
Avengers는 Secret에 대한 권한이 없는 Role을 부여받는다. 여기까지는 상식이다. 그러나 이 정도로는 충분하지 않다. Credential을 사용하는 애플리케이션 종류의 요구사항에 따라 다르지만 보통 Secret은 Volume이나 환경변수로 마운트된다. 그러므로 Pod에 exec
로 접근하는 권한이 있다면 Secret에 간접적으로 접근할 수 있다. 따라서 관련 권한도 통제해야 한다. 또한 Avengers가 애플리케이션을 통제하는 ServiceAccount도 변경하지 못하도록 해야 한다. ServiceAccount를 통해 간접적으로 Secret에 접근할 수 있기 때문이다.
자, 이 정도하면 Kubernetes 클러스터 내에서는 Avengers가 Secret에 접근하지 못 한다. 다만 Secret을 소스코드로 버전 관리하고 있다면 이에 대한 관리도 신경써야 한다. 그래서 Secret은 암호화된 버전관리 저장소에 저장한다. GitHub 같은 일반 저장소를 쓰되 소스코드 파일만 GPG 등으로 암호화할 수도 있지만 여러 모로 불편하다.
- 소스코드를 내려 받은 후 매번 GPG로 난독화를 해야 한다.
- 로컬에 내려받은 소스코드가 암호화되어 있으니 텍스트에디터나 IDE 로 소스코드를 탐색하기 어렵다.
그러므로 Keybase가 제공하는 암호화된 Git 서비스를 이용하던가 spwhitton/git-remote-gcrypt 와 같은 도구를 이용해 직접 암호화된 Git 저장소를 구현하고 관리하는 편이 낫다.
1Password 같은 암호 관리 소프트웨어를 쓸 수도 있다. 하지만 이런 소프트웨어는 소스코드를 관리하는 용도로 만든 건 아니어서 변경사항을 추적하고 반영하기 불편하다. 그렇다고 Hashicorp Vault나 AWS Secrets Manager 등을 쓰기도 애매하다. 그 둘은 Kubernetes의 Secret과 동일한 역할을 할 뿐이지, 개발자가 변경사항을 관리하고 공유하는 용도로는 부적합하다.
마지막으로 자주 듣는 질문에 대해 답하려 한다.
“Secret에 대한 권한이 없는 Avengers가 Secret이 있어야 작동하는 애플리케이션을 배포할 수 있나요?”
답은 ServiceAccount이다. Secret에 접근가능한 ServiceAccount를 Deployment, Statefulset, Pod 등에 붙이면 개발자가 ServiceAccount를 통해 간접적으로 Secret을 통제할 수 있다. 개발자가 Secret을 변경하고 읽지는 못하지만 Secret을 애플리케이션에 붙여서 배포할 수는 있다.
[…] K8s Secret 어떻게 관리할 것인가? […]