Cloud/Kubernetes

SealedSecret 소개 및 사용

cstory-bo 2024. 5. 27. 09:23

Kubernetes에는 Secret이라는 오브젝트가 존재한다.

중요한 정보들을 담는데 어떻게 하면 더 보안을 높일 수 있는 2가지 방안이 존재한다.

Secret이란

먼저 Secret이란

  • db password나 ssh 키, 토큰 등 민감한 정보를 저장하고 관리하기 위해 사용되는 오브젝트이다.
  • ConfigMap과 사용 방법 등 비슷한 면이 많지만 Secret은 좀 더 보안이 중요한 정보들을 안전하게 관리하기 위한 것이다.
  • Secret 종류로는 아래와 같이 8종류가 있다.
Opaque 일반적인 용도로 사용되며, 특정 데이터 구조를 따르지 않습니다.
kubernetes.io/service-account-token 서비스 계정을 위한 토큰을 자동으로 생성하고 관리합니다.
kubernetes.io/dockercfg Docker 레지스트리의 인증 정보를 저장하기 위한 포맷입니다.
kubernetes.io/dockerconfigjson Docker config.json 파일의 내용을 저장합니다.
kubernetes.io/basic-auth 기본 인증을 위한 사용자 이름과 비밀번호를 저장합니다.
kubernetes.io/ssh-auth SSH 키 정보를 저장합니다
kubernetes.io/tls TLS를 사용하는 서버와 클라이언트 사이의 통신을 위한 인증서와 키를 저장합니다.

 

Secret은 기본적으로 Base64인코딩을 지원한다.
하지만 Base64인코딩은 누구나 plaintext를 볼 수 있다.

Sealed Secret

Sealed Secret으로 Secret을 좀 더 안전하게 사용할 수 있다.
특히, GitOps와 같이 소스 코드를 repository에 올릴 때 더욱 안전하게 사용 가능하다.

Sealed Secret은 SealedSecret CRD (Custom Resource Definition), Controller, Kubeseal CLI로 구성되어있다.

동작방법

  1. 사용자가 Sealed Secret 인증서를 가지고 Secret을 암호화한다.
  2. 이렇게 만들어진 SealedSecret은 레퍼지토리에 올려도 Sealed Secret 키가 없으면 복호화 하지 못한다.
  3. Key를 가지고 있으면 Controller가 자동적으로 복호화 하여 Secret과 동일하게 사용가능하다.

여기서 Controller가 가장 중요한 역할을 한다. Controller가 암호화, 복호화를 진행한다.

암호화 알고리즘

비대칭 암호화 알고리즘을 사용한다.

Public Key - 클러스터 외부에서 사용되며, Sealed Secrets를 암호화할 때 사용된다.
Private Key - SealedSecret 리소스를 표준 Kubernetes Secret으로 변환하는 데 사용된다.

SealedSecret 구현

helm 설치

curl https://baltocdn.com/helm/signing.asc | gpg --dearmor | sudo tee /usr/share/keyrings/helm.gpg > /dev/null
sudo apt-get install apt-transport-https --yes
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/helm.gpg] https://baltocdn.com/helm/stable/debian/ all main" | sudo tee /etc/apt/sources.list.d/helm-stable-debian.list
sudo apt-get update
sudo apt-get install helm

sealed-secrets-controller 설치

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

Secret 생성

kubectl create secret generic unsealed-mysql-secret --from-literal MYSQL_ROOT_PASSWORD=k8spass#

kubeseal로 암호화

kubectl create secret generic mysql-secret --from-literal MYSQL_ROOT_PASSWORD=k8spass# --dry-run=client -oyaml > mysql-secret.yaml
cat mysql-secret.yaml
echo "azhzcGFzcyM=" | base64 --decode


cat mysql-secret.yaml | kubeseal -o yaml > sealed-mysql-secret.yaml
kubectl apply -f sealed-mysql-secret.yaml

kubectl get sealedsecrets

mysql deployment로 사용해보기

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
      - name: mysql
        image: mysql:8.0
        ports:
        - containerPort: 3306
        env:
        - name: MYSQL_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysql-secret # 생성한 secret name 입력
              key: MYSQL_ROOT_PASSWORD # secret의 key 입력

mysql에 들어가서 비밀번호 확인

kubectl exec -it mysql-deployment-6c464894f7-sx4ng -- bash
mysql -uroot -p