Working with InstanceGroups

The kops InstanceGroup is a declarative model of a group of nodes. By modifying the object, youcan change the instance type you’re using, the number of nodes you have, the OS image you’re running - essentiallyall the per-node configuration is in the InstanceGroup.

We’ll assume you have a working cluster - if not, you probably want to read how to get started on GCE.

Changing the number of nodes

If you kops get ig you should see that you have InstanceGroups for your nodes and for your master:

  1. > kops get ig
  2. NAME ROLE MACHINETYPE MIN MAX SUBNETS
  3. master-us-central1-a Master n1-standard-1 1 1 us-central1
  4. nodes Node n1-standard-2 2 2 us-central1

Let’s change the number of nodes to 3. We’ll edit the InstanceGroup configuration using kops edit (whichshould be very familiar to you if you’ve used kubectl edit). kops edit ig nodes will openthe InstanceGroup in your editor, looking a bit like this:

  1. apiVersion: kops/v1alpha2
  2. kind: InstanceGroup
  3. metadata:
  4. creationTimestamp: 2017-10-03T15:17:31Z
  5. labels:
  6. kops.k8s.io/cluster: simple.k8s.local
  7. name: nodes
  8. spec:
  9. image: cos-cloud/cos-stable-57-9202-64-0
  10. machineType: n1-standard-2
  11. maxSize: 2
  12. minSize: 2
  13. role: Node
  14. subnets:
  15. - us-central1
  16. zones:
  17. - us-central1-a

Edit minSize and maxSize, changing both from 2 to 3, save and exit your editor. If you wanted to changethe image or the machineType, you could do that here as well. There are actually a lot more fields,but most of them have their default values, so won’t show up unless they are set. The general approach is the same though.

On saving you’ll note that nothing happens. Although you’ve changed the model, you need to tell kops toapply your changes to the cloud.

We use the same kops update cluster command that we used when initially creating the cluster; whenrun without --yes it should show you a preview of the changes, and now there should be only one change:

  1. > kops update cluster
  2. Will modify resources:
  3. InstanceGroupManager/us-central1-a-nodes-simple-k8s-local
  4. TargetSize 2 -> 3

This is saying that we will alter the TargetSize property of the InstanceGroupManager object namedus-central1-a-nodes-simple-k8s-local, changing it from 2 to 3.

That’s what we want, so we kops update cluster --yes.

kops will resize the GCE managed instance group from 2 to 3, which will create a new GCE instance,which will then boot and join the cluster. Within a minute or so you should see the new node join:

  1. > kubectl get nodes
  2. NAME STATUS AGE VERSION
  3. master-us-central1-a-thjq Ready 10h v1.7.2
  4. nodes-g2v2 Ready 10h v1.7.2
  5. nodes-tmk8 Ready 10h v1.7.2
  6. nodes-z2cz Ready 1s v1.7.2

nodes-z2cz just joined our cluster!

Changing the image

That was a fairly simple change, because we didn’t have to reboot the nodes. Most changes though dorequire rolling your instances - this is actually a deliberate design decision, in that we are aimingfor immutable nodes. An example is changing your image. We’re using cos-stable, which is Google’sContainer OS. Let’s try Debian Stretch instead.

If you run gcloud compute images list to list the images available to you in GCE, you should seea debian-9 image:

  1. > gcloud compute images list
  2. ...
  3. debian-9-stretch-v20170918 debian-cloud debian-9 READY
  4. ...

So now we’ll do the same kops edit ig nodes, except this time change the image to debian-cloud/debian-9-stretch-v20170918:

Now kops update cluster will show that you’re going to create a new GCE Instance Template,and that the Managed Instance Group is going to use it:

  1. Will create resources:
  2. InstanceTemplate/nodes-simple-k8s-local
  3. Network name:default id:default
  4. Tags [simple-k8s-local-k8s-io-role-node]
  5. Preemptible false
  6. BootDiskImage debian-cloud/debian-9-stretch-v20170918
  7. BootDiskSizeGB 128
  8. BootDiskType pd-standard
  9. CanIPForward true
  10. Scopes [compute-rw, monitoring, logging-write, storage-ro]
  11. Metadata {cluster-name: <resource>, startup-script: <resource>}
  12. MachineType n1-standard-2
  13. Will modify resources:
  14. InstanceGroupManager/us-central1-a-nodes-simple-k8s-local
  15. InstanceTemplate id:nodes-simple-k8s-local-1507043948 -> name:nodes-simple-k8s-local

Note that the BootDiskImage is indeed set to the debian 9 image you requested.

kops update cluster --yes will now apply the change, but if you were to run kubectl get nodes you would seethat the instances had not yet been reconfigured. There’s a hint at the bottom:

  1. Changes may require instances to restart: kops rolling-update cluster`

These changes require your instances to restart (we’ll remove the COS images and replace them with Debian images). kopscan perform a rolling update to minimize disruption, but even so you might not want to perform the update right away;you might want to make more changes or you might want to wait for off-peak hours. You might just want to wait forthe instances to terminate naturally - new instances will come up with the new configuration - though if you’re notusing preemptible/spot instances you might be waiting for a long time.

Performing a rolling-update of your cluster

When you’re ready to force your instances to restart, use kops rollling-update cluster:

  1. > kops rolling-update cluster
  2. Using cluster from kubectl context: simple.k8s.local
  3. NAME STATUS NEEDUPDATE READY MIN MAX NODES
  4. master-us-central1-a Ready 0 1 1 1 1
  5. nodes NeedsUpdate 3 0 3 3 3
  6. Must specify --yes to rolling-update.

You can see that your nodes need to be restarted, and your masters do not. A kops rolling-update cluster --yes will perform the update.It will only restart instances that need restarting (unless you --force a rolling-update).

When you’re ready, do kops rolling-update cluster --yes. It’ll take a few minutes per node, because for each nodewe cordon the node, drain the pods, shut it down and wait for the new node to join the cluster and for the clusterto be healthy again. But this procedure minimizes disruption to your cluster - a rolling-update cluster is nevergoing to be something you do during your superbowl commercial, but ideally it should be minimally disruptive.

After the rolling-update is complete, you can see that the nodes are now running a new image:

  1. > kubectl get nodes -owide
  2. NAME STATUS AGE VERSION EXTERNAL-IP OS-IMAGE KERNEL-VERSION
  3. master-us-central1-a-8fcc Ready 48m v1.7.2 35.188.177.16 Container-Optimized OS from Google 4.4.35+
  4. nodes-9cml Ready 17m v1.7.2 35.194.25.144 Container-Optimized OS from Google 4.4.35+
  5. nodes-km98 Ready 11m v1.7.2 35.202.95.161 Container-Optimized OS from Google 4.4.35+
  6. nodes-wbb2 Ready 5m v1.7.2 35.194.56.129 Container-Optimized OS from Google 4.4.35+

Next steps: learn how to perform cluster-wide operations, like upgrading kubernetes.