Kops and instance groups

Rationale TL;DR

You deployed Kops and now you want to create an additional node pool

The solution

Cluster changes

First, we need to create a new instance group (what GKE calls a node pool):

kops create ig $NAME --subnet $SUBNET1[,$SUBNET2.*] --name $CLUSTER_NAME --state s3://$BUCKET_NAME

This will bring up your preferred editor (is it vim?) and then you can tweak the IG as you want:

apiVersion: kops.k8s.io/v1alpha2
kind: InstanceGroup
metadata:
  creationTimestamp: "2020-09-11T18:34:56Z"
  labels:
    kops.k8s.io/cluster: CLUSTER_NAME
  name: elasticsearch
spec:
  image: kope.io/k8s-1.17-debian-stretch-amd64-hvm-ebs-2020-07-20
  machineType: t3.medium
  maxSize: 2
  minSize: 2
  nodeLabels:
    dedicated: "true"
    service: elasticsearch
    spot: "false"
  role: Node
  subnets:
  - SUBNET1
  taints:
  - service=elasticsearch:NoSchedule

Set the maxSize and minSize values accordingly. In this example, in setting some taints and node labels. I will use that to prevent any pod but only a few to be scheduled there. The nodeLabels will allow me to schedule the pods of a deployment or statefulset to the nodes in this IG and thus prevent them to be scheduled on a different IG. Bottom line: to use those nodes in that IG for only a specific deployment or statefulset.

And finally, we’d need to update the cluster. Because we want to use Terraform, we need to do this:

kops update cluster  --name $CLUSTER_NAME --state s3://$BUCKET_NAME —target terraform —out .

After this, we need to apply the Terraform plans. Use your CI/CD, I encourage you to do so. Otherwise, you’d need to apply it manually.

Finally, do a rolling update:

kops rolling-update cluster  --name $CLUSTER_NAME --state s3://$BUCKET_NAME --yes