[Kubernetes] Secret 관리 (암호화)

문린이·2024년 7월 11일
0

Secret 관리

쿠버네티스에서 Secret은 비밀번호, API 키, 토큰 등 민감한 정보를 저장하는 데 사용된다. 그러나 Secret은 base64로 인코딩되어 저장된다. 즉, 누구나 쉽게 디코딩할 수 있다.

공식 문서에 따르면 3가지의 Secret 관리 모범 사례를 제공한다.

  1. 저장된 데이터(at rest)에 암호화 구성

  2. 시크릿에 대한 최소 권한 접근 구성

  3. 외부 시크릿에 대한 액세스 구성

이 글에서는 1번 방법에 대해서 설명

테스트

minikube로 테스트

Secret 확인 (설정 X)

secretpassword 인코딩

echo -n secretpassword | base64 

# c2VjcmV0cGFzc3dvcmQ=

test-secret.yaml

apiVersion: v1
kind: Secret
metadata:
  name: test-secret
data:
  password: c2VjcmV0cGFzc3dvcmQ= # secretpassword

배포 후 확인

kubectl apply -f test-secret.yaml

kubectl get secret test-secret -o yaml

echo c2VjcmV0cGFzc3dvcmQ= | base64 --decode

# secretpassword%

etcd 확인

etcd pod에 접속

kubectl -n kube-system exec -it etcd-minikube -- sh
ETCDCTL_API=3 etcdctl \
--cacert /var/lib/minikube/certs/etcd/ca.crt \
--cert /var/lib/minikube/certs/etcd/server.crt \
--key /var/lib/minikube/certs/etcd/server.key \
get /registry/secrets/default/test-secret

위와 같이 Secret에 대한 접근 권한이 있거나 마스터 노드에 접근할 수 있으면 etcd에서 Secret에 내용을 확인할 수 있다.

암호화 구성

EncryptionConfiguration 파일 생성

minikube ssh

mkdir /etc/kubernetes/enc

vi /etc/kubernetes/enc/enc.yaml

enc.yaml

# head -c 32 /dev/urandom | base64
# UdIZ8sbHLgeNLIUEU32lXcvI0EUsCSZPUGTc2eOkDAI= (랜덤)

apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
  - resources:
      - secrets
    providers:
      - aescbc:
          keys:
            - name: key1
              secret: UdIZ8sbHLgeNLIUEU32lXcvI0EUsCSZPUGTc2eOkDAI=
      - identity: {}

kube-apiserver 파일 수정

vi /etc/kubernetes/manifests/kube-apiserver.yaml
apiVersion: v1
kind: Pod
metadata:
  annotations:
    kubeadm.kubernetes.io/kube-apiserver.advertise-address.endpoint: 10.20.30.40:443
  creationTimestamp: null
  labels:
	component: kube-apiserver
    tier: control-plane
  name: kube-apiserver
  namespace: kube-system
spec:
  containers:
  - command:
    - kube-apiserver
    ...
    - --encryption-provider-config=/etc/kubernetes/enc/enc.yaml  # add this line
    volumeMounts:
    ...
    - name: enc                           # add this line
      mountPath: /etc/kubernetes/enc      # add this line
      readOnly: true                      # add this line
    ...
  volumes:
  ...
  - name: enc                             # add this line
    hostPath:                             # add this line
      path: /etc/kubernetes/enc           # add this line
      type: DirectoryOrCreate             # add this line
  ...

수정 후 저장하면 Kubelet이 이를 감지하고 kube-apiserver를 재시작한다.

새 Secret 확인

새로운 Secret을 생성해 준다.

kubectl create secret generic new-secret --from-literal=password=newsecretpassword

생성 후 전과 같이 etcd를 확인해 본다.

kubectl -n kube-system exec -it etcd-minikube -- sh
ETCDCTL_API=3 etcdctl \
--cacert /var/lib/minikube/certs/etcd/ca.crt \
--cert /var/lib/minikube/certs/etcd/server.crt \
--key /var/lib/minikube/certs/etcd/server.key \
get /registry/secrets/default/new-secret

새 Secret이 암호화된 것을 볼 수 있다.

이미 저장된 Secret 확인

아직 이미 저장된 Secret은 암호화되지 않았다.

kubectl get secrets --all-namespaces -o json | kubectl replace -f -

해당 명령어를 실행하면 이미 저장된 Secret도 암호화할 수 있다.

profile
Software Developer

0개의 댓글