In k8s administration, resources like secrets are not well maintained. kubeseal provides a relatively simple way to encrypt the original secret resource and decrypt it through the controller as a way to circumvent the risk of secret leakage.
install kubeseal
1
2
3
4
|
$ wget https://github.com/bitnami-labs/sealed-secrets/releases/download/v0.18.0/kubeseal-0.18.0-linux-amd64.tar.gz
$ tar -xvf kubeseal-0.18.0-linux-amd64.tar.gz
$ cp kubeseal /usr/local/bin/
$ kubeseal --version
|
Install controller
.
1
|
$ kubectl apply -f https://github.com/bitnami-labs/sealed-secrets/releases/download/v0.18.0/controller.yaml
|
After executing the above command, a controller Pod will be started under the kube-system namespace.
1
2
|
$ k get pod -n kube-system |grep seal
sealed-secrets-controller-b9fb75d85-k4csm 1/1 Running 0 7h28m
|
After the pod starts, use port forwarding to map to local.
1
|
$ kubectl -n kube-system port-forward svc/sealed-secrets-controller 8080:8080
|
Usage
Generate an encrypted file
First create a local file called secret-example.yaml
. The value of the secret
field before encoding is: mysupersecret
1
2
3
4
5
6
|
apiVersion: v1
kind: Secret
metadata:
name: secret-example
data:
secret: bXlzdXBlcnNlY3JldAo=
|
Use the following command to convert secret-example.yaml
, to the encrypted file sealed-secret-example.yaml
.
1
|
$ kubeseal --secret-file secret-example.yaml --sealed-secret-file sealed-secret-example.yaml
|
The contents of sealed-secret-example.yaml
are as follows, and spec.encryptedData.secret
is the encrypted content.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
creationTimestamp: null
name: secret-example
namespace: kube-system
spec:
encryptedData:
secret: AgB1ZZg8+J+0HLymOQZdTfWVQZiNkhm5X6WULJuBAAEaQQNhM8i2TV2I1SgKT4sUOCRv90XA1oeFld3XoGPjvYE3leOD1cvK1dDVqno6mNLRziokISk/9fB3cVE2GVgyCud//M53xNpVemDufgsJS2q/KGIOeNEijk9ZM2FaKoLDwtPaVNL0NfmC2xne2XtWJp+/eMOREhbubQhnj5M/Se75axazviuDNf6Ss9fAuR38Msd5DXnKBtyrckEHSa8TDn8ErssOh0ogX14e0/ThN3EWJecSBtx7Xfd0m90+vjmvWevMag442349aquR/qLo0mg40mhcCqSBw/MjaIGZ2F5XRufG1WEP43OgLMTixN2lLSU3eYTrv5t075taI9WJgoOl0DD8UA74EMpX7RMKTiXD6C0XngKmMKg5fUK7JNLFfwHMRPi4zNTwJa9ViDyD0iAJrGGbmMso/nHEtwOtrLE5Rrf0kLQ5N6Lj57gOBdqu903/vDM4Jm695GvEWL2aR3ShOxasHCuZeXj8Q5+KYWeF9sySiJH8bwEtaw6x7j9AxBOwjxWYD0Jvj9KhtlqBa4okSDc3bcgRKGhsSXQx6jOumI5rj+V542hkB6Z8JOtJ17VmzR6XDQDmqSl1FqqwKD5n5yUy5Kf6pJYBnsgKn3TzesQ6JfQbyRLTh1Pn3odOYCnp+Ixbd0Tgn0n5m0KO3RX0hiwGoe0hObIZcsF36g==
template:
data: null
metadata:
creationTimestamp: null
name: secret-example
namespace: kube-system
|
You can save the encrypted file to gitlab.
To create an encrypted file.
1
2
3
4
5
6
|
$ k create -f sealed-secret-example.yaml
sealedsecret.bitnami.com/secret-example created
$ k get sealedsecrets.bitnami.com
NAME AGE
secret-example 6s
|
After creating the encrypted file, the controller will decrypt it and generate the corresponding secret
.
1
2
|
$ k get secrets |grep secret-example
secret-example Opaque 1 2m15s
|
Looking at the contents of the secret
resource generated by the controller, you can see that data.secret
is the same as the secret-example.yaml
file created above.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
$ k get secret secret-example -oyaml
apiVersion: v1
data:
secret: bXlzdXBlcnNlY3JldAo=
kind: Secret
metadata:
creationTimestamp: "2022-06-10T00:50:40Z"
name: secret-example
namespace: kube-system
ownerReferences:
- apiVersion: bitnami.com/v1alpha1
controller: true
kind: SealedSecret
name: secret-example
uid: 57a5b691-9bb5-4dac-800a-1a1baa878299
resourceVersion: "675560"
uid: e0db31ad-082b-4596-9fd0-28cc810d86f4
type: Opaque
|
The ealedSecret
and the corresponding secret
resource must be located in the same namespace.
TIPS
-
The following API is supported by kubeseal
.
Route |
Description |
/healthz |
Health check route useful for the readiness and liveness probes and for creating an external probe; for example with blackbox exporter. |
/metrics |
Endpoint for the Prometheus to retrieve the controller’s metrics. |
/v1/verify |
Validates a secret. |
/v1/rotate |
Rotates the secret. |
/v1/cert.pem |
Retrieves the public certificate. |
-
The certificate used by the controller in the above example is self-generated, and you can also specify your own certificate, which is more convenient for migration and management.
-
With kubeseal
there may be a confusion that if the user mounts the secret of other namespace directly, then this may cause the secret to be leaked. There is an official explanation for this, e.g. you can restrict the namespaces and resource types that users can access via RBAC. See README for more information.