node.jsgoogle-compute-enginegoogle-kubernetes-enginegoogle-compute-api

GKE REST/Node API call to get number of nodes in a pool?


How can I get the current size of a GKE node pool using the REST (or Node) API?

I'm managing my own worker pool using my Express app running on my cluster, and can set the size of the pool and track the success of the setSize operation, but I see no API for getting the current node count. The NodePool resource only includes the original node count, not the current count. I don't want to use gcloud or kubectl on one of my production VMs.

I could go around GKE and try to infer the size using the Compute Engine (GCE) API, but I haven't looked into that approach yet. Note that it seems difficult to get the node count even from Stack Driver. Has anyone found any workarounds to get the current node size?


Solution

  • The worker pool size can be retrieved from the Compute Engine API by getting the instance group associated with the node pool.

    const { google } = require('googleapis')
    const Compute = require('@google-cloud/compute')
    
    const container = google.container('v1')
    const compute = new Compute()
    
    const projectId = 'project-12345'
    const zone = 'us-central1-a'
    const nodePoolId = 'worker-pool'
    const clusterId = 'cluster-name'
    
    async function authorize() {
      const auth = new google.auth.GoogleAuth({
        scopes: [ 'https://www.googleapis.com/auth/cloud-platform' ],
      })
      return auth.getClient()
    }
    
    const getNodePoolSize = async () => {
      const auth = await authorize()
      const clusterName = `projects/${projectId}/zones/${zone}/clusters/${clusterId}`
      const request = { name: clusterName, auth }
      const response = await container.projects.locations.clusters.get(request)
      const nodePool = response.data.nodePools.find(({ name }) => name === nodePoolId)
      const igName = nodePool.instanceGroupUrls[0].match(/.*\/instanceGroupManagers\/([a-z0-9-]*)$/)[1]
      const instanceGroup = await compute.zone(zone).instanceGroup(igName).get()
      return instanceGroup[1 /* 0 is config, 1 is instance */].size
    }
    

    Note that this is using two different Node API mechanisms. We could use google.compute instead of @google-cloud/compute. Also, the two APIs are authenticated differently. The former uses the authorize() method to get a client, while the latter is authenticated via the default account set in environment variables.