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