Sealed Secretsを試してみた
Sealed Secrets
は
Secretリソースを暗号化してくれるものです。
今いる現場でも手動デプロイしているので、Gitで管理すべく試してみました。
今回はRancherで構築したラズパイクラスタ で試します。
ubuntu@k8s1:~$ kubectl get node -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
k8s1 Ready controlplane,etcd 15d v1.24.13 192.168.0.51 <none> Ubuntu 20.04.6 LTS 5.4.0-1089-raspi docker://20.10.24
k8s2 Ready worker 15d v1.24.13 192.168.0.52 <none> Ubuntu 20.04.6 LTS 5.4.0-1069-raspi docker://20.10.24
k8s3 Ready worker 15d v1.24.13 192.168.0.53 <none> Ubuntu 20.04.6 LTS 5.4.0-1089-raspi docker://20.10.24
ラズパイにkubesealインストール
手順はこちら
。
今回はコントロールプレーンにkubesealをインストールします。
arm64版があるので、ラズパイでも使えます。
ubuntu@k8s1:~$ wget https://github.com/bitnami-labs/sealed-secrets/releases/download/v0.23.0/kubeseal-0.23.0-linux-arm64.tar.gz
ubuntu@k8s1:~$ tar -xvzf kubeseal-0.23.0-linux-arm64.tar.gz kubeseal
kubeseal
ubuntu@k8s1:~$ sudo install -m 755 kubeseal /usr/local/bin/kubeseal
ubuntu@k8s1:~$ kubeseal --version
kubeseal version: 0.23.0
Controllerのインストール
手順はこちら
。
Rancherで構築したダウンストリームクラスターなのでRancher GUIを使います。
まずリポジトリを作成します。
Chartsに出てくると思います。
最新のv0.23.0がインストールできるようです。
Rancher名前空間ちゃんと作ってくれないので、あらかじめ作成してます。
サービス名を固定したいのでfullnameOverrideだけ指定しています。
以下のリソースが作られました。
ubuntu@k8s1:~$ kubectl get all -n sealed-secrets-system
NAME READY STATUS RESTARTS AGE
pod/sealed-secrets-controller-68b55774fd-lf7gw 1/1 Running 0 95s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/sealed-secrets-controller ClusterIP 10.43.227.84 <none> 8080/TCP 95s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/sealed-secrets-controller 1/1 1 1 95s
NAME DESIRED CURRENT READY AGE
replicaset.apps/sealed-secrets-controller-68b55774fd 1 1 1 96s
ubuntu@k8s1:~$ kubectl get secret -n sealed-secrets-system
NAME TYPE DATA AGE
sealed-secrets-keygt242 kubernetes.io/tls 2 2m59s
sh.helm.release.v1.sealed-secrets-2-1690010267.v1 helm.sh/release.v1 1 3m7s
使ってみる
こちら の手順で試してみます。
ubuntu@k8s1:~$ echo -n bar | kubectl create secret generic mysecret --dry-run=client --from-file=foo=/dev/stdin -o json >mysecret.json
ubuntu@k8s1:~$ cat mysecret.json
{
"kind": "Secret",
"apiVersion": "v1",
"metadata": {
"name": "mysecret",
"creationTimestamp": null
},
"data": {
"foo": "YmFy"
}
}
fooのbarがYmFyになってますね。
kubesealで暗号化したSealedSecret作ります。
ubuntu@k8s1:~$ kubeseal <mysecret.json >mysealedsecret.json
error: cannot get sealed secret service: services "sealed-secrets-controller" not found.
Please, use the flag --controller-name and --controller-namespace to set up the name and namespace of the sealed secrets controller
サービス名と名前空間を指定しないといけないようです。
ubuntu@k8s1:~$ kubeseal --controller-name sealed-secrets-controller --controller-namespace sealed-secrets-system <mysecret.json >mysealedsecret.json
ubuntu@k8s1:~$ cat mysealedsecret.json
{
"kind": "SealedSecret",
"apiVersion": "bitnami.com/v1alpha1",
"metadata": {
"name": "mysecret",
"namespace": "default",
"creationTimestamp": null
},
"spec": {
"template": {
"metadata": {
"name": "mysecret",
"namespace": "default",
"creationTimestamp": null
}
},
"encryptedData": {
"foo": "AgAJ+P3zx55lVc8/6fyGLo6xjcrrBxElkD/2ZS4GZaK3bClojzam4JASH/0GBZyWqrh0pnoKbtKlBhDe9EIA0+dDz2L5Rizc0UjZdgttVmYTboLjvjbYUFPOdK5/Mk0GcYnIrhYskJQCKFc2Nehlx28Uckfex7UUYV2JZtXEc4niNacBPtFDdypUJQh7LEMcJ8m/Zs0jMgcfrs9y/A+f3JDdWIQicVr/9Uyo5lGrsJxCovIPlyxiBL3uy1V5yn9V5tbpm5l5H+yOdW3l6+/CU+QrUQUbHdJv0Y17IxXvUM4dpnrKUeVXUJ/e9cbmBHx9TzHyl0quBmQ9sC1+KOqf/AbfSz6TFexIww2ALkkxXFKKn8VwRhc3vvbUuyDZQ7mhn0xjaGetZsUjHcPKeupm9RHDrcKZ2fC/CELQQF5HT3YL1EZ9PuzMkvsbzX5rIar7d8EJA+9tIy5l45/fzLw1no5ABtozrXFDBXNl8gK9xzbUmNnGCR+U7lw2HNlxStwctFpT7P0cmToz90AKWBGToBWkChDgsDmUfFGVBXWwOo9dNzb6K+QLZBzJA8k44wM7EEjCpzU9AryreOwP6JzfD+QnCvHtGMu/ZtjPVEqAosWyJvRGznT6Nef6JVHuH7AUf1yeq/qFh7F9k9KD45o9Z3NoGQ3dbgSciTU4qOCI0noYHbkV+EM01tqonq36BTPiKFIsAlc="
}
}
}
無事barが暗号化されたSealedSecretが作成できたようです。
クラスタにデプロイしてみます。
ubuntu@k8s1:~$ kubectl create -f mysealedsecret.json
sealedsecret.bitnami.com/mysecret created
ubuntu@k8s1:~$ kubectl get secret mysecret
NAME TYPE DATA AGE
mysecret Opaque 1 12s
ubuntu@k8s1:~$ kubectl get secret mysecret -o yaml
apiVersion: v1
data:
foo: YmFy
kind: Secret
metadata:
creationTimestamp: "2023-07-22T07:26:44Z"
name: mysecret
namespace: default
ownerReferences:
- apiVersion: bitnami.com/v1alpha1
controller: true
kind: SealedSecret
name: mysecret
uid: b9aae13d-9c73-4858-ad62-e719b3aa78f8
resourceVersion: "5350956"
uid: 91fa0a2b-0a47-4777-a024-7ee72390808a
type: Opaque
ubuntu@k8s1:~$ kubectl get secret mysecret -o jsonpath="{.data.foo}" | base64 -d
bar
デプロイした後でデコードしたらbarが戻ってきた!
なるほど。
GitLabからデプロイ
こちら
で作成したGitLabのKASを使ってGitLabからpodにデプロイしてみます。
まずkubesealでファイルからSealedSecretリソースを作成します。
ubuntu@k8s1:~$ echo -n 'P@ssw0rd' > ./password.txt
ubuntu@k8s1:~$ cat password.txt
P@ssw0rd
ubuntu@k8s1:~$ kubectl create secret generic mypassword --from-file=./password.txt --dry-run=client -o yaml > mypassword.yaml
ubuntu@k8s1:~$ kubeseal --controller-name sealed-secrets-controller --controller-namespace sealed-secrets-system --secret-file mypassword.yaml --format yaml > mysealedpassword.yaml
ubuntu@k8s1:~$ cat mysealedpassword.yaml
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
creationTimestamp: null
name: mypassword
namespace: default
spec:
encryptedData:
password.txt: AgCjTiDrWVaBag5dXyiXX7LdPlfIR+QzLz92hlxOv7/InTt14d1+VlMxQHZx0F0lfG8H24/xA0jlTx91x3SB1cJQpkETZe+sLeo0kdibgFYdzWiJ4pwYW1iP3Qyu1KCrQY0XlZwnmE3uNDc9o8UZBdxhLPHdHJg7hPHWAMa96x4ZnyYP95ezC0rqKZn8Z0qz1kRuDkOIDuAfTtL+nVUTAD2kqrOw+QlD8Dx/zqGksh+fBEo6pq5kN+1+pLVRPhF3GeuaSB7fngLuCxceQslDFmwOk3d90aSUQEo+PaN+jJm9SqnzLPkbWCEd5EX3MGbt8NPqnG5tg2iCyABAaytV9L6EyxvRpNPIW/p4Z+uRRsmmRimDizP/IgFXpdglDQbll30a8LLbhcJ1StiJLRLPSJ3/I/docIaCMgMlQ8aLT8G63Fx57XaEJCVWrUP1oOT8nqJ9V0Awuz3A2T8a5dzSBinrRIG1cwFS6Aia057PQCWz7pHrMGtu+x+TRFTDkkFeLqA1zHoImsnasEyNWemkR5rpxmyFHJl9+GzsjtR/yvVh6E1aTiX+t6avc1P6ysbi6A80Hct5T8X/lRzn45FTGy22yAnVMkNxlmzMl+xuGtiRhbJgxMfSU77VYa8QECdnMMYGDd8BeWgnrKjb9qykQGGz4T1S5s754xj1Z6hiEgfbLmuHf9aUMTC4aKGxz0s8ZQjVGh66tM8Ctw==
template:
metadata:
creationTimestamp: null
name: mypassword
namespace: default
これでgitで管理しても安心。
SealedSecretリソースをpodにマウントして試してみたいので以下のようなyamlを準備します。
ubuntu@k8s1:~/my-project$ cat nginx.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: nginx
name: nginx
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: nginx
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: nginx
spec:
containers:
- image: nginx:latest
name: nginx
resources: {}
volumeMounts:
- name: secret
mountPath: "/tmp"
volumes:
- name: secret
secret:
secretName: mypassword
items:
- key: password.txt
path: secret
status: {}
デプロイするために.gitlab-ci.ymlは以下のようにします。
ubuntu@k8s1:~/my-project$ cat .gitlab-ci.yml
deploy:
stage: deploy
image:
name: bitnami/kubectl:latest
entrypoint: ['']
script:
- kubectl config get-contexts
- kubectl config use-context root/my-project:my-agent
- kubectl apply -f ./mysealedpassword.yaml
- kubectl apply -f ./nginx.yaml
以下のようなファイル構成にします。
my-project/
├── .gitlab-ci.yml
├── README.md
├── mysealedpassword.yaml
└── nginx.yaml
GitLabにpushします。
うまくいけば以下のようにジョブが成功します。
マウントできているか確認します。
ubuntu@k8s1:~/my-project$ kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx-7d86865557-29ncz 1/1 Running 0 9m32s
ubuntu@k8s1:~/my-project$ kubectl exec -it nginx-7d86865557-29ncz -- cat /tmp/secret
P@ssw0rd
平文でマウントされていますね!
まだバージョン1にもなっていないalpha版のようですが、良さそうですね。