MinIO Operator certificate issued by Kubernetes CSR

In the current Kubernetes landscape, the standard approach for creating, managing, and automating TLS certificates is through the use of the kind: CertificateSigningRequest (CSR) resource. This native Kubernetes resource provides a robust and efficient way to handle the entire lifecycle of certificates within your cluster.

By leveraging the CSR resource, you can streamline and automate various aspects of certificate management, including:

  1. Creating certificates: CSRs allow you to easily generate new certificates for your services, ensuring secure communication between components within your cluster.
  2. Renewing certificates: With CSRs, you can automate the process of renewing certificates before they expire, eliminating the need for manual intervention and reducing the risk of service disruptions.
  3. Revoking certificates: In case a certificate needs to be revoked due to security concerns or other reasons, CSRs provide a straightforward mechanism to invalidate the certificate and prevent its further use.

We will focus on utilizing the Kubernetes CSR resource specifically for creating a certificate that can be used by MinIO. By the end of this guide, you will have a clear understanding of how to generate a certificate using CSR, store it securely in a Kubernetes Secret, and configure MinIO to access and use the generated certificate.

The generated private keys and public certificates will be securely stored in a Kubernetes Secret named operator-tls. This Secret will be accessible to the Operators, allowing them to utilize the certificates for secure communication.

Tutorial

To start, we will generate a self-signed private key using the Elliptic Curve Digital Signature Algorithm (ECDSA) with the P-256 curve. ECDSA is a widely-used and secure algorithm for generating key pairs.

Step 1: Generate a Self-Signed Private Key

To start, we will generate a self-signed private key using the “Elliptic Curve Digital Signature Algorithm” (ECDSA) with the P-256 curve. ECDSA is a widely-used and secure algorithm for generating key pairs.

openssl ecparam -name prime256v1 -genkey -noout -out private.key

Optionally you could use a different algorithm, using RSA.

openssl genrsa -out private.key 2048

Step 2: Generate a Certificate Signing Request (CSR)

With the private key generated, we can now create a Certificate Signing Request (CSR). The CSR contains information about the entity requesting the certificate and is signed with the private key.

openssl req -new -key private.key -out curve.csr \

-subj "/O=system:nodes/CN=system:node:operator.minio-operator.svc" \

-addext "subjectAltName = DNS:operator,DNS:operator.minio-operator.svc,DNS:operator.minio-operator.svc.cluster.local"

Step 3: Encode the CSR in Base64

To include the CSR in a Kubernetes resource, we need to convert it to a base64-encoded string.

base64 curve.csr

Step 4: Create a Kubernetes CertificateSigningRequest

Create a file named csr-manual.yaml with the following contents, replacing <copy base64 encoded curve.csr here> with the base64-encoded CSR from the previous step.

apiVersion: certificates.k8s.io/v1

kind: CertificateSigningRequest

metadata:

  name: operator-minio-operator-csr

spec:

  request: <copy base64 encoded curve.csr here>

  signerName: kubernetes.io/kubelet-serving

  expirationSeconds: 604800 #extend here for 1 year long

  groups:

  - system:serviceaccounts

  - system:serviceaccounts:minio-operator

  - system:authenticated

  - system:nodes

  usages:

- "digital signature"

- "key encipherment"

- "server auth"

  username: system:serviceaccount:minio-operator:minio-operator

Note: Regarding EKS 1.21 and 1.22: On EKS 1.22+ the signerName kubernetes.io/legacy-unknown is not allowed, you should set a signerName as in the example above or beta.eks.amazonaws.com/app-serving, for more details on CSR signing on EKS see Certificate signing documentation. On previous versions of EKS (1.21 and below) you could use the certificate CSR API v1beta1 and send the signerName kubernetes.io/legacy-unknown.

Note: on Kubernetes 1.21 and below: The field expirationSeconds was introduced in Kubernetes 1.22, prior to that the field is silently dropped and not honored

Using the csr-manual.yaml file created in the previous step, create the Kubernetes CSR resource.

