<p>What is a recommended way to have the <code>gcloud</code> available from <strong>within</strong> a running App Engine web application?</p>
<p><strong>Background:</strong><br />
The <a href="https://github.com/kubernetes-client/python" rel="nofollow noreferrer">Kubernetes Python Client</a> is using <code>subprocess</code> to execute <code>gcloud</code> (taken from <code>cmd-path</code> configured in <code>~/.kube/config</code>) to refresh access tokens. Because the web application is using the <code>kubernetes</code> python library to interact with a cluster, the <code>gcloud</code> command has to be available within the App Engine service. So this is <strong>not</strong> about running <code>gcloud</code> during a cloudbuild or other CI steps, but having access to <code>gcloud</code> inside the App Engine service.</p>
<p><strong>Possible solution:</strong><br />
During Cloud Build it is of course possible to execute the <a href="https://cloud.google.com/sdk/docs/install#linux" rel="nofollow noreferrer">gcloud install instructions for Linux</a> to make the tool available within the directory of the app, but are there better solutions?</p>
<p>Thanks!</p>

samuirai
<p>IIUC the Python client for Kubernetes requires a Kubernetes config and you're using <code>gcloud container clusters get-credentials</code> to automatically create the config; The Python client for Kubernetes does not require <code>gcloud</code>.</p>
<p>I recommend a different approach that uses Google's API Client Library for GKE (Container) to programmatically create a Kubernetes Config that can be consumed by the Kubernetes Python Client from within App Engine. You'll need to ensure that the Service Account being used by your App Engine app has sufficient permissions.</p>
<p>Unfortunately, I've not done this using the Kubernetes Python client but I am doing this using the Kubernetes Golang client.</p>
<p>The approach is to use Google's Container API to get the GKE cluster's details.</p>
<p>APIs Explorer: <a href="https://cloud.google.com/kubernetes-engine/docs/reference/rest/v1/projects.locations.clusters/get" rel="nofollow noreferrer"><code>clusters.get</code></a></p>
<p>Python API Client Library: <a href="https://googleapis.github.io/google-api-python-client/docs/dyn/container_v1.projects.locations.clusters.html#get" rel="nofollow noreferrer"><code>cluster.get</code></a></p>
<p>From the response (<a href="https://cloud.google.com/kubernetes-engine/docs/reference/rest/v1/projects.locations.clusters" rel="nofollow noreferrer">Cluster</a>), you can create everything you need to create a Kubernetes config that's acceptable to the Kubernetes client.</p>
<p>Here's a summary of the Golang code:</p>
<pre><code>ctx := context.Background()
containerService, _ := container.NewService(ctx)

name := fmt.Sprintf(
    &quot;projects/%s/locations/%s/clusters/%s&quot;,
    clusterProject,
    clusterLocation,
    clusterName,
)

rqst := containerService.Projects.Locations.Clusters.Get(name)
resp, _ := rqst.Do()

cert, _ := base64.StdEncoding.DecodeString(resp.MasterAuth.ClusterCaCertificate)

server := fmt.Sprintf(&quot;https://%s&quot;, resp.Endpoint)

apiConfig := api.Config{
    APIVersion: &quot;v1&quot;,
    Kind:       &quot;Config&quot;,
    Clusters: map[string]*api.Cluster{
        clusterName: {
            CertificateAuthorityData: cert,
            Server:                   server,
        },
    },
    Contexts: map[string]*api.Context{
        clusterName: {
            Cluster:  clusterName,
            AuthInfo: clusterName,
        },
    },
    AuthInfos: map[string]*api.AuthInfo{
        clusterName: {
            AuthProvider: &amp;api.AuthProviderConfig{
                Name: &quot;gcp&quot;,
                Config: map[string]string{
                    &quot;scopes&quot;: &quot;https://www.googleapis.com/auth/cloud-platform&quot;,
                },
            },
        },
    },
}
</code></pre>
