Gitops에서 Secret을 안전하게 관리하기 - SealedSecret

Hoonkii·2023년 12월 11일
0

개요

Gitops 는 쿠버네티스 Manifest 파일을 Git 에서 관리하고 배포할 때에도 Git에 저장된 Manifest로 클러스터에 배포하는 방식이다. 즉 Git은 애플리케이션의 모든 정보가 저장된 Single Source Of Truth가 되는 것이다.

Gitops 방식에서 고민되는 부분 중 하나는 Secret 을 어떻게 관리할 지 이다. 보통 쿠버네티스에서 데이터베이스 유저, 비밀번호 혹은 써드 파티의 API Key 등 민감한 정보는 컨테이너에 안전하게 주입하기 위해 Secret Object를 활용하여 Pod에 주입시킨다.

그런데 Secret Object는 데이터를 암호화한 게 아니라 단순 base64로 인코딩 한 것이기 때문에 Github과 같은 곳에 그대로 올리면 보안 상 취약할 수도 있다. Private Repository에 올렸다고 하더라도 해당 Repository를 클론한 컴퓨터가 탈취되었거나, 혹은 실수로 Public Repository로 전환하거나 하면 Secret 값이 노출될 수 있다.

이러한 문제를 해결해줄 수 있는 SealedSecret에 대해 다뤄보고자 한다.

SealedSecret

SealedSecret은 bitnami-labs에서 만든 오픈소스로 퍼블릭 레포지토리에서도 Secret 값을 안전하게 저장할 수 있게 해준다. 즉 암호화된 SealedSecret 오브젝트를 Git에 올리고 쿠버네티스에서는 이를 바탕으로 Secret 오브젝트를 만들어 Pod에서 활용할 수 있게 한다.

동작 원리

SealedSecret은 클러스터 사이드에는 컨트롤러와 오퍼레이터로 구성되며, 클라이언트 사이드에서는 kubeseal을 사용한다.

사용자는 kubeseal CLI와 쿠버네티스 내 SealedSecret 컨트롤러, 오퍼레이터를 설치해야 한다. 그 후 kubeseal CLI를 활용하여 본인의 Secret 값을 암호화 한 SealedSecret 오브젝트를 얻는다.

예를 들어 다음과 같은 Secret yaml이 있고, kubeseal CLI를 통해서 kubeconfig와 연결된 클러스터의 SealedSecret Controller를 통해서 암호화를 하면

apiVersion: v1
kind: Secret
metadata:
  name: mysecret
  namespace: mynamespace
data:
  foo: YmFy  # <- base64 encoded "bar"

다음과 같이 SealedSecret yaml 파일이 생성된다.

apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
  name: mysecret
  namespace: mynamespace
spec:
  encryptedData:
    foo: AgBy3i4OJSWK+PiTySYZZA9rO43cGDEq.....

이제 SealedSecret yaml이 생성되었으므로, git에 올린다. ArgoCD와 같은 CI/CD 툴로 배포를 하면 SealedSecret 오브젝트가 클러스터에 배포되고 해당 오브젝트는 SealedSecret 컨트롤러에 의해 복호화 되며, 같은 이름의 Secret 오브젝트가 생성된다. 그 이후에는 동일하게 Secret을 사용할 수 있다.

설치 방법

  • 클러스터 사이드

Helm chart를 활용해 빠르게 설치할 수 있다.

먼저 repo를 등록해주자.

helm repo add sealed-secrets https://bitnami-labs.github.io/sealed-secrets

아래 명령어를 통해 차트를 설치하자.

helm install sealed-secrets -n kube-system --set-string fullnameOverride=sealed-secrets-controller sealed-secrets/sealed-secrets

—set-string fullnameOverride 옵션을 준 이유는 헬름 차트가 컨트롤러 이름을 sealed-secrets 로 설치하는데 kubeseal 컨트롤러 이름을 기본적으로 sealed-secrets-controller로 인식하기 때문이다.

설정을 안해주고 배포를 하면 매번 kubeseal을 실행할 때 다음과 같이 컨트롤러 이름을 지정해줘야 한다.

kubeseal --controller-name sealed-secrets <args>
  • 클라이언트 사이드

Mac

brew install kubeseal

Linux

KUBESEAL_VERSION='' # Set this to, for example, KUBESEAL_VERSION='0.23.0'
wget "https://github.com/bitnami-labs/sealed-secrets/releases/download/v${KUBESEAL_VERSION:?}/kubeseal-${KUBESEAL_VERSION:?}-linux-amd64.tar.gz"
tar -xvzf kubeseal-${KUBESEAL_VERSION:?}-linux-amd64.tar.gz kubeseal
sudo install -m 755 kubeseal /usr/local/bin/kubeseal

설치가 끝났다면 Secret yaml을 작성하고, kubeseal을 통해 SealedSecret을 만들 수 있다.

echo -n bar | kubectl create secret generic mysecret --dry-run=client --from-file=foo=/dev/stdin -o json >mysecret.json

kubeseal -f mysecret.json -w mysealedsecret.json

자세한 설치 방법이나 SealedSecret Controller의 키 교체 등과 관련해서는 공식 Github를 꼭 살펴보자.

Outro

SealedSecret은 Gitops에서 Secret 값을 암호화 하여 안전하게 올릴 수 있으며, 애플리케이션 입장에서도 소스코드를 변경하지 않고 그대로 Secret 값을 참조할 수 있었다. 설치 및 사용 방법도 굉장히 간단하기 때문에 Gitops 방식에서 Secret 관리가 고민이라면 도입해보는 것을 추천한다.

profile
개발 공부 내용 정리

0개의 댓글