kubectl apply -f csr-manual.yaml

Step 6: Approve the CSR

Approve the CSR manually. This is a one-time step.

kubectl certificate approve operator-minio-operator-csr

Step 7: Retrieve the Signed Certificate

Get the public certificate from .status.certificate key in the Kubernetes csr resource.

kubectl get csr operator-minio-operator-csr -o jsonpath="{.status.certificate}" | base64 --decode > public.crt

Step 7: Verify the Certificate

Let’s verify the certificate we fetched above.

Extract the certificate from the CSR resource, it will be in base64. Decode the base64 and read it with OpenSSL as shown below.

kubectl get csr operator-minio-operator-csr -ojsonpath="{.status.certificate}" | base64 --decode | openssl x509 -noout -text

A certificate description similar to this would appear:

Certificate:

Data:

     Version: 3 (0x2)

     Serial Number:

         19:35:68:7b:bc:16:51:b1:95:14:15:45:13:27:e2:b7

Signature Algorithm: sha256WithRSAEncryption

     Issuer: CN=kubernetes

     Validity

         Not Before: Mar 15 22:25:10 2023 GMT

         Not After : Mar 14 22:25:10 2024 GMT

     Subject: O=system:nodes, CN=system:node:operator.minio-operator.svc

     Subject Public Key Info:

         Public Key Algorithm: id-ecPublicKey

             Public-Key: (256 bit)

             pub:

                 04:5b:53:08:98:54:8f:45:c9:e9:15:49:73:cc:50:

                 fe:32:ec:33:de:f8:79:6e:87:a9:7d:01:3e:c3:b0:

                 20:21:69:46:33:a5:44:92:18:90:79:4f:b4:e5:d9:

                 a7:94:5f:b1:4b:73:57:e3:3a:cc:d8:be:24:94:3f:

                 32:2d:d3:f4:38

             ASN1 OID: prime256v1

             NIST CURVE: P-256

     X509v3 extensions:

         X509v3 Key Usage: critical

             Digital Signature, Key Encipherment

         X509v3 Extended Key Usage:

             TLS Web Server Authentication

         X509v3 Basic Constraints: critical

             CA:FALSE

         X509v3 Authority Key Identifier:

             keyid:73:58:4C:D0:20:80:2A:C4:7A:5E:EE:26:C0:28:50:CA:F2:05:48:73


         X509v3 Subject Alternative Name:

             DNS:operator, DNS:operator.minio-operator.svc, DNS:operator.minio-operator.svc.cluster.local

Signature Algorithm: sha256WithRSAEncryption

      64:1c:de:99:cd:54:e8:eb:08:fd:89:c5:6a:94:a5:29:dd:a9:

...

The output will display the certificate details, including the subject, issuer, validity period, and extensions.

Step 9: Create a Kubernetes Secret

Finally, this is where the rubber meets the road. We’ll create a Kubernetes secret for Operator to use

kubectl create secret generic --from-file=./private.key --from-file=./public.crt operator-tls -n minio-operator

Next time the operator starts, it will not attempt to create the certificate or the secret, instead it will be using the one we stored in the secret minio-operator.

Simplifying Certificate Management with MinIO and Kubernetes

We couldn’t have written this short tutorial with another object store. Other similar object stores are tremendously complex and time consuming to set up, but we just set up the MinIO operator to use certificates from a secret without too much lift by just using built-in Kubernetes resources.

While other object storage solutions often require complex configurations and time-consuming setup processes, MinIO's design and tight integration with Kubernetes allow developers and administrators to focus on their core business logic, knowing that their object storage is secure and properly authenticated. The simplicity and efficiency of MinIO's certificate management process set it apart from the competition, making it the preferred choice for businesses seeking a powerful and reliable object storage solution.

If you have any questions, encounter challenges, or simply want to share your experiences with MinIO, our vibrant community is here to help. Join us on Slack, where you can connect with fellow MinIO enthusiasts, get expert advice, and stay up-to-date with the latest developments in the world of object storage.