SealedSecret이란?
k8s에서 가장 많이 함께 이용되는 개념 중 하나인 GitOps에서는 매니페스트를 저장소에 배치한다.
이때 배치된 저장소에는 secret도 함께 올라가게 되는데 이 소스는 Base64 encode되있을 뿐 암호화되지 않는다. 때문에 이를 암호화하여 서비스 노드에서 작동할 수 있도록 하여야하는데, 이때 사용하는 대표적인 도구가 SealedSecret이다.
Problem: "I can manage all my K8s config in git, except Secrets."
Solution: Encrypt your Secret into a SealedSecret, which is safe to store - even inside a public repository. > The SealedSecret can be decrypted only by the controller running in the target cluster and nobody else (not even > the original author) is able to obtain the original Secret from the SealedSecret.
구조
SealedSecret은 커스텀 리소스를 생성해 두고 클러스터에 등록하면 클러스터 내부에서 SealedSecret에서 시크릿 리소스로 변환되는 구조이다.
우선 SealedSecret은 k8s 내부 시크릿 리소스로 공개키와 비밀키를 생성한다. 시크릿 리소스를 SealedSecret리소스로 암호화할 때는 클러스터에 있는 공개키를 사용하여 kubeseal 명령어로 암호화하며 리소스를 k8s에 등록하면 SealedSecret 컨트롤러가 비밀키를 사용하여 시크릿 리소스로 복호화한다. SealedSecret 컨트롤러는 모든 비밀 키를 사용하여 복호화를 시도하기 위해 kubeseal 명령어로 암호화하는 키를 로테이션할 수 있게 되어있다.
간단히 다시 말해 대칭키 알고리즘을 활용한 암호화인 것이다.
사용법
$ brew install kubeseal
$ k apply -f https://github.com/bitnami-labs/sealed-secrets/releases/download/v0.22.0/controller.yaml
$ k get secret -n kube-system \
> -L sealedsecrets.bitnami.com/sealed-secrets-key \
> -l sealedsecrets.bitnami.com/sealed-secrets-key
NAME TYPE DATA AGE SEALED-SECRETS-KEY
sealed-secrets-keyxxxxx kubernetes.io/tls 2 15m active
위 명령어를 통해 쉽게 설정할 수 있으며, 이후 kubeseal command를 활용해 암호화하면 된다.
$ cat <<EOF > auth.yaml
>apiVersion: v1
>kind: Secret
>metadata:
> name: auth
>type: Opaque
>data:
> username: cm9vdAo=
> password: cm9vdHJvb3QK
>EOF
$ kubeseal -o yaml < auth.yaml > sealed-auth.yaml
$ cat sealed-auth.yaml
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
creationTimestamp: null
name: auth
namespace: default
spec:
encryptedData:
password: AgCWLO5n5xGrGXIGwqI43Rj7SO7gsKaCgfLPHZZX5yh/D9CnqC9RMkHx24HLxGUwb9tFEVuUEy+SSZrZz1jmzbWGeCGTlP8YEpNSGpIiyGDHTX+vjGPgd6mLssJmZchuT0d0Pui2twqcj/KOfTNfJovdPpEmhK75xl3hhNtVjdYO79wyVsSvxoGuGNp4Mz1UdHF6qr7/80jQCvHmtV2wvvpe7qVoR41rhJBAoz+V/fHK/H6d8og+bFbyhAzsQYC9lz6JYtM01YsUByfVVyRnDmRt98GOzytbyQOx9uROEBj6u3Zt24TKZwY/gCq1gcq4h2RL6pjcsl/eiNNxiITqO8kPJhYBasal6nxPtLy1pb6d+bxLhSOLNSmxmSNFrF6Xwh+7yOviAuVPxZMJffkeRG+cmYRiTu8D39qPXVimwtx+joHxyiZvSFjCAu26diyTzHp/VHQ1a30jRrOnvQN/SddGixx7r5lLXB16j3GkpY1fbeYRGa6OZyrIZiRcLGgTgZ2yjooZRXwks/HYKmqer+UJhkuWN3kC9uYi7H0Fl60k7L1CpjYY0h06b/TOpu6RlZKzHR2gmRzWmudcIjnDscdZwlmyT/UNgjqZ8C+k7yWIBMBB/tT9MSOuKySlOiNkcsWjZIpO+8i3+Uuo0T5CM4yZMtaGkcDprk3/giyCFgaOPjkOjOrOnjdhJCnE02p1FISsvugJrrwgbcM=
username: AgBV5mYAk579rbCNEe/6PswSyePjlxHxHjdLK83mHX9oJIwo3yKMzfo7GAEg8dAmLqoUJIiDXrRxizfuqvfz+3uzY2smNNmUe7jR5RXOU+b8qQULsbOHV8TLV4zsL4hje/63L+T4Rz0w3mG+qpXGF1hYhwEVLS/FRRCGzhCXGMqNBvlVbfDe7fRiSCghJR9+l0j3ZzCUQpjJMTSeRX8oT0FyPVQLaDYRalX36RvWNISMtVklPmmMXvLjcOti571fBjHfkT7LMypZDbYetzRe/RkayuVE/xXZwZCxjR9++BFxTAyuHu9zNocYS7oKNRxoXYYUX27HqZwZjFDmDMiMdX28K7C8hYTBmprN3ZZsr6DQv5i5g4cvNJ5TQjEBymDUJvE7bVy7Ej/lHxVVQ0Uhp0PhyzycZu6kRQwIg2/dP+IUGAUTyVGzBAnZnTU8HrXr1OofwGx1QBl1cISPGdTNcO69xq+C7k2yV8YEvRSL+YBPjRIimRh7r4hMlaqT/IFO6DlrBeFYpzkhqt6S369D9UYxI4ss2fritXTeojdq+xZkmIQ3RP/QFQ5usAVITxOl6zrgmlKrdTpEm+/lkzdW4l1cf0dtQNmX+QU7qeIXIvZoOg6VsC3+BWWntE7Nqauqick74kro9682bK8aFZn1h3Vfzr+j0/eOMdAYj9hHJTJzkkc7e9SbNfW8eq0MlIdE40Iz/+iiUA==
template:
metadata:
creationTimestamp: null
name: auth
namespace: default
type: Opaque
auth.yaml의 암호화가 진행된 모습이 정상적으로 sealed-auth.yaml 에 표시되는 것을 확인할 수 있다.
$ k apply -f sealed-auth.yaml
sealedsecret.bitnami.com/auth created
$ k get sealedsecret/auth secret/auth
NAME AGE
sealedsecret.bitnami.com/auth 81s
NAME TYPE DATA AGE
secret/auth Opaque 2 81s
이후 apply하여 사용할 수 있다.
키 유출 시 대처방법
운영하다보면 github에 키가 유출될 수 있다. 이때는 아래와 같이 키를 로테이트하고 다시 암호화하여야한다.
$ k -n kube-system get pods
NAME READY STATUS RESTARTS AGE
aws-node-jrjwf 1/1 Running 0 39m
aws-node-vjxbs 1/1 Running 0 39m
aws-node-z2v8s 1/1 Running 0 39m
coredns-76b4dcc5cc-dc6xk 1/1 Running 0 48m
coredns-76b4dcc5cc-r8xbb 1/1 Running 0 48m
kube-proxy-7ls78 1/1 Running 0 39m
kube-proxy-s9s59 1/1 Running 0 39m
kube-proxy-sx8r4 1/1 Running 0 39m
sealed-secrets-controller-6dcc946585-b8qrd 1/1 Running 0 26m
$ k -n kube-system exec -it sealed-secrets-controller-6dcc946585-b8qrd -- controller --key-cutoff-time "$(LANG=C date '+%a, %d %b %Y %T %z')"
k get pods -n kube-system을 통해 조회한 sealed-secrets-controller pod를 exec 하여 키를 다시 생성하도록 한다.
$ k get secret -n kube-system \
> -L sealedsecrets.bitnami.com/sealed-secrets-key \
> -l sealedsecrets.bitnami.com/sealed-secrets-key
NAME TYPE DATA AGE SEALED-SECRETS-KEY
sealed-secrets-keys45b5 kubernetes.io/tls 2 114s active
sealed-secrets-keyxvrw5 kubernetes.io/tls 2 29m active
다시 조회해보면 위와 같이 방금 전에 생성된 키도 조회된다.
$ kubeseal --re-encrypt < sealed-auth.yaml > resealed-auth.yaml
위 옵션을 통해 복호화 -> 암호화 가 아니라 다시 암호화할 수 있다.
'DevOps > k8s' 카테고리의 다른 글
k8s dns ndots (0) | 2023.08.15 |
---|---|
k8s의 보안 (0) | 2023.08.13 |
느슨한 결합을 위한 ExternalName 서비스 (0) | 2023.06.21 |
K8S server-side apply & managed fields (0) | 2023.06.18 |
helm install bitnami nginx m1 오류 (0) | 2023.06.10 |