-
Notifications
You must be signed in to change notification settings - Fork 61
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
External Certificate Manager #135
base: main
Are you sure you want to change the base?
Conversation
Signed-off-by: Katherine Stanley <[email protected]>
|
||
The proposal makes a few assumptions: | ||
* Strimzi will not be responsible for installing cert-manager, but we will document the versions of cert-manager that we have tested with. | ||
* Strimzi will not be responsible for creating `Issuer` or `ClusterIssuer` custom resources. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Guess this is because we want to keep for self-signed certs our current way and not to add another option that will mostly add just support burden?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is because there are lots of different issuers that work with cert-manager. So rather than Strimzi having to actively support all the different types, I've proposed that the user creates the Issuer
or ClusterIssuer
and handles supplying a Secret with the trusted certificates for the issuer they have chosen. That way Strimzi can work with any cert-manager issuer integrations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will we need to provide any guidelines on conventions in the docs?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we just need to mention in in the docs properly as users could be confused from different projects where integration of CM works without creating any Issuer (afaiu operator creates self-sign Issuer when it is not created by users).
|
||
If the user has enabled this feature, when Strimzi needs to issue a certificate, instead of using the existing internal mechanism it will create a `Certificate` custom resource. | ||
Strimzi will wait during the reconciliation loop for the `Certificate` status to indicate that the certificate has been issued before continuing. | ||
When issuing cluster certificates (e.g for Kafka etc), once the certificate has been issued, Strimzi will annotate the cert-manager provided Secret with the `strimzi.io/server-cert-hash` annotation with the value being the hash of the certificate in the Secret. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
issuing cluster certificates (e.g for Kafka etc)
- I wonder if it would be useful to include the secret names for these certificates as an example.
If the user updates the Secret to change the certificates included they must increment the annotation to inform Strimzi it has changed. | ||
Similar to today Strimzi will put the annotation on the pods (Kafka, ZooKeeper etc) to be able to spot when the generation has been changed. | ||
|
||
### Issuing certificates |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
### Issuing certificates | |
### Issuing end-entity certificates |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the proposal Kate, it looks good to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I left some nits. But the main thing missing seems to be how you plan to roll out the trust to the new CAs. There is no reference to strimzi.io/ca-key-generation
or to rotation of private keys, so it is not clear how do you expect to handle it.
Although it is nice that it can manage certificates, it would be beneficial if the certificates could be managed by a dedicated certificate manager, such as [cert-manager](https://cert-manager.io/). | ||
This is a feature that is often requested, especially because many organizations have specific compliance requirements with regard to certificates, for example: | ||
* Requiring that CA private keys are not shared. | ||
* Requiring that self-signed certificates cannot be used. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this really helps because the CA will be anyway bootstrapped as self-signed as it is today in most cases, and there is not much we can do about it.
clusterCa: | ||
validityDays: <integer> # notBefore=now, notAfter=now + validityDays | ||
generateCertificateAuthority: <boolean> | ||
generateSecretOwnerReference: <boolean> | ||
renewalDays: <integer> # days before notAfter when we should start renewal | ||
certificateExpirationPolicy: <renew-certificate|replace-key> | ||
certificateIssuer: | ||
type: <internal|cert-manager.io> # (1) | ||
issuerRef: # (2) | ||
name: <string> | ||
kind: <Issuer|ClusterIssuer> | ||
group: <string> # cert-manager.io by default |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should the type separation happen already at the clusterCa
level? It would seem more logical to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@scholzj Do you mean like this?
spec:
clusterCa:
validityDays: <integer> # notBefore=now, notAfter=now + validityDays
generateCertificateAuthority: <boolean>
generateSecretOwnerReference: <boolean>
renewalDays: <integer> # days before notAfter when we should start renewal
certificateExpirationPolicy: <renew-certificate|replace-key>
certificateIssuerType: <internal|cert-manager.io> # (1)
certManagerIssuerRef: # (2)
name: <string>
kind: <Issuer|ClusterIssuer>
group: <string> # cert-manager.io by default
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah. Although I would maybe call it just type
instead of certificateIssuerType
. It would also default to internal
when not set (I hope that can be implemented in the Java api
classes).
I think that would create a better abstraction as not all the fields in the CA configuration might be applicable to all issuer types.
3. Create a `Secret` containing the CAs for Strimzi to trust. | ||
Users can optionally use [trust-manager](https://cert-manager.io/docs/trust/trust-manager/) to create this Secret, but they are responsible for installing trust-manager, creating the `Bundle` CR and annotating the resulting Secret with the Strimzi cert annotation. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we should instead (or next to this) describe the expectation of how the Secret should look like? IIRC, trust-manager creates a Secret will all CAs bundled into a single file? Is that supported / expected?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that this needs some clarification. Maybe a sequence diagram with the PKI generation process including user, CO, trust-manager and cert-manager would also help.
Notes: | ||
* The `Secret` that contains the CAs will be the same `Secret` currently used, so either `<CLUSTER_NAME>-cluster-ca-cert` or `<CLUSTER_NAME>-clients-ca-cert`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should again aim here for a separation of the Strimzi used Secrets and the user-provided Secrets. I.e. the user should provide it in some custom secret and we should copy it ourself into <CLUSTER_NAME>-cluster-ca-cert
or <CLUSTER_NAME>-clients-ca-cert
if needed.
### Handling trust rollout | ||
|
||
Similar to today Strimzi will use the notion of a "generation" to determine whether to roll the cluster to pick up changes in either the `<CLUSTER_NAME>-cluster-ca-cert` or `<CLUSTER_NAME>-clients-ca-cert`. | ||
When the user creates the CA cert Secret they must add the `strimzi.io/ca-cert-generation` annotation to it. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Does this work with the trust-manager suggested earlier?
- Can we work around it and manage the generation ourself? E.g. based on the hash of the user-provided certificate detect changes and bump the generation ourself?
- What is the impact on the
strimzi.io/ca-key-generation
given we now do not have the private key secret?
|
||
If the user has enabled this feature, when Strimzi needs to issue a certificate, instead of using the existing internal mechanism it will create a `Certificate` custom resource. | ||
Strimzi will wait during the reconciliation loop for the `Certificate` status to indicate that the certificate has been issued before continuing. | ||
When issuing cluster certificates (e.g for Kafka etc), once the certificate has been issued, Strimzi will annotate the cert-manager provided Secret with the `strimzi.io/server-cert-hash` annotation with the value being the hash of the certificate in the Secret. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We do not control that Secret, so we should likely not annotate it / rely on its annotation. We need to cary it on the internal Secrets maybe?
|
||
### Issuing certificates | ||
|
||
If the user has enabled this feature, when Strimzi needs to issue a certificate, instead of using the existing internal mechanism it will create a `Certificate` custom resource. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we should make it clear that this is where we control the CN / SANs of the certificates?
During the reconciliation loop, even if all cluster end-entity certificates have been issued, Strimzi will patch the certificate Secrets with the correct `strimzi.io/server-cert-hash` annotation. | ||
The value of this annotation can then be compared with the value on the pods to determine whether the pods need to be restarted to pick up a new Secret. | ||
|
||
For user certificates (issued by the User Operator), the user will be responsible for making sure their applications notice cert-manager renewing the certificates and are updated to use the new certificate. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess UO and the Clients CA deserves more attention here? Will the UO issue the Certificate
resources? How will it keep the certificate Secrets? Or will type: tls-external
be used here?
For cluster certificates (e.g. for Kafka etc), Strimzi will track and handle these changes using the `strimzi.io/server-cert-hash` annotation. | ||
During the reconciliation loop, even if all cluster end-entity certificates have been issued, Strimzi will patch the certificate Secrets with the correct `strimzi.io/server-cert-hash` annotation. | ||
The value of this annotation can then be compared with the value on the pods to determine whether the pods need to be restarted to pick up a new Secret. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure I follow the need to annotate the Secrets here. Normally, during the reconciliation:
- You take the hash of the certiicate
- Use the Hash to annotate the Pod in the Deployment / StrimziPodSet
- Either Kubernetes or Strimzi takes care of rolling the pod based on the Pod annotations being different
1. Install cert-manager and create an `Issuer`. | ||
2. Pause reconciliation for their Kafka cluster. | ||
3. Update the `<CLUSTER_NAME>-cluster-ca-cert` and/or `<CLUSTER_NAME>-clients-ca-cert` Secrets to: | ||
1. contain the CA(s) for the `Issuer` (keeping the old CA cert in the Secret still) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this part is really important - (keeping the old CA cert in the Secret still)
- and should be made more prominent? We should also cover the point when it should be removed.
|
||
### Issuing certificates | ||
|
||
If the user has enabled this feature, when Strimzi needs to issue a certificate, instead of using the existing internal mechanism it will create a `Certificate` custom resource. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I would be very very useful to have this implementation behind an interface and support a mechanism for loading alternative implementations for other external certificate managers. This would allow users to integrate with other external certificate managers
certificateExpirationPolicy: <renew-certificate|replace-key> | ||
certificateIssuer: | ||
type: <internal|cert-manager.io> # (1) | ||
issuerRef: # (2) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The issuerRef element looks to be cert-manager specific rather than something relevant to any external cert manager which could become an issue when supporting other external managers (as mentioned above).
Perhaps the certificateIssuer should instead have a certManager specific sub-element, and add different similar elements in the future that are specific to other certificate managers, i.e. something like:
clusterCa:
certificateIssuer:
certManager:
issuerRef:
name: <string>
kind: <Issuer|ClusterIssuer>
group: <string> # cert-manager.io by default
someOtherManager: <-- future addition -->
managerSpecificConfig:
...
oneOf:
- properties
certManager{}
someOtherManager{}
Or alternatively just allow a map of values to be specified, but that would be less user friendly
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- The property
certificateIssuer.issuerRef
will only be used by Strimzi ifcertificateIssuer.type
is set tocert-manager.io
.
From the above phrase it looks like the intention is to make issuerRef
cert-maanger specific.
* Strimzi will not be responsible for creating `Issuer` or `ClusterIssuer` custom resources. | ||
* Strimzi will create `Certificate` custom resources and will allow the user to influence the contents of these resources by exposing options in the `Kafka` custom resource. | ||
* Strimzi will not directly interact with the lower level `CertificateRequest` and `CertificateSigningRequests` custom resources. | ||
* When Strimzi creates a `Certificate` custom resource, cert-manager will issue the certificate within a reasonable amount of time such that Strimzi can wait during the reconciliation. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we are talking about generating the CA certificate right? Can we make it explicit here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any potential issues with time-outs and retries need to be mentioned here?
|
||
1. Install cert-manager. | ||
2. Create an `Issuer` or `ClusterIssuer` custom resource. | ||
3. Create a `Secret` containing the CAs for Strimzi to trust. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
which CAs are we talking about here? Aren't the cluster CA and clients CA being generate via cert-manager (it relates to my previous question I guess) ... I am confused :-/
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the secret is referenced in the Issuer or ClusterIssuer, should we create it first?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good. I made a few suggested changes to wording for clarity and readability. There are also a couple of questions for further clarification.
|
||
## Proposal | ||
|
||
Strimzi will be updated to allow users to specify that certificates should be issued by an external certificate manager, rather than issued by the Cluster Operator. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Strimzi will be updated to allow users to specify that certificates should be issued by an external certificate manager, rather than issued by the Cluster Operator. | |
Strimzi will be updated to allow users to specify that certificates should be issued by an external certificate manager instead of the Cluster Operator. |
This proposal will specifically describe how this would work for cert-manager, however the user API for configuration will be written in a way that does not prevent other external certificate managers being added in the future. | ||
|
||
The proposal makes a few assumptions: | ||
* Strimzi will not be responsible for installing cert-manager, but we will document the versions of cert-manager that we have tested with. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* Strimzi will not be responsible for installing cert-manager, but we will document the versions of cert-manager that we have tested with. | |
* Strimzi will not be responsible for installing cert-manager, but we will document the supported versions of cert-manager that we have tested with. |
|
||
The proposal makes a few assumptions: | ||
* Strimzi will not be responsible for installing cert-manager, but we will document the versions of cert-manager that we have tested with. | ||
* Strimzi will not be responsible for creating `Issuer` or `ClusterIssuer` custom resources. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will we need to provide any guidelines on conventions in the docs?
* Strimzi will not be responsible for creating `Issuer` or `ClusterIssuer` custom resources. | ||
* Strimzi will create `Certificate` custom resources and will allow the user to influence the contents of these resources by exposing options in the `Kafka` custom resource. | ||
* Strimzi will not directly interact with the lower level `CertificateRequest` and `CertificateSigningRequests` custom resources. | ||
* When Strimzi creates a `Certificate` custom resource, cert-manager will issue the certificate within a reasonable amount of time such that Strimzi can wait during the reconciliation. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any potential issues with time-outs and retries need to be mentioned here?
|
||
1. Install cert-manager. | ||
2. Create an `Issuer` or `ClusterIssuer` custom resource. | ||
3. Create a `Secret` containing the CAs for Strimzi to trust. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the secret is referenced in the Issuer or ClusterIssuer, should we create it first?
Similar to today Strimzi will use the notion of a "generation" to determine whether to roll the cluster to pick up changes in either the `<CLUSTER_NAME>-cluster-ca-cert` or `<CLUSTER_NAME>-clients-ca-cert`. | ||
When the user creates the CA cert Secret they must add the `strimzi.io/ca-cert-generation` annotation to it. | ||
If the user updates the Secret to change the certificates included they must increment the annotation to inform Strimzi it has changed. | ||
Similar to today Strimzi will put the annotation on the pods (Kafka, ZooKeeper etc) to be able to spot when the generation has been changed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar to today Strimzi will use the notion of a "generation" to determine whether to roll the cluster to pick up changes in either the `<CLUSTER_NAME>-cluster-ca-cert` or `<CLUSTER_NAME>-clients-ca-cert`. | |
When the user creates the CA cert Secret they must add the `strimzi.io/ca-cert-generation` annotation to it. | |
If the user updates the Secret to change the certificates included they must increment the annotation to inform Strimzi it has changed. | |
Similar to today Strimzi will put the annotation on the pods (Kafka, ZooKeeper etc) to be able to spot when the generation has been changed. | |
Strimzi will use the current process to determine whether to roll the cluster to pick up changes in the `<CLUSTER_NAME>-cluster-ca-cert` or `<CLUSTER_NAME>-clients-ca-cert` secrets. | |
When a user creates the CA certificate secret, they must add the `strimzi.io/ca-cert-generation` annotation. | |
Strimzi adds this annotation to the pods (Kafka, ZooKeeper, etc.) and uses it to detect when the secrets have changed. | |
If the user updates the secret to change the certificates, they must increment the annotation to inform Strimzi of the change. | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we need to consider maintenance time windows at all?
|
||
## Compatibility | ||
|
||
This feature will be optional and not disabled by default. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This feature will be optional and not disabled by default. | |
This feature will be optional and enabled by default. |
|
||
### Migrating to this feature | ||
|
||
To start using this feature in an existing Kafka cluster the user must: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about a new cluster?
|
||
### Stopping using this feature | ||
|
||
To revert to user managed CAs the user will: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To revert to user managed CAs the user will: | |
To revert to user managed CAs the user must: |
The user is responsible for removing the old `Certificate` resources and uninstalling cert-manager. | ||
|
||
Notes: | ||
* Today we do not document how to go from using user managed CAs to Strimzi managed CAs. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we should?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My feeling was that it wouldn't be a common scenario for customers to move from a mechanism where they have more control, to a mechanism where they have less control.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure it is even supported to go from custom CA to Strimzi CA. At least I do not remember anyone trying it / testing it. In the long term, I think the idea would be also to get rid of the internal CA management - so not sure this would be a issue from my point of view.
This proposal aims to allow Strimzi users to use an external certificate manager, specifically cert-manager, to manage certificates.
Related to strimzi/strimzi-kafka-operator#929