TLS certificate management with cert-manager

The MinIO AIStor Operator supports cert-manager to provision and manage certificates, as an alternative to the Operator. cert-manager obtains valid certificates from an Issuer or ClusterIssuer and can automatically renew certificates prior to expiration.

A ClusterIssuer issues certificates for multiple Namespaces. An Issuer only mints certificates for its own Namespace.

The following instructions implement a self-signed Cluster Issuer. You can also work with other issuers supported by cert-manager. With other issuers, you must provide the Issuer CA certificate to MinIO AIStor, instead of the CAs mentioned in this guide.

Summary

You complete the following steps to manage your TLS certificates with cert-manager:

  1. Install cert-manager

  2. Create cluster issuer

  3. Create CA issuer for operator

  4. Create issuer for operator

  5. Create certificate

  6. If installing for the first time, install operator with auto TLS disabled. If migrating, disable auto TLS.

  7. Create cert-manager certificates for each object store.

  8. Add certificates with cert-manager to object stores. (Replace if migrating and make sure to disable auto TLS)

  9. Trust the object store CA in the operator.

The details

  1. Install cert-manager. See the cert-manager documentation for details. Version 1.12 is recommended.

  2. Create a Cluster Issuer resource for your cluster. This example creates a self-signed cluster issuer but modify to support your environment’s requirements:

    # selfsigned-root-clusterissuer.yaml
    apiVersion: cert-manager.io/v1
    kind: ClusterIssuer
    metadata:
      name: selfsigned-root
    spec:
      selfSigned: {}
    

    and apply the resource.

  3. Create a CA Issuer for the aistor-operator namespace.

    Create a file called operator-ca-tls-secret.yaml with the following contents:

    # operator-ca-tls-secret.yaml
    apiVersion: cert-manager.io/v1
    kind: Certificate
    metadata:
      name: aistor-operator-ca-certificate
      namespace: aistor-operator
    spec:
      isCA: true
      commonName: operator
      secretName: operator-ca-tls
      duration: 70128h # 8y
      privateKey:
        algorithm: ECDSA
        size: 256
      issuerRef:
        name: selfsigned-root # name must match name of ClusterIssuer created with cert-manager
        kind: ClusterIssuer
        group: cert-manager.io
    

    and apply the resource.

    Make sure to trust this certificate in any applications that need to interact with the MinIO AIStor Operator.

  4. Use the operator-ca-tls secret to add an Issuer resource for the aistor-operator namespace.

    Create a file called operator-ca-issuer.yaml with the following contents:

    # operator-ca-issuer.yaml
    apiVersion: cert-manager.io/v1
    kind: Issuer
    metadata:
      name: aistor-operator-ca-issuer
      namespace: aistor-operator
    spec:
      ca:
        secretName: operator-ca-tls
    

    and apply the resource.

  5. Create the TLS certificate. The certificate must be valid for the following DNS domains:

    • sts

    • sts.aistor-operator.svc.

    • sts.aistor-operator.svc.<cluster domain>

    where cluster domain is the internal root DNS domain assigned in your Kubernetes cluster. Typically, this is cluster.local, but confirm the value by checking your CoreDNS configuration for the correct value for your Kubernetes cluster.

    Create a file named sts-tls-certificate.yaml with the following contents:

    # sts-tls-certificate.yaml
    apiVersion: cert-manager.io/v1
    kind: Certificate
    metadata:
      name: sts-certmanager-cert
      namespace: aistor-operator
    spec:
      dnsNames:
        - sts
        - sts.aistor-operator.svc
        - sts.aistor-operator.svc.cluster.local # Replace cluster.local with the value for your domain.
      secretName: sts-tls # required, must be this value
      issuerRef:
        name: aistor-operator-ca-issuer
    

    and apply the resource.

    This creates a secret called sts-tls in the aistor-operator namespace.

    Warning
    The STS service will not start if the sts-tls secret is missing or contains an invalid key-value pair. This secret contains the TLS certificate.
  6. Disable auto TLS for the operator. When you install the operator, set the OPERATOR_STS_AUTO_TLS_ENABLED environment variable to off in the aistor-operator container. Or if the operator is already installed, change the environment variable.

  7. In each object store namespace, request a certificate for a new CA with spec.isCA set to true.

    Your spec should look something like the following:

    # object-store-example-ca-certificate.yaml
    apiVersion: cert-manager.io/v1
    kind: Certificate
    metadata:
      name: object-store-example-ca-certificate
      namespace: object-store-example
    spec:
      isCA: true
      commonName: object-store-example-ca
      secretName: object-store-example-ca-tls
      duration: 70128h # 8y
      privateKey:
        algorithm: ECDSA
        size: 256
      issuerRef:
        name: selfsigned-root # name must match name of ClusterIssuer created with cert-manager
        kind: ClusterIssuer
        group: cert-manager.io
    

    and apply the resource.

  8. Generate a resource definition for an Issuer.

    Your resource spec should look something like the following:

    # object-store-example-ca-issuer.yaml
    apiVersion: cert-manager.io/v1
    kind: Issuer
    metadata:
      name: object-store-example-ca-issuer
      namespace: object-store-example
    spec:
      ca:
        secretName: object-store-example-ca-tls
    

    and apply the resource.

  9. Create the certificate for the object store with cert-manager.

    The certificate must be valid for the following DNS domains:

    • minio.<namespace>
    • minio.<namespace>.svc
    • minio.<namespace>.svc.<cluster domain>
    • *.<object store-name>-hl.<namespace>.svc.<cluster domain>
    • *.<namespace>.svc.<cluster domain>
    • *.<object store-name>.minio.<namespace>.svc.<cluster domain>'

    where:

    • <cluster domain> is the internal root DNS domain assigned in your Kubernetes cluster. Typically, this is cluster.local, but confirm the value by checking your CoreDNS configuration for the correct value for your Kubernetes cluster.

      Different Kubernetes providers manage the root domain differently. Check with your Kubernetes provider for more information.

    • <object store-name> is the name provided to your object store in the metadata.name of the object store YAML. For this example it is myaistor.

    • <namespace> is the value created earlier where the object store will be installed. In the object store YAML, it is defined in the the metadata.namespace field. For this example the value is object-store-example.

    Create a file called object-store-example-minio-certificate.yaml (or whatever suits your naming conventions). The contents of the file should resemble the following, modified to reflect your cluster and object store configurations:

    # object-store-example-minio-certificate.yaml
    apiVersion: cert-manager.io/v1
    kind: Certificate
    metadata:
      name: object store-certmanager-cert
      namespace: object-store-example
    spec:
      dnsNames:
        - "minio.object-store-example"
        - "minio.object-store-example.svc"
        - 'minio.object-store-example.svc.cluster.local'
        - '*.minio.object-store-example.svc.cluster.local'
        - '*.myaistor-hl.object-store-example.svc.cluster.local'
        - '*.myaistor.minio.object-store-example.svc.cluster.local'
      secretName: myaistor-tls
      issuerRef:
        name: object-store-example-ca-issuer
    
