sealedsecrets prototype

This commit is contained in:
marcel-dempers 2022-11-07 15:52:54 +11:00
parent ec8bfc9325
commit 655764b074
3 changed files with 601 additions and 0 deletions

View File

@ -0,0 +1,231 @@
# Introduction to Sealed Secrets
Checkout the [Sealed Secrets GitHub Repo](https://github.com/bitnami-labs/sealed-secrets) </br>
## Create a kubernetes cluster
In this guide we we''ll need a Kubernetes cluster for testing. Let's create one using [kind](https://kind.sigs.k8s.io/) </br>
```
kind create cluster --name sealedsecrets --image kindest/node:v1.23.5
```
See cluster up and running:
```
kubectl get nodes
NAME STATUS ROLES AGE VERSION
sealedsecrets-control-plane Ready control-plane,master 2m12s v1.23.5
```
## Run a container to work in
### run Alpine Linux:
```
docker run -it --rm -v ${HOME}:/root/ -v ${PWD}:/work -w /work --net host alpine sh
```
### install kubectl
```
apk add --no-cache curl
curl -LO https://storage.googleapis.com/kubernetes-release/release/`curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt`/bin/linux/amd64/kubectl
chmod +x ./kubectl
mv ./kubectl /usr/local/bin/kubectl
```
### test cluster access:
```
/work # kubectl get nodes
NAME STATUS ROLES AGE VERSION
sealedsecrets-control-plane Ready control-plane,master 3m26s v1.23.5
```
## Install Sealed Secret Controller
### download the YAML
In this demo we'll use version [0.19.1](https://github.com/bitnami-labs/sealed-secrets/releases/download/v0.19.1/controller.yaml) of the sealed secrets controller downloaded from the
[Github releases](https://github.com/bitnami-labs/sealed-secrets/releases) page
```
curl -L -o ./kubernetes/secrets/sealed-secrets/controller-v0.19.1.yaml https://github.com/bitnami-labs/sealed-secrets/releases/download/v0.19.1/controller.yaml
```
### alternative install Helm
TODO: cover helm https://github.com/bitnami-labs/sealed-secrets#helm-chart
### install the controller
```
kubectl apply -f kubernetes/secrets/sealed-secrets/controller-v0.19.1.yaml
```
### Check the install
```
kubectl -n kube-system get pods
```
TODO: check the logs with `kubectl -n kube-system logs` command
TODO: important logs
```
2022/11/05 21:38:20 New key written to kube-system/sealed-secrets-keymwzn9
2022/11/05 21:38:20 Certificate is
-----BEGIN CERTIFICATE-----
< cert content >
-----END CERTIFICATE-----
2022/11/05 21:38:20 HTTP server serving on :808
```
TODO: check our secret
```
kubectl get secret -n kube-system sealed-secrets-keymwzn9 -o yaml
```
## Download KubeSeal
The same way we downloaded the sealed secrets controller from the [GitHub releases](https://github.com/bitnami-labs/sealed-secrets/releases) page,
we'll want to download kubeseal from the assets section
```
curl -L -o /tmp/kubeseal.tar.gz \
https://github.com/bitnami-labs/sealed-secrets/releases/download/v0.19.1/kubeseal-0.19.1-linux-amd64.tar.gz
apk add tar
tar -xzf /tmp/kubeseal.tar.gz -C /tmp/
chmod +x /tmp/kubeseal
mv /tmp/kubeseal /usr/local/bin/
```
### run kubeseal
We can now run `kubeseal --help`
## Sealing a basic Kubernetes Secret
Looks at our existing Kubernetes secret YAML
```
cat kubernetes/secrets/secret.yaml
```
Create a sealed secret using `stdin`
```
cat kubernetes/secrets/secret.yaml | kubeseal -o yaml > kubernetes/secrets/sealed-secrets/sealed-secret.yaml
```
Create a sealed secret using file
```
kubeseal -f kubernetes/secrets/secret.yaml -o yaml > kubernetes/secrets/sealed-secrets/sealed-secret.yaml
```
Deploy the sealed secret
```
kubectl apply -f kubernetes/secrets/sealed-secrets/sealed-secret.yaml
sealedsecret.bitnami.com/mysecret created
```
Now few seconds later, see the secret
```
kubectl -n default get secret
NAME TYPE DATA AGE
mysecret Opaque 1 25s
```
## How the encryption key is managed
TODO: How the encryption key is managed and stored
TODO: Set a duration to test `--key-renew-period=<value>`
```
apk add nano
export KUBE_EDITOR=nano
```
Set the flag on the command like so to add a new key every 5 min for testing:
```
spec:
containers:
- command:
- controller
- --key-renew-period=5m
kubectl edit deployment/sealed-secrets-controller --namespace=kube-system
```
You should see a new key created under secrets in the `kube-system` namespace
```
kubectl -n kube-system get secrets
```
## Backup your encryption keys
TODO: * backup encryption keys
TODO: migrating kubernetes clusters
```
kubectl get secret -n kube-system \
-l sealedsecrets.bitnami.com/sealed-secrets-key \
-o yaml \
> kubernetes/secrets/sealed-secrets/sealed-secret-keys.key
```
## Migrate your encryption keys to a new cluster
Delete & Deploy a new Kubernetes cluster
```
kind delete cluster --name sealedsecrets
kind create cluster --name sealedsecrets --image kindest/node:v1.23.5
# check the cluster
kubectl get nodes
# redeploy sealed-secrets controller
kubectl apply -f kubernetes/secrets/sealed-secrets/controller-v0.19.1.yaml
kubectl -n kube-system get pods
```
### restore our encryption keys
```
kubectl apply -f kubernetes/secrets/sealed-secrets/sealed-secret-keys.key
```
restart the controller:
```
kubectl delete pod -n kube-system -l name=sealed-secrets-controller
```
### apply our old sealed secret
```
kubectl apply -f kubernetes/secrets/sealed-secrets/sealed-secret.yaml
```
TODO: Encrypted sealed secrets across namespaces https://github.com/bitnami-labs/sealed-secrets#scopes
## Re-encrypting secrets with the latest key
```
kubeseal --re-encrypt <my_sealed_secret.json >tmp.json \
&& mv tmp.json my_sealed_secret.json
```

View File

@ -0,0 +1,354 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
annotations: {}
labels:
name: sealed-secrets-controller
name: sealed-secrets-controller
namespace: kube-system
spec:
minReadySeconds: 30
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
name: sealed-secrets-controller
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
annotations: {}
labels:
name: sealed-secrets-controller
spec:
containers:
- args: []
command:
- controller
env: []
image: docker.io/bitnami/sealed-secrets-controller:v0.19.1
imagePullPolicy: IfNotPresent
livenessProbe:
httpGet:
path: /healthz
port: http
name: sealed-secrets-controller
ports:
- containerPort: 8080
name: http
readinessProbe:
httpGet:
path: /healthz
port: http
securityContext:
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 1001
stdin: false
tty: false
volumeMounts:
- mountPath: /tmp
name: tmp
imagePullSecrets: []
initContainers: []
securityContext:
fsGroup: 65534
serviceAccountName: sealed-secrets-controller
terminationGracePeriodSeconds: 30
volumes:
- emptyDir: {}
name: tmp
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: sealedsecrets.bitnami.com
spec:
group: bitnami.com
names:
kind: SealedSecret
listKind: SealedSecretList
plural: sealedsecrets
singular: sealedsecret
scope: Namespaced
versions:
- name: v1alpha1
schema:
openAPIV3Schema:
description: SealedSecret is the K8s representation of a "sealed Secret" -
a regular k8s Secret that has been sealed (encrypted) using the controller's
key.
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
metadata:
type: object
spec:
description: SealedSecretSpec is the specification of a SealedSecret
properties:
data:
description: Data is deprecated and will be removed eventually. Use
per-value EncryptedData instead.
format: byte
type: string
encryptedData:
additionalProperties:
type: string
type: object
x-kubernetes-preserve-unknown-fields: true
template:
description: Template defines the structure of the Secret that will
be created from this sealed secret.
properties:
data:
additionalProperties:
type: string
description: Keys that should be templated using decrypted data
nullable: true
type: object
metadata:
description: 'Standard object''s metadata. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata'
nullable: true
type: object
x-kubernetes-preserve-unknown-fields: true
type:
description: Used to facilitate programmatic handling of secret
data.
type: string
type: object
required:
- encryptedData
type: object
status:
description: SealedSecretStatus is the most recently observed status of
the SealedSecret.
properties:
conditions:
description: Represents the latest available observations of a sealed
secret's current state.
items:
description: SealedSecretCondition describes the state of a sealed
secret at a certain point.
properties:
lastTransitionTime:
description: Last time the condition transitioned from one status
to another.
format: date-time
type: string
lastUpdateTime:
description: The last time this condition was updated.
format: date-time
type: string
message:
description: A human readable message indicating details about
the transition.
type: string
reason:
description: The reason for the condition's last transition.
type: string
status:
description: 'Status of the condition for a sealed secret. Valid
values for "Synced": "True", "False", or "Unknown".'
type: string
type:
description: 'Type of condition for a sealed secret. Valid value:
"Synced"'
type: string
required:
- status
- type
type: object
type: array
observedGeneration:
description: ObservedGeneration reflects the generation most recently
observed by the sealed-secrets controller.
format: int64
type: integer
type: object
required:
- spec
type: object
served: true
storage: true
subresources:
status: {}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
annotations: {}
labels:
name: sealed-secrets-controller
name: sealed-secrets-controller
namespace: kube-system
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: sealed-secrets-key-admin
subjects:
- kind: ServiceAccount
name: sealed-secrets-controller
namespace: kube-system
---
apiVersion: v1
kind: ServiceAccount
metadata:
annotations: {}
labels:
name: sealed-secrets-controller
name: sealed-secrets-controller
namespace: kube-system
---
apiVersion: v1
kind: Service
metadata:
annotations: {}
labels:
name: sealed-secrets-controller
name: sealed-secrets-controller
namespace: kube-system
spec:
ports:
- port: 8080
targetPort: 8080
selector:
name: sealed-secrets-controller
type: ClusterIP
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
annotations: {}
labels:
name: sealed-secrets-service-proxier
name: sealed-secrets-service-proxier
namespace: kube-system
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: sealed-secrets-service-proxier
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: Group
name: system:authenticated
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
annotations: {}
labels:
name: sealed-secrets-service-proxier
name: sealed-secrets-service-proxier
namespace: kube-system
rules:
- apiGroups:
- ""
resourceNames:
- sealed-secrets-controller
resources:
- services
verbs:
- get
- apiGroups:
- ""
resourceNames:
- 'http:sealed-secrets-controller:'
- http:sealed-secrets-controller:http
- sealed-secrets-controller
resources:
- services/proxy
verbs:
- create
- get
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
annotations: {}
labels:
name: sealed-secrets-key-admin
name: sealed-secrets-key-admin
namespace: kube-system
rules:
- apiGroups:
- ""
resources:
- secrets
verbs:
- create
- list
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
annotations: {}
labels:
name: sealed-secrets-controller
name: sealed-secrets-controller
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: secrets-unsealer
subjects:
- kind: ServiceAccount
name: sealed-secrets-controller
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
annotations: {}
labels:
name: secrets-unsealer
name: secrets-unsealer
rules:
- apiGroups:
- bitnami.com
resources:
- sealedsecrets
verbs:
- get
- list
- watch
- apiGroups:
- bitnami.com
resources:
- sealedsecrets/status
verbs:
- update
- apiGroups:
- ""
resources:
- secrets
verbs:
- get
- list
- create
- update
- delete
- watch
- apiGroups:
- ""
resources:
- events
verbs:
- create
- patch
- apiGroups:
- ""
resources:
- namespaces
verbs:
- get

View File

@ -0,0 +1,16 @@
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
creationTimestamp: null
name: mysecret
namespace: default
spec:
encryptedData:
secret.json: AgBic1vT0+Y9WcUY3GqOlX+Zjstl7IDEY/U/XOykbRXGtUo6kgAG7Bkq/CyoXqDaNKD+4UhRpd9LZUw/6pvMpAjqsgSQw0ZBaALivxyZ7xSJ3/CpfsLlatWQoVWsnIoY8s0VW0eKhKPq0t30sNJSghH9yni3dgvBI3cyS1Xe2s9A7m/eUqUJqa82UE5y1UuRTRNiSUPmAVCaaW1md6K17DB9V7TE4mQn23IYF/xxSjjEhYFwsra2d7AXvSJiY63mHKRltQ6NxzJGA7xpvJTPV2MY1YIz8wsyKk8gQ2WZnnJrNGCoRlkE3hw2ZUFJGrivlWogcVYDL8EW8ngEEGdrhAbbTwzV17GDVt4rqgk6ag37yXL5rc01YD6BVTDGLglb59sRtRNkHAFr8GZmawVosswjRRDNHhzemgmpI2sOAn/ftvM5bjBNStnLBXAvOrh6sKDAiC2hERYegSjc/dwa9sdKI095lOduNXk55HorlyfiJ6bSV7h9Qc/A6P/whjL1YkZ+3iZA2b2DLEOWPSbaRhUYv4vfwkk3Abis3olXfI1dKwRec039AibhSeE/8FcrAik21XScWXT/QEH80yq6fzOUTMQRXLRzx7XRHfawEt6Oz5WV8mmR/XwueYx6Hw/SG8hxx6UUQqPaS66xVJgyL0g2EwonjLEtNQc+5/xrhaWAqyyRoeCB+2da5ZSUYWVhYdw99XNeg9HQ5mQpdPjMBW0/83gG2ZIr8XPgoo3OalYD5vwL4Q8drw==
template:
metadata:
creationTimestamp: null
name: mysecret
namespace: default
type: Opaque