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.