Is there anyway to get all logs from pods in a specific namespace running a dynamic command like a combination of awk and xargs?
kubectl get pods | grep Running | awk '{print $1}' | xargs kubectl logs | grep value
I have tried the command above but it's failing like kubectl logs is missing pod name:
error: expected 'logs [-f] [-p] (POD | TYPE/NAME) [-c CONTAINER]'.
POD or TYPE/NAME is a required argument for the logs command
See 'kubectl logs -h' for help and examples
Do you have any suggestion about how get all logs from Running pods?
Think about what your pipeline is doing:
The kubectl logs command takes as an argument a single pod name, but through your use of xargs you're passing it multiple pod names. Make liberal use of the echo command to debug your pipelines; if I have these pods in my current namespace:
$ kubectl get pods -o custom-columns=name:.metadata.name
name
c069609c6193930cd1182e1936d8f0aebf72bc22265099c6a4af791cd2zkt8r
catalog-operator-6b8c45596c-262w9
olm-operator-56cf65dbf9-qwkjh
operatorhubio-catalog-48kgv
packageserver-54878d5cbb-flv2z
packageserver-54878d5cbb-t9tgr
Then running this command:
kubectl get pods | grep Running | awk '{print $1}' | xargs echo kubectl logs
Produces:
kubectl logs catalog-operator-6b8c45596c-262w9 olm-operator-56cf65dbf9-qwkjh operatorhubio-catalog-48kgv packageserver-54878d5cbb-flv2z packageserver-54878d5cbb-t9tgr
To do what you want, you need to arrange to call kubectl logs multiple times with a single argument. You can do that by adding -n1 to your xargs command line. Keeping the echo command, running this:
kubectl get pods | grep Running | awk '{print $1}' | xargs -n1 echo kubectl logs
Gets us:
kubectl logs catalog-operator-6b8c45596c-262w9
kubectl logs olm-operator-56cf65dbf9-qwkjh
kubectl logs operatorhubio-catalog-48kgv
kubectl logs packageserver-54878d5cbb-flv2z
kubectl logs packageserver-54878d5cbb-t9tgr
That looks more reasonable. If we drop the echo and run:
kubectl get pods | grep Running | awk '{print $1}' | xargs -n1 kubectl logs | grep value
Then you will get the result you want. You may want to add the --prefix argument to kubectl logs so that you know which pod generated the match:
kubectl get pods | grep Running | awk '{print $1}' | xargs -n1 kubectl logs --prefix | grep value
Not directly related to your question, but you can lose that grep:
kubectl get pods | awk '/Running/ {print $1}' | xargs -n1 kubectl logs --prefix | grep value
And even lose the awk:
kubectl get pods --field-selector=status.phase==Running -o name | xargs -n1 kubectl logs --prefix | grep value
I have the following code
#/bin/bash
set -e
set -x
requestResponse=$(ssh jump.gcp.xxxxxxx """source dev2 spi-dev
kubectl get pods -o json | jq '.items[] |select(.metadata.name[0:3]=="fea")' | jq .status.podIP
2>&1""")
echo $requestResponse
In the above code source dev2 spi-dev means we have moved to spi-dev namespace inside dev2 cluster. kubectl get pods -o json | jq '.items[] |select(.metadata.name[0:3]=="fea")' | jq .status.podIP 2>&1""") means to print ip address of pod starting with fea. If I do manually kubectl command works. I have also tried escaping fea like \"fea\"
These triple quotes """ are not working as you expect.
Try to change it like this:
ssh jump.gcp.xxxxxxx << EOF
source dev2 spi-dev
kubectl get pods -o json | \
jq '.items[] | \
select(.metadata.name[0:3]=="fea")' | \
jq .status.podIP 2>&1
EOF
I use below command to sort the pods by age
kubectl get pods --sort-by={metadata.creationTimestamp}
It shows up pods in descending order. How can we select sorting order like ascending?
Not supported by kubectl or the kube-apiserver as of this writing (AFAIK), but a workaround would be:
$ kubectl get pods --sort-by=.metadata.creationTimestamp | tail -n +2 | tac
or if tac is not available (MacOS X):
$ kubectl get pods --sort-by=.metadata.creationTimestamp | tail -n +2 | tail -r
If you want the header:
$ echo 'NAME READY STATUS RESTARTS AGE' | \
kubectl get pods --sort-by=.metadata.creationTimestamp | tail -n +2 | tac
You might just have to adjust the tabs on the header accordingly. Or if you don't want to use tail -n +2 you can use --no-headers. For example:
$ kubectl get pods --sort-by=.metadata.creationTimestamp --no-headers | tac
It Is Quite EASY: Once you have used --no-headers option, the HEADER will not be part of output (ascending ordered-listing of pods) and you can simply reverse sort the outcome of the command.
Here's the complete command to get exactly what is expected:
kubectl get po --sort-by={metadata.creationTimestamp} --no-headers | tac
Sorted kubectl output and awk provide the table view with a header. Installation of extra tools is not needed.
# kubectl get pods --sort-by=.status.startTime | awk 'NR == 1; NR > 1 {print $0 | "tac"}'
An approach with JSON processor offered by paulogrell works also but could require more effort: for some Linux distributions you'll need to download and compile jq from source code. As for the jq command line I'd suggest to add the "name" to the map parameters and sort by "timestamp":
# kubectl get pods -o json | jq '.items | group_by(.metadata.creationTimestamp) | map({"name": .[0].metadata.name, "timestamp": .[0].metadata.creationTimestamp, "count": length}) | sort_by(.timestamp)'
I believe the Kubernetes API doesnt support this option yet, but as a workaround you can use a JSON processor (jq) to adjust its output.
Ascending
kubectl get pods -o json | jq '.items | group_by(.metadata.creationTimestamp) | map({"timestamp": .[0].metadata.creationTimestamp, "count": length}) | sort_by(.count)'
Descending
kubectl get pods -o json | jq '.items | group_by(.metadata.creationTimestamp) | map({"timestamp": .[0].metadata.creationTimestamp, "count": length}) | sort_by(.count) | reverse'
Hope this helps
A simpler version that works on MacOS and retains arbitrary headers:
kubectl get node --sort-by=.metadata.creationTimestamp | { read -r headers; echo "$headers"; tail -r; }
If you are looking for a way to find the latest pod, try:
kubectl get pod --selector='app=my-app-name' \
--sort-by='.metadata.creationTimestamp' \
-o=jsonpath='{.items[-1].metadata.name}'
I'm working with fleetctl and kubectl and would like to extract an IP from kubectl get pod app-etcd:
POD IP CONTAINER(S) IMAGE(S) HOST LABELS STATUS CREATED MESSAGE
app-etcd 10.10.0.1 k8s-socius-node-1/100.100.100.100 name=app-etcd Running 3 days
app-etcd xyz/etcd-discovery Running 3 days
The closest I got to get the IP address is:
kubectl get pod app-etcd | grep -Eo '(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)'
But this gives me both IP addresses (10.10.0.1 and 100.100.100.100); I only want/need the first one to run sed over a config file afterwards.
How do I get only the first address to store it in a variable for further processing?
What if you use awk to get the second column output like
kubectl get pod app-etcd | awk '{print $2}'
kubectl offers json output with --output / -o:
kubectl get -o json pod app-etcd | jsawk 'return this.status.podIP'
When I run some programs over SSH, such as firefox &, I get an error
Error: no display specified
I would like to open many displays, still showing the stdout of each program.
Initial Question: How can I specify the display to get a many-displayed program?
Pablo Santa Cruz gives me the following code as a solution.
I do not understand it.
$ export DISPLAY=yourmachine.yourdomain.com:0.0
$ firefox &
What are yourmachine and yourdomain.com in the command?
The way that X works is the same as the way any network program works. You have a server of some description (in this case, the X display server) which runs on a specific machine, and you have X clients (like firefox) that try to connect to that server to get their information displayed.
Often (on "home" machines), the client and server run on the same box and there's only one server, but X is powerful enough that this doesn't need to happen. It was built with the server/client separation built in from the start.
This allows you to do such wondrous things such as log on to your box (in text mode) halfway around the planet, tell it that the display server is the box you're currently on and, voila, the windows suddenly start appearing locally.
In order for a client to interact with a user, it needs to know how to find the server. There are a number of ways to do this. Many clients allow the -display or --displayoption to specify it:
xeyes -display paxbox1.paxco.com:0.0
Many will use the DISPLAY environment variable if a display isn't specifically given. You can set this variable like any other:
DISPLAY=paxbox1.paxco.com:0.0; export DISPLAY # in .profile
export DISPLAY=paxbox1.paxco.com:0.0 # in your shell
DISPLAY=paxbox1.paxco.com:0.0 firefox & # for that command (shell permitting)
The first part of the DISPLAY variable is just the address of the display server machine. It follows the same rule as any other IP address; it can be a resolvable DNS name (including localhost) or a specific IP address (such as 192.168.10.55).
The second part is X-specific. It gives the X "display" (X server) number and screen number to use. The first (display number) generally refers to a group of devices containing one or more screens but with a single keyboard and mouse (i.e., one input stream). The screen number generally gives the specific screen within that group.
An example would be:
+----------------------------------------+
|paxbox1.paxco.com| |
+-----------------+ |
| |
| +----------+----+ +----------+----+ |
| |Display :0| | |Display :1| | |
| +----------+ | +----------+ | |
| | | | | |
| | +-----------+ | | | |
| | |Screen :0.0| | | | |
| | +-----------+ | | | |
| | +-----------+ | | | |
| | |Screen :0.1| | | | |
| | +-----------+ | | | |
| | +-----------+ | | +-----------+ | |
| | |Screen :0.2| | | |Screen :1.0| | |
| | +-----------+ | | +-----------+ | |
| | +-----------+ | | +-----------+ | |
| | |Screen :0.3| | | |Screen :1.1| | |
| | +-----------+ | | +-----------+ | |
| | +-----------+ | | +-----------+ | |
| | | Keyboard | | | | Keyboard | | |
| | +-----------+ | | +-----------+ | |
| | +-----------+ | | +-----------+ | |
| | | Mouse | | | | Mouse | | |
| | +-----------+ | | +-----------+ | |
| +---------------+ +---------------+ |
| |
+----------------------------------------+
Here you have a single machine (paxbox1.paxco.com) with two display servers. The first has four screens and the second has two. The possibilities are then:
DISPLAY=paxbox1.paxco.com:0.0
DISPLAY=paxbox1.paxco.com:0.1
DISPLAY=paxbox1.paxco.com:0.2
DISPLAY=paxbox1.paxco.com:0.3
DISPLAY=paxbox1.paxco.com:1.0
DISPLAY=paxbox1.paxco.com:1.1
depending on where you want your actual windows to appear and which input devices you want to use.
$ export DISPLAY=yourmachine.yourdomain.com:0.0
$ firefox &
When you are connecting to another machine over SSH, you can enable X-Forwarding in SSH, so that X windows are forwarded encrypted through the SSH tunnel back to your machine. You can enable X forwarding by appending -X to the ssh command line or setting ForwardX11 yes in your SSH config file.
To check if the X-Forwarding was set up successfully (the server might not allow it), just try if echo $DISPLAY outputs something like localhost:10.0.
login to your server via
ssh -X root#yourIP
edit /etc/ssh/sshd_config file, and add this line to it.
X11UseLocalhost no
Restart sshd. for CentOS (check your distribution)
/sbin/service sshd restart
check your DISPLAY
echo $DISPLAY
you should see this
yourIP:10.0
Enjoy
firefox
for more info
Try
export DISPLAY=localhost:0.0
Please do NOT try to set $DISPLAY manually when connecting over SSH.
If you connect via SSH -X and $DISPLAY stays empty, this usually means that no encrypted channel could be established.
Most likely you are missing the package xauth or xorg-x11-xauth. Try to install it on the remote machine using:
sudo apt-get install xauth
or
sudo apt-get install xorg-x11-xauth
After that end and restart your SSH connection. Don't forget to use SSH -X so that X Window output is forwarded to your local machine.
Now try echo $DISPLAYagain to see if $DISPLAY has been set automatically by the SSH demon. It should show you a line with an IP address and a port.
I ran into a similar issue, so maybe this answer will help someone.
The reason for the Error: no display specified error is that Firefox is being launched, but there is no X server (GUI) running on the remote host. You can use X11 forwarding to run Firefox on the remote host, but display it on your local host. On Mac OS X, you will need to download XQuartz in order to use X11 forwarding. Without it, you won't have a $DISPLAY variable set, so if you try and echo $DISPLAY, it will be blank.
Try installing the xorg-x11-xauth package.
I faced similar problem today. So, here's a simple solution:
While doing SSH to the machine, just add Ctrl - Y.
ssh user#ip_address -Y
After login, type firefox &.
And you are good to go.
Even i faced the same in CentOS 6.8.
yum reinstall xorg*
End your current session and open another session in tool like mobiXterm. Make sure session has X11 forwarding enabled in the tool.
I through vnc to understand the X11 more.
To specify the display to get a many-displayed program,
export DISPLAY=IP:DisplayNum.ScreenNum
For example,
vncserver :2
vncserver -list
echo '$DISPLAY'=$DISPLAY
export DISPLAY=:2 # export DISPLAY=IP:DisplayNum or export DISPLAY=:DisplayNum for localhost; So that can vnc connect and see the vnc desktop :2 if $DISPLAY is not :2.
echo '$DISPLAY'=$DISPLAY
I'm using xming server before typing firefox use the following command
export DISPLAY=0:0