<p>Several weeks ago I asked <a href="https://stackoverflow.com/questions/71224960/commands-to-switch-kubectl-and-gcloud-back-and-forth-between-two-totally-separat">this question</a> and received a very helpful answer. The gist of that question was: &quot;<em>how do I switch back and forth between two different K8s/GCP accounts on the same machine?</em>&quot; 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 <code>kubectl</code> and <code>gcloud</code> commands, I don't inadvertently apply them to the wrong project/account.</p>
<p>The answer was to basically leverage <code>kubectl config set-context</code> along with a script.</p>
<p>This question (today) is an extenuation of that question, a &quot;Part 2&quot; so to speak.</p>
<hr />
<p>I am confused about the <em>order</em> in which I:</p>
<ul>
<li>Set the K8s context (again via <code>kubectl config set-context ...</code>); and</li>
<li>Run <code>gcloud init</code>; and</li>
<li>Run <code>gcloud auth</code>; and</li>
<li>Can safely run <code>kubectl</code> and <code>gcloud</code> commands and be sure that I am hitting the right GKE cluster</li>
</ul>
<p>My <em>understanding</em> is that <code>gcloud init</code> only has to be ran once to initialize the <code>gcloud</code> console on your system. Which I have already done.</p>
<p>So my <em>thinking</em> here is that I could be able to do the following:</p>
<pre><code># 1. switch K8s context to Project 1
kubectl config set-context &lt;context for GKE project 1&gt;

# 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 &lt;context for GKE project 2&gt;

# 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
</code></pre>
<p><strong>Is my understanding here correct or is it more involved/complicated than this (and if so, why)?</strong></p>

simplezarg
<p>I'll assume familiarity with the earlier <a href="https://stackoverflow.com/a/71225494/609290">answer</a></p>
<h3><code>gcloud</code></h3>
<p><a href="https://cloud.google.com/sdk/gcloud/reference/init" rel="nofollow noreferrer"><code>gcloud init</code></a> need only be run once per machine and only again if you really want to re-<code>init</code>'ialize the CLI (<code>gcloud</code>).</p>
<p><a href="https://cloud.google.com/sdk/gcloud/reference/auth/login" rel="nofollow noreferrer"><code>gcloud auth login ${ACCOUNT}</code></a> authenticates a (Google) (user or service) account and persists (on Linux by default in <code>${HOME}/.config/gcloud</code>) and renews the credentials.</p>
<p><a href="https://cloud.google.com/sdk/gcloud/reference/auth/list" rel="nofollow noreferrer"><code>gcloud auth list</code></a> lists the accounts that have been <code>gcloud auth login</code>. The results show which account is being used by default (<code>ACTIVE</code> with <code>*</code>).</p>
<p>Somewhat inconveniently, one way to switch between the currently <code>ACTIVE</code> account is to change <code>gcloud</code> <strong>global</strong> (every instance on the machine) configuration using <a href="https://cloud.google.com/sdk/gcloud/reference/config/set" rel="nofollow noreferrer"><code>gcloud config set account ${ACCOUNT}</code></a>.</p>
<h3><code>kubectl</code></h3>
<p>To facilitate using previously authenticated (i.e. <code>gcloud auth login ${ACCOUNT}</code>) credentials with Kubernetes Engine, Google provides the command <a href="https://cloud.google.com/sdk/gcloud/reference/container/clusters/get-credentials" rel="nofollow noreferrer"><code>gcloud container clusters get-credentials</code></a>. This uses the currently <code>ACTIVE</code> <code>gcloud</code> account to create a <code>kubectl</code> context that joins a Kubernetes Cluster with a <em>User</em> and possibly with a Kubernetes Namespace too. <code>gcloud container clusters get-credentials</code> makes changes to <code>kubectl</code> config (on Linux by default in <code>${HOME}/.kube/config</code>).</p>
<p>What is a <em>User</em>? See <a href="https://kubernetes.io/docs/reference/access-authn-authz/authentication/#users-in-kubernetes" rel="nofollow noreferrer">Users in Kubernetes</a>. Kubernetes Engine (via <code>kubectl</code>) wants (OpenID Connect) <a href="https://kubernetes.io/docs/reference/access-authn-authz/authentication/#openid-connect-tokens" rel="nofollow noreferrer">Tokens</a>. And, conveniently, <code>gcloud</code> can provide these tokens for us.</p>
<p>How? Per previous <a href="https://stackoverflow.com/a/71225494/609290">answer</a></p>
<pre><code>user:
  auth-provider:
    config:
      access-token: [[redacted]]
      cmd-args: config config-helper --format=json
      cmd-path: path/to/google-cloud-sdk/bin/gcloud
      expiry: &quot;2022-02-22T22:22:22Z&quot;
      expiry-key: '{.credential.token_expiry}'
      token-key: '{.credential.access_token}'
    name: gcp
