130 lines
3.6 KiB
Markdown
130 lines
3.6 KiB
Markdown
# ETCD Encryption Configuration for Kubernetes
|
|
|
|
To enable static encryption at rest for Kubernetes secrets in ETCD, you need to configure the API Server with an EncryptionConfiguration.
|
|
|
|
## 1. Generate an Encryption Key
|
|
|
|
```bash
|
|
# Generate a 32-byte base64-encoded key
|
|
head -c 32 /dev/urandom | base64
|
|
# Example output: sxFdbKYquCe3EbRWVV+pFe2lS8K8hbiv3V8ExQZ0fD4=
|
|
```
|
|
|
|
## 2. Create EncryptionConfiguration File
|
|
|
|
Create `/etc/kubernetes/encryption-config.yaml` on the control plane node:
|
|
|
|
```yaml
|
|
apiVersion: apiserver.config.k8s.io/v1
|
|
kind: EncryptionConfiguration
|
|
resources:
|
|
- resources:
|
|
- secrets
|
|
providers:
|
|
- aescbc:
|
|
keys:
|
|
- name: key1
|
|
secret: sxFdbKYquCe3EbRWVV+pFe2lS8K8hbiv3V8ExQZ0fD4=
|
|
- identity: {}
|
|
```
|
|
|
|
## 3. Update kube-apiserver Static Pod Manifest
|
|
|
|
Edit `/etc/kubernetes/manifests/kube-apiserver.yaml` on the control plane node:
|
|
|
|
```yaml
|
|
spec:
|
|
containers:
|
|
- name: kube-apiserver
|
|
command:
|
|
- kube-apiserver
|
|
# ... existing flags ...
|
|
- --encryption-provider-config=/etc/kubernetes/encryption-config.yaml
|
|
volumeMounts:
|
|
- name: encryption-config
|
|
mountPath: /etc/kubernetes
|
|
readOnly: true
|
|
volumes:
|
|
- name: encryption-config
|
|
hostPath:
|
|
path: /etc/kubernetes
|
|
type: DirectoryOrCreate
|
|
```
|
|
|
|
## 4. Verify Encryption is Working
|
|
|
|
```bash
|
|
# After restarting the API server, create a secret and verify it's encrypted
|
|
kubectl create secret generic test-secret --from-literal=key=value -n juwan
|
|
|
|
# Check if the secret is encrypted in etcd
|
|
kubectl get secret test-secret -o yaml
|
|
|
|
# You can also check raw etcd data (requires etcd access):
|
|
# etcdctl --endpoints=https://127.0.0.1:2379 get /kubernetes.io/secrets/juwan/test-secret
|
|
# The data should be encrypted (not human-readable)
|
|
```
|
|
|
|
## 5. Important Notes
|
|
|
|
- **Backup your encryption key** in a secure location
|
|
- **Never commit encryption keys** to version control
|
|
- If you lose the key, all encrypted secrets will be unrecoverable
|
|
- After enabling encryption, existing unencrypted secrets will not be automatically encrypted
|
|
- To encrypt existing secrets, you can use: `kubectl delete secret <name> && kubectl create secret ...`
|
|
- Or use: `kubectl patch secret <name> -p '{}' --type=merge` (triggers re-encryption)
|
|
|
|
## 6. RBAC Configuration for JWT Secret
|
|
|
|
The `jwt-secret.yaml` includes RBAC rules that:
|
|
- Create a `jwt-secret` Secret in the `juwan` namespace
|
|
- Create ServiceAccounts for `user-rpc` and `envoy-gateway`
|
|
- Create a Role `jwt-secret-reader` that allows reading only the `jwt-secret` Secret
|
|
- Bind this Role to both ServiceAccounts via RoleBindings
|
|
|
|
This ensures:
|
|
- Only `user-rpc` and `envoy-gateway` Pods can read the JWT secret
|
|
- Other services and users cannot access the JWT secret
|
|
- Least privilege access principle is enforced
|
|
|
|
## 7. Update Deployment to Use ServiceAccount
|
|
|
|
Make sure your Deployment references the ServiceAccount:
|
|
|
|
```yaml
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: user-rpc
|
|
namespace: juwan
|
|
spec:
|
|
template:
|
|
spec:
|
|
serviceAccountName: user-rpc # This is important!
|
|
containers:
|
|
- name: user-rpc
|
|
env:
|
|
- name: JWT_SECRET_KEY
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: jwt-secret
|
|
key: secret-key
|
|
```
|
|
|
|
## 8. For Minikube Users
|
|
|
|
If using Minikube, you can enable encryption with:
|
|
|
|
```bash
|
|
minikube config set apiserver.encryption-provider-config /path/to/encryption-config.yaml
|
|
minikube start
|
|
```
|
|
|
|
Or manually edit the kube-apiserver manifest after starting Minikube:
|
|
|
|
```bash
|
|
minikube ssh
|
|
sudo vi /etc/kubernetes/manifests/kube-apiserver.yaml
|
|
# Add the flags and volume mounts as shown above
|
|
```
|