Does anyone know how to connect a local instance of kubectl
to a Google Kubernetes Engine (GKE) cluster, without using the gcloud
tool locally?
For example:
If you use the gcloud
tool with this command:
gcloud container clusters get-credentials NAME [--zone=ZONE, -z ZONE] [GCLOUD_WIDE_FLAG …]
You'll find a user like this in ~/.kube/config
:
- name: gke_myproj_myzone
user:
auth-provider:
config:
access-token: TOKENSTRING
cmd-args: config config-helper --format=json
cmd-path: /google/google-cloud-sdk/bin/gcloud
expiry: 2018-01-22 18:05:46
expiry-key: '{.credential.token_expiry}'
token-key: '{.credential.access_token}'
name: gcp
As you can see, the default values, the gcloud
tool provides require the glcoud
tool as an auth-provider to log in to your cluster.
Now, what I'm looking for is a way to connect kubectl
to a cluster on a machine, that does not have gcloud
installed.
When kubectl accesses the cluster it uses a stored root certificate and client certificates to access the server. (These are installed in the ~/. kube directory). Since cluster certificates are typically self-signed, it may take special configuration to get your http client to use root certificate.
You can use both Identity and Access Management (IAM) and Kubernetes RBAC to control access to your GKE cluster: IAM is not specific to Kubernetes; it provides identity management for multiple Google Cloud products, and operates primarily at the level of the Google Cloud project.
Launch Cloud ShellCloud Shell comes preinstalled with the Google Cloud CLI and kubectl command-line tool. The gcloud CLI provides the primary command-line interface for Google Cloud, and kubectl provides the primary command-line interface for running commands against Kubernetes clusters.
You may use kubectl
with either a user account, or a service account.
User accounts are designed to be used by humans, hence the apparent "limitation" of the tools: if you use a GKE cluster, a user is assumed to have gcloud
installed and being logged in with it.
You may instead use a service account, which is designed to be used by software. Kubernetes has a dedicated resource type ServiceAccount (not to confuse it with GCP service accounts!). Added benefit - it is a k8s feature, so it doesn't depend on the service implementation you use (GKE, AKS, etc.).
Approach:
You only need gcloud
tool to connect to the cluster for the very first time. Once you have access to the cluster, you can create a new k8s ServiceAccount and use its token in the kubectl
config file.
The service account however will need to be assigned necessary roles (k8s Role
and RoleBinding
resources) in a fine-grained manner.
Your cluster needs to have RBAC authentication enabled for this to work.
Word of caution:
Service account tokens do not expire and therefore special care should be taken to never expose/compromise them. It is probably a good idea to rotate them.
Simple(istic) example:
This a simplified example of how the above can be done. It is rather simplistic because it uses a default namespace, only adds a few roles, and requires a fair amount of manual actions, but it can help you to get started with your own implementation.
Create a file my-service-account.yaml
:
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: my-user
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: my-user-role
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "watch", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: my-user-role-binding
subjects:
- kind: ServiceAccount
name: my-user
roleRef:
kind: Role
name: my-user-role
apiGroup: rbac.authorization.k8s.io
and run kubectl apply -f my-service-account.yaml
to create the resources.
Once the service account is created you can run kubectl get secrets
to find the secret that holds the user token (it has it's name derived from the service account name), then run kubectl get secret <secret-name-here> -o yaml
to get the secret data, and find a token in the data.token
field in the output. The token is base64-encoded, so you will need to decode it first before using in the kubectl
config file (you can use base64 -d
in Linux for this). In the end, relevant part of the kubectl
config file may look like:
apiVersion: v1
clusters:
...
contexts:
...
users:
- name: my-user
user:
token: <token-value-here>
Now you may switch kubectl
context to the one you created for this user, and run:
kubectl get pods
The newly created user can only do the above and pretty much nothing else, since this is what is configured in the associated role. You can find out more about RBAC and the role configuration in the Kubernetes documentation: Using RBAC Authorization.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With