Skip to content

Commit c9a7943

Browse files
authored
Add descriptions (#499)
1 parent 81f2a89 commit c9a7943

File tree

9 files changed

+101
-88
lines changed

9 files changed

+101
-88
lines changed

docs/modules/secret-operator/pages/cert-manager.adoc

+17-14
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,37 @@
1-
= Cert-Manager Integration
1+
= Cert-Manager integration
2+
:description: Integrate Cert-Manager with Stackable Secret Operator to manage certificates. Follow steps for configuration, creating SecretClass, and using certificates in Pods.
3+
:cert-manager: https://cert-manager.io/
4+
:letsencrypt: https://letsencrypt.org/
25

36
WARNING: The Cert-Manager backend is experimental, and subject to change.
47

5-
https://cert-manager.io/[Cert-Manager] is a common tool to manage certificates in Kubernetes, especially when backed by an external
6-
Certificate Authority (CA) such as https://letsencrypt.org/[Let\'s Encrypt].
8+
{cert-manager}[Cert-Manager] is a common tool to manage certificates in Kubernetes, especially when backed by an external Certificate Authority (CA) such as {letsencrypt}[Let\'s Encrypt].
79
810
The Stackable Secret Operator supports requesting certificates from Cert-Manager.
911
1012
[#caveats]
1113
== Caveats
1214
13-
Cert-Manager is designed to manage relatively long-lived certificates that are stored in Kubernetes Secrets. By contrast,
14-
the Stackable Secret Operator is designed to generate temporary short-lived certificates.
15+
Cert-Manager is designed to manage relatively long-lived certificates that are stored in Kubernetes Secrets.
16+
By contrast, the Stackable Secret Operator is designed to generate temporary short-lived certificates.
1517
1618
This has a couple of repercussions:
1719
18-
- Longer-lived certificates mean that a leaked certificate has potential to be abused for longer.
19-
- Application teams may have access to read Secrets in their respective applications' Namespaces.
20+
* Longer-lived certificates mean that a leaked certificate has potential to be abused for longer.
21+
* Application teams may have access to read Secrets in their respective applications' Namespaces.
2022

21-
Where possible, we recommend using the xref:secretclass.adoc#backend-autotls[`autoTls` backend] instead.
23+
Where possible, it is recommended using the xref:secretclass.adoc#backend-autotls[`autoTls` backend] instead.
2224

2325
[#issuer]
2426
== Configuring Cert-Manager
2527

26-
NOTE: We recommend using the xref:secretclass.adoc#backend-autotls[`autoTls` backend] instead for self-signed PKIs. We use Cert-Manager's CA issuer here to show the broader concepts.
28+
NOTE: Using the xref:secretclass.adoc#backend-autotls[`autoTls` backend] instead for self-signed PKIs is recommended.
29+
The Cert-Manager's CA issuer is used in these examples to illustrate the broader concepts.
2730

2831
To do this, you will first need to teach Cert-Manager how to create your certificates.
2932

30-
In a production setup this will likely use an external CA such as ACME or OpenBao/Vault. However, to make this guide self-contained, Cert-Manager will create
31-
a self-signed CA certificate instead.
33+
In a production setup this will likely use an external CA such as ACME or OpenBao/Vault.
34+
However, to make this guide self-contained, Cert-Manager will create a self-signed CA certificate instead.
3235

3336
[source,yaml]
3437
----
@@ -39,8 +42,8 @@ include::example$cert-manager/issuer.yaml[]
3942
[#secretclass]
4043
== Creating a SecretClass
4144

42-
The Stackable Secret Operator needs to know how to request the certificates from Cert-Manager. We do this by creating
43-
a xref:secretclass.adoc[] using the xref:secretclass.adoc#backend-certmanager[`experimentalCertManager` backend].
45+
The Stackable Secret Operator needs to know how to request the certificates from Cert-Manager.
46+
Do this by creating a xref:secretclass.adoc[] using the xref:secretclass.adoc#backend-certmanager[`experimentalCertManager` backend].
4447

4548
[source,yaml]
4649
----
@@ -53,7 +56,7 @@ include::example$cert-manager/secretclass.yaml[]
5356
[#pod]
5457
== Using the certificate
5558

56-
Finally, we can create and expose a Pod that requests and uses the certificate!
59+
Finally, you can create and expose a Pod that requests and uses the certificate!
5760

5861
[source,yaml]
5962
----

docs/modules/secret-operator/pages/index.adoc

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
= Stackable Secret Operator
2+
:description: Stackable Secret Operator enhances Kubernetes Secrets by provisioning Pods with TLS certificates, Kerberos keytabs, and tokens.
23
:github: https://github.com/stackabletech/secret-operator/
34
:crd: {crd-docs-base-url}/secret-operator/{crd-docs-version}/
45

docs/modules/secret-operator/pages/installation.adoc

+3-4
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,8 @@
22

33
There are two ways to run the Stackable Secret Operator:
44

5-
1. Helm managed Docker container deployment on Kubernetes
6-
7-
2. Build from source
5+
. Helm managed Docker container deployment on Kubernetes
6+
. Build from source
87

98
== Prerequisites
109

@@ -14,7 +13,7 @@ You will need:
1413
* kubectl
1514
* Helm
1615

17-
Resource sizing depends on cluster type(s), usage and scope, but as a starting point we recommend a minimum of the following resources for this operator:
16+
Resource sizing depends on cluster type(s), usage and scope, but as a starting point a minimum of the following resources is recommended for this operator:
1817

1918
* 0.2 cores (e.g. i5 or similar)
2019
* 256MB RAM

docs/modules/secret-operator/pages/openshift.adoc

+8-5
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,22 @@
11
= Running on OpenShift
2+
:description: Install Stackable Secret Operator on OpenShift via OperatorHub or Helm. Manual upgrades and cleanup are required due to OLM limitations.
3+
:operatorhub: https://docs.openshift.com/container-platform/4.16/operators/understanding/olm-understanding-operatorhub.html
24

35
== Installation methods
46

5-
The Secret Operator can be installed using either using Helm or via the Operator Hub.
6-
7-
It is not possible to mix the two because they are incompatible. This means that once an operator has been installed via the Operator Hub, it cannot be upgraded with Helm or vice versa.
7+
The Secret Operator can be installed using either Helm or the {operatorhub}[OperatorHub].
88

9+
It is not possible to mix the two because they are incompatible.
10+
This means that once an operator has been installed via the Operator Hub, it cannot be upgraded with Helm or vice versa.
911

1012
== Operator Hub Installation
1113

1214
This operator can be installed from RedHat's Operator Hub.
1315

14-
Unfortunately there are some things you need to be aware of when upgrading or uninstalling the operator from the Operator Hub.
16+
Unfortunately there are some things you need to be aware of when upgrading or uninstalling the operator from the OperatorHub.
1517

16-
Due to limitations of the Operator Lifecycle Manager (OLM) you cannot enable automatic updates of the Stackable Secret Operator. Upgrading to a new version requires you to uninstall the existing version of the operator and then manually remove the following resources:
18+
Due to limitations of the Operator Lifecycle Manager (OLM) you cannot enable automatic updates of the Stackable Secret Operator.
19+
Upgrading to a new version requires you to uninstall the existing version of the operator and then manually remove the following resources:
1720

1821
* SecretClass: tls
1922
* ServiceAccount: secret-operator-service-account
+16-13
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,34 @@
11
= Scope
2+
:description: Stackable Secret Operator supports scopes for secrets like node, pod, and service, adding context like IP, pod names, and DNS to credentials.
23

3-
Secrets often cover some specific aspect of a workload. For example:
4+
Secrets often cover some specific aspect of a workload.
5+
For example:
46

5-
* A Kerberos credential may be bound to one node IP
6-
* An internal TLS certificate's `subjectAlternateName` section must match the `Pod` object's name and service
7+
* A Kerberos credential may be bound to one node IP.
8+
* An internal TLS certificate's `subjectAlternateName` section must match the Pod object's name and service.
79
8-
To solve this, the Stackable Secret Operator has a concept of "scopes", which allow a xref:volume.adoc[] to selectively
9-
include this extra context. The exact effect of the scope depends on which xref:secretclass.adoc#backend[`backend`] is used.
10+
To solve this, the Stackable Secret Operator has a concept of "scopes", which allow a xref:volume.adoc[] to selectively include this extra context.
11+
The exact effect of the scope depends on which xref:secretclass.adoc#backend[`backend`] is used.
1012

1113
== Supported Scopes
1214

1315
[#node]
1416
=== `node`
1517

16-
The `node` scope is resolved to the name of the Kubernetes Node object that the Pod is running on. This will typically
17-
be the DNS name of the node.
18+
The `node` scope is resolved to the name of the Kubernetes Node object that the Pod is running on.
19+
This will typically be the DNS name of the node.
1820

1921
[#pod]
2022
=== `pod`
2123

22-
The `pod` scope is resolved to the name of the Kubernetes Pod. This allows the secret to differentiate between StatefulSet replicas.
24+
The `pod` scope is resolved to the name of the Kubernetes Pod.
25+
This allows the secret to differentiate between StatefulSet replicas.
2326

2427
[#service]
2528
=== `service`
2629

27-
The `service` scope allows Pod objects to specify custom scopes. This should typically correspond to Service objects that the
28-
Pod participate in.
30+
The `service` scope allows Pod objects to specify custom scopes.
31+
This should typically correspond to Service objects that the Pod participate in.
2932

3033
[#listener-volume]
3134
=== `listener-volume`
@@ -43,6 +46,6 @@ note:: The `listener-volume` scope also implies the xref:#node[] scope for xref:
4346
For example, a TLS certificate provisioned by the xref:secretclass.adoc#backend-autotls[`autoTls`] backend, with the scopes
4447
xref:#node[] and xref:#pod[] would contain the following values in its `subjectAlternateName` (SAN) extension field:
4548

46-
- The node's IP address
47-
- The node's fully qualified domain name (`my-node.example.com`)
48-
- The pod's fully qualified domain name (`my-pod.my-service.my-namespace.svc.cluster.local`)
49+
* The node's IP address
50+
* The node's fully qualified domain name (`my-node.example.com`)
51+
* The pod's fully qualified domain name (`my-pod.my-service.my-namespace.svc.cluster.local`)

docs/modules/secret-operator/pages/secretclass.adoc

+31-26
Original file line numberDiff line numberDiff line change
@@ -1,74 +1,78 @@
1-
= `SecretClass`
1+
= SecretClass
2+
:description: A SecretClass in Kubernetes defines secret categories, handling certificate provision and secret management via multiple backends.
3+
:cert-manager: https://cert-manager.io/
24

3-
A `SecretClass` is a cluster-global Kubernetes resource that defines a category of secrets that the Secret Operator knows how to provision.
5+
A _SecretClass_ is a cluster-global Kubernetes resource that defines a category of secrets that the Secret Operator knows how to provision.
46

57
This is intended to provide an abstraction between how the secret is used ("I need a certificate for my cluster's TLS PKI") and how
68
it is provisioned (automatically and generated by the operator's internal CA, provisioned by the cluster administrator, or provisioned by an
79
external service such as Hashicorp Vault).
810

9-
A `SecretClass` looks like this:
11+
A SecretClass looks like this:
1012

1113
[source,yaml]
1214
----
1315
include::example$secretclass-tls.yaml[]
1416
----
15-
<1> Backends are mutually exclusive, only one may be used by each `SecretClass`
17+
<1> Backends are mutually exclusive, only one may be used by each SecretClass
1618
<2> Configures and selects the xref:#backend-autotls[] backend
1719
<3> Configures and selects the xref:#backend-k8ssearch[] backend
1820

1921
[#backend]
2022
== Backend
2123

22-
Each `SecretClass` is a associated with a single backend, which dictates the mechanism for issuing that kind of secret.
24+
Each SecretClass is a associated with a single backend, which dictates the mechanism for issuing that kind of secret.
2325

2426
[#backend-autotls]
2527
=== `autoTls`
2628

2729
*Format*: xref:#format-tls-pem[]
2830

29-
Issues a TLS certificate signed by the Secret Operator. The certificate authority can be provided by the administrator, or managed automatically
30-
by the Secret Operator.
31+
Issues a TLS certificate signed by the Secret Operator.
32+
The certificate authority can be provided by the administrator, or managed automatically by the Secret Operator.
3133

32-
A new certificate and keypair will be generated and signed for each `Pod`, keys or certificates are never reused.
34+
A new certificate and keypair will be generated and signed for each Pod, keys or certificates are never reused.
3335

3436
CAUTION: Attributes of the certificate (such as the expiration date, fingerprint, or serial number) will be regenerated for each
35-
`Pod`, and should not be expected to be stable.
37+
Pod, and should not be expected to be stable.
3638

3739
xref:scope.adoc[Scopes] are used to populate the claims (such as `subjectAlternateName`) of the provisioned certificates.
3840

3941
==== Certificate lifetime
4042

41-
We generally aim to use as short-lived certificates as possible.
43+
By default the Secret Operator will generally aim to use as short-lived certificates as possible.
4244
Short lifetime periods require frequent restarts of services, which may be totally unnoticeable for some products,
4345
annoying for others or fatal for products with a single point of failure and no recovery from outages (e.g. Trino coordinator).
4446

45-
We have spent a considerate amount of time thinking about this issue and decided on the following compromises:
47+
This choice was made deliberately after a considerate amount of time was spent thinking about this issue.
48+
The following compromises were made:
4649

47-
. To enforce security constraints, cluster administrators can set a maximum allowed certificate lifetime
48-
on the SecretClass issuing the certificates (defaults to `15d`).
49-
. We default to a certificate lifetime of `24h`.
50+
. To enforce security constraints, cluster administrators can set a maximum allowed certificate lifetime on the SecretClass issuing the certificates (defaults to `15d`).
51+
. The certificate lifetime is `24h`.
5052
. Pods consuming the certificate can request a longer lifetime or shutdown expiration buffer via annotations
5153
on the xref:volume.adoc[Volume]. If they request a longer lifetime than the SecretClass allows,
5254
it will be shortened to the maximum allowed lifetime.
5355
. To avoid stampeding herds during restarts and spread out the load, certificate durations are lowered by up to 20%.
54-
. The Pods will be evicted `6h` before the certificate expires, to ensure that no Pods are left running with expired secrets. Consumers can override this buffer using Volume annotations.
56+
. The Pods will be evicted `6h` before the certificate expires, to ensure that no Pods are left running with expired secrets.
57+
Consumers can override this buffer using Volume annotations.
5558
This buffer must be long enough that the product is guaranteed to gracefully shut down.
5659

57-
Most of our product operators will not set any specific certificate lifetime, so the default applies.
60+
Most Stackable product operators will not set any specific certificate lifetime, so the default applies.
5861
In case an operator sets a higher lifetime, a tracking issue must be created to document and track the steps to reduce the certificate lifetime.
5962

60-
Users can use podOverrides to extend the certificate lifetime by adding volume annotations. We might add native support for customizing certificate lifetimes in the future to the Stacklet CRDs.
63+
Users can use xref:concepts:overrides.adoc#pod-overrides[podOverrides] to extend the certificate lifetime by adding volume annotations.
64+
Native support for customizing certificate lifetimes in Stacklet CRDs might be added in the future.
6165

6266
==== Certificate Authority rotation
6367

6468
Certificate authorities also have a limited lifetime, and need to be rotated before they expire to avoid cluster disruption.
6569

66-
If configured to provision its own CA (`autoTls.ca.autoGenerate`), the Secret Operator will create CA certificates that are valid for 2 years (`autoTls.ca.caCertificateLifetime`),
67-
and initiate rotation once less than half of that time remains.
70+
If configured to provision its own CA (`autoTls.ca.autoGenerate`), the Secret Operator will create CA certificates that are valid for 2 years (`autoTls.ca.caCertificateLifetime`), and initiate rotation once less than half of that time remains.
6871

6972
To avoid disruption and let the new CA propagate through the cluster, the Secret Operator will prefer using the oldest CA that will last for the entire lifetime of the issued certificate.
7073

71-
NOTE: Expired CA certificates will currently not be deleted automatically. They should be cleaned up manually.
74+
NOTE: Expired CA certificates will currently not be deleted automatically.
75+
They should be cleaned up manually.
7276

7377
==== Reference
7478

@@ -99,11 +103,11 @@ spec:
99103

100104
*Format*: xref:#format-tls-pem[]
101105

102-
Injects a TLS certificate issued by https://cert-manager.io/[Cert-Manager].
106+
Injects a TLS certificate issued by {cert-manager}[Cert-Manager].
103107

104108
WARNING: This backend is experimental, and subject to change.
105109

106-
NOTE: This backend requires https://cert-manager.io/[Cert-Manager] to already be installed and configured.
110+
NOTE: This backend requires {cert-manager}[Cert-Manager] to already be installed and configured.
107111

108112
A new certificate will be requested the first time it is used by a Pod, it will be reused after that (subject to Cert-Manager's renewal rules).
109113

@@ -135,7 +139,8 @@ spec:
135139

136140
Creates a Kerberos keytab file for a selected realm. The Kerberos KDC and administrator credentials must be provided by the administrator.
137141

138-
IMPORTANT: Only MIT Kerberos (krb5) and Active Directory are currently supported. Heimdal is not supported.
142+
IMPORTANT: Only MIT Kerberos (krb5) and Active Directory are currently supported.
143+
Heimdal is not supported.
139144

140145
Principals will be created dynamically if they do not already exist.
141146

@@ -146,15 +151,15 @@ The administrator keytab must have permission to add principals and get their ke
146151
[#ad-principal-conflicts]
147152
===== Principal Conflicts
148153

149-
We recommend that each Active Directory domain should only be used by a single Kubernetes cluster.
154+
Each Active Directory domain should be used by only a single Kubernetes cluster.
150155

151156
This is because each pod, service, and node may be provisioned a principal matching its hostname, and principal names must be unique within a single AD domain.
152157
The Stackable Secret Operator will cache and reuse these credentials within a single Kubernetes cluster, but will not share them across multiple clusters.
153158

154159
If the same AD domain _is_ shared between multiple Kubernetes clusters, the following _must_ be unique across the AD domain:
155160

156-
- The Kubernetes Nodes' names and fully qualified domain names
157-
- The Kubernetes Namespaces' names (only Namespaces that use Kerberos)
161+
* The Kubernetes Nodes' names and fully qualified domain names
162+
* The Kubernetes Namespaces' names (only Namespaces that use Kerberos)
158163

159164
[#ad-samaccountname]
160165
===== Custom `samAccountName` generation
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
= Security
2+
:description: The Secret Operator requires root privileges to manage secrets securely and avoid writing sensitive data to disk. Running in unprivileged mode is discouraged.
23

34
== Container privileges
45

5-
By default, the Secret Operator runs as a set of privileged root containers. This is done for three reasons:
6+
By default, the Secret Operator runs as a set of privileged root containers.
7+
This is done for three reasons:
68

7-
1. We need to run as root to have permission to create the Unix domain socket hosting the Container Storage interface (CSI)
8-
driver. The Kubelet communicates with the CSI driver over this socket.
9-
2. We need to run as root to have permission to write secret material into the pods' volume paths, as directed
10-
by the CSI.
11-
3. We need to run as a privileged container in order to be able to mount the volume folders as RAM disks, in order to avoid
12-
spilling secret material onto disk.
9+
1. The operator needs to run as root to have permission to create the Unix domain socket hosting the Container Storage interface (CSI) driver.
10+
The Kubelet communicates with the CSI driver over this socket.
11+
2. The operator needs to run as root to have permission to write secret material into the pods' volume paths, as directed by the CSI.
12+
3. The operator needs to run as a privileged container in order to be able to mount the volume folders as RAM disks, in order to avoid spilling secret material onto disk.
1313

14-
Running as root is currently a hard requirement. Secret Operator _can_ run in an unprivileged container (by passing
15-
`--set securityContext.privileged=false` to `helm upgrade`), but doing so is strongly discouraged, and users
16-
should be aware that it means that secret material will be written to disk.
14+
Running as root is currently a hard requirement.
15+
Secret Operator _can_ run in an unprivileged container (by passing `--set securityContext.privileged=false` to `helm upgrade`),
16+
but doing so is strongly discouraged, and users should be aware that it means that secret material will be written to disk.

0 commit comments

Comments
 (0)