Several weeks ago I asked this question and received a very helpful answer. The gist of that question was: "how do I switch back and forth between two different K8s/GCP accounts on the same machine?" I have 2 different K8s projects with 2 different emails (gmails) that live on 2 different GKE clusters in 2 different GCP accounts. And I wanted to know how to switch back and forth between them so that when I run kubectl
and gcloud
commands, I don't inadvertently apply them to the wrong project/account.
The answer was to basically leverage kubectl config set-context
along with a script.
This question (today) is an extenuation of that question, a "Part 2" so to speak.
I am confused about the order in which I:
- Set the K8s context (again via
kubectl config set-context ...
); and - Run
gcloud init
; and - Run
gcloud auth
; and - Can safely run
kubectl
andgcloud
commands and be sure that I am hitting the right GKE cluster
My understanding is that gcloud init
only has to be ran once to initialize the gcloud
console on your system. Which I have already done.
So my thinking here is that I could be able to do the following:
# 1. switch K8s context to Project 1
kubectl config set-context <context for GKE project 1>
# 2. authenticate w/ GCP so that now gcloud commands will only hit the GCP
# resources associated with Project 1 (and GCP Account 1)
gcloud auth
# 3. run a bunch of kubectl and gcloud commands for Project/GCP Account 1
# 4. switch K8s context to Project 2
kubectl config set-context <context for GKE project 2>
# 5. authenticate w/ GCP so that now gcloud commands will only hit the GCP
# resources associated with Project 2 (and GCP Account 2)
gcloud auth
# 6. run a bunch of kubectl and gcloud commands for Project/GCP Account 2
Is my understanding here correct or is it more involved/complicated than this (and if so, why)?
CodePudding user response:
I'll assume familiarity with the earlier answer
gcloud
gcloud init
need only be run once per machine and only again if you really want to re-init
'ialize the CLI (gcloud
).
gcloud auth login ${ACCOUNT}
authenticates a (Google) (user or service) account and persists (on Linux by default in ${HOME}/.config/gcloud
) and renews the credentials.
gcloud auth list
lists the accounts that have been gcloud auth login
. The results show which account is being used by default (ACTIVE
with *
).
Somewhat inconveniently, one way to switch between the currently ACTIVE
account is to change gcloud
global (every instance on the machine) configuration using gcloud config set account ${ACCOUNT}
.
kubectl
To facilitate using previously authenticated (i.e. gcloud auth login ${ACCOUNT}
) credentials with Kubernetes Engine, Google provides the command gcloud container clusters get-credentials
. This uses the currently ACTIVE
gcloud
account to create a kubectl
context that joins a Kubernetes Cluster with a User and possibly with a Kubernetes Namespace too. gcloud container clusters get-credentials
makes changes to kubectl
config (on Linux by default in ${HOME}/.kube/config
).
What is a User? See Users in Kubernetes. Kubernetes Engine (via kubectl
) wants (OpenID Connect) Tokens. And, conveniently, gcloud
can provide these tokens for us.
How? Per previous answer
user:
auth-provider:
config:
access-token: [[redacted]]
cmd-args: config config-helper --format=json
cmd-path: path/to/google-cloud-sdk/bin/gcloud
expiry: "2022-02-22T22:22:22Z"
expiry-key: '{.credential.token_expiry}'
token-key: '{.credential.access_token}'
name: gcp
kubectl
uses the configuration file to invoke gcloud config config-helper --format=json
and extracts the access_token
and token_expiry
from the result. GKE can then uses the access_token
to authenticate the user. And, if necessary can renew the token using Google's token endpoint after expiry (token_expiry
).
Scenario
So, how do you combine all of the above.
- Authenticate
gcloud
with all your Google accounts
ACCOUNT="[email protected]"
gcloud auth login ${ACCOUNT}
ACCOUNT="[email protected]"
gcloud auth login ${ACCOUNT} # Last will be the `ACTIVE` account
- Enumerate these
gcloud auth list
Yields:
ACTIVE ACCOUNT
[email protected]
* [email protected] # This is ACTIVE
To set the active account, run:
$ gcloud config set account `ACCOUNT`
- Switch between users for
gcloud
commands
NOTE This doesn't affect
kubectl
Either
gcloud config set account [email protected]
gcloud auth list
Yields:
ACTIVE ACCOUNT
* [email protected] # This is ACTIVE
[email protected]
Or you can explicitly add --account=${ACCOUNT}
to any gcloud
command, e.g.:
# Explicitly unset your account
gcloud config unset account
# This will work and show projects accessible to client1
gcloud projects list [email protected]
# This will work and show projects accessible to client2
gcloud projects list [email protected]
- Create
kubectl
contexts for any|all your Google accounts (viagcloud
)
Either
ACCOUNT="[email protected]"
PROJECT="..." # Project accessible to ${ACCOUNT}
gcloud container clusters get-credentials ${CLUSTER} \
--ACCOUNT=${ACCOUNT} \
--PROJECT=${PROJECT} \
...
Or equivalently using kubectl config set-context
directly:
kubectl config set-context ${CONTEXT} \
--cluster=${CLUSTER} \
--user=${USER} \
But it avoids having to gcloud config get-clusters
, gcloud config get-users
etc.
NOTE
gcloud containers clusters get-credentials
uses derived names for contexts and GKE uses derived names for clusters. If you're confident you can editkubectl
config directly (or usingkubectl config
commands) to rename these cluster, context and user references to suit your needs.
- List
kubectl
contexts
kubectl config get-context
Yields:
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
* client1 a-cluster client1
client2 b-cluster client2
- Switch between
kubectl
contexts (clusters*users)
NOTE This doesn't affect
gcloud
Either
kubectl config use-context ${CONTEXT}
Or* you can explicitly add --context
flag to any kubectl
commands
# Explicitly unset default|current context
kubectl config unset current-context
# This will work and list deployments accessible to ${CONTEXT}
kubectl get deployments --context=${CONTEXT}