# Getting Started with kOps on Spot Ocean

[Ocean](https://spot.io/products/ocean/) by [Spot](https://spot.io/) simplifies infrastructure management for Kubernetes.  With robust, container-driven infrastructure auto-scaling and intelligent right-sizing for container resource requirements, operations can literally "set and forget" the underlying cluster.

Ocean seamlessly integrates with your existing instance groups, as a drop-in replacement for AWS Auto Scaling groups, and allows you to streamline and optimize the entire workflow, from initially creating your cluster to managing and optimizing it on an ongoing basis.

## Features

- **Simplify Cluster Management** —
Ocean's Virtual Node Groups make it easy to run different infrastructure in a single cluster, which can span multiple AWS VPC availability zones and subnets for high-availability.

- **Container-Driven Autoscaling and Vertical Rightsizing** —
Auto-detect your container infrastructure requirements so the appropriate instance size or type will always be available. Measure real-time CPU/Memory consumption of your Pods for ongoing resource optimization.

- **Cloud-Native Showback** —
Gain a granular view of your cluster's cost breakdown (compute and storage) for each and every one of the cluster's resources such as Namespaces, Deployments, Daemon Sets, Jobs, and Pods.

- **Optimized Pricing and Utilization** —
Ocean not only intelligently leverages Spot Instances and reserved capacity to reduce costs, but also eliminates underutilized instances with container-driven autoscaling and advanced bin-packing.

## Prerequisites

Make sure you have [installed kOps](../install.md) and [installed kubectl](../install.md#installing-other-dependencies).

## Setup your environment

### Spot
Generate your credentials [here](https://console.spotinst.com/spt/settings/tokens/permanent). If you are not a Spot Ocean user, sign up for free [here](https://console.spotinst.com/spt/auth/signUp). For further information, please checkout our [Spot API](https://help.spot.io/spotinst-api/) guide, available on the [Spot Help Center](https://help.spot.io/) website.

To use environment variables, run:
```bash
export SPOTINST_TOKEN=<spotinst_token>
export SPOTINST_ACCOUNT=<spotinst_account>
```

To use credentials file, run the [spotctl configure](https://github.com/spotinst/spotctl#getting-started) command:
```bash
spotctl configure
? Enter your access token [? for help] **********************************
? Select your default account  [Use arrows to move, ? for more help]
> act-01234567 (prod)
  act-0abcdefg (dev)
```

Or, manually create an INI formatted file like this:
```ini
[default]
token   = <spotinst_token>
account = <spotinst_account>
```

and place it in:

- Unix/Linux/macOS:
```bash
~/.spotinst/credentials
```
- Windows:
```bash
%UserProfile%\.spotinst\credentials
```

### AWS

Make sure to set up [a dedicated IAM user](./aws.md#setup-iam-user), [DNS records](./aws.md#configure-dns) and [cluster state storage](./aws.md#cluster-state-storage). Please refer to [setup your environment](./aws.md#setup-your-environment) for further details.

## Feature Flags

| Flag | Description |
|---|---|
| `+Spotinst` | Enables the use of the Spot integration. |
| `+SpotinstOcean` | Enables the use of the Spot Ocean integration. |
| `+SpotinstOceanTemplate` - Enables the use of Spot Ocean object as a template for Virtual Node Groups. |
| `+SpotinstHybrid` | Toggles between hybrid and full instance group implementations. Allows you to gradually integrate with Spot Ocean by continuing to use instance groups through AWS Auto Scaling groups, except for specific instance groups labeled with a predefined [metadata label](#metadata-labels). |
| `-SpotinstController` | Toggles the installation of the Spot controller addon off. Please note that the feature flag must be prefixed with a minus (`-`) sign to set its value to `false`, which results in disabling the controller. |

## Creating a Cluster

You can add an Ocean instance group to new or existing clusters. To create a new cluster with a Ocean instance groups, run:

```bash
# configure the feature flags
export KOPS_FEATURE_FLAGS="Spotinst,SpotinstOcean,SpotinstOceanTemplate"

# create the cluster
kops create cluster --zones=us-west-2a example
```

!!!note
    It's possible to have a cluster with both Ocean-managed and unmanaged instance groups.

```bash
# configure the feature flags
export KOPS_FEATURE_FLAGS="Spotinst,SpotinstOcean,SpotinstHybrid"

# create the instance groups
kops create -f instancegroups.yaml
```

```yaml
# instancegroups.yaml
# A cluster with both Ocean-managed and unmanaged instance groups.
---
# Use Ocean in hybrid mode.
apiVersion: kops.k8s.io/v1alpha2
kind: InstanceGroup
metadata:
  labels:
    kops.k8s.io/cluster: "example"
    spotinst.io/hybrid: "true"
  ...
---
# Use AWS Auto Scaling group.
apiVersion: kops.k8s.io/v1alpha2
kind: InstanceGroup
metadata:
  labels:
    kops.k8s.io/cluster: "example"
  ...
```

## Creating an Instance Group

To create a new instance group, run:

```bash
# configure the feature flags
export KOPS_FEATURE_FLAGS="Spotinst,SpotinstOcean,SpotinstOceanTemplate"

# create the instance group
kops create instancegroup --role=node --name=example
```

To create a new instance group and have more control over the configuration, a config file can be used.

```yaml
# instancegroup.yaml
# An instance group with Ocean configuration.
---
apiVersion: kops.k8s.io/v1alpha2
kind: InstanceGroup
metadata:
  labels:
    kops.k8s.io/cluster: "example"
    spotinst.io/spot-percentage: "90"
  spec:
    image: 099720109477/ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-20221206
    instanceMetadata:
      httpPutResponseHopLimit: 1
      httpTokens: required
    machineType: m5.large
    #define the max and min numbers of instances in the group
    maxSize: 3
    minSize: 1
    role: Node
    subnets:
      - us-west-2b
```

## InstanceGroup Metadata Labels

| Label | Description | Default |
|---|---|---|
| `spotinst.io/spot-percentage` | Specify the percentage of Spot instances that should spin up from the target capacity.                                    | `100` |
| `spotinst.io/utilize-reserved-instances` | Specify whether reserved instances should be utilized.                                                                    | `true` |
| `spotinst.io/utilize-commitments` | Specify whether reserved instance commitments should be utilized.                                                         | none |
| `spotinst.io/fallback-to-ondemand` | Specify whether fallback to on-demand instances should be enabled.                                                        | `true` |
| `spotinst.io/draining-timeout` | Specify a period of time, in seconds, after a node is marked for termination during which on running pods remains active. | none |
| `spotinst.io/grace-period` | Specify a period of time, in seconds, that Ocean should wait before applying instance health checks.                      | none |
| `spotinst.io/ocean-default-launchspec` | Specify whether to use the InstanceGroup's spec as the default Launch Spec for the Ocean cluster.                         | none |
| `spotinst.io/ocean-instance-types-whitelist` | Specify whether to whitelist specific instance types.                                                                     | none |
| `spotinst.io/ocean-instance-types-blacklist` | Specify whether to blacklist specific instance types.                                                                     | none |
| `spotinst.io/ocean-instance-types` | Specify a list of instance types that should be used by the Ocean Launch Spec.                                            | none |
| `spotinst.io/autoscaler-disabled` | Specify whether the auto scaler should be disabled.                                                                       | `false` |
| `spotinst.io/autoscaler-default-node-labels` | Specify whether default node labels should be set for the auto scaler.                                                    | `false` |
| `spotinst.io/autoscaler-auto-config` | Specify whether headroom resources should be automatically configured and optimized.                                      | `true` |
| `spotinst.io/autoscaler-auto-headroom-percentage` | Specify the auto headroom percentage (a number in the range [0, 200]) which controls the percentage of headroom.          | none |
| `spotinst.io/autoscaler-headroom-cpu-per-unit` | Specify the number of CPUs to allocate for headroom. CPUs are denoted in millicores, where 1000 millicores = 1 vCPU.      | none |
| `spotinst.io/autoscaler-headroom-gpu-per-unit` | Specify the number of GPUs to allocate for headroom.                                                                      | none |
| `spotinst.io/autoscaler-headroom-mem-per-unit` | Specify the amount of memory (MB) to allocate for headroom.                                                               | none |
| `spotinst.io/autoscaler-headroom-num-of-units` | Specify the number of units to retain as headroom, where each unit has the defined CPU and memory.                        | none |
| `spotinst.io/autoscaler-cooldown` | Specify a period of time, in seconds, that Ocean should wait between scaling actions.                                     | `300` |
| `spotinst.io/autoscaler-scale-down-max-percentage` | Specify the maximum scale down percentage.                                                                                | none |
| `spotinst.io/autoscaler-scale-down-evaluation-periods` | Specify the number of evaluation periods that should accumulate before a scale down action takes place.                   | `5` |
| `spotinst.io/autoscaler-resource-limits-max-vcpu` | Specify the maximum number of virtual CPUs that can be allocated to the cluster.                                          | none |
| `spotinst.io/autoscaler-resource-limits-max-memory` | Specify the maximum amount of total physical memory (in GiB units) that can be allocated to the cluster.                  | none |
| `spotinst.io/restrict-scale-down` | Specify whether the scale-down activities should be restricted.                                                           | none |
| `spotinst.io/other-architecture-images` | Specify other architecture images. | none |

## Cluster Metadata Labels
```yaml
# cluster.yaml
# A Cluster with Ocean configuration.
---
apiVersion: kops.k8s.io/v1alpha2
kind: Cluster
metadata:
  name: "example"
  labels:
    spotinst.io/strategy-cluster-spread-nodes-by: "count"
    spotinst.io/strategy-cluster-orientation-availability-vs-cost: "balanced"    
    spotinst.io/resource-tag-specification-volumes: "true"
  ...
```



| Label | Description                                                                            | Default |
|---|----------------------------------------------------------------------------------------|---|
| `spotinst.io/strategy-cluster-spread-nodes-by` | Specify how Ocean will spread the nodes across markets by this value [vcpu,count].     | `count` |
| `spotinst.io/strategy-cluster-orientation-availability-vs-cost` | Specify approach [cost,balanced,cheapest] that Ocean takes while launching nodes.      | `balanced` |
| `spotinst.io/resource-tag-specification-volumes` | Specify if Volume resources will be tagged with Virtual Node Group tags or Ocean tags. | `false` |
| `spotinst.io/autoscaler-aggressive-scale-down` | Specify  if nodes to be promptly scaled down without any waiting period. | `false` |

## Documentation

If you're new to [Spot](https://spot.io/) and want to get started, please checkout our [Getting Started](https://docs.spot.io/connect-your-cloud-provider/) guide, available on the [Spot Documentation](https://docs.spot.io/) website.

## Getting Help

Please use these community resources for getting help:

- Join our [Spot](https://spot.io/) community on [Slack](http://slack.spot.io/).
- Open a GitHub [issue](https://github.com/kubernetes/kops/issues/new/choose/).
- Ask a question on [Stack Overflow](https://stackoverflow.com/) and tag it with `spot-ocean`.
