Skip to content. | Skip to navigation

Navigation

You are here: Home / Support / Guides / Tools / Kubernetes / Tips and Tricks

Personal tools

Tips and Tricks

kubectl

APIs

One of the most glaring problems with cut'n'pasting from the Internet is that the APIs for various entities have changed. If you get such a complaint your first port of call should be kubectl api-resources.

An example YAML might have been:

apiVersion: extensions/v1beta1
kind: DaemonSet
...

where:

# kubectl api-resources | grep DaemonSet
daemonsets                        ds           apps/v1                                true         DaemonSet

suggests it should be:

apiVersion: apps/v1
kind: DaemonSet
...

Deleting

One thing you appear to be much more casual with is deleting stuff. If you used foo.yml to create a dozen different things then you can just as easily use the same file to delete and modify the same resources:

# kubectl create -f foo.yml
...

Maybe it's not done the right thing for which we can tweak the config:

# vi foo.yml
  ...
# kubectl apply -f foo.yml
...

which will mostly result in complaints about entities already existing with one or more of them reporting being configured.

Finally:

# kubectl delete -f foo.yml
...

All gone!

YAML Entities

Another useful trick is to have kubectl report something akin to the equivalent YAML construction:

# kubectl create ns bob
namespace/bob created
# kubectl get ns/bob -o yaml
apiVersion: v1
kind: Namespace
metadata:
  creationTimestamp: "2022-03-31T10:08:51Z"
  labels:
    kubernetes.io/metadata.name: bob
  name: bob
  resourceVersion: "1525588"
  uid: 708074c5-b1c6-49de-a36b-4b5c594daf29
spec:
  finalizers:
  - kubernetes
status:
  phase: Active

from which we might decipher the equivalent YAML input:

apiVersion: v1
kind: Namespace
metadata:
  name: bob

(Finding the definitive description of all the possible YAML elements and their defaults is left as an exercise for the reader.)

All NameSpaces

Frequently you recall you did something, somewhere. Where was that, again? Here you can throw --all-namespaces or, the more convenient, -A at kubectl:

# kubectl get roles -A
NAMESPACE       NAME                                             CREATED AT
default         my-role                                          2022-03-31T17:40:33Z
...

Found it!

# kubectl delete role/my-role -n default

(Obviously, a bit more care should be taken when deleting things!)

jsonpath

You can do some funky stuff with kubectl -o jsonpath.

A good example is retrieving all the nodes' IP addresses:

# kubectl get nodes -o jsonpath='{ $.items[*].status.addresses[?(@.type=="InternalIP")].address }'

If you want to help yourself derive that expression use:

# kubectl get nodes -o yaml

and then start expanding the jsonpath construction:

# kubectl get nodes -o jsonpath='{ $ }'

(not helpful)

# kubectl get nodes -o jsonpath='{ $.items }'
# kubectl get nodes -o jsonpath='{ $.items[*] }'
# kubectl get nodes -o jsonpath='{ $.items[*].status }'
# kubectl get nodes -o jsonpath='{ $.items[*].status.addresses }'

whereon we finally get something readable.

Perhaps nodes wasn't the best example to start with...

From a previous example:

$ kubectl get svc/nodeport
NAME       TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
nodeport   NodePort   10.99.156.196   <none>        80:32647/TCP   70m

$ kubectl get svc/nodeport -o yaml
apiVersion: v1
kind: Service
metadata:
  labels:
    app: source-ip-app
  name: nodeport
spec:
  ...
  ports:
  - nodePort: 32647
    port: 80
    protocol: TCP
    targetPort: 8080
  ...

from which you might:

$ kubectl get svc/nodeport -o jsonpath='{ $.spec.ports }'
[{"nodePort":32647,"port":80,"protocol":"TCP","targetPort":8080}]

$ kubectl get svc/nodeport -o jsonpath='{ $.spec.ports[0] }'
{"nodePort":32647,"port":80,"protocol":"TCP","targetPort":8080}

$ kubectl get svc/nodeport -o jsonpath='{ $.spec.ports[0].nodePort }'
32647

Logs

You can't normally access microservices and tail -f /var/log/messages but you can access the logs from Pods:

$ kubectl logs pod/<pod-name>

but you might want to hold-fire, there, as that gives you all the logs -- which might be fine but it might also be days worth of repeated, say, healthcheck failures, not so fine.

There's a couple of immediately useful options:

  • --tail <number>
  • -f

Although -f does not imply --tail so you'll (quickly) find out you need to use both.

And don't forget to use -n <namespace> if required.

Document Actions