Skip to content

Commit 24eabdb

Browse files
committed
feat: add skipCertCopy option for SIGHUP-based certificate rotation
This change introduces a new 'skipCertCopy' field to the CrdbCluster API that enables zero-downtime certificate rotation using SIGHUP signals. Changes: - Add skipCertCopy boolean field to CrdbClusterSpec API - Make cert-copy initContainer conditional based on skipCertCopy flag - When skipCertCopy=true: mount certs directly from secrets for SIGHUP rotation - When skipCertCopy=false (default): use initContainer for strict 0400 permissions - Add comprehensive documentation in README.md - Add example manifests demonstrating both modes - Add detailed testing guide When skipCertCopy is enabled: - No initContainer is created - Certificates are mounted directly from Kubernetes secrets - Certificate files have 0440 permissions (group readable) - Certificates can be reloaded via SIGHUP without pod restart When skipCertCopy is disabled (default): - initContainer 'db-init' copies certificates to emptyDir - Private keys have strict 0400 permissions - Pod restart required for certificate rotation Trade-offs are documented in README.md to help users choose the appropriate mode for their security and operational requirements. Fixes: cockroachdb/helm-charts#408 Related: cockroachdb/helm-charts#423 JIRA: CRDB-42772
1 parent b4cfbb4 commit 24eabdb

7 files changed

Lines changed: 1435 additions & 963 deletions

File tree

README.md

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
The CockroachDB Kubernetes Operator deploys CockroachDB on a Kubernetes cluster. You can use the Operator to manage the configuration of a running CockroachDB cluster, including:
44

55
- Authenticating certificates
6+
- Rotating certificates with zero downtime (SIGHUP-based rotation)
67
- Configuring resource requests and limits
78
- Scaling the cluster
89
- Performing a rolling upgrade
@@ -72,6 +73,8 @@ On a production deployment, you should modify the `resources.requests` object in
7273

7374
The Operator generates and approves 1 root and 1 node certificate for the cluster.
7475

76+
For information about certificate rotation options (including zero-downtime rotation), see the [Certificate Rotation](#certificate-rotation) section.
77+
7578
### Apply the custom resource
7679

7780
Apply `example.yaml`:
@@ -96,6 +99,71 @@ cockroachdb-2 1/1 Running 0 46s
9699

97100
Each pod should have `READY` status soon after being created.
98101

102+
## Certificate Rotation
103+
104+
The Operator supports two modes for handling TLS certificates:
105+
106+
### Traditional Mode (default)
107+
108+
By default, when `tlsEnabled: true`, the Operator uses an initContainer (`db-init`) that copies certificates from Kubernetes secrets to an emptyDir volume with strict 0400 permissions on private keys. This ensures maximum security but **requires pod restarts to rotate certificates**.
109+
110+
Example configuration:
111+
```yaml
112+
apiVersion: crdb.cockroachlabs.com/v1alpha1
113+
kind: CrdbCluster
114+
metadata:
115+
name: cockroachdb
116+
spec:
117+
tlsEnabled: true
118+
skipCertCopy: false # or omit this field (default)
119+
# ... other settings
120+
```
121+
122+
### SIGHUP-Based Rotation (Zero Downtime)
123+
124+
For zero-downtime certificate rotation, set `skipCertCopy: true`. This mounts certificates directly from Kubernetes secrets, allowing CockroachDB to reload certificates via SIGHUP signal **without pod restarts**.
125+
126+
Example configuration:
127+
```yaml
128+
apiVersion: crdb.cockroachlabs.com/v1alpha1
129+
kind: CrdbCluster
130+
metadata:
131+
name: cockroachdb
132+
spec:
133+
tlsEnabled: true
134+
skipCertCopy: true # Enable SIGHUP-based rotation
135+
# ... other settings
136+
```
137+
138+
To rotate certificates with SIGHUP mode:
139+
140+
1. Update the Kubernetes secret with new certificates:
141+
```bash
142+
kubectl create secret generic <node-secret-name> \
143+
--from-file=ca.crt=new-ca.crt \
144+
--from-file=tls.crt=new-node.crt \
145+
--from-file=tls.key=new-node.key \
146+
--dry-run=client -o yaml | kubectl apply -f -
147+
```
148+
149+
2. Wait a few seconds for Kubelet to update the mounted secret.
150+
151+
3. Send SIGHUP to the CockroachDB process:
152+
```bash
153+
kubectl exec cockroachdb-0 -- kill -SIGHUP 1
154+
```
155+
156+
4. Repeat for all pods in the cluster.
157+
158+
**Trade-offs:**
159+
160+
| Mode | InitContainer | Permissions | Rotation Method | Use Case |
161+
|------|--------------|-------------|-----------------|----------|
162+
| **Traditional** (`skipCertCopy: false`) | Yes (`db-init`) | 0400 (strict) | Pod restart required | Maximum security, infrequent cert rotation |
163+
| **SIGHUP** (`skipCertCopy: true`) | No | 0440 (group readable) | SIGHUP signal (no restart) | Zero-downtime rotation, frequent cert updates |
164+
165+
For a complete testing guide and examples, see [`examples/TESTING-CERT-ROTATION.md`](examples/TESTING-CERT-ROTATION.md).
166+
99167
## Access the SQL shell
100168

101169
To use the CockroachDB SQL client, first launch a secure pod running the `cockroach` binary.

apis/v1alpha1/cluster_types.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,14 @@ type CrdbClusterSpec struct {
5959
// Default: 26257
6060
// +optional
6161
SQLPort *int32 `json:"sqlPort,omitempty"`
62+
// (Optional) SkipCertCopy determines whether to skip the cert-copy initContainer.
63+
// When true, certificates are mounted directly (allowing SIGHUP-based rotation)
64+
// but may have 0440 permissions instead of 0400.
65+
// When false (default), an initContainer copies certs to ensure 0400 permissions
66+
// but pod restarts are required for certificate rotation.
67+
// Default: false
68+
// +optional
69+
SkipCertCopy bool `json:"skipCertCopy,omitempty"`
6270
// (Optional) TLSEnabled determines if TLS is enabled for your CockroachDB Cluster
6371
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="TLS Enabled",xDescriptors="urn:alm:descriptor:com.tectonic.ui:booleanSwitch"
6472
// +optional

0 commit comments

Comments
 (0)