Linux 查看端口占用情况可以使用 lsof 、ss和 netstat 命令。
一、lsof
lsof命令详解
lsof(list open files)是一个列出当前系统打开文件的工具。lsof 查看端口占用语法格式:
lsof -i:端口号
如查看服务器 2379端口的占用情况:
#注意,lsof默认是没有安装的,需要自行安装
yum install lsof -y
[root@k8s-m1 ~]# lsof -i:2379
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
etcd 5680 root 7u IPv4 42209 0t0 TCP k8s-m1:2379 (LISTEN)
可以看到 2379 端口已经被轻 etcd 服务占用。
lsof -i 需要 root 用户的权限来执行,如下图:
[root@k8s-m1 ~]# lsof -i|more
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
rpcbind 5403 rpc 6u IPv4 41399 0t0 UDP *:sunrpc
rpcbind 5403 rpc 7u IPv4 42127 0t0 UDP *:909
rpcbind 5403 rpc 8u IPv4 42128 0t0 TCP *:sunrpc (LISTEN)
rpcbind 5403 rpc 9u IPv6 42129 0t0 UDP *:sunrpc
rpcbind 5403 rpc 10u IPv6 42130 0t0 UDP *:909
rpcbind 5403 rpc 11u IPv6 42131 0t0 TCP *:sunrpc (LISTEN)
chronyd 5426 chrony 5u IPv4 41466 0t0 UDP localhost:323
chronyd 5426 chrony 6u IPv6 41467 0t0 UDP localhost:323
sshd 5670 root 3u IPv4 48132 0t0 TCP *:ssh (LISTEN)
sshd 5670 root 4u IPv6 48134 0t0 TCP *:ssh (LISTEN)
etcd 5680 root 5u IPv4 42205 0t0 TCP k8s-m1:2380 (LISTEN)
etcd 5680 root 6u IPv4 42208 0t0 TCP localhost:2379 (LISTEN)
etcd 5680 root 7u IPv4 42209 0t0 TCP k8s-m1:2379 (LISTEN)
etcd 5680 root 8u IPv4 42210 0t0 TCP k8s-m1:2380->k8s-m2:48008 (ESTABLISHED)
etcd 5680 root 9u IPv4 45366 0t0 TCP k8s-m1:2380->k8s-m3:41006 (ESTABLISHED)
etcd 5680 root 10u IPv4 45367 0t0 TCP k8s-m1:2380->k8s-m3:41016 (ESTABLISHED)
etcd 5680 root 11u IPv4 42211 0t0 TCP k8s-m1:2380->k8s-m2:48010 (ESTABLISHED)
etcd 5680 root 12u IPv4 43860 0t0 TCP k8s-m1:2379->k8s-m3:57352 (ESTABLISHED)
etcd 5680 root 14u IPv4 61002 0t0 TCP k8s-m1:2379->k8s-m2:48626 (ESTABLISHED)
etcd 5680 root 15u IPv4 7534239 0t0 TCP k8s-m1:2379->k8s-m2:41368 (ESTABLISHED)
etcd 5680 root 16u IPv4 13158470 0t0 TCP k8s-m1:2379->k8s-m1:38664 (ESTABLISHED)
etcd 5680 root 18u IPv4 13137657 0t0 TCP k8s-m1:2379->k8s-m1:38670 (ESTABLISHED)
参数说明:
COMMAND:进程的名称
PID: 进程标识符
USER:进程所有者
FD:文件描述符,应用程序通过文件描述符识别该文件。如cwd、txt等
TYPE:文件类型,如IPv4、IPv6、DIR、REG等
DEVICE:指定磁盘的名称
SIZE:文件的大小
NODE:索引节点(文件在磁盘上的标识)
NAME:打开文件的确切名称
其中:FD不容易理解,特别说明一下:
(1)cwd:表示 current work dirctory,即:应用程序的当前工作目录,这是该应用程序启动的目录,除非它本身对这个目录进行更改
(2)txt:该类型的文件是程序代码,如应用程序二进制文件本身或共享库,如 /sbin/init 程序
(3)lnn: library references (AIX)
(4)er: FD information error (see NAME column)
(5)jld: jail directory(FreeBSD)
(6)ltx: shared library text(code and data)
(7)mxx: hex memory-mapped type number xx.
(8)m86:DOS Merge mapped file
(9) mem: memory-mapped file
(10)mmap: memory-mapped device
(11)pd: parent directory
(12)rtd: root directory
(13)tr: kernel trace file (OpenBSD)
(14)v86 VP/ix mapped file
(15)0:表示标准输出
(16)1:表示标准输入
(17)2:表示标准错误
一般在标准输出、标准错误、标准输入后还跟着文件状态模式:r w u 等
(1)u:表示该文件被打开并处于读取/写入模式
(2)r:表示该文件被打开并处于只读模式
(3)w:表示该文件被打开并处于只写入模式
(4)空格:表示该文件的状态模式为 unknown ,且没有锁定
(5)- : 表示该文件的状态模式为 unknown ,且被锁定
同时在文件状态模式后面,还跟着相关的锁
(1)N:for a Solaris NFS lock of unknown type
(2)r: for a read lock on part of the file
(3)R:for a read lock on the entire file
(4)w: for a write lock on part of the file (文件的部分写锁)
(5)W: for a write lock on the entire file(整个文件的写锁)
(6)u: for a read and write lock of any length
(7)U: for a lock of unknown type
(8)x: for an SCO OpenServer Xenix lock on part of the file
(9)X:for an SCO OpentServer Xenix lock on the entire file
(10)space : if there is no lock
更多 lsof 的命令如下:
lsof : 简单地执行lsof会列出当前系统中所有被打开的文件
lsof -u margu : 列出用户margu打开的文件, 可指定多个用户, 默认是OR的关系
lsof -i : 列出打开的套接字
lsof -i tcp : 列出打开的tcp套接字
lsof -i:80:查看80端口占用
lsof -i :ssh : 列出打开22端口的进程
lsof -i tcp:2379 : 列出打开2379号tcp端口的进程
lsof -n 不将IP转换为hostname,缺省是不加上-n参数
lsof test.txt:显示开启文件abc.txt的进程
lsof -c test:显示abc进程现在打开的文件
lsof -c -p 12345:列出进程号为12345的进程所打开的文件
lsof -g gid:显示归属gid的进程情况
lsof +d /usr/local/:显示目录下被进程开启的文件
lsof +D /usr/local/:同上,但是会搜索目录下的目录,时间较长
lsof -d 4:显示使用fd为4的进程
lsof -i -U:显示所有打开的端口和UNIX domain文件
lsof -p 12345:看进程号为12345的进程打开了哪些文件
lsof -s :列出打开文件的大小,如果没有大小,则留下空白
lsof -d mem : 列出打开映射文件的进程
lsof -d txt : 列出打开的可执行文件
lsof server.log : 列出打开server.log文件的进程, 可指明多个文件
二、lsof应用实例:
1、du和df显示磁盘使用量不一样
用户删除了大量的文件后,du命令就不会在文件系统目录中统计这些文件。如果此时还在运行中的进程持有这个已经被删除的文件句柄,那么这个文件就不会真正在磁盘中被删除,分区超级块中的信息也就不会更改,df命令仍会统计这个被删除的文件。 通过lsof命令查询处于deleted状态的文件,被删除的文件在系统中被标记为deleted。如果系统有大量deleted状态的文件,会导致du和df命令统计结果不一致。
可执行如下命令查看lsof |grep deleted
解决方法
根据lsof列出的进程号,终止相应进程或者重启相应的服务。也可以重启实例,重启实例系统会退出现有的进程,重启后重新加载过程中,会释放调用的deleted文件的句柄。
重要:但某些时候,我们的服务器上没有lsof的命令,而且也不能连外网进行安装,可以通过以下的方法查找deleted状态的文件。
[root@k8s-m1 ~]# ll /proc/*/fd/|grep deleted
lrwx------ 1 mysql mysql 64 Jun 21 14:53 12 -> /tmp/ibdhpN9t (deleted)
lrwx------ 1 mysql mysql 64 Jun 21 14:53 5 -> /tmp/ibJeq1IW (deleted)
lrwx------ 1 mysql mysql 64 Jun 21 14:53 6 -> /tmp/ibhiCbh3 (deleted)
lrwx------ 1 mysql mysql 64 Jun 21 14:53 7 -> /tmp/ib1JgnP9 (deleted)
lrwx------ 1 mysql mysql 64 Jun 21 14:53 8 -> /tmp/ib5ed98m (deleted)
2、查找谁在使用文件系统
在卸载文件系统时,如果该文件系统中有任何打开的文件,操作通常将会失败。那么通过lsof可以找出那些进程在使用当前要卸载的文件系统,如下:
在一个窗口中打开某个路径下的文件,如
[root@k8s-m1 docker]# vim /home/docker/Dockerfile
#新开一个窗口
[root@k8s-m1 ~]# lsof /home/docker
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
bash 25386 root cwd DIR 253,2 4096 16784069 /home/docker
vim 26008 root cwd DIR 253,2 4096 16784069 /home/docker
在这个示例中,用户root正在其/home/docker目录中进行一些操作。一个 bash是实例正在运行,并且它当前的目录为/home/docker,另一个则显示的是vim正在编辑/home/docker下的文件。要成功地卸载/home/docker,应该在通知用户以确保情况正常之后,中止这些进程。 这个示例说明了应用程序的当前工作目录非常重要,因为它仍保持着文件资源,并且可以防止文件系统被卸载。这就是为什么大部分守护进程(后台进程)将它们的目录更改为根目录、或服务特定的目录(如 sendmail 示例中的 /var/spool/mqueue)的原因,以避免该守护进程阻止卸载不相关的文件系统。
3、恢复删除的文件当(不是所有时候都有用,可以尝试)
Linux计算机受到入侵时,常见的情况是日志文件被删除,以掩盖攻击者的踪迹。管理错误也可能导致意外删除重要的文件,比如在清理旧日志时,意外地删除了数据库的活动事务日志。有时可以通过lsof来恢复这些文件。当进程打开了某个文件时,只要该进程保持打开该文件(进程要一直存在,文件要一直被使用,没有被一直使用的文件是不行的),即使将其删除,它依然存在于磁盘中。这意味着,进程并不知道文件已经被删除,它仍然可以向打开该文件时提供给它的文件描述符进行读取和写入。除了该进程之外,这个文件是不可见的,因为已经删除了其相应的目录索引节点。在/proc 目录下,其中包含了反映内核和进程树的各种文件。/proc目录挂载的是在内存中所映射的一块区域,所以这些文件和目录并不存在于磁盘中,因此当我们对这些文件进行读取和写入时,实际上是在从内存中获取相关信息。如/var/log/messages对于许多应用程序,尤其是日志文件和数据库,这种恢复删除文件的方法非常有用,因为这些文件一般都是一直在使用的。
[root@k8s-m1 ~]# rm /var/log/messages
rm: remove regular file ‘/var/log/messages’? y
[root@k8s-m1 ~]# lsof |grep /var/log/messages
rsyslogd 21072 root 9w REG 253,0 333093 101406984 /var/log/messages (deleted)
in:imjour 21072 21074 root 9w REG 253,0 333093 101406984 /var/log/messages (deleted)
in:imudp 21072 21075 root 9w REG 253,0 333093 101406984 /var/log/messages (deleted)
in:imtcp 21072 21076 root 9w REG 253,0 333093 101406984 /var/log/messages (deleted)
in:imtcp 21072 21077 root 9w REG 253,0 333093 101406984 /var/log/messages (deleted)
in:imtcp 21072 21078 root 9w REG 253,0 333093 101406984 /var/log/messages (deleted)
in:imtcp 21072 21079 root 9w REG 253,0 333093 101406984 /var/log/messages (deleted)
in:imtcp 21072 21080 root 9w REG 253,0 333093 101406984 /var/log/messages (deleted)
rs:main 21072 21081 root 9w REG 253,0 333093 101406984 /var/log/messages (deleted)
从上面的信息可以看到 PID 21072 (rsyslogd)打开文件的文件描述符为 9(9w)。同时还可以看到/var/log/messages已经标记被删除了。因此我们可以在 /proc/21072/fd/9 (fd下的每个以数字命名的文件表示进程对应的文件描述符)中查看相应的信息,如下:
[root@k8s-m1 ~]# head -n 5 /proc/21072/fd/9
Jun 25 03:40:01 k8s-m1 rsyslogd: [origin software="rsyslogd" swVersion="8.24.0-34.el7" x-pid="21072" x-info="http://www.rsyslog.com"] rsyslogd was HUPed
Jun 25 03:40:01 k8s-m1 systemd: Started Session 15901 of user root.
Jun 25 03:40:01 k8s-m1 systemd: Started Session 15902 of user root.
Jun 25 03:40:24 k8s-m1 etcd: read-only range request "key:\"/registry/health\" " with result "range_response_count:0 size:7" took too long (171.182021ms) to execute
Jun 25 03:40:27 k8s-m1 etcd: read-only range request "key:\"/registry/services/specs/default/kubernetes\" " with result "range_response_count:1 size:612" took too long (157.340425ms) to execute
恢复:
[root@k8s-m1 ~]# cat /proc/21072/fd/9 > /var/log/messages
二、ss
ss命令详解
ss 是 Socket Statistics 的首字母缩写。顾名思义,ss命令可以用来获取socket统计信息,它可以显示和netstat类似的内容。ss的优势在于它能够显示更多更详细的有关TCP和连接状态的信息,而且比netstat更快速更高效。ss 命令由 iproute2 软件包提供(yum install iproute),默认已经安装,iproute 2 包中的命令可以完全替代 net-tools 包中的 ifconfig、netstat、route 等命令。
下面是一些常用选项和用法:
ss -t:显示所有TCP连接。
ss -u:显示所有UDP连接。
ss -a:显示所有连接,包括监听状态和已建立的连接。
ss -l:显示所有监听状态的连接。
ss -p:显示与连接关联的进程信息。
ss -n:显示IP地址和端口号,而不是主机名和服务名。
ss -o:显示时间戳和超时信息。
ss -e:显示详细的套接字信息。
除了以上的选项外,ss命令还可以与其他命令一起配合使用,例如grep、awk等,以进一步过滤和处理输出结果。
还可以使用ss命令来检查网络连接问题,例如检查某个端口是否被占用、查看连接状态等。
ss示例
列出已建立的连接
默认情况下,如果我们运行ss命令而没有指定其他选项,它将显示所有已建立连接的打开的非侦听套接字的列表,例如TCP,UDP或UNIX套接字。
[root@k8s-m1 ~]# ss |more
Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port
u_str ESTAB 0 0 /run/systemd/journal/stdout 33171 * 44494
u_str ESTAB 0 0 * 32720 * 39019
u_str ESTAB 0 0 * 44138 * 33121
u_str ESTAB 0 0 /run/gssproxy.sock 35473560 * 35473554
u_str ESTAB 0 0 * 44494 * 33171
u_str ESTAB 0 0 /run/dbus/system_bus_socket 35673 * 41457
u_str ESTAB 0 0 * 35472701 * 0
显示监听套接字(listening)
我们可以使用-l选项专门列出当前正在侦听连接的套接字,而不是列出所有的套接字。
[root@k8s-m1 ~]# ss -lt
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 *:30983 *:*
LISTEN 0 128 *:30119 *:*
LISTEN 0 128 *:24007 *:*
LISTEN 0 128 127.0.0.1:10248 *:*
LISTEN 0 128 127.0.0.1:10249 *:*
LISTEN 0 128 127.0.0.1:9099 *:*
LISTEN 0 128 192.168.2.140:2379 *:*
LISTEN 0 128 127.0.0.1:2379 *:*
LISTEN 0 128 192.168.2.140:2380 *:*
显示进程
我们可以用-p选项打印出拥有套接字的进程或PID号。
[root@k8s-m1 ~]# ss -ltp
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 *:30983 *:* users:(("kube-proxy",pid=30105,fd=20))
LISTEN 0 128 *:30119 *:* users:(("kube-proxy",pid=30105,fd=15))
LISTEN 0 128 *:24007 *:* users:(("glusterd",pid=5712,fd=10))
LISTEN 0 128 127.0.0.1:10248 *:* users:(("kubelet",pid=5778,fd=26))
LISTEN 0 128 127.0.0.1:10249 *:* users:(("kube-proxy",pid=30105,fd=14))
LISTEN 0 128 127.0.0.1:9099 *:* users:(("calico-node",pid=30764,fd=3))
LISTEN 0 128 192.168.2.140:2379 *:* users:(("etcd",pid=5680,fd=7))
LISTEN 0 128 127.0.0.1:2379 *:* users:(("etcd",pid=5680,fd=6))
LISTEN 0 128 192.168.2.140:2380 *:* users:(("etcd",pid=5680,fd=5))
......
显示所有tcp sockets
ss -at
显示所有utp sockets
ss -au
只显示 unix 连接
ss -x
列出所有http连接中的连接
显示摘要信息
ss -s
仅显示 IPv4套接字
ss -l4
仅显示 IPv6套接字
ss -l6
不将 IP 地址解析为主机名
如果不想将ip地址解析为主机名称,可以使用-n选项,以防止命令将 IP 地址解析为主机名。但这也会阻止端口号的解析,如下,22端口为ssh服务的端口,不加-n将会显示成ssh
[root@k8s-m1 ~]# ss -l4 -n
Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port
tcp LISTEN 0 128 192.168.2.140:2379 *:*
tcp LISTEN 0 128 127.0.0.1:2379 *:*
tcp LISTEN 0 128 192.168.2.140:2380 *:*
tcp LISTEN 0 128 *:22
dst/src dport/sport相关语法
[root@k8s-m1 ~]# ss dst 192.168.2.141:2379
Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port
tcp ESTAB 0 0 192.168.2.140:42178 192.168.2.141:2379
tcp ESTAB 0 0 192.168.2.140:42244 192.168.2.141:2379
tcp ESTAB 0 0 192.168.2.140:42082 192.168.2.141:2379
tcp ESTAB 0 0 192.168.2.140:42320 192.168.2.141:2379
tcp ESTAB 0 0 192.168.2.140:42802 192.168.2.141:2379
[root@k8s-m1 ~]# ss src 192.168.2.140:22
Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port
tcp ESTAB 0 0 192.168.2.140:ssh 10.12.13.1:54920
tcp ESTAB 0 0 192.168.2.140:ssh 10.12.13.1:52420
tcp ESTAB 0 96 192.168.2.140:ssh 10.12.13.1:63285
ss dport OP PORT
ss sport OP PORT
OP 可以代表以下任意一个:
写法一 | 写法二 | 用途含义 |
---|---|---|
<= | le | 小于或等于某个端口号 |
>= | ge | 大于或等于某个端口号 |
== | eq | 等于某个端口号 |
!= | ne | 不等于某个端口号 |
> | gt | 大于某个端口号 |
< | lt | 小于某个端口号 |
[root@k8s-m1 ~]# ss -tunl sport \< 50
Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port
tcp LISTEN 0 128 *:22 *:*
tcp LISTEN 0 128 :::22 :::*
[root@k8s-m1 ~]# ss -tunl sport lt 50
Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port
tcp LISTEN 0 128 *:22 *:*
tcp LISTEN 0 128 :::22 :::*
通过 TCP 的状态进行过滤
ss 命令还可以通过 TCP 连接的状态进程过滤,支持的 TCP 协议中的状态有: established syn-sent syn-recv fin-wait-1 fin-wait-2 time-wait closed close-wait last-ack listening closing,具体含义可以去了解TCP三次握手和四次挥手过程中的状态。
而除了上面的 TCP 状态,还可以使用下面这些状态:
状态 | 含义 |
---|---|
all | 列出所有的 TCP 状态 |
connected | 列出除了 listening 和 closing 之外的所有 TCP 状态。 |
synchronized | 列出除了 syn-sent 之外的所有 TCP 状态。 |
bucket | 列出 maintained 的状态,如:time-wait 和 syn-recv。 |
big | 列出和 bucket 相反的状态。 |
如:查看Ipv4处于listening状态的进程
[root@k8s-m1 ~]# ss -l4 state listening
Netid Recv-Q Send-Q Local Address:Port Peer Address:Port
tcp 0 128 *:30983 *:*
tcp 0 128 *:30119 *:*
tcp 0 128 *:24007 *:*
tcp 0 128 127.0.0.1:10248 *:*
tcp 0 128 127.0.0.1:10249 *:*
tcp 0 128 127.0.0.1:9099 *:*
tcp 0 128 192.168.2.140:2379 *:*
tcp 0 128 127.0.0.1:2379 *:*
tcp 0 128 192.168.2.140:2380 *:*
tcp 0 128 *:32589 *:*
#注意以下用法的区别
[root@k8s-m1 ~]# ss -4n state listening '( sport = :22 )'
Netid Recv-Q Send-Q Local Address:Port Peer Address:Port
tcp 0 128 *:22 *:*
[root@k8s-m1 ~]# ss -ln state listening '( sport = :ssh )'
Netid Recv-Q Send-Q Local Address:Port Peer Address:Port
tcp 0 128 *:22 *:*
tcp 0 128 :::22 :::*
[root@k8s-m1 ~]# ss -ln state listening '( dport = :ssh or sport = :ssh )'
Netid Recv-Q Send-Q Local Address:Port Peer Address:Port
tcp 0 128 *:22 *:*
tcp 0 128 :::22 :::*
对比netstat和ss查看端口的效果
[root@k8s-m1 ~]# netstat -anp|grep 2379|grep LISTEN
tcp 0 0 192.168.2.140:2379 0.0.0.0:* LISTEN 5680/etcd
tcp 0 0 127.0.0.1:2379 0.0.0.0:* LISTEN 5680/etcd
[root@k8s-m1 ~]# ss -l4|grep 2379
tcp LISTEN 0 128 192.168.2.140:2379 *:*
tcp LISTEN 0 128 127.0.0.1:2379 *:*
[root@k8s-m1 ~]#
更多ss的语法请自行摸索,可以通过ss -h查看帮助信息!!!
三、netstat
netstat -tunlp 用于显示 tcp,udp 的端口和进程等相关情况。
netstat 查看端口占用语法格式:
netstat -tunlp | grep 端口号
-t (tcp) 仅显示tcp相关选项
-u (udp)仅显示udp相关选项
-n 拒绝显示别名,能显示数字的全部转化为数字
-l 仅列出在Listen(监听)的服务状态
-p 显示建立相关链接的程序名
例如查看 2379端口的情况,使用以下命令:
[root@k8s-m1 ~]# netstat -anp|grep 2379|more
tcp 0 0 192.168.2.140:2379 0.0.0.0:* LISTEN 5680/etcd
tcp 0 0 127.0.0.1:2379 0.0.0.0:* LISTEN 5680/etcd
tcp 0 0 192.168.2.140:42178 192.168.2.141:2379 ESTABLISHED 30213/kube-apiserve
tcp 0 0 192.168.2.140:42244 192.168.2.141:2379 ESTABLISHED 30213/kube-apiserve
tcp 0 0 192.168.2.140:42082 192.168.2.141:2379 ESTABLISHED 30213/kube-apiserve
更多命令:
netstat -ntlp //查看当前所有tcp端口
netstat -ntulp | grep 80 //查看所有80端口使用情况
netstat -ntulp | grep 3306 //查看所有3306端口使用情况
在查到端口占用的进程后,如果你要杀掉对应的进程可以使用 kill 命令:
kill -9 PID
如上实例,我们看到 2379端口对应的 PID 为 5680,使用以下命令杀死进程:
kill -9 5680
批量杀掉关于etcd的进程
pkill etcd文章来源:https://www.toymoban.com/news/detail-501281.html
更多关于运维方面的相关知识,请前往博客主页查看。文章来源地址https://www.toymoban.com/news/detail-501281.html
到了这里,关于Linux 查看端口占用情况的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!