Tip
For this example, the object store name is myaistor. We recommend naming the secret in the field spec.secretName as <object store-name>-tls as a naming convention.
and apply the resource.

Deploy the object store using cert-manager for TLS certificate management

When deploying a object store, you must set the TLS configuration such that:

  • The object store does not automatically generate its own certificates (spec.requestAutoCert: false) and

  • The object store has a valid cert-manager reference (spec.externalCertSecret)

This directs the Operator to deploy the object store using the cert-manager certificates exclusively.

The following YAML spec provides a baseline configuration meeting these requirements:

apiVersion: minio.min.io/v2
kind: Tenant
metadata:
  name: myaistor
  namespace: object-store-example
spec:
...
  ## Disable default tls certificates.
  requestAutoCert: false
  ## Use certificates generated by cert-manager.
  externalCertSecret:
    - name: myaistor-tls
      type: cert-manager.io/v1
...

Trust the object store CA

To trust the object store CA, you must pass the certificate to the Operator as a secret. The Operator does not trust the object store CA by default.

To trust the CA, create a secret with the prefix operator-ca-tls- followed by a unique identifier in the aistor-operator namespace.

The Operator mounts and trusts all certificates issued by the provided CAs. This is required because the Operator performs health checks using the /minio/health/cluster endpoint.

To create the operator-ca-tls-object-store-example secret:

Copy the object store cert-manager generated CA public key (ca.crt) into the aistor-operator namespace. This allows the Operator to trust the cert-manager issued CA and all certificates derived from it.

  1. Create a ca.crt file containing the CA:

    kubectl get secrets -n object-store-example object-store-example-ca-tls -o=jsonpath='{.data.ca\.crt}' | base64 -d > ca.crt
    
  2. Create the secret:

    kubectl create secret generic operator-ca-tls-object-store-example --from-file=ca.crt -n aistor-operator
    

This example includes the object store namespace as a suffix to the secret name operator-ca-tls-object-store-example. This approach makes it easy to identify the namespace the CA comes from. In your deployment, include the name of your object store namespace to link secrets more easily to related resources.

  1. Deploy the object store.

    Use the modified baseline object store YAML to disable AutoCert and reference the secret you generated.