Skip to content

Commit

Permalink
Update mcs config
Browse files Browse the repository at this point in the history
- Add replicas in mcs configuration
- Add support for TLS for MCS - MinIO Server connection
- Update env variables in MCS secret to match MCS standard env vars
  • Loading branch information
nitisht committed May 18, 2020
1 parent acad2ca commit 53ee997
Show file tree
Hide file tree
Showing 9 changed files with 120 additions and 80 deletions.
15 changes: 14 additions & 1 deletion docs/mcs.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ MCS Configuration is a part of MinIOInstance yaml file. Check the sample file [a
|-----------------------|-------------|
| spec.mcs | Defines the mcs configuration. mcs is a graphical user interface for MinIO. Refer [this](https://github.com/minio/mcs) |
| spec.mcs.image | Defines the mcs image |
| spec.mcs.mcsAccessKey | Specify the access key to be used by mcs |
| spec.mcs.replicas | Number of MCS pods to be created. |
| spec.mcs.mcsSecret | Use this secret to assign mcs credentials to MinIOInstance. |
| spec.mcs.selector | Add a selector for the mcs. Which will be used by the mcs container for grouping. (Note: Should not match the labels provided in `spec.selector`) |
| spec.mcs.metadata | This allows a way to map metadata to the mcs container. Internally `metadata` is a struct type as [explained here](https://godoc.org/k8s.io/apimachinery/pkg/apis/meta/v1#ObjectMeta). [Note: Should match the labels in `spec.mcs.selector`] |
Expand All @@ -39,3 +39,16 @@ Alternatively, you can deploy the example like this
```
kubectl create -f https://raw.githubusercontent.com/minio/minio-operator/master/examples/minioinstance-mcs.yaml
```

Above example file uses CSR for self signed certificate generation. MinIO requires one certificates/key pair

- X.509 certificate for the MinIO server and the corresponding private key.

Accordingly, you'll need to approve the CSR request, using below approach

```
kubectl get csr
kubectl certificate approve <csr-name>
```

Once all the CSRs are approved, MinIO Operator will deploy MCS Pods and start MinIO Server with MCS integration.
2 changes: 1 addition & 1 deletion docs/operator-fields.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ If the MirrorInstance is named as `mirrorinstance`, resources and their names as
| spec.securityContext | Define a security context for the MinIOInstance pod. Refer [this document](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) for details. |
| spec.mcs | Defines the mcs configuration. mcs is a graphical user interface for MinIO. Refer [this](https://github.com/minio/mcs) |
| spec.mcs.image | Defines the mcs image. |
| spec.mcs.mcsAccessKey | Specify the access key to be used by mcs |
| spec.mcs.replicas | Number of MCS pods to be created. |
| spec.mcs.mcsSecret | Use this secret to assign mcs credentials to MinIOInstance. |
| spec.mcs.selector | Add a selector for the mcs. Which will be used by the mcs container for grouping. (Note: Should not match the labels provided in `spec.selector`) |
| spec.mcs.metadata | This allows a way to map metadata to the mcs container. Internally `metadata` is a struct type as [explained here](https://godoc.org/k8s.io/apimachinery/pkg/apis/meta/v1#ObjectMeta). [Note: Should match the labels in `spec.mcs.selector`] |
Expand Down
4 changes: 2 additions & 2 deletions examples/minioinstance-kes.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,8 @@ spec:
storage: 10Gi
## Define configuration for MCS (Graphical user interface for MinIO)
mcs:
image: minio/mcs:v0.0.3
mcsAccessKey: "mcs"
image: minio/mcs:v0.0.4
replicas: 2
mcsSecret:
name: minio-mcs-secret
metadata:
Expand Down
17 changes: 10 additions & 7 deletions examples/minioinstance-mcs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,11 @@ metadata:
name: minio-mcs-secret
type: Opaque
data:
mcshmacjwt: WU9VUkpXVFNJR05JTkdTRUNSRVQ= # base 64 encoded "YOURJWTSIGNINGSECRET" (echo -n 'YOURJWTSIGNINGSECRET' | base64)
mcspbkdfpassphrase: U0VDUkVU # base 64 encoded "SECRET" (echo -n 'SECRET' | base64)
mcspbkdfsalt: U0VDUkVU # base 64 encoded "SECRET" (echo -n 'SECRET' | base64)
mcssecretkey: WU9VUk1DU1NFQ1JFVA== # base 64 encoded "YOURMCSSECRET" (echo -n 'YOURMCSSECRET' | base64)
MCS_HMAC_JWT_SECRET: WU9VUkpXVFNJR05JTkdTRUNSRVQ= # base 64 encoded "YOURJWTSIGNINGSECRET" (echo -n 'YOURJWTSIGNINGSECRET' | base64)
MCS_PBKDF_PASSPHRASE: U0VDUkVU # base 64 encoded "SECRET" (echo -n 'SECRET' | base64)
MCS_PBKDF_SALT: U0VDUkVU # base 64 encoded "SECRET" (echo -n 'SECRET' | base64)
MCS_ACCESS_KEY: WU9VUk1DU0FDQ0VTUw== # base 64 encoded "YOURMCSACCESS" (echo -n 'YOURMCSACCESS' | base64)
MCS_SECRET_KEY: WU9VUk1DU1NFQ1JFVA== # base 64 encoded "YOURMCSSECRET" (echo -n 'YOURMCSSECRET' | base64)
---
apiVersion: v1
kind: Service
Expand Down Expand Up @@ -84,8 +85,8 @@ spec:
storage: 10Gi
## Define configuration for MCS (Graphical user interface for MinIO)
mcs:
image: minio/mcs:v0.0.3
mcsAccessKey: "mcs"
image: minio/mcs:v0.0.4
replicas: 2
mcsSecret:
name: minio-mcs-secret
metadata:
Expand All @@ -100,7 +101,7 @@ spec:
# name: tls-ssl-minio
## Enable Kubernetes based certificate generation and signing as explained in
## https://kubernetes.io/docs/tasks/tls/managing-tls-in-a-cluster
requestAutoCert: false
requestAutoCert: true
## PodManagement policy for pods created by StatefulSet. Can be "OrderedReady" or "Parallel"
## Refer https://kubernetes.io/docs/tutorials/stateful-application/basic-stateful-set/#pod-management-policy
## for details. Defaults to "Parallel"
Expand Down Expand Up @@ -136,6 +137,7 @@ spec:
## restarts the pods if liveness checks fail.
liveness:
httpGet:
scheme: HTTPS
path: /minio/health/live
port: 9000
initialDelaySeconds: 120
Expand All @@ -147,6 +149,7 @@ spec:
## Disable this check if you're setting PodManagementPolicy to "OrderedReady".
readiness:
httpGet:
scheme: HTTPS
path: /minio/health/ready
port: 9000
initialDelaySeconds: 120
Expand Down
4 changes: 2 additions & 2 deletions examples/minioinstance.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,8 @@ spec:
# value: storage
## Define configuration for mcs (A graphical user interface for MinIO)
mcs:
image: minio/mcs:v0.0.3
mcsAccessKey: "mcs"
image: minio/mcs:v0.0.4
replicas: 2
mcsSecret:
name: minio-mcs-secret
selector:
Expand Down
5 changes: 4 additions & 1 deletion pkg/apis/operator.min.io/v1/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ const MirrorCRDResourceKind = "MirrorInstance"
// MCS Related Constants

// DefaultMCSImage specifies the latest MCS Docker hub image
const DefaultMCSImage = "minio/mcs:v0.0.3"
const DefaultMCSImage = "minio/mcs:v0.0.4"

// MCSInstanceLabel is applied to the MCS pods of a MinIOInstance cluster
const MCSInstanceLabel = "v1.min.io/mcs"
Expand All @@ -127,6 +127,9 @@ const MCSAdminPolicyName = "mcsAdmin"
// MCSRestartPolicy defines the default restart policy for MCS Containers
const MCSRestartPolicy = corev1.RestartPolicyAlways

// DefaultMCSReplicas specifies the default number of MCS pods to be created if not specified
const DefaultMCSReplicas = 2

// KES Related Constants

// DefaultKESImage specifies the latest KES Docker hub image
Expand Down
58 changes: 50 additions & 8 deletions pkg/apis/operator.min.io/v1/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@ package v1

import (
"context"
"crypto/tls"
"errors"
"fmt"
"net"
"net/http"
"path"
"strconv"
"time"
Expand Down Expand Up @@ -167,8 +169,13 @@ func (mi *MinIOInstance) EnsureDefaults() *MinIOInstance {
}
}

if mi.HasMCSEnabled() && mi.Spec.MCS.Image == "" {
mi.Spec.MCS.Image = DefaultMCSImage
if mi.HasMCSEnabled() {
if mi.Spec.MCS.Image == "" {
mi.Spec.MCS.Image = DefaultMCSImage
}
if mi.Spec.MCS.Replicas == 0 {
mi.Spec.MCS.Replicas = DefaultMCSReplicas
}
}

if mi.HasKESEnabled() {
Expand Down Expand Up @@ -292,7 +299,7 @@ func (mi *MinIOInstance) HasKESSelector() bool {
// CreateMCSUser function creates an admin user
func (mi *MinIOInstance) CreateMCSUser(minioSecret, mcsSecret map[string][]byte) error {

var accessKey, secretKey, mcsSecretKey []byte
var accessKey, secretKey, mcsAccessKey, mcsSecretKey []byte
var ok bool

host := net.JoinHostPort(mi.MinIOCIServiceHost(), strconv.Itoa(MinIOPort))
Expand All @@ -310,19 +317,30 @@ func (mi *MinIOInstance) CreateMCSUser(minioSecret, mcsSecret map[string][]byte)
return errors.New("secretkey not provided")
}

mcsSecretKey, ok = mcsSecret["mcssecretkey"]
mcsAccessKey, ok = mcsSecret["MCS_ACCESS_KEY"]
if !ok {
return errors.New("MCS_ACCESS_KEY not provided")
}

mcsSecretKey, ok = mcsSecret["MCS_SECRET_KEY"]
if !ok {
return errors.New("mcssecretkey not provided")
return errors.New("MCS_SECRET_KEY not provided")
}

madmClnt, err := madmin.New(host, string(accessKey), string(secretKey), Scheme == "https")
if err != nil {
return err
}
// try to add user with a 20 seconds timeout

if Scheme == "https" {
madmClnt = setUpInsecureTLS(madmClnt)
}

// add user with a 20 seconds timeout
ctx, cancel := context.WithTimeout(context.Background(), time.Second*20)
defer cancel()
if err = madmClnt.AddUser(ctx, mi.Spec.MCS.MCSAccessKey, string(mcsSecretKey)); err != nil {

if err = madmClnt.AddUser(ctx, string(mcsAccessKey), string(mcsSecretKey)); err != nil {
return err
}

Expand Down Expand Up @@ -351,13 +369,37 @@ func (mi *MinIOInstance) CreateMCSUser(minioSecret, mcsSecret map[string][]byte)
return err
}

if err = madmClnt.SetPolicy(context.Background(), MCSAdminPolicyName, string(mi.Spec.MCS.MCSAccessKey), false); err != nil {
if err = madmClnt.SetPolicy(context.Background(), MCSAdminPolicyName, string(mcsAccessKey), false); err != nil {
return err
}

return nil
}

// Set up admin client to use self certificates
func setUpInsecureTLS(api *madmin.AdminClient) *madmin.AdminClient {
// Keep TLS config.
tlsConfig := &tls.Config{
// Can't use SSLv3 because of POODLE and BEAST
// Can't use TLSv1.0 because of POODLE and BEAST using CBC cipher
// Can't use TLSv1.1 because of RC4 cipher usage
MinVersion: tls.VersionTLS12,
InsecureSkipVerify: true,
}

var transport http.RoundTripper = &http.Transport{
DialContext: (&net.Dialer{
Timeout: 10 * time.Second,
KeepAlive: 15 * time.Second,
}).DialContext,
TLSClientConfig: tlsConfig,
}

// Set custom transport.
api.SetCustomTransport(transport)
return api
}

// OwnerRef returns the OwnerReference to be added to all resources created by MinIOInstance
func (mi *MinIOInstance) OwnerRef() []metav1.OwnerReference {
return []metav1.OwnerReference{
Expand Down
16 changes: 11 additions & 5 deletions pkg/apis/operator.min.io/v1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,11 +154,17 @@ type Zone struct {

// MCSConfig defines the credentials for mcs
type MCSConfig struct {
Image string `json:"image,omitempty"`
MCSAccessKey string `json:"mcsAccessKey"`
MCSSecret *corev1.LocalObjectReference `json:"mcsSecret,omitempty"`
Selector *metav1.LabelSelector `json:"selector,omitempty"`
Metadata *metav1.ObjectMeta `json:"metadata,omitempty"`
// Replicas defines number of pods for KES StatefulSet.
// +optional
Replicas int32 `json:"replicas,omitempty"`
// Image defines the MinIOInstance Docker image.
// +optional
Image string `json:"image,omitempty"`
// This secret provides all environment variables for KES
// This is a mandatory field
MCSSecret *corev1.LocalObjectReference `json:"mcsSecret,omitempty"`
Selector *metav1.LabelSelector `json:"selector,omitempty"`
Metadata *metav1.ObjectMeta `json:"metadata,omitempty"`
}

// KESConfig defines the specifications for KES StatefulSet
Expand Down
79 changes: 26 additions & 53 deletions pkg/resources/deployments/mcs-deployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,59 +27,33 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// Returns the MCS environment variables set in configuration.
func mcsEnvironmentVars(mi *miniov1.MinIOInstance) []corev1.EnvVar {
envVars := make([]corev1.EnvVar, 0)
if mi.HasMCSSecret() {
var secretName string
secretName = mi.Spec.MCS.MCSSecret.Name
envVars = append(envVars, corev1.EnvVar{
Name: "MCS_HMAC_JWT_SECRET",
ValueFrom: &corev1.EnvVarSource{
SecretKeyRef: &corev1.SecretKeySelector{
LocalObjectReference: corev1.LocalObjectReference{
Name: secretName,
},
Key: "mcshmacjwt",
},
},
}, corev1.EnvVar{
Name: "MCS_PBKDF_PASSPHRASE",
ValueFrom: &corev1.EnvVarSource{
SecretKeyRef: &corev1.SecretKeySelector{
LocalObjectReference: corev1.LocalObjectReference{
Name: secretName,
},
Key: "mcspbkdfpassphrase",
},
},
}, corev1.EnvVar{
Name: "MCS_PBKDF_SALT",
ValueFrom: &corev1.EnvVarSource{
SecretKeyRef: &corev1.SecretKeySelector{
LocalObjectReference: corev1.LocalObjectReference{
Name: secretName,
},
Key: "mcspbkdfsalt",
},
},
}, corev1.EnvVar{
// Adds required MCS environment variables
func mcsEnvVars(mi *miniov1.MinIOInstance) []corev1.EnvVar {
envVars := []corev1.EnvVar{
{
Name: "MCS_MINIO_SERVER",
Value: miniov1.Scheme + "://" + net.JoinHostPort(mi.MinIOCIServiceHost(), strconv.Itoa(miniov1.MinIOPort)),
}, corev1.EnvVar{
Name: "MCS_SECRET_KEY",
ValueFrom: &corev1.EnvVarSource{
SecretKeyRef: &corev1.SecretKeySelector{
LocalObjectReference: corev1.LocalObjectReference{
Name: secretName,
},
Key: "mcssecretkey",
},
}
if miniov1.Scheme == "https" {
envVars = append(envVars, corev1.EnvVar{
Name: "MCS_MINIO_SERVER_TLS_SKIP_VERIFICATION",
Value: "on",
})
}
return envVars
}

// Returns the MCS environment variables set in configuration.
func mcsSecretEnvVars(mi *miniov1.MinIOInstance) []corev1.EnvFromSource {
envVars := []corev1.EnvFromSource{
{
SecretRef: &corev1.SecretEnvSource{
LocalObjectReference: corev1.LocalObjectReference{
Name: mi.Spec.MCS.MCSSecret.Name,
},
},
}, corev1.EnvVar{
Name: "MCS_ACCESS_KEY",
Value: mi.Spec.MCS.MCSAccessKey,
})
},
}
return envVars
}
Expand Down Expand Up @@ -123,24 +97,23 @@ func mcsContainer(mi *miniov1.MinIOInstance) corev1.Container {
},
ImagePullPolicy: miniov1.DefaultImagePullPolicy,
Args: args,
Env: mcsEnvironmentVars(mi),
Env: mcsEnvVars(mi),
EnvFrom: mcsSecretEnvVars(mi),
Resources: mi.Spec.Resources,
}
}

// NewForMCS creates a new Deployment for the given MinIO instance.
func NewForMCS(mi *miniov1.MinIOInstance) *appsv1.Deployment {

var replicas int32 = 1

d := &appsv1.Deployment{
ObjectMeta: metav1.ObjectMeta{
Namespace: mi.Namespace,
Name: mi.MCSDeploymentName(),
OwnerReferences: mi.OwnerRef(),
},
Spec: appsv1.DeploymentSpec{
Replicas: &replicas,
Replicas: &mi.Spec.MCS.Replicas,
Selector: mi.Spec.MCS.Selector,
Template: corev1.PodTemplateSpec{
ObjectMeta: mcsMetadata(mi),
Expand Down

0 comments on commit 53ee997

Please sign in to comment.