0

Background

I'm trying to test a PostgreSQL container with InSpec 2.1.10, but I cannot get a simple port check to return true, even though Docker, netstat, and psql all report that the port is properly mapped. While it's possible this is a bug in InSpec, it seems more likely that the problem exists between the keyboard and the chair. What have I missed?

Repeatable Tests

My Spec

# port_test.rb
describe port(5432) do
  it { should be_listening }
end

My Testing Commands

container=$(docker run -d -P --rm postgres:alpine)
inspec exec port_test.rb -t docker://$container

My Output

Profile: tests from test.rb (tests from test.rb)
Version: (not specified)
Target:  docker://8caceaa7e2eefa4a2bf50a58ea1ddf9c927c08d3397e3d9ad5b60d3519971380

  Port 5432
     ×  should be listening
     expected `Port 5432.listening?` to return true, got false

Test Summary: 0 successful, 1 failure, 0 skipped

But It Should Work!

Everything but InSpec reports that things are working as expected.

$ docker port $container
5432/tcp -> 0.0.0.0:32770

# from inside container using netstat
$ docker exec $container netstat -lntp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 0.0.0.0:5432            0.0.0.0:*               LISTEN      -
tcp        0      0 :::5432                 :::*                    LISTEN      -

# on macOS Docker host; flags are the macOS equivalent to `-lntp`
$ netstat -anv | fgrep $(docker port $container | cut -d: -f2)
tcp6       0      0  ::1.32770              *.*                    LISTEN      131072 131072    709      0
tcp4       0      0  *.32770                *.*                    LISTEN      131072 131072    709      0

# connecting to database in container from host
$ psql -V \
       -h localhost \
       -p $(docker port $container | cut -d: -f2)
psql (PostgreSQL) 10.3
2

You did everything right, it is the correct InSpec test and use with Docker!

You encountered a bug in InSpec that is related to InSpec's netstat output parsing combination with Alpine's netstat output.

See InSpec's output for postgres container instead of postgres:alpine:

$ inspec exec docker_test.rb -t docker://1c8162517c22                                                               1d15h master[a5ff79d3]

Profile: tests from docker_test.rb (tests from docker_test.rb)
Version: (not specified)
Target:  docker://1c8162517c229ff8c87ab3e8c909f46b4370d7c63a65c0f973a5c10fdebda800

  Port 5432
     ✔  should be listening

Test Summary: 1 successful, 0 failures, 0 skipped

In your case, the problem is that Apline's netstat reports a different output then other Linux eg. Ubuntu, CentOS:

# netstat -tulpen
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       User       Inode      PID/Program name    
tcp        0      0 0.0.0.0:5432            0.0.0.0:*               LISTEN      999        108791     -                   
tcp6       0      0 :::5432                 :::*                    LISTEN      999        108792     -  

On Alpine, the inode output is missing:

netstat -tulpen
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 0.0.0.0:5432            0.0.0.0:*               LISTEN      -
tcp        0      0 :::5432                 :::*                    LISTEN      -

That is why InSpec is not able to parse the netstat output. It is clearly a bug in InSpec. As a mitigation, I recommend to install the iproute2 package for alpine containers via apk add iproute2. InSpec prefers ss over netstat. Please report this bug to InSpec team.

  • 1
    You're right. Using a different OS for the container base and adding iproute2 to the Alpine container both solved the problem. I've opened a bug on the issue. – CodeGnome Mar 28 '18 at 12:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.