Skip to content

Commit

Permalink
feat(storage-class): add option to create storage class (#5)
Browse files Browse the repository at this point in the history
* If `createStorageClass  === true` create storageClass
* storageClassParams, and volumeProvisioner options added.
* if `createStorageClass` is false, and `storageClassName` is given, storageClass won't get created, and statefulset will use `storageClassName`.
  • Loading branch information
Hunter-Thompson authored Feb 6, 2021
1 parent 223a7ad commit 65498bb
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 13 deletions.
10 changes: 8 additions & 2 deletions API.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,13 @@ new MyMongo(scope: Construct, name: string, opts: STSOptions)
* **name** (<code>string</code>) *No description*
* **opts** (<code>[STSOptions](#cdk8s-mongo-sts-stsoptions)</code>) *No description*
* **image** (<code>string</code>) The Docker image to use for this app.
* **createStorageClass** (<code>boolean</code>) Option to create storage class, if enabled, a storage class will be created for the statefulset. __*Default*__: true
* **defaultReplicas** (<code>number</code>) Number of replicas. __*Default*__: 3
* **namespace** (<code>string</code>) The Kubernetes namespace where this app to be deployed. __*Default*__: 'default'
* **resources** (<code>[ResourceRequirements](#cdk8s-mongo-sts-resourcerequirements)</code>) Resources requests for the DB. __*Default*__: Requests = { CPU = 200m, Mem = 256Mi }, Limits = { CPU = 400m, Mem = 512Mi }
* **storageClass** (<code>string</code>) The storage class to use for our PVC. __*Optional*__
* **storageClassName** (<code>string</code>) The storage class to use for our PVC. __*Default*__: 'gp2-expandable'
* **storageClassParams** (<code>Map<string, string></code>) Storage class params. __*Default*__: { type = gp2, fsType: ext4 }
* **volumeProvisioner** (<code>string</code>) Each StorageClass has a provisioner that determines what volume plugin is used for provisioning PVs. __*Default*__: 'kubernetes.io/aws-ebs'
* **volumeSize** (<code>string</code>) The Volume size of our DB in string, e.g 10Gi, 20Gi. __*Optional*__


Expand Down Expand Up @@ -93,10 +96,13 @@ Name | Type | Description
Name | Type | Description
-----|------|-------------
**image**🔹 | <code>string</code> | The Docker image to use for this app.
**createStorageClass**?🔹 | <code>boolean</code> | Option to create storage class, if enabled, a storage class will be created for the statefulset.<br/>__*Default*__: true
**defaultReplicas**?🔹 | <code>number</code> | Number of replicas.<br/>__*Default*__: 3
**namespace**?🔹 | <code>string</code> | The Kubernetes namespace where this app to be deployed.<br/>__*Default*__: 'default'
**resources**?🔹 | <code>[ResourceRequirements](#cdk8s-mongo-sts-resourcerequirements)</code> | Resources requests for the DB.<br/>__*Default*__: Requests = { CPU = 200m, Mem = 256Mi }, Limits = { CPU = 400m, Mem = 512Mi }
**storageClass**?🔹 | <code>string</code> | The storage class to use for our PVC.<br/>__*Optional*__
**storageClassName**?🔹 | <code>string</code> | The storage class to use for our PVC.<br/>__*Default*__: 'gp2-expandable'
**storageClassParams**?🔹 | <code>Map<string, string></code> | Storage class params.<br/>__*Default*__: { type = gp2, fsType: ext4 }
**volumeProvisioner**?🔹 | <code>string</code> | Each StorageClass has a provisioner that determines what volume plugin is used for provisioning PVs.<br/>__*Default*__: 'kubernetes.io/aws-ebs'
**volumeSize**?🔹 | <code>string</code> | The Volume size of our DB in string, e.g 10Gi, 20Gi.<br/>__*Optional*__


Expand Down
51 changes: 42 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,34 @@ Create a Replicated, Password protected MongoDB Statefulset on Kubernetes, power
**cdk8s-sts-mongo** is a [cdk8s](https://cdk8s.io) library, and also uses [cvallance/mongo-k8s-sidecar](https://github.com/cvallance/mongo-k8s-sidecar) to manage the MongoDB replicaset.

```typescript
new MyMongo(this, 'dev', {
image: 'mongo',
namespace: 'databases',
defaultReplicas: 3,
volumeSize: '10Gi',
storageClass: 'gp2',
});
import { Construct } from 'constructs';
import { App, Chart, ChartProps } from 'cdk8s';
import { MyMongo } from 'cdk8s-mongo-sts';

export class MyChart extends Chart {
constructor(scope: Construct, id: string, props: ChartProps = { }) {
super(scope, id, props);
new MyMongo(this, 'dev', {
image: 'mongo',
namespace: 'databases',
defaultReplicas: 3,
volumeSize: '10Gi',
createStorageClass: true,
volumeProvisioner: 'kubernetes.io/aws-ebs',
storageClassName: "io1-slow",
storageClassParams: {
type: 'io1',
fsType: 'ext4',
iopsPerGB: "10",
},
});

}
}

const app = new App();
new MyChart(app, 'asd');
app.synth();
```

Create a secret for your DB that starts with the same name as your Statefulset with the following keys :
Expand All @@ -25,12 +46,24 @@ password

See [this](https://kubernetes.io/docs/concepts/configuration/secret/) for documentation on Kubernetes secrets.

Then the Kubernetes manifests created by `cdk8s synth` command will have Kubernetes resources such as `Statefulset`, `Service`, `ClusterRole`, `ClusterRoleBinding`, `ServiceAccount` as follows.
Then the Kubernetes manifests created by `cdk8s synth` command will have Kubernetes resources such as `Statefulset`, `Service`, `ClusterRole`, `ClusterRoleBinding`, `ServiceAccount`, and `StorageClass` as follows.

<details>
<summary>manifest.k8s.yaml</summary>

```yaml
allowVolumeExpansion: true
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: io1-slow
parameters:
fsType: ext4
type: io1
iopsPerGB: "10"
provisioner: kubernetes.io/aws-ebs
reclaimPolicy: Retain
---
apiVersion: v1
kind: Service
metadata:
Expand Down Expand Up @@ -165,7 +198,7 @@ spec:
resources:
requests:
storage: 10Gi
storageClassName: gp2
storageClassName: io1-slow
```
</details>
Expand Down
45 changes: 43 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,30 @@ export interface STSOptions {
*/
readonly volumeSize?: string;

/**
* Option to create storage class, if enabled, a storage class will be created for the statefulset
* @default true
*/
readonly createStorageClass?: boolean;

/**
* The storage class to use for our PVC
* @default 'gp2-expandable'
*/
readonly storageClass?: string;
readonly storageClassName?: string;

/**
* Each StorageClass has a provisioner that determines what volume plugin is used for provisioning PVs. This field must be specified.
* See [this](https://kubernetes.io/docs/concepts/storage/storage-classes/#provisioner) for Ref
* @default 'kubernetes.io/aws-ebs'
*/
readonly volumeProvisioner?: string;

/**
* Storage class params
* @default - { type = gp2, fsType: ext4 }
*/
readonly storageClassParams?: { [name: string]: string };

/**
* Resources requests for the DB.
Expand Down Expand Up @@ -82,6 +102,9 @@ export class MyMongo extends Construct {
const imageName = opts.image;
const namespace = opts.namespace ?? 'default';
this.namespace = namespace;
var storageClassName = opts.storageClassName ?? 'gp2-expandable';
const volumeProvisioner = opts.volumeProvisioner ?? 'kubernetes.io/aws-ebs';
const storageClassParams = opts.storageClassParams ?? { type: 'gp2', fsType: 'ext4' };
const resources = {
limits: convertQuantity(opts.resources?.limits, {
cpu: '400m',
Expand All @@ -94,6 +117,23 @@ export class MyMongo extends Construct {
};
const labels = { db: name };

if (opts.createStorageClass === true) {
const storageClassOpts: k8s.KubeStorageClassProps = {
metadata: {
name: opts.storageClassName,
},
provisioner: volumeProvisioner,
allowVolumeExpansion: true,
reclaimPolicy: 'Retain',
parameters: {
...storageClassParams,
},
};
const storageclass = new k8s.KubeStorageClass(this, 'storageclass', storageClassOpts);
this.name = storageclass.name;
var storageClassName = storageclass.name;
}

const serviceOpts: k8s.KubeServiceProps = {
metadata: {
namespace: namespace,
Expand Down Expand Up @@ -173,7 +213,7 @@ export class MyMongo extends Construct {
},
spec: {
accessModes: ['ReadWriteOnce'],
storageClassName: opts.storageClass,
storageClassName: storageClassName,
resources: {
requests: volumerequest,
},
Expand Down Expand Up @@ -294,6 +334,7 @@ export class MyMongo extends Construct {

const sts = new k8s.KubeStatefulSet(this, 'sts', stsOpts);
this.name = sts.name;

}
}

Expand Down

0 comments on commit 65498bb

Please sign in to comment.