48

I am new to k8s and I am running into a little problem here.

Here's the context: I need to invoke kubectl delete [podname] via a crontask once a day, and wait until k8s recreates the pod, then log into the container in that pod and run a shell command.

So I query the deployment and get something like this:

user@host:~$ kubectl get pods
NAME                             READY     STATUS    RESTARTS   AGE
firstpod-123456789-something           1/1       Running   570        2d
secondpod-http-backend-something       1/1       Running   597        2d

then I wrote a bash script that would delete the pods in a 5 minutes interval. That's the easy part.

Suppose I invoke kubectl delete firstpod-123456789-something and wait for k8s to recreate a new pod. That new pod would have a new name like firstpod-[some random hash here]-something

The problem is that I need to capture the name of that pod in my bash script so then I can exec a command in that pod like uname -a or whatever as to verify that the new pod is up and running just fine.

I googled it and read the kubectl docs but I don't think there's an easy way to do this via a bash script? I am assuming that the only way to get the pod name here would be via the k8s API?

I am happy to use any solution at this point. I wonder if there's any way that I rename the new pod when k8s spawns up a new one? so I could grep for a specific keyword?

Note that I don't want to egrep something like firstpod-[0-9]-something because that's just an example. A lot of pods have a lot of different names, that was just an example.

Thanks!

nickgryg
  • 25,567
  • 5
  • 77
  • 79
Bluz
  • 5,980
  • 11
  • 32
  • 40

5 Answers5

97

You need to label your deployment somehow, for example we set label app: myapp below:

apiVersion: extensions/v1beta1                                                                                                                                                                          
kind: Deployment                                                                                                                                                                                        
metadata:                                                                                                                                                                                               
  name: nginx                                                                                                                                                                                     
spec:                                                                                                                                                                                                   
  template:                                                                                                                                                                                             
    metadata:                                                                                                                                                                                           
      labels:                                                                                                                                                                                           
        app: my-app                                                                                                                                                                                
    spec:                                                                                                                                                                                               
      containers:                                                                                                                                                                                       
      - image: nginx                                                                                                                                                    
        name: nginx  

After that you can get deployment's pod name very easy:

POD=$(kubectl get pod -l app=my-app -o jsonpath="{.items[0].metadata.name}")

and execute some command there, for example:

kubectl exec -ti $POD -- uname -a
nickgryg
  • 25,567
  • 5
  • 77
  • 79
  • 13
    use `-o name` instead of `-o jsonpath=...` – Adam Jan 30 '19 at 12:06
  • 8
    @Adam Unfortunately this prefixes the result with the type - eg. `pod/mypodname`. Such a shame, as that's SO much easier to remember. – Dan Feb 21 '19 at 16:50
  • 1
    in my context, this is not helping because I can't label the deployment but that's not due to a technical limitation, it's just a contextual company policy (let's put it that way) so I am going to accept your answer because it sounds like it's the right way to go in purely technical terms. – Bluz May 09 '19 at 10:45
  • So if we have 2 pods and we want to get the name of the LATEST one, how do we do that ? I see `AGE` column but not sure how to use it ..?!? – Prathamesh dhanawade Sep 04 '20 at 16:21
  • 2
    don't forget to add your namespace if your pod is in one – Pezhvak Nov 04 '21 at 23:22
  • Tested this with `-o name` and `kubectl exec` seems to support the `pod/` prefix now. – Michael Schnerring Jan 21 '22 at 20:22
  • I can confirm that `pod/` works when supplied to `kubectl exec`. This PowerShell one-liner ended up being what I needed: `kubectl exec -it $(kubectl get pods -o name | Select-String ) -- /bin/bash`, which runs bash in the found pod. – Adrian Wiik Jun 10 '22 at 09:11
27

Like Nickolay wrote, use a label to help selecting. Then you can use

kubectl get pods -l app=my-app -o custom-columns=:metadata.name

This gets you the name of the pod that has the label "app=my-app"

P.Stromberg
  • 371
  • 3
  • 5
  • While this may answer the question, providing additional context regarding how and/or why it solves the problem would improve the answer's long-term value.[Read this](https://stackoverflow.com/help/how-to-answer). – Shanteshwar Inde May 07 '19 at 09:07
  • Hi, is there a way to select the latest pod name only, when the new pod is being deployed? – yaja6021 Aug 16 '20 at 11:40
  • 3
    I append `--no-headers` to remove header (which becomes empty line if not using it) – laimison Apr 22 '21 at 17:25
4

Complementing what @nickgryg said, if kubernetes is in the cloud you can add the namespace and kubeconfig to get the pod name:

kubectl get pods -l app=my-app -o jsonpath="{.items[0].metadata.name}" -n my-namespace --kubeconfig=/home/$USER/.kube/kubeconfig

And to delete it with a single command, you can use the following:

NAMESPACE=my-namespace APP_NAME=my-app && kubectl delete -n $NAMESPACE pod $(kubectl get pods -l app=$APP_NAME -o jsonpath="{.items[0].metadata.name}" -n $NAMESPACE --kubeconfig=/home/$USER/.kube/kubeconfig) --kubeconfig=/home/$USER/.kube/kubeconfig
RexRod
  • 51
  • 1
  • 3
2

All other answers doesnt work for me

Not working option

kubectl -n $NAMESPACE get pods  -l app.kubernetes.io/name=nats  -o name

working option

kubectl -n $NAMESPACE get pods  --selector=app.kubernetes.io/name=nats  -o name
ImranRazaKhan
  • 1,955
  • 5
  • 33
  • 74
0

Another important/useful point is that you might want just the Running pod; there might be many more in "Terminated" state. Combining useful tips from the comments of others, I get:

kubectl get pod -n $NAMESPACE -l app=$PODNAME -o name --field-selector=status.phase=Running
parkerfath
  • 1,648
  • 1
  • 12
  • 18