쿠버네티스에서 Secret은 비밀번호, API 키, 토큰 등 민감한 정보를 저장하는 데 사용된다. 그러나 Secret은 base64로 인코딩되어 저장된다. 즉, 누구나 쉽게 디코딩할 수 있다.
공식 문서에 따르면 3가지의 Secret 관리 모범 사례를 제공한다.
이 글에서는 1번 방법에 대해서 설명
minikube로 테스트
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 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에 내용을 확인할 수 있다.
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: {}
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을 생성해 준다.
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은 암호화되지 않았다.
kubectl get secrets --all-namespaces -o json | kubectl replace -f -
해당 명령어를 실행하면 이미 저장된 Secret도 암호화할 수 있다.