Going In

안녕하세요~! 오늘은 k8s 에서 pod 를 운영할 때 기밀정보를 어떻게 관리하면 좋고, 기밀정보에 대한 관리의 책임은 어떤 component 가 갖고 있는지 한번 알아보도록 할게요
서비스되고 있는 서비스 서버들이 많아질 수록 보안에 대한 중요성 또한 점점 커지고 있는데요.
과연 정말 보안적으로 안전한가? 에 대한 의문점까지 같이 해결해보도록 해보죠 ㅎㅎ
Secret
What is secret?
A Secret is an object that contains a small amount of sensitive data such as a password, a token, or a key.
k8s 에서의 secret 은 password, token, key 와 같이 소량의 기밀정보를 포함하고 있는 것을 의미합니다.
우리가 secret 을 사용함으로써 application server 가 배포되는 pod 에는 더 이상 기밀정보를 포함시킬 필요가 없는 것이죠.
pod 와는 독립적인 life cycle 을 가져감으로써 기밀정보가 노출되는 것에 대한 위험성도 줄이고, 관리 체계를 다르게 가져갈 수 있기 때문에 많은 사람들이 기밀정보를 k8s secret 에 등록하고 운영합니다.
How use secret?
보통은 yaml file 을 통해 쉽게 생성해볼 수 있습니다.
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
USER_NAME: YWRtaW5fdXNlcgo=
PASSWORD: YWRtaW5fcGFzc3dvcmQK
위와 같이 kind 를 secret 으로 정의해주시고, data 에 저장하고하는 기밀정보를 key value 형태로 넣어주시면 됩니다.
단, value 는 base64 encoding 처리를 해준 뒤에 넣어주어야 하는 것을 꼭 기억해주세요.
mac 에서 base64 encdoe / decode 하는 방법은 아래와 같습니다.
# encoding
echo test_encoding | base64
# decoding
echo dGVzdF9lbmNvZGluZwo= | base64 --decode
위에서 정의한 yaml 을 생성하기 위해서는 아래와 같은 명령어를 추가 실행해주면 됩니다.
kubectl apply -f secrets.yaml
위와 같이 생성한 뒤에 kubectl describe secrets 를 해준다면?
mysecret 이라는 secret 이 생성된 것을 보실 수 있네요 ㅎㅎ
k8s dashboard 를 활용중이시라면, secert 영역에 들어가셔서도 확인해볼 수 있습니다.
Apply on pod
위와 같이 secret 을 정의하였으면 pod 에서 참고할 수 있게 지정해볼 수 있는데요.
여러가지 방법이 있겠지만, 환경변수로 지정하는 방법을 예제로 보여드릴까 합니다.
apiVersion: v1
kind: Pod
metadata:
name: secret-test-pod
spec:
containers:
- name: test-container
image: registry.k8s.io/busybox
command: [ "/bin/sh", "-c", "env" ]
envFrom: # env variable
- secretRef:
name: mysecret # secret name
restartPolicy: Never
위와 같이 pod 에서 envFrom 이라는 옵션을 주어, secret 에 속한 모든 기밀정보를 일괄적으로 가져올 수 있습니다.
이렇게 일괄적으로 가져오는 것을 원치 않는다면, 일부만 가져오는 것도 가능합니다.
apiVersion: v1
kind: Pod
metadata:
name: secret-env-pod
spec:
containers:
- name: mycontainer
image: redis
env:
- name: SECRET_USERNAME
valueFrom:
secretKeyRef: # secret refer
name: mysecret # secret name
key: USER_NAME
restartPolicy: Never
위 처럼 말이죠.

하지만 위와 같이 정리하다보니 정말 secret 이 안전할까? 에 대한 의문이 있을 것입니다.
이에 대해서 고찰해보도록 해볼게요
Does secret is really safe on security?
놀랍게도 secret 을 특정 조치 없이 사용한다면 보안적으로 안전하지 않습니다. 그에 대한 이유를 알아보도록 해보겠습니다.
Base64
아까 설정값에서 base64 encoding 해서 값을 넣는다고 했었는데요. base64 encoding 은 절대 안전하지 않습니다.
https://en.wikipedia.org/wiki/Base64
base64 는 바이너리 데이터를 공통 ASCII 문자로 표현하기 위한 수단에 불과하기 때문이죠. 따라서 encoding 여부가 보안을 충족시킨다고 보기에는 어렵습니다.
Warning of the secret
documentation 에도 잘 나와 있는 내용인데요.
이는 secret 데이터가 etcd 영역에 저장되는데, etcd 에 저장될 때 encryption 되지 않고 plain text 를 유지하여 저장하기 때문이죠.
encryption 하지 않는다는 것은 base64 encoding 만 적용되는 것을 의미하고, 이 데이터가 탈취당하게 되면 누구나 쉽게 기밀정보를 획득할 수 있게 됩니다.

따라서 k8s cluster 를 운영한다면, 첫번째로 encryption 기능을 추가하여 secret 이 저장될 수 있게 하는 것이 중요합니다.
두번째로는 RBAC(Rolee base access control) rule 을 정의하고, secret 에 접근할 수 있는 권한을 최소 권한으로 유지하도록 하는 것인데요. 배포되는 pod 와 특정 개발자에게만 권한을 부여해서 컨트롤 하는 방식입니다.
세번째로는 secret 에 접근가능한 container 를 제한하는 것인데요. 이는 yaml 설정으로 제한한다면 크게 무리는 없을 것입니다.
마지막으로는 secret 을 저장하는 것을 cluster 에 하지말고, 외부 provider 들을 이용하라 인데요.
https://secrets-store-csi-driver.sigs.k8s.io/concepts.html#provider-for-the-secrets-store-csi-driver
Concepts - Secrets Store CSI Driver
The diagram below illustrates how Secrets Store CSI volume works: Similar to Kubernetes secrets, on pod start and restart, the Secrets Store CSI driver communicates with the provider using gRPC to retrieve the secret content from the external Secrets Store
secrets-store-csi-driver.sigs.k8s.io
각 cloud 벤더사별로 정리되어 있어, 벤더사에 맞는 driver 를 적용해서 진행하면 됩니다.
정리하며
오늘은 k8s secret 에 대해 알아보았네요.
요즘 개인정보 유출 사고가 발생하여 고객들에게 피해가 되는 사례가 늘고 있는 만큼
서비스를 개발하는 개발자들도 이를 꼭 신경써서 유출되는 슬픈 사례가 발생하지 않았으면 하네요 ㅎㅎ
참고자료
Secrets | Kubernetes
'Developer > Kubernetes' 카테고리의 다른 글
[K8S] Pod topology spread constraint - 토폴로지 분배 제약 (0) | 2023.08.26 |
---|---|
[K8S] HPA - 쿠버네티스 Horizontal Pod AutoScaler (2) | 2021.12.26 |
[k8s/쿠버네티스] - Deployment로 애플리케이션 배포 (0) | 2020.07.20 |
Docker - python server기반 Dockerfile을 만들어보자 (0) | 2020.07.04 |
[쿠버네티스 입문] - Pod 운영 (0) | 2019.01.15 |