K8s를 운영하다 보면 흔히들 비밀정보를 관리를 해야하는 경우가 생긴다.
- 비밀정보 : DB 정보, ID/PW 등의 일반적으로 노출되면 안되는 정보들이다.
기본적으로 K8s에서는 Secrets Kind를 제공하고 있지만, 여러가지 사유에 의해서 재직중인 회사에서는 Vault를 사용하고 있고, Secrets과의 장/단점과 설치와 사용 방법에 대해 간략하게 리뷰하고자 한다!
Vault vs K8s secrets
아래의 장/단점만 보면 크게 Vault를 사용해야되는 장점이 없어보일 수 있으나 가장 큰 장점은 UI가 있어서 사용이 간편하고,
DDB 등으로 백업을 하고 있기 때문에 휴먼에러 등으로 비밀정보를 삭제하는 경우 복원이 쉽다.
다만, 반대로 가장 큰 단점은 Vault를 사용하기 위해서는 각 Pod에 Sidecar 형식으로 Container를 주입해야하는점이다.
- Container 주입은 어렵지 않지만, Pod에 추가적인 Resource가 할당된다.
구분 | 장점 | 단점 |
K8s Secret | 1. Deployment에 정의하는것만으로 사용이 가능하다. - 추가적인 sidecar 또는 Resource가 없어도 된다. |
1. Secret 정보를 디코딩 할 수 있다. - Base64로만 인코딩하므로 보안적으로 좋지는 않다. 2. 버전 관리가 쉽지 않으며, 잘못삭제한 경우 복구가 어렵다. 3. 디코딩 입력하는 과정에서 null 등의 문자열로 깨질 수 있다. |
Vault | 1. 사용이 간편하며, 접근통제하기 용이하다. - UI Dashboard를 제공하고 있으며 2. ns + sa로 통제가 가능하다. 3. ddb 등으로 버전 관리와 복구가 쉽다. |
1. Container 개수가 많아질 수 있다. - pod에 vault container가 필요하다. - k8s 추가 resource 필요하다. |
Vault 배포 방법
설치는 Helm으로 배포하는 방법이 가장 쉽고, 간편한 방법인것 같다.
아래 과정을 따라하면 쉽게 배포할 수 있고 Vault Docs에도 잘 나와있다. 사실 Docs만 봐도 설치는 어렵지 않다.
아래는 필자가 주로 하는 방식이라서, Chart Pull하고 했는데 더 좋은 방법도 많고 다양한 방법이 있으니 편한 방법으로 하면 된다.
#helm chart를 받기 위한 repo 등록
helm repo add hashicorp https://helm.releases.hashicorp.com
helm repo update
#vault helm chart pull
helm pull hashicorp/vault
#위에서 pull한 chart 압축해제
tar -xvf vault-0.24.1.tgz
#helm chart + vaules로 배포
#배포하기 이전에는 diff로 실제 변경분을 확인하는게 좋다.
helm upgrade --install vault ./vault -f ./{vault helm values}.yaml
아래는 Vault Helm Values이다. Vault Chart를 보면 훨씬 더 많은 옵션이 존재한다. 하지만 대부분 선택값이고 아래와 같이 설정해도 Vault 배포는 가능하다.
그리고 Vault에서는 HA 구성이 중요하다. 아래는 AWS DDB를 기준으로 HA 구성을 한것이다. 이외에도 Consul? 등의 방법이 존재하나 DDB로 HA 구성하는게 가장 손쉬운것 같아서 DDB로 구성한다.
- 더 좋은? 더 향상된 옵션이 있시면 댓글로 알려주세요~
USER-SUPPLIED VALUES:
server:
dev:
enabled: false
ha:
config: |
ui = true
listener "tcp" {
tls_disable = 1
address = "[::]:8200"
cluster_address = "[::]:8201"
}
storage "dynamodb" {
ha_enabled = "true"
region = "{region location}"
table = "{table name}"
}
service_registration "kubernetes" {}
seal "awskms" {
region = "{region location}"
kms_key_id = "{kms id}"
}
enabled: true
replicas: 2
image:
repository: hashicorp/vault
ingress:
annotations:
alb.ingress.kubernetes.io/certificate-arn: {vault domain acm arn}
alb.ingress.kubernetes.io/healthcheck-path: /v1/sys/health?standbyok=true
alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS": 443}]'
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/waf2-acl-id: {vault waf arn}
kubernetes.io/ingress.class: alb
enabled: true
hosts:
- host: {vault domain name}
paths:
- /
pathType: Prefix
service:
enabled: true
type: NodePort
serviceAccount:
annotations:
eks.amazonaws.com/role-arn: {vault service account iam arn}
위 방법으로 Vault를 배포하게 되면 아래와 같이 Vault Pod이 Running 상태가 되지 않는다.
그리고 ELB Target에서도 Unhealthy로 나타난다. 이는 현재 Vault를 배포만 하고 Vault를 활성화하지 않았기 때문이다.
Vault를 활성화 하기 이전에 Vault Pod에 접속하면 상태를 확인해보면 아래와 같이 Sealed=true 이다.
즉, 암호화 되어 있음을 뜻하고 있고 아직 Vault 활성화가 되지 않았다는 뜻이다. HA 정보도 없고 Active Date도 없다.
/ $ vault status
Key Value
--- -----
Recovery Seal Type awskms
Initialized false
Sealed true
Total Recovery Shares 0
Threshold 0
Unseal Progress 0/0
Unseal Nonce n/a
Version 1.13.1
Build Date 2023-03-23T12:51:35Z
Storage Type dynamodb
HA Enabled true
Vault Setup 방법
vault operator init 실행
vault operator init을 하면 아래와 같이 Root와 Recovery Key를 확인할 수 있다.
Root Key는 말 그대로 최고 관리자 Key이다. 그리고 Recovery Key는 Vault에서 비밀정보를 삭제 또는 복구할 때 사용하는 Key이다.
아래 Key는 최초에만 확인이 가능하며, 복구하기 위해서 필요한 값이므로 반드시 어떤 공간에 저장해야 한다.
/ $ vault operator init
Recovery Key 1: ssc2DPxxxxxxxxxxxxxxxx
Recovery Key 2: qIB5GHxxxxxxxxxxxxxxxx
Recovery Key 3: nCbp+5xxxxxxxxxxxxxxxx
Recovery Key 4: siAofpxxxxxxxxxxxxxxxx
Recovery Key 5: bMgzUxxxxxxxxxxxxxxxxx
Initial Root Token: hvs.xxxxxxxxxxxxxx
Success! Vault is initialized
vault operator init을 하면 아래와 같이 상태값이 변하고, 이때부터 Ingress로 설정한 Domain으로 접속이 가능하다.
하지만 필자는 K8s에 서비스가 올라가있기 때문에 Kubernetes 인증을 한번 해줘야한다.
/ $ vault status
Key Value
--- -----
Recovery Seal Type shamir
Initialized true
Sealed false
Total Recovery Shares 5
Threshold 3
Version 1.13.0
Build Date 2023-03-01T14:58:13Z
Storage Type dynamodb
Cluster Name vault-xxxxxxxxxx
Cluster ID 0a34b5d0-xxxxxxxxx
HA Enabled true
HA Cluster https://vault-0.vault-internal:8201
HA Mode active
Active Since 2023-04-18T09:31:58.227157353Z
Kubernetes 인증 활성화
인증을 활성화하는 방법도 어렵지 않다.
해당 인증을 활성화하지 않으면 Sidecar로 주입된 Vault-injector가 비밀정보를 확인할 수 없다.
VAULT_TOKEN에는 위에서 init하였을 때 확인한 ROOT token 값을 넣으면 된다.
# Vault Pod에 접속하여 아래 명령어 실행
/ $ export VAULT_TOKEN=hvs.xxxxxxxxxxxxxxx
/ $ vault auth enable kubernetes
Success! Enabled kubernetes auth method at: kubernetes/
/ $ vault write auth/kubernetes/config \
> token_reviewer_jwt="$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" \
> kubernetes_host="https://$KUBERNETES_PORT_443_TCP_ADDR:443" \
> kubernetes_ca_cert=@/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
Success! Data written to: auth/kubernetes/config
Kubernetes 인증까지 활성화하면 Vault 사용을 위한 준비는 모두 마쳤다.
Vault 배포가 정상적이라면 아래와 같이 1개의 Deployment, 1개의 Statefulset이 생긴다.
- 위 Helm Values에서 replicas=2로 지정했다. 그렇기 때문에 vault-0, -1이 배포되었다.
- 실제로는 Master-Slave로 구성되며 Master가 업무 수행을 하고/Master의 Probe가 정상적이지 않다면 Slave로 역할이 넘어간다.
- 반대로 Slave로 요청하더라도, Master로 Redirection 된다.
그리고 Vault values에서도 알 수 있듯이 storage를 DDB로 설정했기 때문에 Vault Setup을 만료한 다음에 DDB가 아래의 모습이다.
기본적으로 비밀정보를 다루는 오픈소스이기 때문에 실제 DDB의 값들도 모두 암호화 되어 있다.
이번 게시물에서는 Vault에 대한 설치 방법에 대해 알아보았다.
위에서 언급한것과 같이 Vault는 Sidecar로 구성된다. 즉, Vault를 사용하고자 하는 Pod에 Vault Sidecar annotation을 설정해야 한다. 그렇게 되면 Pod에 서비스 + vault container로 떠 있게 된다!!
다음 게시물에서는 실제 Vault에 대한 사용 방법에 대해 알아보고자 한다!!
끝!!
'기술 이모저모 > [Ops] Devops' 카테고리의 다른 글
[Vault] Vault 서비스 사용 방법[2/2] (0) | 2023.04.30 |
---|---|
[Vault] Vault 서비스 사용 방법[1/2] (0) | 2023.04.30 |
[SLA] 서비스 안전성의 주요 지표 SLI, SAO + SLA (0) | 2023.04.02 |
[Karpenter] Karpenter vs Cluster AutoScaler 장/단점 비교 (0) | 2023.03.26 |
[Karpenter] Karpenter를 활용하여 EKS 노드 비용 최적화[1/2] (0) | 2023.03.25 |