Skip to content

Commit

Permalink
feat(eks): managed nodegroup support (#6759)
Browse files Browse the repository at this point in the history
feat(aws-eks): managed nodegroup support (#6759   )

BREAKING CHANGE: `Cluster` now creates a default managed nodegroup as its default capacity. Set the new cluster property `defaultCapacityType` to `DefaultCapacityType.EC2` to preserve `EC2` as its default capacity.

Closes #5086
  • Loading branch information
pahud authored Mar 25, 2020
1 parent 53f82f0 commit 74169bf
Show file tree
Hide file tree
Showing 10 changed files with 817 additions and 66 deletions.
44 changes: 34 additions & 10 deletions packages/@aws-cdk/aws-eks/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ manifests within EKS clusters.

This example defines an Amazon EKS cluster with the following configuration:

- 2x **m5.large** instances (this instance type suits most common use-cases, and is good value for money)
- Managed nodegroup with 2x **m5.large** instances (this instance type suits most common use-cases, and is good value for money)
- Dedicated VPC with default configuration (see [ec2.Vpc](https://docs.aws.amazon.com/cdk/api/latest/docs/aws-ec2-readme.html#vpc))
- A Kubernetes pod with a container based on the [paulbouwer/hello-kubernetes](https://github.com/paulbouwer/hello-kubernetes) image.

Expand All @@ -49,12 +49,20 @@ cluster.addResource('mypod', {

### Capacity

By default, `eks.Cluster` is created with x2 `m5.large` instances.
By default, `eks.Cluster` is created with a managed nodegroup with x2 `m5.large` instances.

```ts
new eks.Cluster(this, 'cluster-two-m5-large');
```

To use the traditional self-managed Amazon EC2 instances instead, set `defaultCapacityType` to `DefaultCapacityType.EC2`

```ts
const cluster = new eks.Cluster(this, 'cluster-self-managed-ec2', {
defaultCapacityType: eks.DefaultCapacityType.EC2
});
```

The quantity and instance type for the default capacity can be specified through
the `defaultCapacity` and `defaultCapacityInstance` props:

Expand All @@ -73,16 +81,13 @@ new eks.Cluster(this, 'cluster-with-no-capacity', { defaultCapacity: 0 });

The `cluster.defaultCapacity` property will reference the `AutoScalingGroup`
resource for the default capacity. It will be `undefined` if `defaultCapacity`
is set to `0`:
is set to `0` or `defaultCapacityType` is either `NODEGROUP` or undefined.

```ts
const cluster = new eks.Cluster(this, 'my-cluster');
cluster.defaultCapacity!.scaleOnCpuUtilization('up', {
targetUtilizationPercent: 80
});
```
And the `cluster.defaultNodegroup` property will reference the `Nodegroup`
resource for the default capacity. It will be `undefined` if `defaultCapacity`
is set to `0` or `defaultCapacityType` is `EC2`.

You can add customized capacity through `cluster.addCapacity()` or
You can add `AutoScalingGroup` resource as customized capacity through `cluster.addCapacity()` or
`cluster.addAutoScalingGroup()`:

```ts
Expand All @@ -93,6 +98,25 @@ cluster.addCapacity('frontend-nodes', {
});
```

### Managed Node Groups

Amazon EKS managed node groups automate the provisioning and lifecycle management of nodes (Amazon EC2 instances)
for Amazon EKS Kubernetes clusters. By default, `eks.Nodegroup` create a nodegroup with x2 `t3.medium` instances.

```ts
new eks.Nodegroup(stack, 'nodegroup', { cluster });
```

You can add customized node group through `cluster.addNodegroup()`:

```ts
cluster.addNodegroup('nodegroup', {
instanceType: new ec2.InstanceType('m5.large'),
minSize: 4,
});
```


### Fargate

AWS Fargate is a technology that provides on-demand, right-sized compute
Expand Down
56 changes: 54 additions & 2 deletions packages/@aws-cdk/aws-eks/lib/cluster.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { FargateProfile, FargateProfileOptions } from './fargate-profile';
import { HelmChart, HelmChartOptions } from './helm-chart';
import { KubernetesPatch } from './k8s-patch';
import { KubernetesResource } from './k8s-resource';
import { Nodegroup, NodegroupOptions } from './managed-nodegroup';
import { spotInterruptHandler } from './spot-interrupt-handler';
import { renderUserData } from './user-data';

Expand Down Expand Up @@ -239,6 +240,13 @@ export interface ClusterProps extends ClusterOptions {
* @default m5.large
*/
readonly defaultCapacityInstance?: ec2.InstanceType;

/**
* The default capacity type for the cluster.
*
* @default NODEGROUP
*/
readonly defaultCapacityType?: DefaultCapacityType
}

/**
Expand Down Expand Up @@ -310,10 +318,18 @@ export class Cluster extends Resource implements ICluster {

/**
* The auto scaling group that hosts the default capacity for this cluster.
* This will be `undefined` if the default capacity is set to 0.
* This will be `undefined` if the `defaultCapacityType` is not `EC2` or
* `defaultCapacityType` is `EC2` but default capacity is set to 0.
*/
public readonly defaultCapacity?: autoscaling.AutoScalingGroup;

/**
* The node group that hosts the default capacity for this cluster.
* This will be `undefined` if the `defaultCapacityType` is `EC2` or
* `defaultCapacityType` is `NODEGROUP` but default capacity is set to 0.
*/
public readonly defaultNodegroup?: Nodegroup;

/**
* If this cluster is kubectl-enabled, returns the `ClusterResource` object
* that manages it. If this cluster is not kubectl-enabled (i.e. uses the
Expand Down Expand Up @@ -422,7 +438,11 @@ export class Cluster extends Resource implements ICluster {
const minCapacity = props.defaultCapacity === undefined ? DEFAULT_CAPACITY_COUNT : props.defaultCapacity;
if (minCapacity > 0) {
const instanceType = props.defaultCapacityInstance || DEFAULT_CAPACITY_TYPE;
this.defaultCapacity = this.addCapacity('DefaultCapacity', { instanceType, minCapacity });
this.defaultCapacity = props.defaultCapacityType === DefaultCapacityType.EC2 ?
this.addCapacity('DefaultCapacity', { instanceType, minCapacity }) : undefined;

this.defaultNodegroup = props.defaultCapacityType !== DefaultCapacityType.EC2 ?
this.addNodegroup('DefaultCapacity', { instanceType, minSize: minCapacity } ) : undefined;
}

const outputConfigCommand = props.outputConfigCommand === undefined ? true : props.outputConfigCommand;
Expand Down Expand Up @@ -470,6 +490,24 @@ export class Cluster extends Resource implements ICluster {
return asg;
}

/**
* Add managed nodegroup to this Amazon EKS cluster
*
* This method will create a new managed nodegroup and add into the capacity.
*
* @see https://docs.aws.amazon.com/eks/latest/userguide/managed-node-groups.html
* @param id The ID of the nodegroup
* @param options options for creating a new nodegroup
*/
public addNodegroup(id: string, options?: NodegroupOptions): Nodegroup {
// initialize the awsAuth for this cluster
this._awsAuth = this._awsAuth ?? this.awsAuth;
return new Nodegroup(this, `Nodegroup${id}`, {
cluster: this,
...options,
});
}

/**
* Add compute capacity to this EKS cluster in the form of an AutoScalingGroup
*
Expand Down Expand Up @@ -935,6 +973,20 @@ export enum CoreDnsComputeType {
FARGATE = 'fargate'
}

/**
* The default capacity type for the cluster
*/
export enum DefaultCapacityType {
/**
* managed node group
*/
NODEGROUP,
/**
* EC2 autoscaling group
*/
EC2
}

const GPU_INSTANCETYPES = ['p2', 'p3', 'g4'];

export function nodeTypeForInstanceType(instanceType: ec2.InstanceType) {
Expand Down
3 changes: 2 additions & 1 deletion packages/@aws-cdk/aws-eks/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ export * from './fargate-profile';
export * from './helm-chart';
export * from './k8s-patch';
export * from './k8s-resource';
export * from './fargate-cluster';
export * from './fargate-cluster';
export * from './managed-nodegroup';
Loading

0 comments on commit 74169bf

Please sign in to comment.