회사에서 EKS에 CWPP를 배포할수있는 소중한 기회를 얻었다.
( 도입해준 회사에 무한한 감사를 )
github에 helm chart 올리고 argocd로 배포할 생각인데...
key값들을 그냥 vaule에 박아서 사용하라네..?
회사에선 vault를 사용중이었기 때문에 혹시 몰라 업체에 연락해서 지원되는지 물어봤는데 지원은 안해준다고 답변을 받았다.
기존 helm chart를 손보고 vault injector로 secret, configmap을 안쓰도록 해봤는데 잘안되더라.
그래서 생각한게 처음에는 sealed secret 이었다.
설치는 꽤나 간편했고 사용하는 것도 딱히 어렵진 않았다.
하지만 결국에 secret을 쓰는건 똑같았다.
마치 뫼비우스 띠에 갇힌 느낌이랄까?
sops 쓰는것 마냥 로컬에서 sealed secret controller로 암호화 해줘야하는것도 생각보다 번거로운 일이었고
인프라팀에게 내용 공유해드렸더니, 이미 사용중인 vault가 있는데 또 관리해야할 리소스를 만드는게 맞는가 싶다고 하셨다.
내용을 듣다보니 맞는말이네? ㅋㅋㅋㅋㅋㅋ
그러면서 vault secret operator를 공유해주셨다.
내용을 훑어보니 sealed secret이랑 크게 다르진 않아 보였다.
차이점은 인증 방식 정도?
오히려 세팅만 잘하면 관리자 입장에선 sealed secret처럼 번거롭게 암호화 과정을 거치치 않아도 되는게 좋아 보였다.
그럼 뭐다?
바로 테스트 해봤다.
aws-vault exec dev -- helm install --namespace <namespace> <resource-name> hashicorp/vault-secrets-operator \
--set "defaultVaultConnection.enabled=true" \
--set "defaultVaultConnection.address=http://vault-internal.vault.svc.cluster.local:8200"
kubernetes role을 사용한다.
role을 사용할 sa, sa ns도 지정.
apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultAuth
metadata:
name: test-vault-auth
namespace: {{ .Release.Namespace }}
spec:
method: kubernetes
mount: kubernetes
kubernetes:
role: test-role # vault role name
serviceAccount: security-sa # secret을 사용할 앱에서 만들어질 SA Name(vault role에 입력했던 것과 동일해야함)
audiences: # role을 생성할 때 넣었던 audience 값 입력
- security
apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultStaticSecret
metadata:
name: {{ include "EDR.fullname" . }}-vault-static-secret
namespace: {{ .Release.Namespace }}
spec:
type: kv-v2 # type
# mount path
mount: security # Secret Engine name
# path of the secret
path: dockerconfigjson
# dest k8s secret
destination:
name: {{ include "EDR.fullname" . }}-pull-secret # kubernetes secret으로 생성할 kubernetes secret name 입력
create: true # kubernetes secret으로 생성여부
type: kubernetes.io/dockerconfigjson # imagepullsecret 일때는 명시필요함.
# static secret refresh interval
refreshAfter: 60s
# Name of the CRD to authenticate to Vault
vaultAuthRef: {{ include "EDR.fullname" . }}-vault-auth
# 기존에 envfrom > confimapRef로 설정되어있던걸 secretRef로 변경
# env: 환경 변수를 세밀하게 설정하거나 개별적으로 관리하고 싶을 때 사용.
# envFrom: ConfigMap 또는 Secret의 모든 키-값 쌍을 환경 변수로 가져올 때 사용.
- envFrom:
- secretRef:
name: {{ include "EDR.fullname" . }}-config
역시나 테스트환경과 운영환경의 일치가 중요하다는것을 한번더 깨닫는다.
근데 실제 운영환경은 서로 다른 클러스터에 있었다.
PUT https://vault.com/v1/auth/kubernetes/login
Code: 403. Errors: * permission denied"
배포해보려고 하니 위와 같이 permission denied가 발생했다.
kubernetes role에 도메인도 바꿔보고, ca, token 값도 변경해봤으나 동일했다.
Kubernetes auth method Doc를 차근차근 읽어보고 답을 찾을수 있었다
kubernetes api 서버가 인증요청을 처리할때 특정 주체에게 권한을 위임할수 있도록 서비스 어카운트에 system:auth-delegator 권한을 바인딩 해줘야 했다.
kubectl create clusterrolebinding vault-client-auth-delegator \
--clusterrole=system:auth-delegator \
--group=group1 \
--serviceaccount=default:svcaccount1 \
...
그래서 VaultAuth에서 사용하는 SA에 ClusterRoleBinding을 구성하도록 HelmChart에 template을 추가했다.
이로써 gitops 환경에 key값을 하드코딩 하지 않고 secret으로 사용할 수 있게 되었다.