Can you ping it, yes you can!
In this blog post I will show how you can setup a very simple distributed ping application to troubleshoot network issues. In traditional cases you can run ping from your local host or ssh to a host where you would issue the command. But think of the edge, the network issue is on a shop floor, in a vechicle, in the retail store. How can you run ping there?
Figuring out a failing network
I was recently working with one of our customers on an intermittent network problem. My go-to tool for troubleshooting networks is always ping—checking how far outside a host you can reach by sending ICMP echo requests.
Since the problem was intermittent, we wanted something more continuous. The idea was to deploy a ping application that would repeatedly ping a set of hosts on the edge network and then correlate missed pings with possible network issues.
Meet the pinger applications
Creating a ping application is straightforward, just use an alpine container and run ping.
name: pinger
services:
- name: pinger
mode: replicated
replicas: 1
share-pid-namespace: false
containers:
- name: pinger
image: registry-1.docker.io/alpine
cmd:
- ping
- 172.27.64.1
network:
outbound-access:
allow-all: true
This works great when there is a single address you want to ping.
But what if you want to deploy it to multiple sites and the ping target is different at each site?
Easy!
For each site add a label called ping-target
, for example:
name: test-site
...
labels:
ping-target: 172.27.64.21
Now the application is simply changed to
name: pinger-labels
services:
- name: pinger
mode: replicated
replicas: 1
share-pid-namespace: false
containers:
- name: pinger
image: registry-1.docker.io/alpine
cmd:
- ping
- ${SYS_SITE_LABELS[ping-target]}
network:
outbound-access:
allow-all: true
Note how the target addressed is fetched from the label called ping-target
.
That’s all good and well, but we realized that we wanted to ping multiple hosts on each edge site.
We therefore changed the site labels to this:
name: test-site
...
labels:
ping-targets: 172.27.64.1;172.27.64.20;172.27.64.21
And the application became a little more complicated, so we decided to put the script as a separate file that runs.
name: pinger-labels-multi
services:
- name: pinger
mode: replicated
replicas: 1
share-pid-namespace: false
volumes:
- name: script
config-map:
items:
- name: pinger-script
data: |
#!/bin/sh
# Replace ; with space
ADDRS=$(echo "${SYS_SITE_LABELS[ping-targets]}" | tr ";" " ")
while true; do
for addr in $ADDRS; do
ping -c 1 $addr
done
sleep 10
done
containers:
- name: pinger
image: registry-1.docker.io/alpine
mounts:
- volume-name: script
files:
- name: pinger-script
mount-path: /pinger-script
cmd:
- sh
- /pinger-script
network:
outbound-access:
allow-all: true
Conclusion
As you can see, with just an Alpine container and a few lines of configuration, you can deploy a distributed ping application without writing any custom code. This provides continuous network visibility and helps correlate connectivity issues across multiple sites.