</code></pre>
<p><code>kubectl</code> uses the configuration file to invoke <code>gcloud config config-helper --format=json</code> and extracts the <code>access_token</code> and <code>token_expiry</code> from the result. GKE can then use the <code>access_token</code> to authenticate the user. And, if necessary can renew the token using Google's token endpoint after expiry (<code>token_expiry</code>).</p>
<h3>Scenario</h3>
<p>So, how do you combine all of the above.</p>
<ol>
<li>Authenticate <code>gcloud</code> with all your Google accounts</li>
</ol>
<pre class="lang-sh prettyprint-override"><code>ACCOUNT=&quot;client1@gmail.com&quot;
gcloud auth login ${ACCOUNT}

ACCOUNT=&quot;client2@gmail.com&quot;
gcloud auth login ${ACCOUNT} # Last will be the `ACTIVE` account
</code></pre>
<ol start="2">
<li>Enumerate these</li>
</ol>
<pre class="lang-sh prettyprint-override"><code>gcloud auth list
</code></pre>
<p>Yields:</p>
<pre><code>ACTIVE  ACCOUNT
        client1@gmail.com
*       client2@gmail.com # This is ACTIVE

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
</code></pre>
<ol start="3">
<li>Switch between users for <code>gcloud</code> commands</li>
</ol>
<blockquote>
<p><strong>NOTE</strong> This <strong>doesn't</strong> affect <code>kubectl</code></p>
</blockquote>
<p><strong>Either</strong></p>
<pre class="lang-sh prettyprint-override"><code>gcloud config set account client1@gmail.com
gcloud auth list
</code></pre>
<p>Yields:</p>
<pre><code>ACTIVE  ACCOUNT
*       client1@gmail.com # This is ACTIVE
        client2@gmail.com
</code></pre>
<p><strong>Or</strong> you can explicitly add <a href="https://cloud.google.com/sdk/gcloud/reference#--account" rel="nofollow noreferrer"><code>--account=${ACCOUNT}</code></a> to <strong>any</strong> <code>gcloud</code> command, e.g.:</p>
<pre class="lang-sh prettyprint-override"><code># Explicitly unset your account
gcloud config unset account

# This will work and show projects accessible to client1
gcloud projects list --account=client1@gmail.com

# This will work and show projects accessible to client2
gcloud projects list --account=client2@gmail.com
</code></pre>
<ol start="2">
<li>Create <code>kubectl</code> contexts for any|all your Google accounts (via <code>gcloud</code>)</li>
</ol>
<p><strong>Either</strong></p>
<pre class="lang-sh prettyprint-override"><code>ACCOUNT=&quot;client1@gmail.com&quot;
PROJECT=&quot;...&quot; # Project accessible to ${ACCOUNT}
gcloud container clusters get-credentials ${CLUSTER} \
--ACCOUNT=${ACCOUNT} \
--PROJECT=${PROJECT} \
...
</code></pre>
<p><strong>Or</strong> equivalently using <code>kubectl config set-context</code> directly:</p>
<pre class="lang-sh prettyprint-override"><code>kubectl config set-context ${CONTEXT} \
--cluster=${CLUSTER} \
--user=${USER} \
</code></pre>
<p>But it avoids having to <code>gcloud config get-clusters</code>, <code>gcloud config get-users</code> etc.</p>
<blockquote>
<p><strong>NOTE</strong> <code>gcloud containers clusters get-credentials</code> uses derived names for contexts and GKE uses derived names for clusters. <strong>If you're confident</strong> you can edit <code>kubectl</code> config directly (or using <code>kubectl config</code> commands) to rename these cluster, context and user references to suit your needs.</p>
</blockquote>
<ol start="3">
<li>List <code>kubectl</code> contexts</li>
</ol>
<pre class="lang-sh prettyprint-override"><code>kubectl config get-context
</code></pre>
<p>Yields:</p>
<pre><code>CURRENT   NAME       CLUSTER    AUTHINFO   NAMESPACE
*         client1    a-cluster  client1
          client2    b-cluster  client2
</code></pre>
<ol start="4">
<li>Switch between <code>kubectl</code> contexts (clusters*users)</li>
</ol>
<blockquote>
<p><strong>NOTE</strong> This <strong>doesn't</strong> affect <code>gcloud</code></p>
</blockquote>
<p><strong>Either</strong></p>
<pre class="lang-sh prettyprint-override"><code>kubectl config use-context ${CONTEXT}
</code></pre>
<p><em>Or</em>* you can explicitly add <code>--context</code> flag to <strong>any</strong> <code>kubectl</code> commands</p>
<pre class="lang-sh prettyprint-override"><code># Explicitly unset default|current context
kubectl config unset current-context

# This will work and list deployments accessible to ${CONTEXT}
kubectl get deployments --context=${CONTEXT}
</code></pre>
