Search code examples
google-kubernetes-enginegcloud

GKE list namespaces of another cluster


I need a list of all namespaces inside all the clusters in a GKE Project.

kubectl get ns will return namespaces in current-content and it's not ideal to keep switching contexts to get namespaces. Is there something in gcloud cli which I can use?

gcloud container clusters describe doesn't show namespaces :(


Solution

  • Interesting question.

    Because there are 2-level of API interaction (Google Cloud, Kubernetes) and because each CLI (gcloud, kubectl) is configured distinctly, I think (!?) the only way to do this is by going through a KUBECONFIG configured with each cluster.

    Repeatedly gcloud container cluster get-credentials is more expensive but should not be necessary. But context switching through KUBECONFIG is cheap and this should only entail updating the current-context value.

    PROJECT="..."
    

    Then to build the KUBECONFIG:

    # Build KUBECONFIG comprising Project's clusters
    # KUBECONFIG may include deleted Clusters
    # Assumes that all the clusters are either REGION or ZONE
    gcloud container clusters list \
    --project=${PROJECT} \
    --format="value(name,location)" |\
    while read NAME LOCATION
    do
      gcloud container clusters get-credentials ${NAME} \
      --region=${LOCATION} \
      --project=${PROJECT}
    done
    

    Then to iterate over it:

    # Use the current Clusters in the Project as the source
    # You could iterate over KUBECONFIG Clusters but this may not be current
    gcloud container clusters list \
    --project=${PROJECT} \
    --format="value(name,location)" |\
    while read NAME LOCATION
    do
      kubectl config use-context gke_${PROJECT}_${LOCATION}_${NAME}
      kubectl get namespaces
    done
    

    Thinking about this again, there's an easier way. You don't need to revise the current context with --use-context, you can simply set the context on the kubectl get namespaces command:

    gcloud container clusters list \
    --project=${PROJECT} \
    --format="value(name,location)" |\
    while read NAME LOCATION
    do
      kubectl get namespaces \
      --context=gke_${PROJECT}_${LOCATION}_${NAME}
    done
    
    Update

    If your script has issues with | while read NAME LOCATION, please try the following alternative e.g. for the last example:

    ROWS=$(\
      gcloud container clusters list \
      --project=${PROJECT} \
      --format="csv[no-heading](name,location)")
    
    for ROW in ${ROWS}
    do
      IFS=, read NAME LOCATION <<< ${ROW}
      kubectl get namespaces \
      --context=gke_${PROJECT}_${LOCATION}_${NAME}
    done
    ```