Tenant external client certificate for KES, create certificate issued by Kubernetes CSR - minio/wiki GitHub Wiki
Purpose
This doc will guide on how to create a secret that stores a private key and a Kubernetes issued public certificate.
We will save those private key and public certificate in a secret called external-client-cert
under the tenant namespace, then we will instruct in Tenant to use that secret in the externalClientCertSecret
field.
What is this certificate for?
For the MinIO server to talk to KES service, MinIO on this scenario is a client, and in order for MinIO to authenticate himself with KES, needs an authentication method, instead of user/password (BasicAuth), JWT or other methods, here we use a certificate for mutual TLS (mTLS)
Create the certificate
Private key
We begin by creating a self signed private key, using Elliptic curve P256
openssl ecparam -name prime256v1 -genkey -noout -out private.key
Optinally you could use a different algorithm, ie: using RSA
openssl genrsa -out private.key 2048
Certificate signing request
Then create a signing request
# make sure to replace here <tenant name> and <tenant namespace>
openssl req -new -key private.key -out curve.csr \
-subj "/O=system:nodes/CN=system:node:*.<tenant name>-hl.<tenant namespace>.svc.cluster.local" \
-addext "subjectAltName=DNS:minio.<tenant namespace>.svc.cluster.local,DNS:minio.<tenant namespace>,DNS:minio.<tenant namespace>.svc,DNS:*.<tenant name>-hl.<tenant namespace>.svc.cluster.local,DNS:*.<tenant namespace>.svc.cluster.local"
Create CSR Request
Get the csr in base64
cat curve.csr | base64
Copy this inside a csr-client-manual.yaml file
#csr-client-manual.yaml
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
name: external-client-cert-csr
spec:
request: <copy base64 encoded curve.csr here>
signerName: kubernetes.io/kube-apiserver-client
expirationSeconds: 31536000 #extend to 1 year or whatever cert duration makes sense
groups:
- system:authenticated
- system:nodes
usages:
- "digital signature"
- "key encipherment"
- "client 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 orbeta.eks.amazonaws.com/app-serving
, for more details on CSR signing on EKS see Certificate signing documentation. On previos versions of EKS (1.21 and below) you could use the certificate CSR APIv1beta1
and send the signerNamekubernetes.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 droped and not honored.
Create CSR resource
kubectl apply -f csr-client-manual.yaml
Approve CSR, get the public certificate issued by k8s
Approve CSR
kubectl certificate approve external-client-cert-csr
Get the public crt to local filesystem
kubectl get csr external-client-cert-csr -o jsonpath="{.status.certificate}" | base64 --decode > public.crt
external-client-cert
secret
Create the Finally, we create a secret for the Tenant to use
kubectl create secret generic --from-file=./private.key --from-file=./public.crt external-client-cert -n <tenant namespace>
Setup the tenant
Last step is to instruct the tenant to use the certificates we stored in the secret external-client-cert
, set this secret name in the tenant yaml CRD
apiVersion: minio.min.io/v2
kind: Tenant
metadata:
name: <tenant name>
namespace: <tenant namespace>
spec:
...
externalClientCertSecret:
name: external-client-cert
type: Opaque