If you're starting using Google Cloud Platform, maybe after following my guide on deploying your first service to GKE, you'll probably want to setup a few command-line tools to be able to access your Kubernetes cluster from your terminal.
The usual tool to do that is
kubectl, but as we're in the context of GCP/GKE here, we'll use the
gcloud utility to set everything up.
gcloud and init
Google provides an interactive installer which makes this step easy.
Answers to the installation questions are obvious enough that we don't have to detail them here.
gcloud installed, start a new terminal session to load the new
$PATH and the command completion.
gcloud init in your new terminal to initialize the tool.
It will send you to a Google login page so that you can choose the Google account you want to connect with when using
gcloud. Once you've selected and authorized the correct account, go back to your terminal.
It will ask you to pick the GCP project you'd like to use: choose the one that holds the GCP resources you want to work with.
If you have several projects you'd like to be able to access, you can run
gcloud init again and choose to create a new configuration for those projects (connecting to a different Google account if necessary).
You will then be able to switch between configurations using
gcloud configurations activate <config name>.
Your project might have a randomly generated name, something like
proud-dolphin-461842. If you don't know which to choose, head over to your Cloud Console home: your project ID is there:
You're then asked whether you'd like to configure a default Compute Region and Zone. You should say yes. I'm not sure which use case makes it less practical to do it, but if you don't you'll have to add a
--zone argument to all your
Choose the region/zone where your resources are hosted. If you came from my GKE deployment guide, that would be the region you chose to create your cluster in.
Install the interactive CLI
gcloud comes with a very handy interactive CLI to help you discover commands and their parameters. It's a beta feature that you can access using
gcloud beta interactive.
The first run of this command will install the component for you. Then, it'll run it:
Personally, I have added an alias to my zsh profile so that
ig will open this interactive CLI:
Run the following to install
kubectl on your machine:
gcloud components install kubectl
You might a warning at the end of the installation, letting you know another version of
kubectl has been found on your computer. It can happen if you've installed Docker for Mac for instance.
To make sure you're using gcloud's version of
which kubectl; the tool's path should look like this:
If it doesn't, tweak your
$PATH variable or remove the other version you've got.
kubectl for your GKE cluster
gcloud will help you configure things properly.
Just run this command to have a
kubectl config generated for your GKE cluster:
If you're not sure what the name of your cluster is,
gcloud can tell you:
$ gcloud container clusters list NAME LOCATION MASTER_VERSION MASTER_IP MACHINE_TYPE NODE_VERSION NUM_NODES STATUS test-cluster europe-west1-b 1.12.8-gke.10 184.108.40.206 n1-standard-1 1.12.8-gke.10 1 RUNNING
Finally, if you've got a single cluster, or at least one main cluster you want to be working with, I highly encourage you to set it default in your config:
$ gcloud config set container/cluster test-cluster Updated property [container/cluster].
This will automatically fill in the
--cluster argument in commands that require it.
Explore your Kubernetes resources
Now that everything is set up, you can start playing!
Since you are on GKE, you have to keep in mind that it brings its own concepts on top of those from Kubernetes. This will help you know which tool to use when you want to get detailed information about a resource.
I covered the subject in my introduction to deploying to GKE.
As a result, you'll use
kubectl to get information on your nodes, pods, deployments, services, config maps and secrets (
kubectl api-resources will give you a full list), whereas
gcloud can be used to get information on your cluster, node pools, and the VM instances that are used to concretize your k8s nodes.
kubectl: get & describe
Your best friends to learn more about your k8s resources are
kubectl get <type> and
kubectl describe <type>/<name>.
To get started, you can try
kubectl get all:
$ kubectl get all NAME READY STATUS RESTARTS AGE pod/wordpress-d74bfbbc4-qg6fl 1/1 Running 0 3d NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/kubernetes ClusterIP 10.119.0.1 <none> 443/TCP 3d service/wordpress-dq858 LoadBalancer 10.119.13.142 220.127.116.11 80:32647/TCP 3d NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE deployment.apps/wordpress 1 1 1 1 3d NAME DESIRED CURRENT READY AGE replicaset.apps/wordpress-d74bfbbc4 1 1 1 3d replicaset.apps/wordpress-ff54c57ff 0 0 0 3d NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE horizontalpodautoscaler.autoscaling/wordpress-hpa Deployment/wordpress 1%/80% 1 1 1 3d
Here I can see I've got one pod running, two services, one deployment, two replicasets (including an obsolete one) and one horizontal pod autoscaler, which is used to automatically spin up new pods for the wordpress deployment.
Let's delete the useless replicaset:
$ kubectl delete replicaset.apps/wordpress-ff54c57ff replicaset.apps "wordpress-ff54c57ff" deleted
I want to learn more about the pod:
$ kubectl describe pod/wordpress-d74bfbbc4-qg6fl Name: wordpress-d74bfbbc4-qg6fl Namespace: default Priority: 0 PriorityClassName: <none> Node: gke-test-cluster-default-pool-7fa0b2b7-pdqm/10.132.0.2 Start Time: Sun, 26 Sep 2019 11:20:21 +0200 Labels: app=wordpress pod-template-hash=d74bfbbc4 Annotations: kubernetes.io/limit-ranger: LimitRanger plugin set: cpu request for container wordpress Status: Running IP: 10.52.0.10 Controlled By: ReplicaSet/wordpress-d74bfbbc4 Containers: wordpress: Container ID: docker://f8732ac0514ddc25c11625941f619b3d98dbddef4a57eb6f33a37147d3a82c21 Image: wordpress:latest Image ID: docker-pullable://wordpress@sha256:0524b6843bd9a310c8e7201fd2d624b9db84baf57e65abf6c22426cd09b55426 Port: <none> Host Port: <none> State: Running Started: Sun, 26 Sep 2019 11:20:43 +0200 Ready: True Restart Count: 0 Requests: cpu: 100m Environment: WORDPRESS_DB_HOST: <set to the key 'WORDPRESS_DB_HOST' of config map 'wordpress-config'> Optional: false WORDPRESS_DB_USER: <set to the key 'WORDPRESS_DB_USER' of config map 'wordpress-config'> Optional: false WORDPRESS_DB_NAME: <set to the key 'WORDPRESS_DB_NAME' of config map 'wordpress-config'> Optional: false WORDPRESS_DB_PASSWORD: <set to the key 'DB_PASSWD' in secret 'wordpress-db'> Optional: false Mounts: /var/run/secrets/kubernetes.io/serviceaccount from default-token-pz6ww (ro) Conditions: Type Status Initialized True Ready True ContainersReady True PodScheduled True Volumes: default-token-pz6ww: Type: Secret (a volume populated by a Secret) SecretName: default-token-pz6ww Optional: false QoS Class: Burstable Node-Selectors: <none> Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s node.kubernetes.io/unreachable:NoExecute for 300s Events: <none>
If you've followed my deploy guide to GKE, you will probably recognize some of the information here!
Note that nodes aren't listed by
kubectl get all, so let's list them specifically:
$ kubectl get nodes NAME STATUS ROLES AGE VERSION gke-test-cluster-default-pool-7fa0b2b7-pdqm Ready <none> 3d v1.12.8-gke.10
describe a node, you get interesting information about the pods it's hosting and the resources currently in use:
$ kubectl describe node/gke-test-cluster-default-pool-7fa0b2b7-pdqm ... redacted for your brain's sake ... Non-terminated Pods: (7 in total) Namespace Name CPU Requests CPU Limits Memory Requests Memory Limits AGE --------- ---- ------------ ---------- --------------- ------------- --- default wordpress-d74bfbbc4-qg6fl 100m (10%) 0 (0%) 0 (0%) 0 (0%) 3d kube-system heapster-v1.6.1-6bf7c45b48-qxvz5 63m (6%) 63m (6%) 215840Ki (7%) 215840Ki (7%) 2d kube-system kube-dns-564d97dc9c-vsvxr 260m (27%) 0 (0%) 110Mi (4%) 170Mi (6%) 3d kube-system kube-dns-autoscaler-76fcd5f658-xbxnt 20m (2%) 0 (0%) 10Mi (0%) 0 (0%) 2d kube-system kube-proxy-gke-test-cluster-default-pool-7fa0b2b7-pdqm 100m (10%) 0 (0%) 0 (0%) 0 (0%) 3d kube-system l7-default-backend-6f8697844f-7sfd5 10m (1%) 10m (1%) 20Mi (0%) 20Mi (0%) 2d kube-system metrics-server-v0.3.1-5b4d6d8d98-hk2pw 48m (5%) 143m (15%) 105Mi (3%) 355Mi (13%) 2d Allocated resources: (Total limits may be over 100 percent, i.e., overcommitted.) Resource Requests Limits -------- -------- ------ cpu 601m (63%) 216m (22%) memory 466720Ki (17%) 773920Ki (28%)
You can see I've got 7 pods running on that node: 6 are from the
kube-system namespace, meaning they're not my own pods but services required by Kubernetes or GKE:
metrics-server are used for monitoring,
kube-dns* for networking purposes and
l7-default-backend, which is an HTTP load balancing service.
default namespace, there's my wordpress pod.
In terms of resource, you can see that I'm requesting 63% of my node's CPU capacity, and 17% of its memory capacity.
To get a better understanding of requests and limits, check out this post on Google Cloud's blog.
gcloud: list & describe
The syntax for
gcloud commands is similar to the
gcloud <module> <type> <list> and
gcloud <module> <type> <describe> <name>.
The one thing that can be tricky at first, is figuring out what
module you should look into. There are many, so here's a quick rule of thumb: if the resource is specific to GKE, it's going to be
container; else, you should try
|Resource type||Module||List command|
|Node (the VM instance)||compute||
With what we've covered so far on this blog,
compute might not seem so important, but that's also where you'll find
backend-buckets and the other resources related to HTTP(S) Load Balancers.
Access your pods
If you've got a running pod, but it's not exposed via a service, you can still access whatever's running on it using port forwarding.
Let's take the example of my wordpress pod:
$ kubectl get pods NAME READY STATUS RESTARTS AGE wordpress-d74bfbbc4-qg6fl 1/1 Running 0 3d $ kubectl port-forward wordpress-d74bfbbc4-qg6fl 8888:80 Forwarding from 127.0.0.1:8888 -> 80 Forwarding from [::1]:8888 -> 80
I can now access my Wordpress instance listening to the port 80 of this pod, by connecting to http://localhost:8888!
Please just take a second to think about what's going on behind the scene of this very simple command 🤯
Note that you can do the same with a deployment instead of a single pod:
$ kubectl port-forward deployment/wordpress 8888:80
SSH into your pod's containers
It might be handy sometimes to get into a running container of your pod, for debug purposes for instance.
kubectl makes this super easy. You need to know your pod's name, and the name of the container you want to enter. Then it's very similar to what you'd do with Docker:
$ kubectl describe pod/wordpress-d74bfbbc4-qg6fl Name: wordpress-d74bfbbc4-qg6fl Namespace: default ... Containers: wordpress: <- this is the container's name ... $ kubectl exec -it wordpress-d74bfbbc4-qg6fl -c wordpress bash root@wordpress-d74bfbbc4-qg6fl:/var/www/html#
Note that you can omit the container argument (
-c wordpress here):
exec will then run the specified command within the first container in the pod. When it's a single-container pod, that makes things even easier!
I hope this little tour of
kubectl will help you get started with managing your Kubernetes cluster from the command line!
And if you're into automation, you should know that both commands allow you to get YAML or JSON output, which will be easily processable within your scripts.
--format=json to your