TCP dump encapsulated in docker does not consume a large amount of CPU resources, but cannot completely capture packets

  docker, question

I want to test the package grabbing performance of a platform based on docker. Docker allocates 10%(4-core) CPU with 128M of memory. The virtual machine is a Linux system with 4 cores.
Using tcpdump in docker to grab a package, tcpdump only accounts for 6% of CPU of the single core when viewed with top, but the summary of grabbing a package shows that there is a package that has not been caught. The ksoftirqd process accounts for only about 0.7% of the CPU.

Well, I’ll answer the question myself.

On linux systems, after using tcpdump to grab a package, you will be prompted:


Simply put, captured is the number of data packets obtained after tcpdump processing, that is, the number of data packets in the finally obtained pcap file; Received is all packets processed by the filter; Dropped is the number of unprocessed packets.
The result of received by filter depends on the operating system running tcpdump and its configuration. If a filter is specified, the packet will be calculated regardless of whether it is matched by the filter expression, even if they are matched by the filter expression, and regardless of whether tcpdump reads and processes them, i.e. if a packet is received, the received by filter will be incremented by 1. If the sock receive buffer is full, the packet is discarded and dropped by kernel is incremented by 1, so the counts of received by filter and dropped by kernel are maintained by the kernel.
The reason for packet loss is that after libcap caught the packet, the upper layer of tcpdump did not take it out in time, causing the libcap buffer to overflow, thus discarding the unprocessed packet, which is shown here as dropped by kernel. The kernel here is not meant to be abandoned by the linux kernel, but by the tcpdump kernel, libcap.

There are also some solutions, such as:
1, -n parameters, reverse domain name resolution is prohibited ()
2, -s parameters to control the length of grab packets
(Using a larger capture range not only increases the processing time of the message, but also correspondingly reduces the buffer number of the message, which may lead to the loss of the message. Try to keep snaplen as small as possible, as long as it can accommodate the required protocol information. )
3. Output the data package to cap file
4. use sysctl to modify SO_REVBUF parameter and increase libcap buffer length

Method 1 I tried, but the effect was not satisfactory.
Method 2 has also been tried, with good results. However, I originally wanted to test the performance of the bag, so I definitely had to grasp the whole bag. After thinking about it, I gave up the plan.
Method 3 This … I originally output it to the file, but there is still the problem of packet loss, so it seems that there is no use for eggs.
Method 4 feels a bit complicated, but in the previous explanation, it was also mentioned that the packet loss was caused by insufficient buffer. Therefore, I think this method has a door, but it is just a little troublesome. Then I had a brainwave. I found a -B parameter in tcpdump that can modify the buffer size. ha ha! !

So the final solution is: I used the -B parameter to modify the buffer size of tcpdump! ! !
Note here that if the -B option is not specified, then the buffer size defaults to 32768. in this case, I will take two and try -B 65535.
Hee hee, all of a sudden what packet loss flew away ~ ~