1. ip命令

1.1. 摘要

  ip是iproute2软件包里面的一个强大的网络配置工具,它能够替代一些传统的网络管理工具。例如:ifconfig、route等。这个手册将分章节介绍ip命令及其选项。  

1.2. ip命令的语法

  ip命令的用法如下:

[root@node01 ~]# ip
Usage: ip [ OPTIONS ] OBJECT { COMMAND | help }
ip [ -force ] -batch filename
where OBJECT := { link | address | addrlabel | route | rule | neigh | ntable |
tunnel | tuntap | maddress | mroute | mrule | monitor | xfrm |
netns | l2tp | fou | macsec | tcp_metrics | token | netconf | ila |
vrf }
OPTIONS := { -V[ersion] | -s[tatistics] | -d[etails] | -r[esolve] |
-h[uman-readable] | -iec |
-f[amily] { inet | inet6 | ipx | dnet | mpls | bridge | link } |
-4 | -6 | -I | -D | -B | -0 |
-l[oops] { maximum-addr-flush-attempts } | -br[ief] |
-o[neline] | -t[imestamp] | -ts[hort] | -b[atch] [filename] |
-rc[vbuf] [size] | -n[etns] name | -a[ll] | -c[olor]}

  其中,OPTIONS是一些修改ip行为或者改变其输出的选项。所有的选项都是以

-字符开头,分为长、短两种形式。目前,ip支持如下选项:

  • -V,-Version 打印ip的版本并退出。
  • -s,-stats,-statistics 输出更为详尽的信息。如果这个选项出现两次或者多次,输出的信息将更为详尽。
  • -f,-family 这个选项后面接协议种类,包括:inet、inet6或者link,强调使用的协议种类。如果没有足够的信息告诉ip使用的协议种类,ip就会使用默认值inet或者any。link比较特殊,它表示不涉及任何网络协议。
  • -4 是-family inet的简写。
  • -6 是-family inet6的简写。
  • -0 是-family link的简写。
  • -o,-oneline 对每行记录都使用单行输出,回行用字符代替。如果你需要使用wc、grep等工具处理ip的输出,会用到这个选项。
  • -r,-resolve 查询域名解析系统,用获得的主机名代替主机IP地址。

  OBJECT是你要管理或者获取信息的对象。目前ip认识的对象包括:

  • link 网络设备
  • address 一个设备的协议(IP或者IPV6)地址
  • neighbour ARP或者NDISC缓冲区条目
  • route 路由表条目
  • rule 路由策略数据库中的规则
  • maddress 多播地址
  • mroute 多播路由缓冲区条目
  • tunnel IP上的通道

  另外,所有的对象名都可以简写,例如:address可以简写为addr,甚至是a

  COMMAND设置针对指定对象执行的操作,它和对象的类型有关。一般情况下,ip支持对象的增加(add)、删除(delete)和展示(show或者list)。有些对象不支持所有这些操作,或者有其它的一些命令。对于所有的对象,用户可以使用help命令获得帮助。这个命令会列出这个对象支持的命令和参数的语法。如果没有指定对象的操作命令,ip会使用默认的命令。一般情况下,默认命令是list,如果对象不能列出,就会执行help命令。

  ARGUMENTS是命令的一些参数,它们倚赖于对象和命令。ip支持两种类型的参数:flag和parameter。flag由一个关键词组成;parameter由一个关键词加一个数值组成。为了方便,每个命令都有一个可以忽略的默认参数。例如,参数dev是ip link命令的默认参数,因此ip link ls eth0等于ip link ls dev eth0。我们将在后面的章节详细介绍每个命令的使用,命令的默认参数将使用default标出。

  几乎所有的关键词都可以简写为前几个字母。在交互工作时,简写的方式非常方便,但是我们不建议在脚本中使用简写形式。另外,在讲述过程中,所有的“官

方”简写方式都会在文章中列出。

1.3. ip的错误信息

  由于以下原因,ip可能会操作失败:

  命令行语法错误:一个未知的关键词(an unknown keyword);错误的IP地址格式(incorrectly formated IP address)。在这种情况下,ip会打印出错误信息然后退出,在错误信息中会包含失败的原因。有时ip也会打印帮助信息。

参数不能通过一致性校验

由于用户没有提供足够的信息,造成ip无法从参数中编译出内核请求。内核返回某些系统调用的错误。ip使用perror(3)输出错误信息,因此输出的错误信息包含一段注释以及系统调用号。内核返回RTNETLINK请求错误。这类错误信息以"RTNETLIK answers"开头。

  ip的所有操作都是原子操作。例如,如果ip执行失败,它不会系统的任何东西,ip link command例外,它会修改某些设备参数。

  我们无法列出所有的错误信息,尤其是语法错误。不过,错误信息的意思都非常明确。下面,我们列举一些经常出现的错误信息:

内核不支持netlink(netlink用于在内核模块和用户之间传递信息),会出现以下错

误信息:

Cannot open netlink socket: Invalid value

内核不支持RTNETLINK,会出现以下错误信息:

Cannot talk to rtnetlink: Connect refused

Cannot send dump request: Connect refused

如果在编译内核时没有配置CONFIG_IP_MULTIPLE_TABLES选项。在使用ip规则时会出现和下面的信息类似的错误信息:

kuznet@kaise $ ip rule list
RTNETLINK error: Invalid argument
dump terminated

1.3.1. ip link--配置网络设备

对象 link由网络设备,对应的命令显示以及设备的状态变化组成。

命令 set和show(或者list)

1.3.2. ip link set--改变设备的属性

缩写:set、s

参数:

  • dev NAME(default) 指定进行操作的网络设备
  • up/down 起动/关闭设备。
    • 例如:ip link set dev eth0 up
  • arp on/off 改变网络设备的NOARP选项。
    • 如果设备处于UP状态,不允许进行这个操作。不过,内核和ip都不会对在这种情况下的这个操作进行检查。在设备处于运行状态下改变这个选项会造成无法预料的后果。
  • multicast on/off 改变网络设备的MULTICAST选项。
  • dynamic on/off 改变网络设备的DYNAMIC选项。
  • name NAME 把设备的名字改为NAME(例如:eth0)。如果设备处于运行状态或者已经配置了地址,建议不要进行这个操作。
  • txqueuelen NUMBER或者txqlen NUMBER 改变设备传输队列的长度。
    • 例如:ip link set dev eth0 txqueuelen 100
  • mtu NUMBER 改变网络设备MTU(最大传输单元)的值。
    • 例如:ip link set dev eth0 mtu 1500
  • address LLADDRESS 修改网络设备的MAC地址。
    • 例如:ip link set dev eth0 address 00:01:4f:00:15:f1
  • broadcat LLADDRESS或者brd LLADDRESS 修改数据链路层广播地址。
    • 注意:对于大多数的网络设备(例如:以太网),修改链路层广播地址会对网络造成破坏。因此,如果对此没有很深的理解,最好不要使用这个操作。
  • peer LLADDRESS 当使用点对点连接时,使用这个操作可以修改对端的数据链路层地址。
    • 注意:ip不能修改PROMISC或者ALLMULTI选项。这两个选项已经比较陈旧,而且也不应该随便修改。
    • 注意:如果同时修改多个参数,任何一个修改失败,ip都会立即取消操作。这种情况可能使系统进入无法预料的状态。为了避免出现这种情况,尽量不要使用ip link set同时修改多个参数,例如:ip link set dev eth0 mtu 1500 txqueuelen 100

1.3.3. ip link show--显示设备属性

缩写:show、list、lst、sh、ls、l

参数

dev NAME(default) NAME指定网络设备名称,例如:eth0。如果省略了这个参数,所有的设备属性就都会被列出。

up 只显示处于活动状态网络接口的信息。

输出格式

[root@node01 ~]# ip link ls eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1442 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
link/ether 00:16:3e:56:05:bb brd ff:ff:ff:ff:ff:ff
[root@node01 ~]# ip link ls virbr0
4: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN mode DEFAULT group default qlen 1000
link/ether 52:54:00:46:c5:28 brd ff:ff:ff:ff:ff:ff
[root@node01 ~]#

  在显示的信息中,每个引号之前的数字是一个接口索引,用于识别网络接口。这个数字后面是网络接口的名字(例如:eth0、dummy等),它也和网络接口一一对应。不过,在某些情况下,例如:驱动模块被卸载,对应的接口名就会从列表中消失,而其它新创建的接口就会使用相同的名字。系统管理员可以ip link set name修改接口的名字。

  接口名可以是别的,或者是@NONE。这意味着这个设备被绑定到其它的设备,例如数据包被发送到这个设备,由这个设备封装,并从master设备发出。如果设备名字是NONE,就表示master设备是未知的。

  接着,我们看到的是mtu(Maximal Transfer Unit,最大传输单元)。它决定这个接口单个数据包能够传输多少数据。

  qdisc(queuing discipline)显示这个网络接口使用的排队算法。noqueue表示不对数据包进行排队;noop表示这个网络接口出于黑洞模式,也就是所有进入本网络设备的数据会直接被丢弃。qlen是网络接口传输队列的默认长度。

网络接口可以有如下标志:

  • UP 这个设备处于运行状态,可以接收、发送数据包。
  • LOOPBACK 这个接口不能用于和其它的主机通讯,所有发送到这个接口的数据包都会返回,而且这种接口只能接收反弹回来的数据包。
  • BROADCAST 这个设备具有把数据包发送到所有主机的能力。以太网连接是一个很典型的例子。
  • POINTTOPOINT 两个节点之间是直接连接的。某个接点发出的所有数据包都会发到对端节点,接收到的所有数据包也都是从对端节点发过来的。
  • MULTICAST 这个标志表示设备具有多播能力,能够把数据包发送到某些相邻的网络节点。实际上,广播是多播的一个特例,它的多播组包括连接上的所有节点。

    从定义上,POINTTOPOINT和BROADCAST连接都属于多播。

如果网络接口的标志不属于LOOPBACK、BROADCAST和POINTTOPOINT的任何一个,就假定是NMBA(Non-Broadcast Multi-Access)类型。这是最为普遍的一个标志。

  • PROMISC 设备处于混杂模式,接收连接上的所有数据,不管目的地址是否是自己。通常,这种模式主要用于网桥和网络监视。
  • ALLMULTI 设备接收连接上的所有多播数据包,多播路由器(muliticast router)使用这种模式。
  • NOARP 这个标志和其它的标志不同,它的含义和涉及的网络协议有关。它一般表示这个设备无需地址解析,软件或者硬件不必借助于系统协议栈的帮助就知道如何把数据包投递到目的地。
  • DYNAMIC 这个标志表示这个网络接口是动态建立和撤消的。
  • SLAVE 表示这个接口被绑定到其它的网络接口。

除此之外,还有其它一些标志。这些标志或者已经过时(例如:NOTRAILERS),或者还没有实现(如:DEBUG),或者只是特定于某些设备(例如:MASTER、AUTOMEDIA、PORTSEL)。因此,在此我们不作讨论。

对于PROMISC和ALLMULTI标志,ifconfig和ip显示的值是不同的。ip link ls命令显示的是设备的真正状态,而ifconfig显示的是自己设置的虚拟设备状态。

  显示信息的第二行包含和链路层地址(MAC地址)相关的信息。其中,第一个词(ether、sit)定义接口的硬件类型。而接口的硬件类型又决定MAC地址的格式和语法。默认的格式是硬件的MAC地址和广播地址(如果是点对点连接方式,就是对端的地址),地址是用冒号隔开的16进制数字。不过,默写类型的连接有其特定的地址格式,例如:IP通道的地址格式是用点分开的IP地址。

  • NBMA(Non-Broadcast Multi-Access)连接没有明确定义的广播地址和对端地址。不过,这个域包含一些有用的信息,例如:倚赖于ARP服务器的广播地址。

使用这个命令不会显示多播地址,需要使用ip maddr ls命令。详情请参考第9节ip maddr ls。

统计信息

  使用-statistics选项,ip命令会打印出网络接口的统计信息,例如:

worker:/etc/sysconfig/network # ip -s link ls eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
link/ether 00:16:3e:c2:49:da brd ff:ff:ff:ff:ff:ff
RX: bytes packets errors dropped overrun mcast
1342786 17496 0 1147 0 0
TX: bytes packets errors dropped carrier collsns
587396 6368 0 0 0 0
altname enp0s16
altname ens16

RXTX分别是接收和发送统计信息的开头。得到的统计信息包括:

  • bytes 网络接口发送或者收到的字节数。如果字节数超过数据类型能够表示的最大数值,就会造成回卷。因此,你如果想连续监视这个指标,需要一个用户空间的监控进程周期性地保存这个数据。
  • packets 网络接口收到或者发送的数据包个数。
  • errors 发生错误的次数。
  • dropped 由于系统资源限制,而丢弃数据包的数量。
  • overrun 由于发生堵塞,收到的数据包被丢弃的数量。如果接口发生堵塞,就意味着内核或者你的机器太慢,无法处理收到的数据。
  • mcast 收到的多播数据包数量,只有很少的设备支持这个选项。
  • carrier 连接介质出现故障的次数,例如:网线接触不好。
  • collsns 以太网类型介质发生冲突的事件次数。
  • compressed 压缩数据包的总数。这个指标只适用于使用VJ头压缩的网络接口。

如果-s选项出现两次或者更多次,ip会输出更为详细的错误信息统计。

worker:/etc/sysconfig/network # ip -s -s link ls eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
link/ether 00:16:3e:c2:49:da brd ff:ff:ff:ff:ff:ff
RX: bytes packets errors dropped overrun mcast
1372546 17902 0 1175 0 0
RX errors: length crc frame fifo missed
0 0 0 0 0
TX: bytes packets errors dropped carrier collsns
601100 6543 0 0 0 0
TX errors: aborted fifo window heartbeat transns
0 0 0 0 2
altname enp0s16
altname ens16
worker:/etc/sysconfig/network #

  这些错误的名字是纯以太化的,对于其它种类的设备,这些域可能有不同的解释。

1.4. ip address--协议地址管理

缩写 address、addr、a

对象 这里的地址是绑定到网络设备上的协议(IP或者IPv6)地址。每个网络设备至少应该有一个协议地址。而且,一个网络设备可以绑定多个协议地址。

ip addr命令能够显示网络设备的协议地址及其性质,添加新的地址,删除旧的地址。

1.4.1. 命令 add、delete、flush和show(或者list)

1.4.2. ip address add--添加一个新的协议地址

缩写:add、a

参数

  • dev NAME 被操作的设备名
  • local ADDRESS(default) 接口的地址,地址格式和协议有关。IPv4地址使用.进行分隔,而IPv6地址使用冒号分隔。ADDRESS可以跟着一个斜杠和表示掩码位数的十进制数字。
  • peer ADDRESS 点对点接口对端的地址。ADDRESS也可以跟着一个斜杠和表示掩码位数的十进制数字。
  • broadcast ADDRESS 接口的广播地址。为了方便,可以使用+和-(注1)代替广播地址。例如:

    ip addr add local 192.168.1.1/24 brd + dev eth0

    ip addr add local 192.168.1.1/28 brd - dev eth0
  • label NAME 为每个地址设置一个字符串作为标签。为了和Linux-2.0的网络别名兼容,这个字符串必须以设备名开头,接着一个冒号,例如:

    #ip addr add local 192.168.4.1/28 brd + label eth0:1 dev eth0
  • scope SCOPE_VALUE(注2) 设置地址的有效范围,它用于内核为数据包设置源地址。有效的范围在/etc/iproute2/tr_scopes文件列出,系统预先设定了一些范围值:
    • global 这个地址全局有效。
    • site 这个地址是局部连接,也就是只有目标地址是这个设备地址时,才有效。
    • site (只适用于IPv6)地址在站点内部有效。
    • host 地址在主机内部有效。

注1:使用-,ip addr ls显示的是网络地址;使用+,ip addr ls显示的是广播地址。

注2:有关scope,在附录A中有更为详细的解释。

示例

在回环设备上添加一个回环地址:
worker:/etc/sysconfig/network # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:16:3e:c2:49:da brd ff:ff:ff:ff:ff:ff
altname enp0s16
altname ens16
inet 10.160.xxx.xxx/26 brd 10.160.xxx.xxx scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::216:3eff:fec2:49da/64 scope link
valid_lft forever preferred_lft forever
worker:/etc/sysconfig/network # ip addr add 127.0.0.2/8 dev lo brd + scope host
worker:/etc/sysconfig/network # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet 127.0.0.2/8 brd 127.255.255.255 scope host secondary lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:16:3e:c2:49:da brd ff:ff:ff:ff:ff:ff
altname enp0s16
altname ens16
inet 10.160.xxx.xxx/26 brd 10.160.xxx.xxx scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::216:3eff:fec2:49da/64 scope link
valid_lft forever preferred_lft forever
worker:/etc/sysconfig/network # 在以太网接口eth0上增加一个地址10.0.0.1,掩码长度为24位(155.155.155.0),标准广播地址,标签为eth0:Alias:
#ip addr add 10.0.0.1/24 brd + dev eth0 label eth0:Alias

1.4.3. ip address delete--删除一个协议地址

缩写:delete、del、d

参数

  这个命令的参数和ip addr add命令的参数一致。其中,只有设备名是必需的

参数,其它都是可选的。如果没有给定除设备名之外的其它参数,ip就会删除这个

设备的第一个地址。

示例

删除回环设备的一个回环地址。不过,最好不要作这种尝试。
worker:/etc/sysconfig/network # ip addr del 127.0.0.2/8 dev lo
worker:/etc/sysconfig/network # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:16:3e:c2:49:da brd ff:ff:ff:ff:ff:ff
altname enp0s16
altname ens16
inet 10.160.xxx.xxx/26 brd 10.160.xxx.xxx scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::216:3eff:fec2:49da/64 scope link
valid_lft forever preferred_lft forever
worker:/etc/sysconfig/network #
以下shell代码可以取消设备上的所有IP地址。
while ip -f inet add del dev eth0;do
:nothing
done

另外,可以使用ip addr flush命令取消IP地址

1.4.4. ip address show--显示协议地址

缩写:show、list、lst、sh、ls、l

参数

  • dev NAME(default) 设备的名字
  • scope SCOPE_VAL 只列出这个范围的地址
  • to PREFIX 只列出和PREFIX匹配的地址,例如:

    ip addr ls to 192.168.1.1
  • label PATTERN 只列出标签匹配PATTERN的地址,PATTERN是一个shell风格的正则表达式。
  • dynamic和permanent 这两个参数只适用于IPv6。使用dynamic,ip就只列出动态地址;使用permanent,ip就只列出固定地址。
  • tentative 这个参数只适用于IPv6,只列出没有通过重复地址检测[参考2]的地址

  • deprecated 这个参数只适用于IPv6,只列出deprecated[参考2]地址。
  • primary和secondary 只列出主(primary)或从(secondary)地址。

输出格式

worker:~ # ip address list eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:16:3e:c2:49:da brd ff:ff:ff:ff:ff:ff
altname enp0s16
altname ens16
inet 10.160.xxx.xxx/26 brd 10.160.xxx.xxx scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::216:3eff:fec2:49da/64 scope link
valid_lft forever preferred_lft forever
worker:~ #
worker:~ # ip link list eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
link/ether 00:16:3e:c2:49:da brd ff:ff:ff:ff:ff:ff
altname enp0s16
altname ens16
worker:~ #

输出的头两行和ip link ls的输出是相同的。

接着是IP和IPv6地址、广播地址以及其它的地址属性:范围(scope)、标志(flag)和标签(label)。地址标志由内核设置,系统管理员不能修改。目前,内核定义了以下标志:

  • secondary 为输出的数据包选择默认源地址时,内核不使用这个地址。如果一个设备已经有了一个地址,又给它设置了同一网段的不同地址,第二个地址就成为从(secondary)地址。例如:eth0已经有一个地址192.168.1.108/24,如果又给它一个地址192.168.1.3/24,192.168.1.3/24的就会被内核标记为从地址。
  • dynamic 这个地址是通过无状态的自动配置建立的(stateless
  • autoconfiguration)[参考2]。如果地址仍然有效,在输出中,还包括两个时间信息。preferred_lft期满后,地址就会变成deprecated状态;valiid_lft期满后,地址将失效。
  • deprecated 这个地址是不允许的,也就是说,地址虽然有效,但是不能使用它建立新的连接。
  • tentative 由于重复地址监测[参考2]还没有完成或者监测失败,这个地址不能使用。

1.4.5. ip address flush--清除协议地址

缩写:flush、f

简介

  这个命令可以清除按照某种条件选择的协议地址。

参数

  这个命令的参数和ip address show相同。唯一的区别是,如果不给定参数它什么都不会做

警告

  这个命令(和后面讨论的所有flush命令)非常危险。如果出现错误,将无法恢复,它会清除被操作的地址。

statistics选项

  如果在ip addr flush命令中使用了-statistics选项,命令将输出更为详尽的信息。输出的信息包括删除地址的数目和清理地址列表的圈数。如果使用了两次-s选项,ip addr flush会按照上节叙述的格式输出所有被删除的地址。

示例

删除属于私网10.0.0.0/8的所有地址:
worker:~ # ip -s -s address flush to 192/8
Nothing to flush.
worker:~ # ip -s -s a f to 10/8
2: dummy inet 10.7.7.7/16 brd 10.7.255.255 scope global dummy
3: eth0 inet 10.10.7.7/16 brd 10.10.255.255 scope global eth0
4: eth1 inet 10.8.7.7/16 brd 10.8.255.255 scope global eth1 *** Round 1,deleting 3 addresses ***
*** Flush is complete after 1 round ***
worker:~ # 取消所有以太网卡的IP地址
worker:~ # ip -4 addr flush label "eth0" 最后一个例子是对IPv6地址的操作。在启动了转发或者关闭了自动配置之后,你需要取消通过无状态地址自动配置获得的主机地址:
worker:~ # ip -6 addr flush dynamic

1.5. ip neighbour--neighbour/arp表管理命令

缩写 neighbour、neighbor、neigh、n

对象 邻接(neighbour)对象实现同一网段协议地址和链路层地址的绑定。在内核中,这些条目被组织到表中。IPv4的相邻表也被叫做ARP表。

ip neighbour命令支持对条目及其属性的显示、添加和删除。

命令 add、change、replace、delete、fulsh、show(或者list)

  附录B将详细描述如何使用ip管理代理ARP/NDISC。

ip neighbour add -- 添加一个新的邻接条目
ip neighbour change--修改一个现有的条目
ip neighbour replace--替换一个已有的条目

缩写:add、a;change、chg;replace、repl

简介:这三个命令用来建立一个邻接表的条目或者更新现有的邻接表条目。

参数

  • to ADDRESS(default) 相邻的协议地址。可以是IPv4或者IPv6。

  • dev NAME 和相邻节点连接的设备。

  • lladdr LLADDRESS 邻居的链路层地址。LLADDRESS可以为空。

  • nud NUD_STATE 邻接条目的状态。nud是Neighbour Unreachability Detection的缩写。可能的状态包括:

    • permanent--邻接条目永远有效并且只能由管理员删除。
    • noarp--邻接条目有效,不必对其有效性进行确认。在其生命期期满时会被删除。
  • reachable--在超时时间之内,这个邻接条目是有效的。

  • stale--这个邻接条目是有效的,但是比较可疑。如果条目是有效的,ip neigh不会改变邻接状态,也不会修改其地址。

示例

在设备eth0上,为地址10.0.0.3添加一个permanent ARP条目:
worker:~ # ip neighbour add 10.0.0.3 lladdr 0:0:0:0:0:1 dev eth0 nud permanent
ip neigh add 10.0.0.3 lladdr 0:0:0:0:0:1 dev eth0 nud perm 把状态改为reachable
ip neigh chg 10.0.0.3 dev eth0 nud reachable

1.5.1. ip neighbour delete--删除一个邻接条目

缩写:delete、del、d

简介

  这个命令用来删除一个邻接条目

参数

  这个命令的参数和ip neigh add命令的相同,只不过lladdr和nud将被忽略。

示例

删除设备eth0上的一个ARP条目10.0.0.3
ip neigh del 10.0.0.3 dev eth0

执行了删除命令之后,被删除的条目不会马上消失,它会在系统的下次垃圾收集时被删除。如果被操作的条目正在使用,将不能被删除。

警告

  如果试图删除或者手工修改一个由内核建立的noarp条目,会导致一些不可预知的行为。

1.5.2. ip neighbour show--显示网络邻居的信息

缩写:show、list、sh、ls

简介

  这个命令用于显示网络邻居信息。

参数

  • to ADDRESS(default) 指定要显示的地址
  • dev NAME 只显示设备NAME的邻居
  • unused 只显示当前没有使用的邻居
  • nud NUD_STATE 只列出处于NUD_STATE状态的邻接条目。NUD_STATE的值下面将会介

    绍。nud all表示所有的状态。这个选项可以使用多次。如果缺少这个选项,ip会

    列出除none和noarp状态的所有条目。

输出格式

worker:~ # ip neighbour show
10.160.xxx.xxx dev eth0 lladdr 48:f8:db:d2:46:02 STALE
10.160.xxx.xxx dev eth0 lladdr 00:00:5e:00:01:04 REACHABLE
fe80::216:3eff:fed3:4e33 dev eth0 lladdr 00:16:3e:d3:4e:33 router STALE
fe80::216:3eff:fe47:ad29 dev eth0 lladdr 00:16:3e:47:ad:29 router STALE
worker:~ # ip neighbour show dev eth0
10.160.xxx.xxx lladdr 48:f8:db:d2:46:02 STALE
10.160.xxx.xxx lladdr 00:00:5e:00:01:04 REACHABLE
fe80::216:3eff:fed3:4e33 lladdr 00:16:3e:d3:4e:33 router STALE
fe80::216:3eff:fe47:ad29 lladdr 00:16:3e:47:ad:29 router STALE
worker:~ # ip neighbour ls
10.160.xxx.xxx dev eth0 lladdr 48:f8:db:d2:46:02 STALE
10.160.xxx.xxx dev eth0 lladdr 00:00:5e:00:01:04 REACHABLE
fe80::216:3eff:fed3:4e33 dev eth0 lladdr 00:16:3e:d3:4e:33 router STALE
fe80::216:3eff:fe47:ad29 dev eth0 lladdr 00:16:3e:47:ad:29 router STALE
worker:~ #

每行的第一部分是网络邻居的协议地址。第二部分是设备名。省下的部分是这个邻接条目的信息。

lladdr是这个设备的链路层地址。

nud是条目代表连接的状态。下面是状态的完整列表和简单描述:

  • none 网络邻居的状态为空。
  • incomplete 这个邻居正在被解析。
  • reachable 网络邻居有效并且可达。
  • stale 邻居有效,但是可能不可达。因此,内核将在首次传输时进行检查。
  • delay 一个数据包已经发到处于stale的网络邻居,内核在等待应答信息。
  • probe delay计时器过期,还没有收到确认信息。内核开始使用ARP/NDISC消息包探测这个网络邻居。
  • failed 解析失败。
  • noarp 网络邻居有效,不必检查。
  • permanent 这是一个noarp条目,只有系统管理员可以从邻接表中把它删除。

在这些状态中,除了none、faliled和incomplete.

IPVv6网络邻居可以有一个叫做router的标志,它表示这个节点是一个IPv6路由器。

  • -statistics

    -statistics选项可以显示很多有用的信息。例如:
worker:~ # ip -s n ls 10.160.xxx.xxx
10.160.xxx.xxx dev eth0 lladdr 00:16:3e:8a:8b:9e ref 1 used 2/2/2 probes 4 REACHABLE
worker:~ #

输出信息里面多了ref和用斜缸分开的三个时间。ref表示有多少用户使用这个条目;三个时间分别是使用时间、确认时间和刷新时间。因此,上面输出中的时间表示:

条目12秒之前刚刚使用过;

13秒之前被确认;

20秒之前被更新。

1.5.3. ip neighbour flush--清除邻接条目

缩写:flush、f

简介

  这个命令用来清除符合某个条件的邻接表条目。

参数

  这个命令的参数和ip neigh sh相同。不同之处是,如果没有参数,它什么也不会做。而且,默认情况下,被删除的条目不包括处于permanent和noarp状态的条目。

-statistics

  使用了-statistics选项,这个命令的输出将更为详尽。它会输出删除的条目数和清除邻接表遍历的次数。如果使用了两个-s选项,命令的输出将包括被删除条目的信息。

示例

worker:~ # ip -s -s neighbour flush 10.160.xxx.xxx
10.160.xxx.xxx dev eth0 lladdr 00:16:3e:8a:8b:9e used 101/101/75 probes 4 STALE *** Round 1, deleting 1 entries ***
*** Flush is complete after 1 round ***
worker:~ #

1.6. 路由表管理

缩写:route、ro、r

对象

  路由条目保存在内核的路由表中,它们包含寻找到其它网络节点的路径信息。路由表条目都包括一对网络地址/掩码长度以及可选的TOS值等信息。如果数据包目的地址位于属于路由条目的的范围,以及路由的TOS等于0或者等于数据包的TOS,它就匹配路由条目。如果一个数据包匹配多个路由条目,系统内核将按照以下规则决定选择哪个路由:

  注:作者在文中把地址被子网掩码屏蔽后的部分/掩码长度这种表达方式叫做前缀(prefix)。例如:10/8表示网络10.0.0.0,子网掩码长度是8位;10.1/16表示网络10.1.0.0,子网掩码长度是16位;

  • 范围最小的优先匹配,较大的放弃;
  • 路由TOS等于数据包TOS的匹配,不等于的放弃;
  • 如果经过上面两步的选择,还有数个路由,就选择优先值最高的路由;
  • 如果还有数个路由可供选择,就重复进行第一步。

为了简化,我们使用{prefix,tos,preference}来标记每个路由。

1.6.1. 路由属性

  路由条目提供IP数据包投递所需的路由信息、数据(例如:输出设备、下一跳的路由器)和一些可选属性(例如:路径的最大传输单元MTU或者源地址等)。这些属性将在后面的章节详细介绍。

1.6.2. 路由类型

  路由的设置以及其它的可选属性都依赖于路由类型。最重要的路由类型是unicast路由,这种类型的路由表示到另外主机的真实路由。一般情况下,通常的路由表只有这种类型的路由条目。不过,还存在其它类型的路由,使用的语法也不相同。Linux-2.2理解以下几种类型的路由:

  • unicast 这种类型的路由描述到目的地址的真实路径。
  • unreachable 这些目的地址是不可达的。如果发过去的数据包都被丢弃并且收到ICMP信息host unreachable,目的地址就会被标记为不可达。在这种情况下,本地发送者将返回EHOSTUNREACH错误。
  • blackhole 这些目的地址不可达,而且发过去的数据包都被丢弃。在这种情况下,本地发送者将返回EINVAL错误。
  • prohibit 这些路由是不可达的。发过去的数据包都被丢弃,而且产生ICMP信息communication administratively prohibited 。本地发送者会返回EACCESS错误。
  • local 目的地址被分配给本机。数据包通过回环被投递到本地。
  • broadcast 目的地址是广播地址,数据包作为链路广播发送。
  • throw 和策略规则(policy rule)一块使用的控制路由。如果选择了这种路由,就会认为没有发现路由,在这个表中的查询就会被终止。没有找到策略路由就相当于在路由表中没有找到路由,数据包会被丢弃,并产生ICMP信息net unreachable。本地发送者会返回ENETUNREACH错误。
  • nat 特定的NAT路由。目标地址属于哑地址(或者称为外部地址),在转发前需要进行地址转换。
  • anycast 目标是anycast地址,被分配给本机。这类地址和本地地址大同小异,不同的是这类地址不能用于任何数据包的源地址。
  • multicast 使用多播路由。在普通的路由表中,这种路由并不存在。

1.6.3. 路由表

从Linux-2.2开始,内核把路由归纳到许多路由表中,这些表都进行了编号,编号数字的范围是1到255。另外,为了方便,还可以在/etc/iproute2/rt_tables中为路由表命名。默认情况下,所有的路由都会被插入到表main(编号254)中。在进行路由查询时,内核只使用路由表main。

实际上,还有另外一个路由表也一直存在,这个表是不可见的,而且极为重要。这就是表local。这个表保存本地和广播路由。内核会自动维护这个路由表,通常系统管理员没有必要对它进行修改,甚至不必看到。

在使用策略路由(policy routing)时,我们将使用多个路由。在这种情况下,表识别符有很多参数,因此需要使用{prefix,tos,preference}的形式唯一地识别每个路由。

1.6.4. ip route add -- 添加新路由,ip route change -- 修改路由,ip route replace -- 替换已有的路由

缩写:add、a;change、chg;replace、repl

参数

  • to PREFIX或者to TYPE PREFIX(default) 路由的目标前缀(prefix)。如果TYPE被忽略,ip命令就会使用默认的类型unicast。其它的类型在上一节都有介绍。

  • PREFIX是一个IP或者IPv6地址,也可以跟着一个斜杠和掩码长度。如果没有掩码长度,ip命令就假定是一个单一ip地址。另外,还有一个特殊的PREFIX--default(缺省路由),它等于IPv4的0/0,或者IPv6的::/0。

  • tos TOS 或者defield TOS 定义服务类型关键词。在进行路由匹配时,内核首先比较数据包的TOS和route的TOS,如果没有和数据包TOS相同的路由,还可以选择TOS等于0的路由。TOS或者是一个十六进制的数字,或者是一个由/etc/iproute2/rt_dsfield文件定义的识别符。

  • metric NUMBER或者preference NUMBER 定义路由的优先值,NUMBER时一个任意的32位数字。

  • table TABLEID 路由要加入的表。TABLEID或者是一个数字或者是/etc/iproute2/rt_tables文件定义的一个字符串。如果没有这个参数,ip命令就会把路由加入到表main中,本地(local)、广播(broadcast)和网络地址转换(nat)路由除外。在默认情况下,这些类型的路由都会被加入表local中。

  • dev NAME 输出设备的名字

  • via ADDRESS 指定下一跳路由器的地址。实际上,这个域的可靠性取决于路由类型。对于通常的unicast路由,它或者是真正的下一跳路由器地址,或者如果它是BSD兼容模式安装的直接路由,它可以是一个网络接口的本地地址。对于NAT路由,它是转换后的地址。

  • src ADDRESS 在向目的prefix发送数据包时选择的源地址。

  • realm REALMID 指定路由分配的realm。REALM可以是一个数字或者/etc/iproute2/rt_realms文件定义的一个字符串。有关realm更为详细的信息请看附录(Route realms and policy propagation, rtacct)。

  • mtu MTU或者mtu lock MTU 设置到达目的路径的最大传输单元(MTU)。如果没有使用修饰符lock,内核会通过路径最大传输单元发现(Path MTU Discovery)机制更新MTU;如果使用了修饰符lock,内核就不会测试路径的最大传输单元。在这种情况下,发出的所有IPv4数据包DF域都会被设置为0(允许分片),对于IPv6数据包也允许分片。

  • window NUMBER 设置到目的地址TCP连接的最大窗口值,以字节为单位。使用这个参数可以限制对端发送数据的速率。

  • rtt NUMBER 估算初始往返时间(Round Trip Time)

  • rttvar NUMBER 估算初始往返时间偏差(RTT variance)

  • ssthresh NUMBER 估算慢启动阀值(slow start threshould)

  • cwnd NUMBER 把拥挤窗口(congestion window)值锁定为NUMBER。如果没有lock标记,这个值会被忽略。

  • advmss NUMBER 设置在建立TCP连接时,向目的地址声明的最大报文段大小

  • (Maximal Segment Size,MSS)。如果没有设置,Linux内核会使用计算第一跳的最大传输单元得到的数值。

  • nexthop NEXTHOP 设置多路径路由的下一跳地址。NEXTHOP比较复杂,它的语法和以下高层参数类似:

    • via ADDRESS--表示下一跳路由器;
    • dev NAME--表示输出设备;
    • weight NUMBER--在多路由路径中,这个元素的权重。表示相对带宽或者服务质量。
  • scope SCOPE_VAL 路由前缀(prefix)覆盖的范围。SCOPE_VAL可以是一个数字,也可以是/etc/iproute2/rt_scope文件定义的一个字符串。如果没有这个参数,ip命令就会根据具体情况猜测:对于经过网关的unicast路由,就设置为global;对于直连的unicast路由和广播路由,就设置为link;对于本地路由,就设置为host。

  • protocol RTPROTO 本条路由得路由协议识别符。RTPROTO可以是一个数字,也可以是/etc/iproute2/rt_protos文件定义的一个字符串。如果使用时没有提供这个参数,ip命令就使用默认值boot(也就是说,ip命令认为添加路由的人不知道自己做了些什么)。有些协议值有其固定的解释:

  • redirect--路由是由ICMP重定向加入的;

  • kernel--路由是由内核在自动配置期间加入的;

  • boot--路由是启动过程中加入的。如果一个路由监控程序将要启动,这些路由都会被清除;

  • static--为了覆盖动态路由,由系统管理员手工添加的路由。路由监控程序也会优先考虑这类路由,甚至可能通告给其对端;

  • ra--路由是通过路由发现协议加入的(Router Discovery Protocol)。

    其它的值没有保留,系统管理员可以自由分配(或者不分配)给协议标记。至少,路由监控程序应该注意对一些唯一协议值的设置,这些协议值在rtnetlink.h文件或者rt_protos数据库中分配。

  • onlink 假装和下一跳路由器是直接相连的,即使它没有匹配任何接口前缀(prefix)。

  • equalize 允许把数据包随机从多个路由发出。如果没有这个路由修饰符,内核就会冻结下一跳路由的地址。

示例

设置到网络10.0.0/24的路由经过网关193.233.7.65
ip route add 10.0.0/24 via 193.233.7.65 修改到网络10.0.0/24的直接路由,使其经过设备dummy
ip route chg 10.0.0/24 dev dummy 加入缺省多路径路由,让ppp0和ppp1分担负载(注意:scope值并非必需,它只不过是告诉内核,这个路由要经过网关而不是直连的。实际上,如果你知道远程端点的地址,使用via参数来设置就更好了)。
ip route add default scope global nexthop dev ppp0 nexthop dev ppp1 设置NAT路由。在转发来自192.203.80.144的数据包之前,先进行网络地址转换,把这个地址转换为193.233.7.83(回来的转换将会在后面的章节路由策略中介绍)。
ip route add nat 192.203.80.142 via 193.233.7.83

1.6.5. ip route delete-- 删除路由

缩写:delete、del、d

参数

  ip route del使用和ip route add相同的参数,不过语法稍有不同。这个命令使用关键词(to、tos、preference和table)选择要删除的路由。如果命令中使用了可选属性,ip命令会校验这个属性和要删除的路由是否一致;如果没有给定关键词或者属性不一致,ip route del会执行失败。

示例

删除上一节命令加入的多路径路由
ip route del default scope global nexthop dev ppp0 nexthop dev ppp1

1.6.6. ip route show -- 列出路由

缩写:show、list、sh、ls、l

简介

  使用这个命令,你可以看到路由表的内容,或者查询符合某些条件的路由。

参数

  • to SELECTOR(default) 只选择到给定地址的路由。 SELECTOR由修饰符(root、match、exact,可选)和一个前缀(prefix)组成。root PREFIX表示选择前缀(prefix)不短于PREFIX的路由,例如:root 0/0将选在路由表里面的全部路由;

  • match PREFIX表示选择前缀(prefix)不长于PREFIX的路由,match 10.1/16会选择前缀(prefix)是10.1/16、10./8和0/0的全部路由;而exact PREFIX(或者just PREFIX)表示精确匹配。如果没有这些选项(ip route ls),ip命令就假定是ip route ls to root 0/0,将列出系统的所有路由。

  • tos TOS或者dsfield TOS 只列出tos等于TOS的路由

  • table TABLEID 列出路由表TABLEID里面的路由。缺省设置是table main。

  • TABLEID或者是一个真正的路由表ID或者是/etc/iproute2/rt_tables文件定义的字符串,或者是以下的特殊值:

  • all -- 列出所有表的路由;

  • cache -- 列出路由缓存的内容。

  • cloned或者cached 列出被克隆出来的路由(由于某些路由属性改变,例如:MTU,而由某些路由派生出来的路由)。实际上,它的内容和表缓存的内容是一样的。

  • from SELECTOR 和to的语法是相同的,只不过由目的地址换为源地址而已。注意:这个选项之适用于被克隆出来的路由。

  • protocol RTPROTO 只列出协议是RTPROTO的路由

  • scope SCOPE_VAL 只列出范围是SCOPE_VAL的路由

  • type TYPE 只列出类型为TYPE的路由

  • dev NAME 只列出通过设备NAME的路由

  • via PREFIX 只列出下一跳通过PREFIX的路由

  • src PREFIX 只列出源地址属于PREFIX的路由

  • realm REALMID或者raalm FROMREALM/TOREALM 只列出realm为REALMID的路由

示例

计算使用gated/bgp协议的路由个数
kuznet@amber:~ $ ip route ls proto gated/bgp |wc
1413 9891 79010
kuznet@amber:~ $ 计算路由缓存里面的条数,由于被缓存路由的属性可能大于一行,以此需要使用
-o选项
uznet@amber:~ $ ip -o route list cloned |wc
159 2543 18707
kuznet@amber:~ $

输出格式

  通常,在这个命令输出的信息中,每个路由纪录占一行。不过,有时某些纪录可能会超过一行,例如被克隆出来的路由或者包含一些额外的信息。如果在命令中使用了-o选项,在每个纪录中,会使用代替回车作为回行标记。例如:

[root@node01 ~]# ip route show 192.168.2.1/24
192.168.2.0/24 dev eth0 proto kernel scope link src 192.168.2.161
[root@node01 ~]#

如果是列出被克隆的条目,输出信息将是另外的形式。例如:

kuznet@amber:~ $ ip route list 193.233.7.82 tab cache
193.233.7.82 from 193.233.7.82 dev eth0 src 193.233.7.65 realms inr.ac/inr.ac
cache <src-direct,redirect> mtu 1500 rtt 300 iif eth0
193.233.7.82 dev eth0 src 193.233.7.65 realms inr.ac
cache mtu 1500 rtt 300
kuznet@amber:~ $

输出信息的第二行是以关键词cache开头的,显示路由的其它缓存标记和属性。本行的第一个域是cache <缓存标记>,缓存标记包括:

  • local 数据包被投递到本地。它适用于本地回环单向传播(unicast)路由,如果这个主机是对应广播组的一个成员,它也适用于广播路由何多播路由。
  • reject 路径无效。任何试图通过这个路由的企图都会导致错误。
  • mc 目的是多播地址(multicast)。
  • brd 目的是广播地址(broadcast)。
  • src-direct 源地址是在一个直接连接的接口。
  • redirected 路由是由ICMP重定向建立的。
  • redirect 数据包通过这个路由将触发ICMP重定向。
  • fastroute 路由适合用于快速路由(fastroute)。
  • equalize 使数据包随机地通过这个路由。
  • dst-nat 目的地址需要进行地址转换。
  • src-nat 源地址需要进行地址转换。
  • masq 源地址需要伪装(masquerading)。
  • notify 修改/删除这个路由将触发RTNETLINK报警。

接着是一些路由属性,支持的属性如下:

  • error 对于reject路由,这是返回给本地发送者的错误码。这些错误码也会被转换为ICMP错误码,发送给远程发送者。
  • expires 到了超时时间,这个条目就会消失。
  • iif 需要这个路由的数据包如期到达这接口。

统计选项

  如果在命令中使用-statistics选项,ip命令会给出一些更为详尽的信息:

  • users 使用这个路由的用户数。
  • age 显示这个路由最后使用时的时间。
  • used 自从建立这个路由以来,它被查询的次数。

1.6.7. ip route flush -- 擦除路由表

缩写:flush、f

简介

  使用这个命令,可以很方便地删除符合某些条件的路由。

参数

  这个命令的参数和ip route show命令的参数相同,只不过被操作的路由表不会被显示出来。它和ip route show命令唯一的区别是它们的缺省操作,ip route show会显示出路由表main的所有条目,而ip route flush只会给出帮助信息,不对路由表进行任何操作。至于这个区别的原因,恐怕不必多做解释了吧?

统计选项

  如果在这个命令中使用了-statistics选项,它就会显示一些冗余信息。这些信息包括:被删除的路由数和删除过程中遍历路由表的次数。如果这个选项使用了两次,ip还会输出被删除路由的详细信息。

示例

# 第一个例子是删除路由表main中的所有网关路由(例如:在路由监控程序挂掉之后):
netadm@amber:~ # ip -4 ro flush scope global type unicast # 第二个例子是清除所有被克隆出来的IPv6路由: netadm@amber:~ # ip -6 -s -s ro flush cache
3ffe:2400::220:afff:fef4:c5d1 via 3ffe:2400::220:afff:fef4:c5d1
dev eth0 metric 0
cache used 2 age 12sec mtu 1500 rtt 300
3ffe:2400::280:adff:feb7:8034 via 3ffe:2400::280:adff:feb7:8034
dev eth0 metric 0
cache used 2 age 15sec mtu 1500 rtt 300
3ffe:2400::280:c8ff:fe59:5bcc via 3ffe:2400::280:c8ff:fe59:5bcc
dev eth0 metric 0
cache users 1 used 1 age 23sec mtu 1500 rtt 300
3ffe:2400:0:1:2a0:ccff:fe66:1878 via 3ffe:2400:0:1:2a0:ccff:fe66:1878
dev eth1 metric 0
cache used 2 age 20sec mtu 1500 rtt 300
3ffe:2400:0:1:a00:20ff:fe71:fb30 via 3ffe:2400:0:1:a00:20ff:fe71:fb30
dev eth1 metric 0
cache used 2 age 33sec mtu 1500 rtt 300
ff02::1 via ff02::1 dev eth1 metric 0
cache users 1 used 1 age 45sec mtu 1500 rtt 300 *** Round 1, deleting 6 entries ***
*** Flush is complete after 1 round ***
netadm@amber:~ # ip -6 -s -s ro flush cache
Nothing to flush.
netadm@amber:~ # # 第三个例子是在gated程序挂掉之后,清除所有的BGP路由: netadm@amber:~ # ip ro ls proto gated/bgp |wc
1408 9856 78730
netadm@amber:~ # ip -s ro f proto gated/bgp
*** Round 1, deleting 1408 entries ***
*** Flush is complete after 1 round ***
netadm@amber:~ # ip ro f proto gated/bgp
Nothing to flush.
netadm@amber:~ # ip ro ls proto gated/bgp
netadm@amber:~ #

1.6.8. ip route get -- 获得单个路由

缩写:get、g

简介

  使用这个命令可以获得到达目的地址的一个路由以及它的确切内容。

参数

  • to ADDRESS(default) 目标地址
  • from ADDRESS 源地址
  • tos TOS或者dsfield TOS 服务类型
  • iif NAME 数据包进来的设备
  • oif NAME 数据包出去的设备
  • connected ip route get命令至少要有参数to ADDRESS。使用connected参数,如果没有给出源地址(from ADDRESS),ip就会重新在路由表中查询能够到达目的地址的源地址,给出获得的第一个源地址到目的地址的路由。如果使用了策略路由,会有所不同。

ip route get命令和ip route show命令执行的操作是不同的。ip route show命令只是显示现有的路由,而ip route get命令在必要时会派生出新的路由。

输出格式

  这个命令的输出格式和ip route ls相同。

示例

搜索到193.233.7.82的路由
kuznet@amber:~ $ ip route get 193.233.7.82
193.233.7.82 dev eth0 src 193.233.7.65 realms inr.ac
cache mtu 1500 rtt 300
kuznet@amber:~ $ 搜索目的地址是193.233.7.82,来自193.233.7.82,从eth0设备到达的路由(这条命令会产生一条非常有意思的路由,这是一条到193.233.7.82的回环路由)
kuznet@amber:~ $ ip r g 193.233.7.82 from 193.233.7.82 iif eth0
193.233.7.82 from 193.233.7.82 dev eth0 src 193.233.7.65
realms inr.ac/inr.ac
cache <src-direct,redirect> mtu 1500 rtt 300 iif eth0
kuznet@amber:~ $ 获得一个多播路由,数据包来自主机193.233.7.82,从eth0设备进入,目的地址是多播组地址224.2.127.254(需要运行多播路由监控程序pimd)。这个命令产生的路由与上面的不大相同,它包含常规部分和多播部分。常规部分用于把数据包投递到本地ip监控程序。这里,本地地址不是多播组的成员,因此这个路由没有local标记,只用于转发数据包。这个路由的输出设备是回环设备。多播部分包含额外的输出接口。
kuznet@amber:~ $ ip r g 224.2.127.254 from 193.233.7.82 iif eth0
multicast 224.2.127.254 from 193.233.7.82 dev lo
src 193.233.7.65 realms inr.ac/cosmos
cache <mc> iif eth0 Oifs: eth1 pimreg
kuznet@amber:~ $

下面我们举一个复杂一些的例子。我们首先为一个目标地址添加一个无效的网关路由,而实际上和这个地址是直连的。

netadm@alisa:~ # ip route add 193.233.7.98 via 193.233.7.254
netadm@alisa:~ # ip route get 193.233.7.98
193.233.7.98 via 193.233.7.254 dev eth0 src 193.233.7.90
cache mtu 1500 rtt 3072
netadm@alisa:~ # 然后,我们ping一下193.233.7.98: netadm@alisa:~ # ping -n 193.233.7.98
PING 193.233.7.98 (193.233.7.98) from 193.233.7.90 : 56 data bytes
From 193.233.7.254: Redirect Host(New nexthop: 193.233.7.98)
64 bytes from 193.233.7.98: icmp_seq=0 ttl=255 time=3.5 ms
From 193.233.7.254: Redirect Host(New nexthop: 193.233.7.98)
64 bytes from 193.233.7.98: icmp_seq=1 ttl=255 time=2.2 ms
64 bytes from 193.233.7.98: icmp_seq=2 ttl=255 time=0.4 ms 64 bytes from 193.233.7.98: icmp_seq=3 ttl=255 time=0.4 ms
64 bytes from 193.233.7.98: icmp_seq=4 ttl=255 time=0.4 ms
^C
--- 193.233.7.98 ping statistics ---
5 packets transmitted, 5 packets received, 0% packet loss
round-trip min/avg/max = 0.4/1.3/3.5 ms
netadm@alisa:~ # 输出结果可以看出,路由器193.233.7.254知道有更好的路由,因此送回一个ICMP重定向信息。然后,我们再看看路由表的情况: netadm@alisa:~ # ip route get 193.233.7.98
193.233.7.98 dev eth0 src 193.233.7.90
cache <redirected> mtu 1500 rtt 3072
netadm@alisa:~ #

1.7. ip route -- 路由策略数据库管理命令

缩写:rule、ru

对象

  路由策略数据库的规则用于控制选择路由的算法。

Internet上采用的路由算法一般是基于数据包目的地址的。理论上,也可以由TOS域决定,不过这没有实际应用。要了解经典路由算法的详细情况请参考RFC-1812。

而在某些情况下,我们不只是需要通过数据包的目的地址决定路由,可能还需要通过其他一些域:源地址、IP协议、传输层端口甚至数据包的负载。这就叫做:策略路由(policy routing)。

注意:策略路由(policy routing)不等于路由策略(rouing policy)。

在这种情况下,传统的基于目的地址的路由表就无法满足要求了,需要使用路由策略数据库(routing policy database,RPDB)代替,通过它选择执行某些路由。

这些规则可以由很多不同的状态,而且它们没有天生的次序,要由系统管理员决定。RPDB可以匹配以下的域:

  • 数据包的源地址;
  • 数据包的目的地址;
  • 服务类型(Type of Service);
  • 进入的网络接口;

匹配IP协议和传输层端口也是可能的,不过这要依靠iptables或者ipchains通过fwmark为某些数据包做标记,并重定向。

每个路由策略由一个选择符(selector)和一个操作(action)组成。系统按照顺序搜索路由策略数据库,把选择符和{源地址、目的地址、进入接口、tos、fwmark}等关键词进行匹配,如果匹配成功,就执行action定义的操作。操作或者成功返回,或者失败并且中止对路由策略。否则,系统继续查询路由策略数据库。

操作如何定义?最原始的操作是选择下一跳(nexthop)和输出设备(output device)。Cisco IOS使用这种方式,我们姑且把这叫做匹配并设置(match & set)。而Linux的方式则更为灵活,Linux允许的操作包括:基于目的地址的路由表查询以及按照最长匹配的原则从路由表中选择路由。因此,匹配并设置(match & set)的方式只是一个最简单的特例而已。

在系统启动时,内核会为路由策略数据库配置三条缺省的规则:

优先级 选择符 操作 解释
0 匹配任何条件 查询路由表local(ID 255) 路由表local是一个特殊的路由表,包含对于本地和广播地址的高优先级控制路由。rule 0非常特殊,不能被删除或者覆盖。
32766 匹配任何条件 查询路由表main(ID 254) 路由表main(ID 254)是一个通常的表,包含所有的无策略路由。系统管理员可以删除或者使用另外的规则覆盖这条规则。
32767 匹配任何条件 查询路由表default(ID 253) 路由表default(ID 253)是一个空表,它是为一些后续处理保留的。对于前面的缺省策略没有匹配到的数据包,系统使用这个策略进行处理。这个规则也可以删除。

  不要混淆路由表和策略:规则指向路由表,多个规则可以引用一个路由表,而且某些路由表可以没有策略指向它。如果系统管理员删除了指向某个路由表的所有规则,这个表就没有用了,但是仍然存在,直到里面的所有路由都被删除,它才会消失。

1.7.1. 规则类型

路由策略规则数据库可以包括如下类型的规则:

  • unicast 返回从被引用的路由表中发现的路由
  • blackhole 丢弃数据包,不做任何反应
  • unreachable 产生网络不可达(Network is unreachable)的ICMP错误信息
  • prohibit 产生通讯被禁止(Communication is administratively prohibited)的ICMP错误信息
  • nat 把数据报的源地址转换为其它的值。详情请参考附录C

1.7.2. 命令

  add、delete、show(或者list)

1.7.3. ip rule add -- 插入新的规则

ip rule delete -- 删除规则

缩写:add、a;delete、del、d

参数

  • type TYPE(default) 这个规则的类型。有效的类型上一节已经介绍过了。
  • from PREFIX 匹配的源地址
  • iif NAME 选择数据包进入的设备。如果接口是回环设备,这个规则就只匹配源于本机的数据包。这意味着,你可以为本机发出的数据包和要转发的数据包分别建立路由表,使两者完全隔离。
  • tos TOS或者dsfield TOS 选择匹配的TOS值
  • fwmark MARK 选择要匹配的fwmark值
  • priority PREFERENCE 设置这个规则的优先级。每个规则的优先级都应该明确设置为一个唯一的数值。实际上,由于历史的原因,ip roule add命令无需任何优先级的值,也不必是唯一的。如果用户没有在命令中提供优先级的值,内核会自动选择。如果用户提供的优先级值已经存在,内核也不会拒绝这次请求,而是在相同优先级的规则前面插入新的规则。
  • table TABLEID 如果规则选择符匹配,就被查询的路由表识别符。
  • realms FROM/TO 如果规则匹配和路由表查询成功,选择的realms值。
  • nat ADDRESS 设置要进行网络地址转换的IP地址段。ADDRESS或者是进行网络地址转换ip地址段,或者是一个本机地址,甚至可以是0。

警告

使用上面两个命令对路由策略数据库进行的任何修改都不会马上生效。只有使用ip route flush cach命令刷新路由缓存之后才会生效。

示例

通过路由表inr.ruhep路由来自源地址为192.203.80/24的数据包
ip ru add from 192.203.80/24 table inr.ruhep prio 220 把源地址为193.233.7.83的数据报的源地址转换为192.203.80.144,并通过表1进行路由
ip ru add from 193.233.7.83 nat 192.203.80.144 table 1 prio 320 删除无用的缺省规则
ip ru del prio 32767

1.7.4. ip rule show -- 列出路由规则

缩写:show、list、sh、ls、l

参数

  好消息,这个命令没有参数。

输出格式

kuznet@amber:~ $ ip ru ls
0: from all lookup local
200: from 192.203.80.0/24 to 193.233.7.0/24 lookup main
210: from 192.203.80.0/24 to 192.203.80.0/24 lookup main
220: from 192.203.80.0/24 lookup inr.ruhep realms inr.ruhep/radio-msu
300: from 193.233.7.83 to 193.233.7.0/24 lookup main
310: from 193.233.7.83 to 192.203.80.0/24 lookup main
320: from 193.233.7.83 lookup inr.ruhep map-to 192.203.80.144
32766: from all lookup main
kuznet@amber:~ $
  • 每行第一部分的数字是规则的优先级,接着是选择符。
  • 关键词lookup后面接着路由表识别符。
  • 如果规则要进行网络地址转换,还需要一个关键词map-to设置转换以后的地址。

上面的示例非常简单,192.203.80.0/24和193.233.7.0/24组成内部网络,但是它们向外发送数据包要通过不同的路由。主机193.233.7.83和外界会话时,地址需要转换为192.203.80.144。

1.8. ip maddress -- 多播地址管理

1.8.1. 对象

  这个命令管理的对象是多播地址。

1.8.2. 命令

  add、delete、show(或者list)

1.8.3. ip maddress show -- 列出多播地址

缩写:show、list、sh、ls、l

参数

dev NAME(defautl) 设备名         

输出格式

kuznet@alisa:~ $ ip maddr ls dummy
2: dummy
link 33:33:00:00:00:01
link 01:00:5e:00:00:01
inet 224.0.0.1 users 2
inet6 ff02::1
kuznet@alisa:~ $

输出的第一行是设备的索引和设备名。后面几行是多播地址,每行由协议识别符开头。关键词link表示这是链路层多播地址。

如果一个多播地址有几个用户,那么用户数就在users关键词之后列出。上面的例子没有出现关键词static,它表示这个地址是由ip maddr add命令加入的。

1.8.4. ip maddress add -- 加入多播地址

ip maddress delete -- 删除多播地址

缩写:add、a;delete、del、d

简介

  使用这两个命令,我们可以添加/删除在网络接口上监听的链路层多播地址。这个命令只能管理链路层地址。

参数

  • address LLADDRESS(default) 链路层多播地址
  • dev NAME 加入/脱离这个多播地址的设备

示例

  让我们继续上一小节的例子

netadm@alisa:~ # ip maddr add 33:33:00:00:00:01 dev dummy
netadm@alisa:~ # ip -O maddr ls dummy
2: dummy
link 33:33:00:00:00:01 users 2 static
link 01:00:5e:00:00:01
netadm@alisa:~ # ip maddr del 33:33:00:00:00:01 dev dummy

  注意:ip命令和内核都不会检查多播地址的有效性。这意味着你可以使用unicast地址代替多播地址。大多数驱动都会忽略unicast地址,但是有些驱动(例如:tulip)会把这个unicast地址加入其过滤器。这样作的效果有些奇怪,如果你使用了别的主机或者路由器的地址作为多播地址,你就可以收到发送到它们的数据包。不过,这并非一个bug,而是内核的一个功能。它可以用于网络监视。

1.9. ip mroute -- 多播路由缓存管理

1.9.1. 缩写

  mroute、mr

1.9.2. 对象

  这个命令的操作对象是多播路由缓存条目,这个缓存是由一个用户空间的多播路由监控进程(例如pimd或者mrouted)建立的。

  目前,由于受和多播路由引擎接口的限制,还不能通过ip命令修改多播路由对象,因此我们只能查看。

1.9.3. 命令

  show或者list

1.9.4. ip mroute show -- 列出多播路由缓存条目

缩写:show、list、sh、ls、l

参数

  • to PREFIX(default) 选择到目的多播地址是PREFIX
  • iif NAME 接收多播数据包的网络接口
  • from PREFIX PREFIX选择多播路由的IP源地址

输出格式

kuznet@amber:~ $ ip mroute ls
(193.232.127.6, 224.0.1.39) Iif: unresolved
(193.232.244.34, 224.0.1.40) Iif: unresolved
(193.233.7.65, 224.66.66.66) Iif: eth0 Oifs: pimreg
kuznet@amber:~ $

多播路由缓存条目是(S,G)形式的,S是源地址,G是多播组。iif是接收多播数据包的网络接口,如果设备名是关键词unresolved,就表示路由监控进程不能解析这个条目;接下来的关键词是oif,它后面跟着一些输出网络接口,接口之间用空格分开。

统计信息

使用-statistics选项,我们可以得到更为详细的输出信息,包括:数据包的数量,通过这条路由转发的字节数以及到达错误接口的数据包数量(如果有)。

kuznet@amber:~ $ ip -s mr ls 224.66/16
(193.233.7.65, 224.66.66.66) Iif: eth0 Oifs: pimreg
9383 packets, 300256 bytes
kuznet@amber:~ $

1.10. ip tunnel -- 通道配置

1.10.1. 缩写

  tunnel、tunl

1.10.2. 对象

  ip tunnel命令的操作对象是网络通道(tunnel)。所谓通道(tunnel)是指把数据包封装到IPv4数据包中,使用IP协议发出。有关通道的更多信息,请参考iproute的文档Tunnels over IP in Linux-2.2。

1.10.3. 命令

  add、delete、change、show或者list

1.10.4. ip tunnel add -- 添加新的通道

ip tunnel change -- 修改现有的通道

ip tunnel delete -- 删除一个通道

缩写:add、a;change、chg;delete、del、d

参数

  • name NAME(default) 选择通道设备名
  • mode MODE 设置通道模式。有效的模式包括:ipip、sit和gre。
  • remote ADDRESS 设置通道远端地址
  • local ADDRESS 设置进入通道数据包的固定本地地址,必须是在本机另外一个接口上的地址。
  • ttl N 设置进入通道数据包的TTL为N。N是一个1—255之间的数字。0是一个特殊的值,表示这个数据包的TTL值是继承(inherit)的。ttl参数的缺省值是:inherit。
  • tos T或者dsfield T 设置进入通道数据包的TOS域,缺省是inherit。
  • dev NAME 把通道绑定到设备NAME,以便进入通道的数据包只能通过NAME设备路由,并且当对端发生变化时,不能够在另外的设备解开封装。
  • nopmtudisc 在这个通道上禁止路径最大传输单元发现( Path MTU Discovery)。默认情况下,这个功能是打开的。注意:这个选项和固定的ttl是不兼容的,如果使用了固定的ttl参数,系统会打开路径最大传输单元发现( Path MTU Discovery)功能。
  • key k,ikey k,okey k 只适用于GRE通道,设置keyed GRE通道的key。K或者是一个数字或者是IP地址形式的数字序列。参数key在通道的双向使用,ikey和okey为输入和输出设置不同的key。
  • csum,icsum,ocsum 只用于GRE通道,计算进入通道数据包的校验和。ocsum表示只计算出去的数据包的校验和;icsum表示只计算进入的数据包的校验和;而csum等于icsum ocsum。
  • seq,iseq,oseq 只适用于GRE通道,顺序发送/接收数据包。oseq使向外的数据包顺序发送;iseq要求所有进入的数据包都是按照顺序的;而seq等于iseq oseq。

示例

建立一个点对点通道,最大TTL是32
netadm@amber:~ # ip tunnel add Cisco mode sit remote 192.31.7.104
local 192.203.80.1 ttl
32

1.10.5. ip tunnel show -- 列出现有的通道

缩写:show、list、sh、ls、l

参数

  无

输出格式

kuznet@amber:~ $ ip tunnel ls Cisco
Cisco: ipv6/ip remote 192.31.7.104 local 192.203.80.142 ttl 32
kuznet@amber:~ $

输出的第一部分是通道的设备名,接着是通道模式。下面就是设置通道时的各个参数。

统计信息

kuznet@amber:~ $ ip -s tunl ls Cisco
Cisco: ipv6/ip remote 192.31.7.104 local 192.203.80.142 ttl 32
RX: Packets Bytes Errors CsumErrs OutOfSeq Mcasts
12566 1707516 0 0 0 0
TX: Packets Bytes Errors DeadLoop NoRoute NoBufs
13445 1879677 0 0 0 0
kuznet@amber:~ $

以上输出结果里面的数字和使用ip -s link show的输出是一样的,但是每个标志都是特定于通道的。

  • CsumErrs 对于打开校验和检验的GRE通道,这个数字是由于校验和错误而丢弃的数据包数量。
  • OutOfSeg 在打开顺序功能的GRE通道内,由于顺序错误而丢弃的数据包数量。
  • Mcasts 在GRE通道上接收到的多播数据包的数量。
  • DeadLoop 由于通道是回环到自己而没有传输的数据包数目。
  • NoRoute 由于到对端没有路由而没有被传输的数据包数目。
  • NoBufs 由于内核不能分配缓冲区而没有被传输的数据包数目。

1.11. ip monitor和rtmon -- 状态监视

ip命令可以用于连续地监视设备、地址和路由的状态。这个命令选项的格式有点不同,命令选项的名字叫做monitor,接着是操作对象:

ip monitor [ file FILE ] [ all | OBJECT-LIST ]

OBJECT-LIST是一些被监控的对象,它可以包括link、address和route。如果没有给出file参数,ip命令就打开RTNETLINK,在上面监听,并把状态的变化输出到标准输出设备。

如果使用了file参数,ip命令就不是在RTNETLINK上监听,而是打开由file参数指定的包含RTNETLINK信息的二进制文件,把解析的结果显示出来。这种历史文件可以有工具产生。这个工具具有和ip monitor命令的语法类似的命令行。理想的情况是,在网络配置命令起动之前运行rtmon命令(当然,你可以在任意的时间起动rtmon,它会记录从起动开始的状态变化)。你可以在起动脚本中插入以下命令行:

rtmon file /var/log/rtmon.log

如果我们执行如下命令:

[root@nixe0n root]ip route add dev eth0 to 61.133.4.7 via 211.99.114.
65
[root@nixe0n root]ip route del dev eth0 to 61.133.4.7

然后,我们使用ip monitor命令分析/var/log/rtmon.log会得到如下输出结果:

[root@nixe0n root]ip monitor file /var/log/rtmon.log r
Timestamp: Wed Nov 6 20:25:54 2002 733331 us
1: lo: mtu 16436 qdisc noqueue
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth0: mtu 1500 qdisc pfifo_fast
link/ether 00:01:4f:00:15:f1 brd ff:ff:ff:ff:ff:ff
Timestamp: Wed Nov 6 20:25:58 2002 33700 us
61.133.4.7 via 211.99.114.65 dev eth0
Timestamp: Wed Nov 6 20:25:59 2002 924124 us
Deleted 61.133.4.7 via 211.99.114.65 dev eth0
[root@nixe0n root]

1.12. rtacct -- 路由范围和策略传播

  在使用OSPF或者BGP协议的路由器上,其路由表可能会很大。如果我们需要对其进行归类或者计算通过每条路由的数据包,就需要保留很多信息。更糟糕的是,如果我们需要区别的不止是数据包的目的地址,还要包括它们的源地址,这个任务就更为复杂了,几乎无法解决。

  对于这个问题,Cisco IOS Release 12.0 Quality of Service SolutionsConfiguration Guide: Configuring QoS Policy Propagation via Border Gateway Protocol提出了一个解决方案,就是把策略从路由协议迁移到转发引擎。基本上,通过BGP的Cisco策略迁移(Cisco Policy Propagation via BGP)就是基于此种方式,它使路由器保留所有和转发引擎关系紧密的RIB(Routing Information Base,路由信息库),以便策略路由规则能够监查所有的路由属性,包括ASPATH的信息和团体(community)字符串。

  而Linux把这分为由用户空间监控维护的路由信息库(Routing Infomation Base,RIB),和内核层的转发信息库(Forwarding Infomation Base,FIB)。

  这是我们的幸运,因为还有另外的解决方案,而这个方案允许更为灵活的策略和更为丰富的语义。

  换句话说,可以在用户空间根据路由的属性把它们归类,例如:BGP路由的ASPATH、团体(community);OSPF路由的标记和它们的范围。而管理员手工添加路由时,也知道它们的属性。按照这个标准划分的集合(我们把它们叫做realm)数量就很少了,因此按照路由的源地址和目的地址进行完全的分类就可以管理了。

  因此,每个路由都可以被分配到一个范围(realm)中。一般这是有路由监控进程作的,不过对于静态路由,也可以使用ip route命令手工处理。

  在某些情况下(例如路由监控进程不理解realm)为了方便,漏掉的realm可以由路由策略规则补齐。

  内核使用如下算法计算每个数据包的源范围(realm)和目的范围(realm):

If route has a realm, destination realm of the packet is set to it.

If rule has a source realm, source realm of the packet is set to it.

If destination realm was not get from route and rule has destination realm, it is also set.

If at least one of realms is still unknown, kernel finds reversed route to the source of the packet.

If source realm is still unknown, get it from reversed route.

If one of realms is still unknown, swap realms of reversed routes and apply step 2 again.

  这个过程完成后,我们就知道了数据包的源范围和目的范围。如果某些还是未知,它就会被设置为0(realm unknown)

  范围(realm)主要还是由TC(Traffic Control)的路由类别(route classifier)使用,我们可以使用路由类别把数据包分配到给不同的流量类(trafffic class),为数据包计数,以及为它们制定调度策略。

  相对于TC,使用realm为进入的数据包计数就简单多了,但这是一个非常有用的应用。内核可以根据realm收集总结数据包统计信息。在用户空间,我们可以使用工具rtacct查看这些信息。例如:

kuznet@amber:~ $ rtacct russia
Realm BytesTo PktsTo BytesFrom PktsFrom
russia 20576778 169176 47080168 153805
kuznet@amber:~ $

  结果表示,这个路由器收到153805个来自russia地区的数据包,并且向russia转发了169176个数据包。russia范围由ASPATH(路径自治系统)在俄罗斯的路由组成。

2. nmcli命令

2.1. 查看网卡状态

[root@localhost ~]# nmcli device status
DEVICE TYPE STATE CONNECTION
ens16 ethernet connected ens16
lo loopback unmanaged --
[root@localhost ~]# nmcli -f state,device device
STATE DEVICE
connected ens16
unmanaged lo
[root@localhost ~]# nmcli -t device
ens16:ethernet:connected:ens16
lo:loopback:unmanaged:
[root@localhost ~]# nmcli -f state,device -t device
connected:ens16
unmanaged:lo
[root@localhost ~]#
# 显示当前配置集名称和关联设备名称
[root@worker pam.d]# nmcli -f NAME,DEVICE,FILENAME connection show
NAME DEVICE FILENAME
ens16 ens16 /etc/sysconfig/network-scripts/ifcfg-ens16
[root@worker pam.d]#

2.2. 激活网卡

[root@worker /]# nmcli connection up eth0

[root@worker /]# nmcli connection down eth0

2.3. 了解 nmcli

  • nmcli 是一个命令行工具,用于控制 NetworkManager 和报告网络状态。
  • 它可以用作 nm-applet 或其他图形客户端的替代品。nmcli 用于创建、显示、编辑、删除、激活和停用网络连接,以及控制和显示网络设备状态。
  • 连接存储在配置文件中
  • 必须运行 NetworkManager 服务才能管理这些文件

2.4. 比较 nm-settings 与 ifcfg-* 指令 (IPv4)

nmcli con mod ifcfg-* file 影响
ipv4.method manual BOOTPROTO=none 静态配置的 IPv4 地址
ipv4.method auto BOOTPROTO=dhcp 将从 DHCPv4 服务器查找配置设置
ipv4.address "192.168.0.10/24" IPADDR=192.168.0.10
PREFIX=24
设置静态 IPv4 地址、网络前缀
ipv4.gateway 192.168.0.1 GATEWAY=192.168.0.1 设置IPV4网关
ipv4.dns 8.8.8.8 DNS1=8.8.8.8 修改 /etc/resolv.conf 以使用此 名称服务器
ipv4.dns-search example.com DOMAIN=example.com 修改 /etc/resolv.conf 以在搜索指令中使用此域
ipv4.ignore-auto-dns true PEERDNS=no 忽略来自 DHCP 服务器的 DNS 服务器信息
connection.autoconnect yes ONBOOT=yes 在启动时自动激活此连接
connection.id eth0 NAME=eth0 此连接的名称
connection.interface-name eth0 DEVICE=eth0 连接绑定到具有此名称的网络接口
802-3-ethernet.mac-address 08:00:27:4b:7a:80 HWADDR=08:00:27:4b:7a:80 连接绑定到具有此 MAC 地址的网络接口
ipv4.never-default no DEFROUTE=yes 切勿将提供的接口网关用作默认网关

2.5. 比较 nm-settings 与 ifcfg-* 指令 (IPv6)

nmcli con mod ifcfg-* file Effect
ipv6.method manual IPV6_AUTOCONF=no IPv6 是静态配置的
ipv6.method auto IPV6_AUTOCONF=yes 将使用来自路由器广告的 SLAAC 配置网络设置。
ipv6.method dhcp IPV6_AUTOCONF=no
DHCPV6C=yes
将使用 DHCPv6 而非 SLAAC 配置网络设置
ipv6 . addresses "2001:db8::a/64 2001:db8::1" IPV6ADDR=2001:db8::a/64 IPV6_DEFAULTGW=2001:db8::1 设置静态 IPv6 地址和网关
ipv6.dns . . . DNS0=. . . 修改 /etc/resolv.conf 以使用此 名称服务器
ipv6.dns-search example.com DOMAIN=example.com 修改 /etc/resolv.conf以在****搜索 指令 中使用该域
ipv6.ignore-auto-dns true IPV6_PEERDNS=no 忽略来自 DHCP 服务器的 DNS 服务器信息
connection.autoconnect yes ONBOOT=YES 开机时自动激活连接
connection.id eth0 NAME=eth0 链接的名称
connection.interface-name eth0 DEVICE=eth0 连接绑定到具有此名称的此网络接口
802-3-ethernet.mac-address . . . HWADDR=. . . 连接绑定到具有此 MAC 地址的网络接口

2.6. Brief list of nmcli commands syntax

Command Purpose
nmcli dev status 显示所有网络接口的网络管理器状态
nmcli con show 列出所有连接
nmcli con show name 列出连接名称的当前设置
nmcli con add con-name name .. 添加一个名为 name 的新连接
nmcli con mod name .. 修改连接名称
nmcli con reload 告诉 networkManager 重新读取配置文件(在手动编辑后很有用)
nmcli con up name 激活连接名称
nmcli dev dis dev 停用并断开网络接口 dev 上的当前连接
nmcli con del name 删除连接名称及其配置文件

2.7. nmcli command examples (cheatsheet)

Below are some of the chosen nmcli command examples

2.7.1. Check if NetworkManager is running

You can use below command to check if NetworkManager is running or not

root@debian:~# nmcli -t -f RUNNING general
running
root@debian:~#

To get a general status

root@debian:~# nmcli general
STATE CONNECTIVITY WIFI-HW WIFI WWAN-HW WWAN
已连接 完全 已启用 已启用 已启用 已启用
root@debian:~#

2.7.2. List all the available device

To view and list all the available devices on your Linux system

root@debian:~# nmcli device list
错误:不能理解参数 "list"。试下换成传递 --help 参数。
root@debian:~# nmcli device status
DEVICE TYPE STATE CONNECTION
ens16 ethernet 已连接 Wired connection 1
docker0 bridge 连接(外部) docker0
lo loopback 未托管 --
root@debian:~# nmcli d s
DEVICE TYPE STATE CONNECTION
ens16 ethernet 已连接 Wired connection 1
docker0 bridge 连接(外部) docker0
lo loopback 未托管 --
root@debian:~#

2.7.3. List all the available connections

To list all the available connections

root@debian:~# nmcli connection show
NAME UUID TYPE DEVICE
Wired connection 1 6acdbab0-c50d-4e9b-866b-743c30c7f199 ethernet ens16
docker0 1b1dadc3-a230-4213-9031-3826281e4591 bridge docker0
root@debian:~#
root@debian:~# nmcli c s
NAME UUID TYPE DEVICE
Wired connection 1 6acdbab0-c50d-4e9b-866b-743c30c7f199 ethernet ens16
docker0 1b1dadc3-a230-4213-9031-3826281e4591 bridge docker0
root@debian:~#

2.7.4. List all the configuration of interface

To view all the configured values (default and custom) of an interface

root@debian:~# nmcli connection show docker0 # docker0是从第三步命令中获取的名称 nmcli connection show
connection.id: docker0
connection.uuid: 1b1dadc3-a230-4213-9031-3826281e4591
connection.stable-id: --
connection.type: bridge
... ...

2.7.5. Check physical network device status

Now the status of all the connection network devices

root@debian:~# nmcli  device status
DEVICE TYPE STATE CONNECTION
ens16 ethernet 已连接 Wired connection 1
docker0 bridge 连接(外部) docker0
lo loopback 未托管 --
root@debian:~#

2.7.6. Change hostname using nmcli

You can ideally change hostname using hostnamectl command, but you can also update hostname using nmcli

To get the current hostname

root@debian:~# nmcli general hostname
debian
root@debian:~# nmcli general hostname swx
root@debian:~# nmcli general hostname
swx
root@debian:~# hostname
swx

2.7.7. Create a new ethernet connection and assign static IP Address

In this example nmcli configures the eth2 interface statically, using the IPv4 address and network prefix 10.10.10.4/24 and default gateway 10.10.10.1, but still auto connects at

startup and saves its configuration into /etc/sysconfig/network-scripts/ifcfg-eth2 file.

root@debian:~# nmcli connection add con-name eth2 type ethernet ifname eth2 ipv4.method manual ipv4.addresses 192.168.0.2/24 ipv4.gateway 192.168.0.1
连接 "eth2" (d54753de-5d73-430a-95de-6ec9a6d9ea57) 已成功添加。
root@debian:~#

2.7.8. Create a new ethernet connection and assign DHCP IP Address

The following command will add a new connection for the interface eth2, which will get IPv4 networking information using DHCP and will autoconnect on startup. The configuration will be

saved in /etc/sysconfig/network-scripts/ifcfg-eth2 because the con-name is eth2

root@debian:/etc/network/interfaces.d# nmcli connection add con-name eth2 type ethernet ifname eth2 ipv4.method auto
Warning: There is another connection with the name 'eth2'. Reference the connection by its uuid '815926c7-4713-41ba-9b90-741bdbecced7'
连接 "eth2" (815926c7-4713-41ba-9b90-741bdbecced7) 已成功添加。
root@debian:/etc/network/interfaces.d#

We can verify the same in the mapped interface configuration file

root@debian:~# egrep BOOTPROTO /etc/sysconfig/network-scripts/ifcfg-eth2
BOOTPROTO=dhcp

2.7.9. Create and configure bond connection (active-backup) with two slave interface

You can create bond connection with multiple slave interface using nmcli.

HINT:

There are 6 types of bonding mode 802.3ad/balance-alb/balance-tlb/broadcast/active-backup/balance-rr/balance-xor

Delete any configuration file which exists for slave interface

root@debian # nmcli connection delete eth1
root@debian # nmcli connection delete eth2

使用 nmcli 添加绑定接口。此命令添加主绑定连接,命名绑定接口mybond0并使用活动备份模式。我已经为MIIUPDELAYDOWNDELAY提供了一些虚拟值。如果您希望使用“ primary=<ifname>”添加主界面

root@debian # nmcli connection add type bond ifname mybond0 bond.options "mode=active-backup,downdelay=5,miimon=100,updelay=10"
已成功添加连接 'bond-mybond0' (a5c76dbe-550b-4abf-8dc0-88184ade369e)。

同样,对于循环绑定,您可以将 bond.options 用作“ downdelay=5,miimon=100,mode=balance-rr,updelay=10

接下来添加mybond0使用 nmcli 的从站。此命令将第一个从站绑定到 eth1 接口

root@debian:~# nmcli con add type ethernet ifname eth1 master mybond0
Connection 'bond-slave-eth1' (54dc4282-b90b-4469-9cbf-82bce042de85) successfully added.

This command binds slave 2 to eth2 interface

\# nmcli con add type ethernet ifname eth2 master mybond0
Connection 'bond-slave-eth2' (41a5b4a6-8e6b-4df9-bff2-b67c5328311a) successfully added.

List the active connections. So we have our bond and slave interface with us.

# nmcli con show
NAME UUID TYPE DEVICE
bond-mybond0 25ce17b2-fffb-4bf1-a5a3-e7593299f303 bond mybond0
bond-slave-eth1 54dc4282-b90b-4469-9cbf-82bce042de85 ethernet eth1
bond-slave-eth2 41a5b4a6-8e6b-4df9-bff2-b67c5328311a ethernet eth2
eth0 d05aee6a-a069-4e55-9fe4-771ca3336db6 ethernet eth0

Here I am setting static IP Address, NetMask, Gateway, DNS and DNS Search to mybond0 using nmcli

# nmcli con mod bond-mybond0 ipv4.method manual ipv4.address 10.10.10.8/24 ipv4.gateway 10.10.10.1 ipv4.dns 8.8.8.8 ipv4.dns-search example.com
  • NOTE:

    • To use DHCP IP, use ipv4.method auto and do not provide any IP Address related details in the above command

Verify your mybond0 configuration file

# egrep 'BOOTPROTO|IPADDR|PREFIX|GATEWAY|DNS' /etc/sysconfig/network-scripts/ifcfg-bond-mybond0
BOOTPROTO=none
IPADDR=10.10.10.8
PREFIX=24
GATEWAY=10.10.10.1
DNS1=8.8.8.8

refresh/reload the network configuration change for mybond0

# nmcli con up bond-mybond0
Connection successfully activated (master waiting for slaves) (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/11)

Verify the bond IP Address

# ip addr show mybond0
7: mybond0: <BROADCAST,MULTICAST,MASTER,UP,LOWER\_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 08:00:27:0d:ca:0c brd ff:ff:ff:ff:ff:ff
inet 10.10.10.8/24 brd 10.10.10.255 scope global noprefixroute mybond0
valid\_lft forever preferred\_lft forever

Verify the list of available connection

# nmcli con show --active
NAME UUID TYPE DEVICE
eth1 01fa0bf4-b6bd-484f-a9a3-2b10ff701dcd ethernet eth1
eth0 2e9f0cdd-ea2f-4b63-b146-3b9a897c9e45 ethernet eth0

2.7.10. Create and configure Network Bridge

2.7.10.1. What is Network Bridge?

  • 网桥将多个物理接口的资源整合到一个虚拟接口中。
  • 网桥类似于虚拟 LAN 接口,但又有点相反。
  • 网桥将网络适配器连接到一个子网,并为所有网桥客户端提供一个统一的网络。
  • 例如,如果您有一个 16 端口非托管交换机并且它已满并且您需要将其他客户端添加到同一网络,那么您可以将网络适配器添加到您的 pfSense 安装然后创建一个网桥以加入一个新的满交换机客户端到同一个网络。

The basic format of a nmcli command is as follows:

nmcli \[OPTIONS\] OBJECT { COMMAND | help }

where OBJECT can be one of the following options: general, networking, radio, connection, device, agent, and monitor. You can use any prefix of these options in your commands. For example, nmcli con help, nmcli c help, nmcli connection help generate the same output.

2.7.10.2. Check if Bridging Kernel Module is installed

在 CentOS/RHEL 7/8 中,默认加载桥接模块。如有必要,您可以通过以 root 身份发出以下命令来确保模块已加载:

# lsmod | grep bridge
bridge 136173 0

如果未加载模块,则可以使用安装模块

# modprobe --first-time bridge

To display information about the module, issue the following command:

# modinfo bridge

2.7.10.3. 在 RHEL/CentOS 7 中使用 nmcli 配置网桥

使用 nmcli 创建和配置网桥的第一步是创建实际的网桥接口,然后我们将物理设备分配给网桥。

2.7.10.4. Create bridge interface

To create a bridge, named bridge-app-br0, issue a command as follows as root:

\[root@centos-7 ~\]# nmcli connection add type bridge ifname app-br0
Connection 'bridge-app-br0' (39b1a2d0-23ab-4c9d-9cb5-a2ec32a21075) successfully added.
  • " bridge" 前缀将自动添加到连接名称中。如果未指定接口名称,名称将默认为bridgebridge-1bridge-2等。
2.7.10.4.1. Create slave interface for bridge

要使用 nmcli 创建和配置网桥,我们还需要添加或启用接口。要将第一个接口(例如 eno51)从属到网桥 app-br0,请发出如下命令:

[root@centos-7 ~\]# nmcli con add type ethernet con-name br-slave-1 ifname eno51 master app-br0
Connection 'br-slave-1' (5dd3f7d7-e618-4850-b2d6-29c889d19937) successfully added.

Similarly to add second slave interface to bridge app-br0

[root@centos-7 ~\]# nmcli con add type ethernet con-name br-slave-2 ifname eno52 master app-br0
Connection 'br-slave-2' (092d51b9-0807-45ea-b0bb-9cf0da9995b5) successfully added.
2.7.10.4.2. Assign static or dhcp IP and configure network bridge using nmcli

网桥接口有多种可配置选项,您可以使用 nmcli 对其进行修改。例如,默认情况下启用生成树协议 (STP)。使用的值来自 IEEE 802.1D-1998 标准。要为此网桥禁用 STP,请以 root 身份发出如下命令:

[root@centos-7 ~\]# nmcli con modify bridge-app-br0 bridge.stp no

To view the bridge settings, issue the following command:

[root@centos-7 ~\]# nmcli -f bridge con show bridge-app-br0
bridge.mac-address: --
bridge.stp: no
bridge.priority: 32768
bridge.forward-delay: 15
bridge.hello-time: 2
bridge.max-age: 20
bridge.ageing-time: 300
bridge.multicast-snooping: yes

Syntax to assign DHCP IP using nmcli

nmcli connection add type ethernet ifname  con-name  ipv4.method auto

Syntax to assign static IP using nmcli

nmcli connection add type ethernet ifname  con-name  ipv4.method manual ipv4.address / ipv4.gateway

To setup ethernet, configure following command options:

  • con-name - 连接名称是连接配置文件的名称,不应与表示设备的接口名称混淆
  • ifname - 接口名称
  • type - 允许的值为:ethernet、wifi、wimax、gsm、cdma、infiniband、bluetooth、vlan、bond、bond-slave
  • ipv4.method - 具体说明接口配置是通过 dhcp(自动)还是静态(手动)。
  • ipv4.address - CIDR 表示中的 IPv4 地址
  • ipv4.gateway - IPv4 网关地址
  • ipv6.address - IPv6 地址(如果启用了 IPv6,则可选)
[root@centos-7 ~\]# nmcli con modify bridge-app-br0 ipv4.method manual ipv4.address "192.151.12.6/26" ipv4.gateway "192.151.12.62"  ipv4.dns 8.8.8.8 ipv4.dns-search example.com

Here I have assigned a static IP Address of 192.151.12.6 with a Netmask prefix of 26, gateway of 192.151.12.62 and DNS server IP as 8.8.8.8 to the network bridge app-br0 interface.

To view the connections, issue the following command:

[root@centos-7 ~\]# nmcli con show
NAME UUID TYPE DEVICE
Ethernet connection 2 b9bcd5b2-0342-4c35-9800-0c9436d2fe60 802-3-ethernet eno49
br-slave-1 5dd3f7d7-e618-4850-b2d6-29c889d19937 802-3-ethernet eno51
br-slave-2 092d51b9-0807-45ea-b0bb-9cf0da9995b5 802-3-ethernet eno52
bridge-app-br0 39b1a2d0-23ab-4c9d-9cb5-a2ec32a21075 bridge app-br0
eno50 5215c9b8-6f7d-4caa-9792-81dc099f41fc 802-3-ethernet eno50
eno55 0d918152-fdf6-4b87-9ac0-cb91fbb621c7 802-3-ethernet eno55
virbr0 b9030451-b81a-4727-86f6-6f2fbe9f7118 bridge virbr0
virbr1 12996be2-6d66-423a-8882-1533633a4a7e bridge virbr1
eno49 2ff6c44e-f016-4359-8eaf-121071bc612d 802-3-ethernet --
eno51 a9031c75-f1f4-481e-bdc3-942b89a554c1 802-3-ethernet --

如您所见,新创建的网桥和从属接口在可用连接列表中可见。

brctl用于设置、维护和检查 linux 内核中的以太网桥配置。该命令brctl show显示以太网桥的所有当前实例

[root@centos-7 ~\]# brctl show
bridge name bridge id STP enabled interfaces
app-br0 8000.9cdc7177ef51 no eno51
eno52
2.7.10.4.3. Verify network bridge configuration

现在我们已经完成了在 RHEL/CentOS 7 中使用 nmcli 创建和配置网桥的步骤。为了验证我们的配置,我们可以检查是否为 app-br0 分配了 IP 地址。

[root@centos-7 ~\]# ip addr show dev app-br0
23: app-br0: <BROADCAST,MULTICAST,UP,LOWER\_UP> mtu 1500 qdisc noqueue state UP qlen 1000
link/ether 9c:dc:71:77:ef:51 brd ff:ff:ff:ff:ff:ff
inet 192.151.12.6/26 brd 192.151.12.63 scope global app-br0
valid\_lft forever preferred\_lft forever
inet6 fe80::f479:8a1:4dd0:1df0/64 scope link
valid\_lft forever preferred\_lft forever

Next try to ping the gateway of the bridge interface and make sure it is reachable

[root@centos-7 ~\]# ping 192.151.12.62
PING 192.151.12.62 (192.151.12.62) 56(84) bytes of data.
64 bytes from 192.151.12.62: icmp\_seq=1 ttl=64 time=19.0 ms
64 bytes from 192.151.12.62: icmp\_seq=2 ttl=64 time=0.706 ms
64 bytes from 192.151.12.62: icmp\_seq=3 ttl=64 time=19.6 ms
^C
--- 192.151.12.62 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2001ms
rtt min/avg/max/mdev = 0.706/13.134/19.671/8.792 ms

Since nmcli makes persistent changes to the network configuration, you can also verify the network configuration files created by nmcli. The bridge interface configuration file is "ifcfg-bridge-app-br0"

[root@centos-7 ~\]# cd /etc/sysconfig/network-scripts/
[root@centos-7 network-scripts\]# cat ifcfg-bridge-app-br0
DEVICE=app-br0
STP=no
TYPE=Bridge
PROXY\_METHOD=none
BROWSER\_ONLY=no
BOOTPROTO=none
DEFROUTE=yes
IPV4\_FAILURE\_FATAL=no
IPV6INIT=yes
IPV6\_AUTOCONF=yes
IPV6\_DEFROUTE=yes
IPV6\_FAILURE\_FATAL=no
IPV6\_ADDR\_GEN\_MODE=stable-privacy
NAME=bridge-app-br0
UUID=39b1a2d0-23ab-4c9d-9cb5-a2ec32a21075
ONBOOT=yes
IPADDR=192.151.12.6
PREFIX=26
GATEWAY=192.151.12.62
DNS1=8.8.8.8
DOMAIN=example.com

Similarly verify the configuration file of the slave interface of network bridge.

[root@centos-7 ~\]# cat ifcfg-br-slave-1
TYPE=Ethernet
NAME=br-slave-1
UUID=5dd3f7d7-e618-4850-b2d6-29c889d19937
DEVICE=eno51
ONBOOT=yes
BRIDGE=app-br0 [root@centos-7 ~\]# cat ifcfg-br-slave-2
TYPE=Ethernet
NAME=br-slave-2
UUID=092d51b9-0807-45ea-b0bb-9cf0da9995b5
DEVICE=eno52
ONBOOT=yes
BRIDGE=app-br0

Check your default gateway

[root@centos-7 ~\]# ip route
default via 192.151.12.62 dev app-bridge proto static metric 426
2.7.10.4.4. Restart Network Manager Connections

To reload the connection interface

[root@centos-7 ~\]# nmcli connection reload

You can do much more than create and configure network bridge nmcli, for the complete list of options follow the man page of nmcli tool.

2.8. Create and configure Network Teaming

在本文中,我将通过各种示例分享使用 nmcli (NetworkManager)(在 RHEL 和 CentOS 7 和 8 上验证)配置 NIC 绑定 或网络绑定的分步指南。

Red Hat Enterprise Linux 7使用一个小型内核驱动程序和一个用户空间守护程序实现网络分组teamd, . 内核高效地处理网络数据包并teamd处理逻辑和接口处理。称为runners的软件实现负载平衡和主动备份逻辑,例如 roundrobin。以下跑步者可用于 teamd。

  • broadcast: 一个简单的运行器,它从所有端口传输每个数据包。
  • round robin: 一个简单的运行器,它以循环法从每个端口传输数据包。
  • activebackup: 这是一个故障转移运行器,它监视链接更改并选择一个活动端口进行数据传输。
  • loadbalance: 这个运行器监控流量并使用哈希函数在选择数据包传输端口时尝试达到完美的平衡。
  • lacp: 实现 802.3ad 链路聚合控制协议。可以使用与负载平衡运行器相同的传输端口选择可能性。

The following runners are available to teamd

Runner Explanation
broadcast 一个简单的运行器,它从所有端口传输搜索数据包
roundrobin 一个简单的运行器,它以循环方式从每个端口传输数据包。
activebackup 这是一个故障转移运行器,它监视链接更改并选择一个活动端口进行数据传输
loadbalance 该运行器监控流量并使用哈希函数在选择数据包传输端口时尝试达到完美的平衡。
lacp 实施 802.3ad LinkAggregation 控制协议。可以使用与负载平衡运行器相同的传输端口选择可能性。

All network interaction is done through a team interface, composed of multiple network port interfaces. When controlling teamed port interfaces using NetworkManager, and especially when fault finding, keep the following in mind:

  • 启动网络组接口不会自动启动端口接口。
  • 启动端口接口总是会启动成组接口。
  • 停止组合接口也会停止端口接口。
  • 没有端口扫描的成组接口启动静态 IP 连接。
  • 没有端口的组在启动 DHCP 连接时等待端口。

2.8.1. Configure NIC teaming

The [nmcli](https://www.golinuxcloud.com/nmcli-command-examples-cheatsheet-centos-rhel/) command can be used to create and manage team and port interfaces. The following four steps are used to create, activate and configure NIC teaming interface:

  1. Create the team interface.
  2. Determine the IPv4 and/or IPv6 attributes of the team interface.
  3. Assign the port interfaces.
  4. Bring the team and port interfaces up/down.

2.8.2. Create team interface

Use nmcli command to create a connection for the network team interface, with the following syntax:

Syntax:

nmcli con add type team con-name CNAME ifname INAME \[config JSON\]

where CNAME will be the name used to refer to the connection, INAME will be the interface name, and JSON specifies the runner to be used.

JSON has the following syntax:

'{"runner":{"name":"METHOD"}}'

where METHOD is one of the following: broadcast, round robin, activebackup, load balance, or lacp.

2.8.3. Create the team interface connection profile with nmcli

以下命令将创建一个名为 的连接配置文件myteam,它将提供一个名为 的团队设备team0。将使用组队模式activebackup并ethtool使用链路监控:

With static IP addressing:

# nmcli connection add type team con-name myteam ifname team0 config '{"runner": {"name": "activebackup"}, "link\_watch": {"name": "ethtool"}}' ip4 192.151.27.17/32 gw4 192.151.27.62
Connection 'myteam' (6d3af1ac-dc3f-49a1-9c20-f7eed14636b1) successfully added.

My sample configuration file after executing the above command

# cat ifcfg-myteam
DEVICE=team0
TEAM\_CONFIG="{"runner": {"name": "activebackup"}, "link\_watch": {"name": "ethtool"}}"
BOOTPROTO=none
IPADDR=192.151.27.17
PREFIX=32
GATEWAY=192.151.27.62
DEFROUTE=yes
IPV4\_FAILURE\_FATAL=no
IPV6INIT=yes
IPV6\_AUTOCONF=yes
IPV6\_DEFROUTE=yes
IPV6\_FAILURE\_FATAL=no
IPV6\_ADDR\_GEN\_MODE=stable-privacy
NAME=myteam
UUID=6d3af1ac-dc3f-49a1-9c20-f7eed14636b1
ONBOOT=yes
DEVICETYPE=Team

With DHCP addressing:

# nmcli connection add type team con-name myteam ifname team0 config '{"runner": {"name": "activebackup"}, "link\_watch": {"name": "ethtool"}}'

2.8.4. Assign the port interfaces

Use the nmcli command to create each of the port interfaces with the following syntax:

nmcli con add type team-slave con-name CNAME ifname INAME master TEAM

其中CNAME将是用于引用端口INAME的名称,是现有接口的名称,并TEAM指定网络组接口的连接名称。

Create a profile for each team port (slave)

主参数必须引用团队设备名称,而不是团队配置文件名称。在下面的示例中,接口eno53和eno54被添加到team0:

# nmcli connection add type team-slave con-name myteam-port1 ifname eno53 master team0
Connection 'myteam-port1' (02d469f7-5bf1-4ea6-82ea-9e0007d19afe) successfully added. # 3. nmcli connection add type team-slave con-name myteam-port2 ifname eno54 master team0
Connection 'myteam-port2' (386a0f1a-b017-462d-8f77-786d0d661217) successfully added.

My sample configuration file for the slaves

# cat ifcfg-myteam-port1
NAME=myteam-port1
UUID=02d469f7-5bf1-4ea6-82ea-9e0007d19afe
DEVICE=eno53
ONBOOT=yes
TEAM\_MASTER=team0
DEVICETYPE=TeamPort
# cat ifcfg-myteam-port2
NAME=myteam-port2
UUID=386a0f1a-b017-462d-8f77-786d0d661217
DEVICE=eno54
ONBOOT=yes
TEAM\_MASTER=team0
DEVICETYPE=TeamPort

验证您的更改

[root@openstack ~\]# ifconfig team0
team0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.151.27.17 netmask 255.255.255.255 broadcast 192.151.27.17
inet6 fe80::2084:8dda:d77f:9e61 prefixlen 64 scopeid 0x20
ether d2:06:75:eb:a5:2e txqueuelen 1000 (Ethernet)
RX packets 3 bytes 214 (214.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 115 bytes 25305 (24.7 KiB)
TX errors 0 dropped 4 overruns 0 carrier 0 collisions 0

Open another terminal and ping the local network gateway through the team0 interface. let this ping continue to run as you perform the following steps

# ping -I team0 192.151.27.62
PING 192.151.27.62 (192.151.27.62) from 192.151.27.17 team0: 56(84) bytes of data.
64 bytes from 192.151.27.62: icmp\_seq=1 ttl=64 time=2.47 ms
64 bytes from 192.151.27.62: icmp\_seq=2 ttl=64 time=3.05 ms
^C
--- 192.151.27.62 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 2.475/2.764/3.054/0.294 ms

2.8.5. Bring the team and port interfaces up/down

nmcli command can also be used to manage the connections for the team and port interfaces with the following syntax:

nmcli dev dis INAME
nmcli con up CNAME

INAME是要管理的组或端口接口的设备名称。CNAME是该接口CNAME的连接名称 其中是要管理的组或端口接口的连接名称。

确认团队正在按预期使用该teamdctl程序。至少,确保正在使用正确的跑步者,否则连接可能无法正常工作:

# teamdctl team0 state
setup:
runner: activebackup
ports:
eno53
link watches:
link summary: up
instance\[link\_watch\_0\]:
name: ethtool
link: up
down count: 0
eno54
link watches:
link summary: up
instance\[link\_watch\_0\]:
name: ethtool
link: up
down count: 0
runner:
active port: eno53

Open a new terminal and let us bring down the active interface eno53 in the team0 and check the impact

# nmcli dev dis eno53
Device 'eno53' successfully disconnected.
# ping -I team0 192.151.27.62
PING 192.151.27.62 (192.151.27.62) from 192.151.27.17 team0: 56(84) bytes of data.
64 bytes from 192.151.27.62: icmp_seq=1 ttl=64 time=7.44 ms
64 bytes from 192.151.27.62: icmp_seq=2 ttl=64 time=9.84 ms
64 bytes from 192.151.27.62: icmp_seq=3 ttl=64 time=4.36 ms
64 bytes from 192.151.27.62: icmp_seq=63 ttl=64 time=77.4 ms
^C
--- 192.151.27.62 ping statistics ---
63 packets transmitted, 63 received, 0% packet loss, time 62092ms
rtt min/avg/max/mdev = 0.586/14.202/125.945/18.422 ms

But there is no impact to my active connection and the active port changes to eno54

# teamdctl team0 state
setup:
runner: activebackup
ports:
eno54
link watches:
link summary: up
instance\[link\_watch\_0\]:
name: ethtool
link: up
down count: 0
runner:
active port: eno54

恢复原来的端口接口并关闭另一个端口接口。但在此之前,让我们获取连接名称port1

# nmcli con show
NAME UUID TYPE DEVICE
myteam 6d3af1ac-dc3f-49a1-9c20-f7eed14636b1 team team0
myteam-port2 386a0f1a-b017-462d-8f77-786d0d661217 802-3-ethernet eno54
myteam-port1 02d469f7-5bf1-4ea6-82ea-9e0007d19afe 802-3-ethernet \--

So from the above output we know myteam-port1 is inactive so let it bring back UP.

# nmcli con up myteam-port1
Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/94) # 3. nmcli dev dis eno54
Device 'eno54' successfully disconnected.

And now as wee see the active port is back to eno53

# teamdctl team0 state
setup:
runner: activebackup
ports:
eno53
link watches:
link summary: up
instance\[link\_watch\_0\]:
name: ethtool
link: up
down count: 0
runner:
active port: eno53

再次注意,ping 继续到达本地网关。

2.9. Reload connection using nmcli (restart)

从磁盘重新加载所有连接文件。默认情况下,NetworkManager 不监视对连接文件的更改。因此,您需要使用此命令来告诉 NetworkManager 在对它们进行更改时从磁盘重新读取连接配置文件。

root@debian:~# nmcli connection reload
root@debian:~#

2.9.

2.10. Interactively add/edit a connection

You can use nmcli con edit to Edit an existing connection or add a new one, using an interactive editor. In the below example we will edit eth1's IP Address

root@debian:~# nmcli connection edit eth2

===| nmcli 交互式连接编辑器 |===

正在编辑已有的连接 "802-3-ethernet":"eth2"

输入 "help" 或 "?" 查看可用的命令。
输入 "print" 来显示所有的连接属性。
输入 "describe [<设置>.<属性>]" 来获得详细的属性描述。 您可编辑下列设置:connection, 802-3-ethernet (ethernet), 802-1x, dcb, sriov, ethtool, match, ipv4, ipv6, hostname, tc, proxy
nmcli> print
===============================================================================
连接配置集详情 (eth2)
===============================================================================
connection.id: eth2
connection.uuid: d54753de-5d73-430a-95de-6ec9a6d9ea57
connection.stable-id: --
connection.type: 802-3-ethernet
connection.interface-name: eth2
connection.autoconnect: 是
connection.autoconnect-priority: 0
connection.autoconnect-retries: -1 (default)
connection.multi-connect: 0(default)
connection.auth-retries: -1
connection.timestamp: 0
connection.read-only: 否
connection.permissions: --
connection.zone: --
connection.master: --
connection.slave-type: --
connection.autoconnect-slaves: -1(default)
connection.secondaries: --
connection.gateway-ping-timeout: 0
connection.metered: 未知
connection.lldp: default
connection.mdns: -1(default)
connection.llmnr: -1(default)
connection.wait-device-timeout: -1
-------------------------------------------------------------------------------
802-3-ethernet.port: --
802-3-ethernet.speed: 0
802-3-ethernet.duplex: --
802-3-ethernet.auto-negotiate: 否
802-3-ethernet.mac-address: --
802-3-ethernet.cloned-mac-address: --
802-3-ethernet.generate-mac-address-mask:--
802-3-ethernet.mac-address-blacklist: --
802-3-ethernet.mtu: 自动
802-3-ethernet.s390-subchannels: --
802-3-ethernet.s390-nettype: --
802-3-ethernet.s390-options: --
802-3-ethernet.wake-on-lan: default
802-3-ethernet.wake-on-lan-password: --
-------------------------------------------------------------------------------
ipv4.method: manual
ipv4.dns: --
ipv4.dns-search: --
ipv4.dns-options: --
ipv4.dns-priority: 0
ipv4.addresses: 192.168.0.2/24
ipv4.gateway: 192.168.0.1
ipv4.routes: --
ipv4.route-metric: -1
ipv4.route-table: 0 (unspec)
ipv4.routing-rules: --
ipv4.ignore-auto-routes: 否
ipv4.ignore-auto-dns: 否
ipv4.dhcp-client-id: --
ipv4.dhcp-iaid: --
ipv4.dhcp-timeout: 0 (default)
ipv4.dhcp-send-hostname: 是
ipv4.dhcp-hostname: --
ipv4.dhcp-fqdn: --
ipv4.dhcp-hostname-flags: 0x0(none)
ipv4.never-default: 否
ipv4.may-fail: 是
ipv4.dad-timeout: -1 (default)
ipv4.dhcp-vendor-class-identifier: --
ipv4.dhcp-reject-servers: --
-------------------------------------------------------------------------------
ipv6.method: auto
ipv6.dns: --
ipv6.dns-search: --
ipv6.dns-options: --
ipv6.dns-priority: 0
ipv6.addresses: --
ipv6.gateway: --
ipv6.routes: --
ipv6.route-metric: -1
ipv6.route-table: 0 (unspec)
ipv6.routing-rules: --
ipv6.ignore-auto-routes: 否
ipv6.ignore-auto-dns: 否
ipv6.never-default: 否
ipv6.may-fail: 是
ipv6.ip6-privacy: -1(unknown)
ipv6.addr-gen-mode: stable-privacy
ipv6.ra-timeout: 0 (default)
ipv6.dhcp-duid: --
ipv6.dhcp-iaid: --
ipv6.dhcp-timeout: 0 (default)
ipv6.dhcp-send-hostname: 是
ipv6.dhcp-hostname: --
ipv6.dhcp-hostname-flags: 0x0(none)
ipv6.token: --
-------------------------------------------------------------------------------
proxy.method: none
proxy.browser-only: 否
proxy.pac-url: --
proxy.pac-script: --
-------------------------------------------------------------------------------
nmcli> help
------------------------------------------------------------------------------
---[ 主菜单 ]---
goto [<设置> | <属性>] :: 转到设置或属性
remove <设置>[.<属性>] | <属性> :: 移除设置或重置属性值
set [<设置>.<属性> <值>] :: 设置属性值
describe [<设置>.<属性>] :: 描述属性
print [all | <设置>[.<属性>]] :: 输出连接
verify [all | fix] :: 验证连接
save [persistent|temporary] :: 保存连接
activate [<接口名>] [/<ap>|<nsp>] :: 激活连接
back :: 转到上层(返回)
help/? [<命令>] :: 输出此帮助
nmcli <配置选项> <值> :: nmcli configuration
quit :: 退出 nmcli
------------------------------------------------------------------------------
nmcli> print ipv4.address
ipv4.addresses: 192.168.0.2/24
nmcli> remove ipv4.address "192.168.0.2/24"
nmcli> print ipv4.address
ipv4.addresses: (null)
nmcli> set ipv4.address "192.168.1.2/24"
错误:设置 "addresses" 属性失败:无效的前缀 '24"'; 只允许 <1-32>
nmcli> set ipv4.address 192.168.1.2/24
您是否也要将 "ipv4.method" 设为 "manual"?[yes]: yes
nmcli> print ipv4.address
ipv4.addresses: 192.168.1.2/24
nmcli> verify
验证连接:OK
nmcli> save
成功地更新了连接 "eth2" (d54753de-5d73-430a-95de-6ec9a6d9ea57)。
nmcli> quit
root@debian:~#

Now verify your changes in eth1's configuration file

# egrep IPADDR /etc/sysconfig/network-scripts/ifcfg-eth1
IPADDR= 192.168.1.2

2.11. Change ethernet connection BOOTPROTO from DHCP to Static

Now to change ethernet connection BOOTPROTO from DHCP to static using nmcli, we must modify ipv4.method directive to use manual

# nmcli con mod eth2 ipv4.method manual ipv4.address 10.10.10.4/24 ipv4.gateway 10.10.10.1

Now verify the network configuration file for eth2

# egrep 'BOOTPROTO|IPADDR|PREFIX|GATEWAY' /etc/sysconfig/network-scripts/ifcfg-eth2
BOOTPROTO=none
IPADDR=10.10.10.4
PREFIX=24
GATEWAY=10.10.10.1

2.12. Change ethernet connection BOOTPROTO from Static to DHCP

Similarly to change ethernet connection BOOTPROTO from static to DHCP using nmcli, we must modify ipv4.method directive to use auto

# nmcli con mod eth2 ipv4.method auto

Now verify the eth2 network configuration file

# egrep 'BOOTPROTO|IPADDR|PREFIX|GATEWAY' /etc/sysconfig/network-scripts/ifcfg-eth2
BOOTPROTO=dhcp
IPADDR=10.10.10.4
PREFIX=24
GATEWAY=10.10.10.1

如您所见,我们仍然有 IPADDR 和先前命令中的其他变量,但它们被认为是空的,因为您可以看到我的 DHCP 已分配10.10.10.5给 eth2

# ip addr show dev eth2
4: eth2: <BROADCAST,MULTICAST,UP,LOWER\_UP> mtu 1500 qdisc pfifo\_fast state UP group default qlen 1000
link/ether 08:00:27:a8:19:0a brd ff:ff:ff:ff:ff:ff
inet 10.10.10.5/24 brd 10.10.10.255 scope global noprefixroute dynamic eth2
valid\_lft 1068sec preferred\_lft 1068sec
inet6 fe80::b81f:a58b:43f1:b8d3/64 scope link noprefixroute
valid\_lft forever preferred\_lft forever

2.13. Change ONBOOT directive using nmcli

接口配置文件中默认ONBOOT为yes。所以要禁用 ONBOOT 我们必须修改connection.autoconnect指令使用nmcli

在更改此指令之前验证 ONBOOT 值

# egrep 'ONBOOT' /etc/sysconfig/network-scripts/ifcfg-eth2
ONBOOT=yes

更改 ONBOOT 指令,使用 nmcli 禁用 ONBOOT

# nmcli con mod eth2 connection.autoconnect no

重新验证 eth2 的 ONBOOT 指令

# egrep 'ONBOOT' /etc/sysconfig/network-scripts/ifcfg-eth2
ONBOOT=no

2.14. Change DEFROUTE directive (Never use this network for default route)

默认情况下,我们为任何以太网连接添加的任何网关也将被视为默认网关,以关闭此指令ipv4.never-default使用nmcli

DEFROUTE在我们对 eth2 配置文件中的任何更改验证指令之前

# egrep '^DEFROUTE' /etc/sysconfig/network-scripts/ifcfg-eth2
DEFROUTE=yes

所以默认情况下这个指令是开启的,我们将禁用 eth2 的默认网关选项。要关闭此指令,我们必须选择ipv4.never-defaultas " yes"

# nmcli con mod eth2 ipv4.never-default yes

接下来验证 eth2 的 DEFROUTE 指令

# egrep '^DEFROUTE' /etc/sysconfig/network-scripts/ifcfg-eth2
DEFROUTE=no

2.15. Disable IPv6 Address for ethernet connection (IPV6INIT)

默认情况下IPV6INIT,任何以太网连接类型都启用 IPv4 和 IPv6 连接类型 ( )。仅使用 IPv4 并使用禁用 IPv6nmcli

验证 eth2 的 IPv6 连接类型的现有状态

# egrep  'IPV6INIT' /etc/sysconfig/network-scripts/ifcfg-eth2
IPV6INIT=yes

ipv6.method所以这是启用的,我们将使用带有 nmcli 的指令禁用 IPv6 连接类型

# nmcli con mod eth2 ipv6.method ignore
  • HINT:

    • 支持的输入参数为ipv6.methodignore、auto、dhcp、link-local、manual、shared。您可以使用相同的选项启用/禁用 IPv4ipv4.method

现在重新验证 eth2 配置文件中的 IPV6INIT 指令

# egrep  'IPV6INIT' /etc/sysconfig/network-scripts/ifcfg-eth2
IPV6INIT=no

2.16. Change “Automatically Connect” Directive

By default any ethernet connection will be allowed to automatically connect, you can modify this using

# nmcli con mod eth2 connection.autoconnect no

2.17. Add or Modify DNS to existing connection

You can use ipv4.dns to add DNS server to an new connection or modify any existing connection using nmcli.

Currently there are no DNS server IP provided for eth1

# egrep DNS /etc/sysconfig/network-scripts/ifcfg-eth1

Next modify connection to add DNS Server IP Address

# nmcli con mod eth1 ipv4.dns 8.8.8.8

Verify the eth1 config file

[root@rhel-8 ~\]# egrep DNS /etc/sysconfig/network-scripts/ifcfg-eth1
DNS1=8.8.8.8

2.18. Append single/multiple DNS Server to connection

使用+prefix withipv4.dns将新的 DNS IP 地址附加到使用 nmcli 的现有连接。在前面的示例中,我们添加了 8.8.8.8 作为我的 eth1 的 DNS 服务器。现在我们将 8.2.2.2 附加到同一个连接

# nmcli con mod eth1 +ipv4.dns 8.2.2.2

验证eth1配置文件

# egrep DNS /etc/sysconfig/network-scripts/ifcfg-eth1
DNS1=8.8.8.8
DNS2=8.2.2.2
  • 您还可以附加来自其他多值(容器)属性的单个或多个值,如 ipv4.dns、ipv4.addresses、bond.options 等

2.19. Remove single/multiple DNS Server from connection

据了解,+我们附加了 so - 我们从接口连接中删除了 DNS 服务器的单个/多个条目nmcli

# nmcli con mod eth1 -ipv4.dns 8.2.2.2,8.8.8.8

Verify the eth1 configuration file

# egrep DNS /etc/sysconfig/network-scripts/ifcfg-eth1
  • 您还可以从其他多值(容器)属性(如 ipv4.dns、ipv4.addresses、bond.options 等)中删除单个或多个值

2.20. Display selected fields with values of connection

您可以使用“”列出连接的所有配置值,nmcli con show <ifname>但这会为您提供一长串详细信息,实际上您还可以获取单个连接提供的指令的选定值

获取eth1的IPv4地址

root@debian:~#  nmcli -g ip4.address connection show Wired\ connection\ 1
11.160.xxx.xxx/25

You can use -g to print values from specific fields using nmcli

# nmcli -g ip4.address,ipv4.dns connection show eth1
8.8.8.8,8.2.2.2
10.10.10.4/24

但正如您所见,我们没有得到字段到值的映射。您可以使用-fnmcli 指定应打印哪些字段(列名)。特定命令的有效字段名称不同。通过向选项提供无效值来列出可用字段--fields

# nmcli -f ipv4.dns,ipv4.addresses,ipv4.gateway con show eth1
ipv4.dns: 8.8.8.8,8.2.2.2
ipv4.addresses: 10.10.10.4/24
ipv4.gateway: 10.10.10.1

您可以选择这些字段:ipv4.method、ipv4.dns、ipv4.dns-search、ipv4.dns-options、ipv4.dns-priority、ipv4.addresses、ipv4.gateway、ipv4.routes、ipv4.route-metric、 ipv4.route-table,ipv4.ignore-auto-routes,ipv4.ignore-auto-dns,ipv4.dhcp-client-id,ipv4.dhcp-timeout,ipv4.dhcp-send-hostname,ipv4.dhcp-hostname, ipv4.dhcp-fqdn,ipv4.never-default,ipv4.may-fail,ipv4.dad-timeout

2.21. Monitor connection and device activity

使用 nmcli monitor 可以观察 NetworkManager 活动。监视连接状态、设备或连接配置文件的变化。在这个例子中,我们将在一个终端中执行nmcli monitoreth1,在另一个终端中,我们将对 eth1 连接进行一些修改

# nmcli con mod eth1 ipv4.method manual ipv4.address 10.10.10.4/24

As you see, after the modification, the monitor command gives below output

# nmcli con monitor eth1
eth1: connection profile changed

2.22. Activate a connection

Just opposite to what we used above, we will use nmcli con up

# nmcli con up eth2
Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/23)

Verify the list of available connection

# nmcli con show --active
NAME UUID TYPE DEVICE
eth1 01fa0bf4-b6bd-484f-a9a3-2b10ff701dcd ethernet eth1
eth0 2e9f0cdd-ea2f-4b63-b146-3b9a897c9e45 ethernet eth0
eth2 186053d4-9369-4a4e-87b8-d1f9a419f985 ethernet eth2

2.23. De-activate a connection

Deactivate a connection from a device without preventing the device from further auto-activation using nmcli con down <ifname>. Multiple connections can be passed to the command.

# nmcli connection down eth1
Connection 'eth1' successfully deactivated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/32)

Verify the list of active connections

# nmcli con show --active
NAME UUID TYPE DEVICE
eth0 d05aee6a-a069-4e55-9fe4-771ca3336db6 ethernet eth0

NOTE:

If you are connected to your server using this interface then your connection would close once the connection is de-activated

2.24. Delete connection

lastly in nmcli command examples, you can delete all type of available connection using "nmcli con del <ifname>"

# nmcli con del bond-mybond0 bond-slave-eth1 bond-slave-eth2
Connection 'bond-mybond0' (25ce17b2-fffb-4bf1-a5a3-e7593299f303) successfully deleted.
Connection 'bond-slave-eth1' (54dc4282-b90b-4469-9cbf-82bce042de85) successfully deleted.
Connection 'bond-slave-eth2' (41a5b4a6-8e6b-4df9-bff2-b67c5328311a) successfully deleted.
root@debian:~# nmcli connection  show
NAME UUID TYPE DEVICE
Wired connection 1 6acdbab0-c50d-4e9b-866b-743c30c7f199 ethernet ens16
docker0 1b1dadc3-a230-4213-9031-3826281e4591 bridge docker0
eth2 d54753de-5d73-430a-95de-6ec9a6d9ea57 ethernet --
eth2 815926c7-4713-41ba-9b90-741bdbecced7 ethernet --
root@debian:~# nmcli connection delete eth2
成功删除连接 "eth2" (d54753de-5d73-430a-95de-6ec9a6d9ea57)。
成功删除连接 "eth2" (815926c7-4713-41ba-9b90-741bdbecced7)。
root@debian:~# nmcli connection show
NAME UUID TYPE DEVICE
Wired connection 1 6acdbab0-c50d-4e9b-866b-743c30c7f199 ethernet ens16
docker0 1b1dadc3-a230-4213-9031-3826281e4591 bridge docker0
root@debian:~#

3. traceroute命令

3.1. 追踪TCP端口

traceroute -T -O info -p 5630 11.11.61.60

4. lsof命令

4.1. -i 参数

4.1.1. -i 显示所有链接

root@debian:~# lsof -i
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
systemd 1 root 35u IPv4 16375 0t0 TCP *:sunrpc (LISTEN)
systemd 1 root 36u IPv4 16376 0t0 UDP *:sunrpc
systemd 1 root 37u IPv6 127 0t0 TCP *:sunrpc

4.1.2. -i 6 仅获取IPv6流量

root@debian:~# lsof -i 6
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
systemd 1 root 37u IPv6 127 0t0 TCP *:sunrpc (LISTEN)
systemd 1 root 38u IPv6 15321 0t0 UDP *:sunrpc
rpcbind 371 _rpc 6u IPv6 127 0t0 TCP *:sunrpc (LISTEN)
rpcbind 371 _rpc 7u IPv6 15321 0t0 UDP *:sunrpc
avahi-dae 429 avahi 13u IPv6 20551 0t0 UDP *:mdns
avahi-dae 429 avahi 15u IPv6 20553 0t0 UDP *:45461
cupsd 495 root 6u IPv6 615 0t0 TCP localhost:ipp (LISTEN)
rpc.mount 501 root 10u IPv6 19723 0t0 UDP *:41389
rpc.mount 501 root 11u IPv6 19726 0t0 TCP *:57059 (LISTEN)
rpc.mount 501 root 14u IPv6 19735 0t0 UDP *:41529
rpc.mount 501 root 15u IPv6 19738 0t0 TCP *:59177 (LISTEN)
rpc.mount 501 root 18u IPv6 19747 0t0 UDP *:34004
rpc.mount 501 root 19u IPv6 19750 0t0 TCP *:34029 (LISTEN)
chronyd 518 _chrony 6u IPv6 17020 0t0 UDP localhost:323
sshd 594 root 4u IPv6 17163 0t0 TCP *:ssh (LISTEN)
sshd 955 root 9u IPv6 22683 0t0 TCP localhost:6010 (LISTEN)
root@debian:~#

4.1.3. -i TCP 仅显示TCP链接(UDP类似)

root@debian:~# lsof -i TCP
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
systemd 1 root 35u IPv4 16375 0t0 TCP *:sunrpc (LISTEN)
systemd 1 root 37u IPv6 127 0t0 TCP *:sunrpc (LISTEN)
rpcbind 371 _rpc 4u IPv4 16375 0t0 TCP *:sunrpc (LISTEN)
rpcbind 371 _rpc 6u IPv6 127 0t0 TCP *:sunrpc (LISTEN)
cupsd 495 root 6u IPv6 615 0t0 TCP localhost:ipp (LISTEN)
cupsd 495 root 7u IPv4 616 0t0 TCP localhost:ipp (LISTEN)
rpc.mount 501 root 9u IPv4 19720 0t0 TCP *:34007 (LISTEN)
rpc.mount 501 root 11u IPv6 19726 0t0 TCP *:57059 (LISTEN)
rpc.mount 501 root 13u IPv4 19732 0t0 TCP *:45701 (LISTEN)
rpc.mount 501 root 15u IPv6 19738 0t0 TCP *:59177 (LISTEN)
rpc.mount 501 root 17u IPv4 19744 0t0 TCP *:42815 (LISTEN)
rpc.mount 501 root 19u IPv6 19750 0t0 TCP *:34029 (LISTEN)
crio 575 root 14u IPv4 17254 0t0 TCP localhost:33653 (LISTEN)
sshd 594 root 3u IPv4 17161 0t0 TCP *:ssh (LISTEN)
sshd 594 root 4u IPv6 17163 0t0 TCP *:ssh (LISTEN)
sshd 955 root 4u IPv4 22654 0t0 TCP debian:ssh->11.0.34.161:63491 (ESTABLISHED)
sshd 955 root 9u IPv6 22683 0t0 TCP localhost:6010 (LISTEN)
sshd 955 root 10u IPv4 22684 0t0 TCP localhost:6010 (LISTEN)
sshd 982 root 4u IPv4 22688 0t0 TCP debian:ssh->11.0.34.161:63495 (ESTABLISHED)

4.1.4. -i :port 来显示与指定端口相关的网络信息

  • lsof -i TCP:22
  • lsof -i TCP:1024
root@debian:~# lsof -i :22
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
sshd 594 root 3u IPv4 17161 0t0 TCP *:ssh (LISTEN)
sshd 594 root 4u IPv6 17163 0t0 TCP *:ssh (LISTEN)
sshd 955 root 4u IPv4 22654 0t0 TCP debian:ssh->11.0.34.161:63491 (ESTABLISHED)
sshd 982 root 4u IPv4 22688 0t0 TCP debian:ssh->11.0.34.161:63495 (ESTABLISHED)
root@debian:~#
root@debian:~# lsof -i :22
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
sshd 594 root 3u IPv4 17161 0t0 TCP *:ssh (LISTEN)
sshd 594 root 4u IPv6 17163 0t0 TCP *:ssh (LISTEN)
sshd 955 root 4u IPv4 22654 0t0 TCP debian:ssh->11.0.34.161:63491 (ESTABLISHED)
sshd 982 root 4u IPv4 22688 0t0 TCP debian:ssh->11.0.34.161:63495 (ESTABLISHED)
root@debian:~# lsof -i TCP:22
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
sshd 594 root 3u IPv4 17161 0t0 TCP *:ssh (LISTEN)
sshd 594 root 4u IPv6 17163 0t0 TCP *:ssh (LISTEN)
sshd 955 root 4u IPv4 22654 0t0 TCP debian:ssh->11.0.34.161:63491 (ESTABLISHED)
sshd 982 root 4u IPv4 22688 0t0 TCP debian:ssh->11.0.34.161:63495 (ESTABLISHED)
root@debian:~# lsof -i UDP:111
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
systemd 1 root 36u IPv4 16376 0t0 UDP *:sunrpc
systemd 1 root 38u IPv6 15321 0t0 UDP *:sunrpc
rpcbind 371 _rpc 5u IPv4 16376 0t0 UDP *:sunrpc
rpcbind 371 _rpc 7u IPv6 15321 0t0 UDP *:sunrpc
root@debian:~#

4.1.5. -i @host显示指定主机的链接

root@debian:~# lsof -i @11.0.34.161
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
sshd 955 root 4u IPv4 22654 0t0 TCP debian:ssh->11.0.34.161:63491 (ESTABLISHED)
sshd 982 root 4u IPv4 22688 0t0 TCP debian:ssh->11.0.34.161:63495 (ESTABLISHED)
root@debian:~#
root@debian:~# lsof -i TCP@11.0.34.161
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
sshd 955 root 4u IPv4 22654 0t0 TCP debian:ssh->11.0.34.161:63491 (ESTABLISHED)
sshd 982 root 4u IPv4 22688 0t0 TCP debian:ssh->11.0.34.161:63495 (ESTABLISHED)
root@debian:~# lsof -i UDP@11.0.34.161
root@debian:~#

4.1.6. -i @host:port 显示基于主机与端口的链接

4.2. -u 参数

使用 -u 选项可以列出指定用户已经打开的文件,该选项后面可以接多个用户名,每个用户名之间用空格隔开,表示列出所有指定用户已打开的所有文件

4.2.1. 指定或排除用户名(^)

root@debian:~# lsof -u root |more
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
systemd 1 root cwd DIR 253,1 4096 2 /
systemd 1 root rtd DIR 253,1 4096 2 /
systemd 1 root txt REG 253,1 1739200 27267067 /usr/lib/systemd/systemd
systemd 1 root mem REG 253,1 149576 27263978 /usr/lib/x86_64-linux-gnu/libgpg-error.so.0.29.0
systemd 1 root mem REG 253,1 3076992 27263040 /usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
root@debian:~# lsof -u ^root |more
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
rpcbind 371 _rpc cwd DIR 253,1 4096 2 /
rpcbind 371 _rpc rtd DIR 253,1 4096 2 /
rpcbind 371 _rpc txt REG 253,1 59792 27280848 /usr/sbin/rpcbind
rpcbind 371 _rpc mem REG 253,1 51696 27264526 /usr/lib/x86_64-linux-gnu/libnss_files-2.31.so
rpcbind 371 _rpc mem REG 253,1 18688 27264519 /usr/lib/x86_64-linux-gnu/libdl-2.31.so
rpcbind 371 _rpc mem REG 253,1 93000 27264530 /usr/lib/x86_64-linux-gnu/libresolv-2.31.so
rpcbind 371 _rpc mem REG 253,1 22448 27263807 /usr/lib/x86_64-linux-gnu/libkeyutils.so.1.9

4.2.2. 找出文件已删除但仍然在占用空间的文件

root@debian:~# lsof  -u root | grep delete
root@debian:~#

4.2.3. 列出目录中打开的文件

+D 选项会列出一个目录和其子目录中打开的文件

+d 选项只会列出当前目录下已打开的文件

root@debian:/home/cnpc# lsof +D /home/cnpc/
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
bash 979 root cwd DIR 253,1 4096 10485762 /home/cnpc
vi 22046 root cwd DIR 253,1 4096 10485762 /home/cnpc
vi 22046 root 3u REG 253,1 12288 10485934 /home/cnpc/.test.txt.swp
bash 22058 root cwd DIR 253,1 4096 10485762 /home/cnpc
lsof 22086 root cwd DIR 253,1 4096 10485762 /home/cnpc
lsof 22087 root cwd DIR 253,1 4096 10485762 /home/cnpc
root@debian:/home/cnpc# lsof +d /home/cnpc/
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
bash 979 root cwd DIR 253,1 4096 10485762 /home/cnpc
vi 22046 root cwd DIR 253,1 4096 10485762 /home/cnpc
vi 22046 root 3u REG 253,1 12288 10485934 /home/cnpc/.test.txt.swp
bash 22058 root cwd DIR 253,1 4096 10485762 /home/cnpc
lsof 22092 root cwd DIR 253,1 4096 10485762 /home/cnpc
lsof 22093 root cwd DIR 253,1 4096 10485762 /home/cnpc
root@debian:/home/cnpc#

4.3. -p 参数

进程ID是操作系统进程的唯一标识,从结果中可以知道这个进程ID对应的进程是MySQL

root@debian:/home/cnpc# lsof -p 22046
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
vi 22046 root cwd DIR 253,1 4096 10485762 /home/cnpc
vi 22046 root rtd DIR 253,1 4096 2 /
vi 22046 root txt REG 253,1 3169376 27284868 /usr/bin/vim.basic
vi 22046 root mem REG 253,1 51696 27264526 /usr/lib/x86_64-linux-gnu/libnss_files-2.31.so
vi 22046 root mem REG 253,1 71608 27284737 /usr/lib/x86_64-linux-gnu/gconv/libGB.so
vi 22046 root mem REG 253,1 123240 29755269 /usr/share/vim/vim82/lang/zh_CN/LC_MESSAGES/vim.mo
vi 22046 root mem REG 253,1 3256640 27277411 /usr/lib/locale/locale-archive
vi 22046 root mem REG 253,1 149520 27264529 /usr/lib/x86_64-linux-gnu/libpthread-2.31.so
vi 22046 root mem REG 253,1 617128 27265192 /usr/lib/x86_64-linux-gnu/libpcre2-8.so.0.10.1
vi 22046 root mem REG 253,1 1905632 27264518 /usr/lib/x86_64-linux-gnu/libc-2.31.so
vi 22046 root mem REG 253,1 18688 27264519 /usr/lib/x86_64-linux-gnu/libdl-2.31.so
vi 22046 root mem REG 253,1 26552 27274724 /usr/lib/x86_64-linux-gnu/libgpm.so.2
vi 22046 root mem REG 253,1 38936 27263335 /usr/lib/x86_64-linux-gnu/libacl.so.1.1.2253
vi 22046 root mem REG 253,1 166120 27265199 /usr/lib/x86_64-linux-gnu/libselinux.so.1
vi 22046 root mem REG 253,1 187792 27266305 /usr/lib/x86_64-linux-gnu/libtinfo.so.6.2
vi 22046 root mem REG 253,1 1321344 27264520 /usr/lib/x86_64-linux-gnu/libm-2.31.so
vi 22046 root mem REG 253,1 22640 27284532 /usr/lib/x86_64-linux-gnu/gconv/EUC-CN.so
vi 22046 root mem REG 253,1 27002 27284735 /usr/lib/x86_64-linux-gnu/gconv/gconv-modules.cache
vi 22046 root mem REG 253,1 177928 27264514 /usr/lib/x86_64-linux-gnu/ld-2.31.so
vi 22046 root 0u CHR 136,0 0t0 3 /dev/pts/0
vi 22046 root 1u CHR 136,0 0t0 3 /dev/pts/0
vi 22046 root 2u CHR 136,0 0t0 3 /dev/pts/0
vi 22046 root 3u REG 253,1 12288 10485934 /home/cnpc/.test.txt.swp
root@debian:/home/cnpc#

-p 选项后面可以指定多个进程ID,每个进程ID之间用逗号分隔,如果想排除掉某个进程打开的文件,可以在该进程ID前面加上 ^符号

root@debian:/home/cnpc# lsof -p ^1,2,3,4
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
kthreadd 2 root cwd DIR 253,1 4096 2 /
kthreadd 2 root rtd DIR 253,1 4096 2 /
kthreadd 2 root txt unknown /proc/2/exe
rcu_gp 3 root cwd DIR 253,1 4096 2 /
rcu_gp 3 root rtd DIR 253,1 4096 2 /
rcu_gp 3 root txt unknown /proc/3/exe
rcu_par_g 4 root cwd DIR 253,1 4096 2 /
rcu_par_g 4 root rtd DIR 253,1 4096 2 /
rcu_par_g 4 root txt unknown /proc/4/exe
root@debian:/home/cnpc#

4.4. -t 参数

-t 选项之后表示结果只列出PID列,也就是进程ID列,其他列都忽略。

root@debian:/home/cnpc# lsof -p ^1,2,3,4 -t
2
3
4
root@debian:/home/cnpc#

5. tcpdump命令

5.1. 查看网络接口列表

[root@master01 ~]# tcpdump  -D
1.eth0
2.virbr0
3.nflog (Linux netfilter log (NFLOG) interface)
4.nfqueue (Linux netfilter queue (NFQUEUE) interface)
5.usbmon1 (USB bus number 1)
6.usbmon2 (USB bus number 2)
7.usbmon3 (USB bus number 3)
8.usbmon4 (USB bus number 4)
9.usbmon5 (USB bus number 5)
10.any (Pseudo-device that captures on all interfaces)
11.lo [Loopback]
[root@master01 ~]#

5.2. 网络接口抓包

5.2.1. 指定端口

[root@master01 ~]# tcpdump -i eth0
[root@master01 ~]# tcpdump -i 1 # 通过-D获取的接口列表序号

5.2.2. 所有接口

[root@master01 ~]# tcpdump -i any

5.2.3. 基于IP地址过滤

# 根据源ip进行过滤
tcpdump -i eth2 src 192.168.10.100 # 根据目标ip进行过滤
tcpdump -i eth2 dst 192.168.10.200

5.2.4. 基于网段过滤

# 若你的ip范围是一个网段,可以直接这样指定
tcpdump net 192.168.10.0/24 # 根据源网段进行过滤
tcpdump src net 192.168 # 根据目标网段进行过滤
tcpdump dst net 192.168

5.2.5. 基于端口进行过滤

# 指定特定端口进行过滤
tcpdump port 8088 # 根据源端口进行过滤
tcpdump src port 8088 # 根据目标端口进行过滤
tcpdump dst port 8088 # 同时指定两个端口你可以这样写
tcpdump port 80 or port 8088
# 也可以简写成这样
tcpdump port 80 or 8088 # 如果你的想抓取的不再是一两个端口,而是一个范围,一个一个指定就非常麻烦了,此时你可以这样指定一个端口段。
tcpdump portrange 8000-8080
tcpdump src portrange 8000-8080
tcpdump dst portrange 8000-8080 # 对于一些常见协议的默认端口,我们还可以直接使用协议名,而不用具体的端口号
tcpdump tcp port http

5.3. 参数解析

  • -n:不把ip转化成域名,直接显示 ip,避免执行 DNS lookups 的过程,速度会快很多
  • -nn:不把协议和端口号转化成名字,速度也会快很多。
  • -N:不打印出host 的域名部分。比如,如果设置了此选现,tcpdump 将会打印'nic' 而不是 'nic.ddn.mil'.
  • -t :在每行的输出中不输出时间
  • -tt:在每行的输出中会输出时间戳
  • -ttt:输出每两行打印的时间间隔(以毫秒为单位)
  • -tttt:在每行打印的时间戳之前添加日期的打印(此种选项,输出的时间最直观)
  • -x:以16进制的形式打印每个包的头部数据(但不包括数据链路层的头部)
  • -xx:以16进制的形式打印每个包的头部数据(包括数据链路层的头部)
  • -X:以16进制和 ASCII码形式打印出每个包的数据(但不包括连接层的头部),这在分析一些新协议的数据包很方便。
  • -XX:以16进制和 ASCII码形式打印出每个包的数据(包括连接层的头部),这在分析一些新协议的数据包很方便。
  • -i:指定要过滤的网卡接口,如果要查看所有网卡,可以 -i any
  • -Q: 选择是入方向还是出方向的数据包,可选项有:in, out, inout,也可以使用 --direction=[direction] 这种写法
  • -A:以ASCII码方式显示每一个数据包(不显示链路层头部信息). 在抓取包含网页数据的数据包时, 可方便查看数据
  • -l : 基于行的输出,便于你保存查看,或者交给其它工具分析
  • -q : 简洁地打印输出。即打印很少的协议相关信息, 从而输出行都比较简短.
  • -c : 捕获 count 个包 tcpdump 就退出
  • -s : tcpdump 默认只会截取前 96 字节的内容,要想截取所有的报文内容,可以使用 -s number, number 就是你要截取的报文字节数,如果是 0 的话,表示截取报文全部内容。
  • -S : 使用绝对序列号,而不是相对序列号
  • -C:file-size,tcpdump 在把原始数据包直接保存到文件中之前, 检查此文件大小是否超过file-size. 如果超过了, 将关闭此文件,另创一个文件继续用于原始数据包的记录. 新创建的文件名与-w 选项指定的文件名一致, 但文件名后多了一个数字.该数字会从1开始随着新创建文件的增多而增加. file-size的单位是百万字节(nt: 这里指1,000,000个字节,并非1,048,576个字节, 后者是以1024字节为1k, 1024k字节为1M计算所得, 即1M=1024 * 1024 = 1,048,576)
  • -F:使用file 文件作为过滤条件表达式的输入, 此时命令行上的输入将被忽略.
  • -D : 显示所有可用网络接口的列表
  • -e : 每行的打印输出中将包括数据包的数据链路层头部信息
  • -E : 揭秘IPSEC数据
  • -L :列出指定网络接口所支持的数据链路层的类型后退出
  • -Z:后接用户名,在抓包时会受到权限的限制。如果以root用户启动tcpdump,tcpdump将会有超级用户权限。
  • -d:打印出易读的包匹配码
  • -dd:以C语言的形式打印出包匹配码.
  • -ddd:以十进制数的形式打印出包匹配码

5.4. 过滤规则组合

  • and:所有的条件都需要满足,也可以表示为 &&
  • or:只要有一个条件满足就可以,也可以表示为 ||
  • not:取反,也可以使用 !

5.4.1. 举例

tcpdump src 10.5.2.3 and dst port 3389
tcpdump 'src 10.0.2.4 and (dst port 3389 or 22)'

6. yum命令

yum,全称“Yellow dog Updater, Modified”,是一个专门为了解决包的依赖关系而存在的软件包管理器。就好像 Windows 系统上可以通过 360 软件管家实现软件的一键安装、升级和卸载,Linux 系统也提供有这样的工具,就是 yum。

6.1. 配置YUM

6.1.1. 挂载ISO

自动挂载

写入/etc/fstab

[root@localhost ~]# cat /etc/fstab 

#
# 7. /etc/fstab
# 8. Created by anaconda on Wed Feb 22 16:13:40 2023
#
# 9. Accessible filesystems, by reference, are maintained under '/dev/disk'
# 10. See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
/dev/mapper/centos-root / ext4 defaults 1 1
UUID=0fce42ee-d18b-41cd-a8f8-26e17076203a /boot ext4 defaults 1 2
UUID=E872-E5B0 /boot/efi vfat umask=0077,shortname=winnt 0 0
/dev/mapper/centos-home /home ext4 defaults 1 2
/dev/mapper/centos-maildata /maildata ext4 defaults 1 2
/dev/mapper/centos-swap swap swap defaults 0 0
/root/CentOS-7.9-x86_64-Everything-2009.iso /media iso9660 defaults 0 0
[root@localhost ~]#

手动挂载

[root@localhost ~]# mount -t iso9660 /home/CentOS-7.9-x86_64-Everything-2009.iso /media
[root@localhost ~]# mount -o loop /home/CentOS-7.9-x86_64-Everything-2009.iso /media

6.1.2. 配置YUM文件

CentOS 6 & CentOS7

[root@localhost ~]# cd /etc/yum.repos.d
[root@ /etc/yum.repos.d]# mkdir -p /etc/yum.repos.d/bak
[root@ /etc/yum.repos.d]# mv CentOS* bak
[root@ /etc/yum.repos.d]# vi system.repo
[system]
name=system
baseurl=file:///media #镜像挂载路径,按照配置填写
enabled=1
gpgcheck=0 #0表示不用检查:
[root@ /etc/yum.repos.d]#

CentOS 8

CentOS 8 之后,rpm包分别存放在两个路径下,需要注意,都需要单独列出来

[root@~]# cd /etc/yum.repos.d
[root@/etc/yum.repos.d]# mkdir -p /etc/yum.repos.d/bak
[root@/etc/yum.repos.d]# mv CentOS* bak
[root@/etc/yum.repos.d]# vi system.repo
[BaseOS]
name=system
baseurl=file:///media/BaseOS
enabled=1
gpgcheck=0 [AppStream]
name=system
baseurl=file:///media/AppStream
enabled=1
gpgcheck=0
  • [base]:容器名称,一定要放在[]中。
  • name:容器说明,可以自己随便写。
  • mirrorlist:镜像站点,这个可以注释掉。
  • baseurl:我们的 yum 源服务器的地址。默认是 CentOS 官方的 yum 源服务器,是可以使用的。如果你觉得慢,则可以改成你喜欢的 yum 源地址。
  • enabled:此容器是否生效,如果不写或写成 enabled 则表示此容器生效,写成 enable=0 则表示此容器不生效。
  • gpgcheck:如果为 1 则表示 RPM 的数字证书生效;如果为 0 则表示 RPM 的数字证书不生效。
  • gpgkey:数字证书的公钥文件保存位置。不用修改。

6.2. 常用命令

6.2.1. 缓存

yum makecache     // 构建缓存
yum clean all // 清除所有缓存

6.2.2. 更新&升级

yum update 				        // 更新所有的包
yum upgrade // 升级所有的包
yum check-update // 检查所有可更新的包
yum update package1 // 更新指定程序包package1
yum upgrade package1 // 升级指定程序包package1
yum groupupdate group1 // 升级程序组group1
yum --exclude=python* update // 升级的时候不升级python相关的包

6.2.3. 安装

yum install -y				    // 全部安装
yum install -y package1 // 安装指定的安装包package1
yum localinstall -y ~ // 从硬盘安装rpm包并使用yum解决依赖
yum groupinsall -y group1 // 安装程序组group1

6.2.4. 查找&显示

yum list 				    // 显示所有已经安装和可以安装的程序包
yum list python // 显示出名为python的包
yum list python* // 显示出名为python开头的所有的包
yum list updates // 显示出所有可以更新的包
yum list installed // 显示出所有已经安装的包
yum list extras // 显示出所有已安装但是不在yum仓库里的包
yum grouplist // 查看系统中已经安装的和可用的软件组,可用的可以安装
yum info // 显示所有已经安装和可以安装的程序包的信息
yum info python // 显示出名为python的包的信息
yum info python* // 显示出名为python开头的所有的包的信息
yum info updates // 显示出所有可以更新的包的信息
yum info installed // 显示出所有已经安装的包的信息
yum info extras // 显示出所有已安装但是不在yum仓库里的包的信息
yum groupinfo group1 // 显示程序组group1信息
yum search python // 根据关键字python查找相关的包
yum deplist python // 查看程序python依赖情况
yum provides python // 检测python包中包含的文件以及软件提供的功能。

6.2.5. 删除

yum remove package1 			// 删除程序包package1
yum groupremove group1 // 删除程序组group1

6.2.6. 清除缓存

yum clean packages        		// 清除缓存目录下的软件包
yum clean headers // 清除缓存目录下的 headers
yum clean oldheaders // 清除缓存目录下旧的 headers

6.2.7. 操作历史

yum history            // 显示yum操作历史,是按照/var/log/yum.log进行的查找
yum history info 6 // 查看第六条信息
yum history undo 6 // 撤销第六步,如果第六步是安装,则执行此命令,将删除第六步所安装的程序,。如果第六步是卸载,那么执行此命令,则进行安装卸载掉的程序
yum history redo 6 // 重做第六步

6.2.8. yum update和yum upgrade的区别

yum update和yum upgrade的功能是一样的,都是将需要更新的package更新至软件源中的最新版。区别是 yum upgrade会删除旧版本的package,而yum update则会保留。因此如果软件依赖旧版本的package,最好是使用 yum update,确保不会出现兼容问题。

yum update 		// 升级所有的包同时也升级软件和系统内核
yum upgrade // 只升级所有包,不升级软件和系统内核 PS:但是重启后软件和系统内核一样会升级

7. apt命令

8. ufw命令

UFW 是一个 Arch Linux、De­bian 或 Ubuntu 中管理防火墙规则的前端,可大大简化防火墙的配置过程。

8.1. 启用/禁用

root@dmz-logserver:/# ufw enable  #启用
root@dmz-logserver:/# ufw disable #禁用

8.2. 状态查询

root@dmz-logserver:/# ufw status
Status: active To Action From
-- ------ ----
Anywhere ALLOW 11.0.xxx.xxx/26
Anywhere ALLOW 11.160.xxx.xxx/24
Anywhere ALLOW 11.160.xxx.xxx/24
Anywhere ALLOW 11.160.xxx.xxx/24 root@dmz-logserver:/#
root@dmz-logserver:/# ufw verbose
Status: active To Action From
-- ------ ----
Anywhere ALLOW 11.0.xxx.xxx/26
Anywhere ALLOW 11.160.xxx.xxx/24
Anywhere ALLOW 11.160.xxx.xxx/24
Anywhere ALLOW 11.160.xxx.xxx/24 root@dmz-logserver:/#

8.3. 现有规则查询

root@dmz-logserver:/# ufw status verbose
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), disabled (routed)
New profiles: skip To Action From
-- ------ ----
Anywhere ALLOW IN 11.0.xxx.xxx/26
Anywhere ALLOW IN 11.160.xxx.xxx/24
Anywhere ALLOW IN 11.160.xxx.xxx/24
Anywhere ALLOW IN 11.160.xxx.xxx/24 root@dmz-logserver:/# ufw status numbered
Status: active To Action From
-- ------ ----
[ 1] Anywhere ALLOW IN 11.0.xxx.xxx/26
[ 2] Anywhere ALLOW IN 11.160.xxx.xxx/24
[ 3] Anywhere ALLOW IN 11.160.xxx.xxx/24
[ 4] Anywhere ALLOW IN 11.160.xxx.xxx/24 root@dmz-logserver:/#

8.4. 添加规则

8.4.1. 入站规则(allow)

默认情况,没有允许就是拒绝(入站),使用 ufw allow <端口> 来添加允许访问的端口或协议。

ufw allow ssh  #添加22端口
ufw allow http #添加80端口
ufw allow https #添加443端口
ufw allow 2333/tcp #添加2333端口,仅TCP协议
ufw allow 6666/udp #添加6666端口,仅UDP协议
ufw allow 8888:9999 #添加8888到9999之间的端口
ufw allow from 11.0.xxx.xxx/26 # 允许此网段访问所有端口
ufw allow from 11.160.xxx.xxx/26 to any port 514 # 允许网段访问514端口
ufw deny from 11.160.xxx.xxx/24

8.4.2. 拒绝访问(deny)

使用 ufw deny <端口> 来添加拒绝入站的端和协议,与添加允许的类似。

ufw deny ssh  #添加22端口
ufw deny http #添加80端口
ufw deny https #添加443端口
ufw deny 2333/tcp #添加2333端口,仅TCP协议
ufw deny 6666/udp #添加6666端口,仅UDP协议
ufw deny 8888:9999 #添加8888到9999之间的端口
ufw deny from 11.0.xxx.xxx/26 # 允许此网段访问所有端口
ufw deny from 11.160.xxx.xxx/26 to any port 514 # 允许网段访问514端口
ufw deny from 11.160.xxx.xxx/24

8.5. 删除规则

先使用 ufw status 查看规则,再使用 ufw delete [规则] <端口> 来删除规则。

如果你有很多条规则,使用 numbered 参数,可以在每条规则上加个序号数字。

然后使用 ufw delete <序号> 来删除规则。

root@p3terx:~# ufw status numbered  #列出规则,并加上序号。
Status: active To Action From
-- ------ ----
[ 1] 20,21,22,80,888,8888/tcp ALLOW IN Anywhere
[ 2] 39000:40000/tcp ALLOW IN Anywhere
[ 3] 8896/tcp ALLOW IN Anywhere
[ 4] 8896/udp ALLOW IN Anywhere
[ 5] 443/tcp ALLOW IN Anywhere
[ 6] 20,21,22,80,888,8888/tcp (v6) ALLOW IN Anywhere (v6)
[ 7] 39000:40000/tcp (v6) ALLOW IN Anywhere (v6)
[ 8] 8896/tcp (v6) ALLOW IN Anywhere (v6)
[ 9] 8896/udp (v6) ALLOW IN Anywhere (v6)
[10] 443/tcp (v6) ALLOW IN Anywhere (v6) root@p3terx:~# ufw delete 4 #删除上面的第4条规则
Deleting:
allow 8896/udp
Proceed with operation (y|n)? y #最后会询问你是否进行操作

8.6. 配置文件

vim /etc/ufw/before.rules # 配置文件
-A ufw-before-input -p icmp --icmp-type echo-request -j ACCEPT # 允许 ping
-A ufw-before-input -p icmp --icmp-type echo-request -j DROP # 禁止ping
ufw reload # 配置生效

9. docker命令

9.1. docker 信息

#启动docker服务
systemctl start docker
#查看docker服务状态
systemctl status docker
#查看docker版本
docker version
#查看docker容器信息2. docker info
#查看docker容器帮助
docker --help2.1. ```
# 镜像管理命令
# 查看本地所有镜像
docker images

REPOSITORY:镜像来自哪个仓库

TAG:镜像的标签信息,版本之类的信息

IMAGE ID:镜像创建时的id

CREATED:镜像创建的时间

SIZE:镜像文件大小

9.1.1. 查看具体镜像命令

#含中间映像层
docker images -a
#只显示镜像ID
docker images -q
#含中间映像层
docker images -qa
#显示镜像摘要信息(DIGEST列)
docker images --digests
#显示指定镜像的历史创建;-H:镜像大小和日期
docker history -H ${镜像名}
```2.3.
### 6.3. 镜像搜索 ```bash
#搜索仓库Oracle镜像
docker search Oracle
# --filter=stars=600:只显示 starts>=600 的镜像
docker search --filter=stars=600 Oracle
# --no-trunc 显示镜像完整 DESCRIPTION 描述
docker search --no-trunc Oracle
# --automated :只列出 AUTOMATED=OK 的镜像
docker search --automated Oracle

9.1.2. 镜像下载

#下载Redis官方最新镜像,相当于:docker pull redis:latest
docker pull redis
#下载仓库所有Redis镜像
docker pull -a redis
#下载私人仓库镜像
docker pull bitnami/redis

9.1.3. 5.镜像删除

#单个镜像删除,相当于:docker rmi redis:latest
docker rmi redis
#强制删除(针对基于镜像有运行的容器进程)
docker rmi -f redis
#多个镜像删除,不同镜像间以空格间隔
docker rmi -f redis tomcat nginx

9.2. 容器管理

对于容器的操作可使用CONTAINER ID 或 NAMES

9.2.1. 运行容器

docker run -d --name=redis redis:latest
• run:代表启动容器
• -d:以后台方式运行
• --name:指定一个容器的名字,此后操作都需要使用这个名字来定位容器。
• redis:latest:容器所使用的镜像名字

9.2.2. 容器启动

#启动一个或多个已经被停止的容器
docker start redis
#重启容器
docker restart redis

9.2.3. 查看容器

#查看正在运行的容器
docker ps
#查看正在运行的容器的ID
docker ps -q
#查看正在运行+历史运行过的容器
docker ps -a
#显示运行容器总文件大小
docker ps -s

CONTAINER ID:容器启动的id

IMAGE:使用哪个镜像启动的容器

COMMAND:启动容器的命令

CREATED:创建容器的时间

STATUS:容器启动时间

PORTS:容器映射到宿主机的端口

NAMES:容器启动的名字

9.2.4. 容器的停止与删除

#停止一个运行中的容器
docker stop redis
#杀掉一个运行中的容器
docker kill redis
#删除一个已停止的容器
docker rm redis
#删除一个运行中的容器
docker rm -f redis
#删除多个容器
docker rm -f $(docker ps -a -q)
docker ps -a -q | xargs docker rm
# -v 删除容器,并删除容器挂载的数据卷
docker rm -v redis

9.2.5. 容器的进入与退出

#使用run方式在创建时进入
docker run -it redis /bin/bash
#使用交互模式进入容器
docker exec -it redis /bin/bash
#使用守护进程方式启动容器
docker run -td name=hello1 centos
#关闭容器并退出
exit

9.2.6. 容器与主机间数据拷贝(容器外操作)

#将Redis容器中的文件copy至本地路径
docker cp Redis:/${container_path} ${local_path}
#将主机文件copy至Redis容器d
docker cp ${local_path} Redis:/${container_path}/

9.2.7. 查看容器日志

#查看redis容器日志
docker logs Redis
#查看容器redis从2021年09月15日后的最新2条日志
docker logs --since="2021-09-15" --tail=2 redis
#查看redis最新容器日志
docker logs -f -t --tail=2 redis
-f :跟踪日志输出
-t :显示时间戳
--tail :仅列出最新N条容器日志

9.3. 文件夹映射

Docker中的数据可以存储在类似于虚拟机磁盘的介质中,在Docker中称为数据卷(Data Volume)。数据卷可以用来存储Docker应用的数据,也可以用来在Docker容器间进行数据共享。数据卷呈现给Docker容器的形式就是一个目录,支持多个容器间共享,修改也不会影响镜像。使用Docker的数据卷,类似在系统中使用 mount 挂载一个文件系统。操作Docker数据卷,需要理解以下几点:

1)一个数据卷是一个特别指定的目录,该目录利用容器的UFS文件系统可以为容器提供一些稳定的特性或者数据共享。数据卷可以在多个容器之间共享。

2)创建数据卷,只要在docker run命令后面跟上-v参数即可创建一个数据卷,当然也可以跟多个-v参数来创建多个数据卷,当创建好带有数据卷的容器后,就可以在其他容器中通过--volumes-froms参数来挂载该数据卷了,而不管该容器是否运行。也可以在Dockerfile中通过VOLUME指令来增加一个或者多个数据卷。

3)如果有一些数据想在多个容器间共享,或者想在一些临时性的容器中使用该数据,那么最好的方案就是你创建一个数据卷容器,然后从该临时性的容器中挂载该数据卷容器的数据。这样,即使删除了刚开始的第一个数据卷容器或者中间层的数据卷容器,只要有其他容器使用数据卷,数据卷都不会被删除的。

4)不能使用docker export、save、cp等命令来备份数据卷的内容,因为数据卷是存在于镜像之外的。备份方法: 创建一个新容器,挂载数据卷容器,同时挂载一个本地目录,然后把远程数据卷容器的数据卷通过备份命令备份到映射的本地目录里面。如下:

# docker run --rm --volumes-from DATA -v $(pwd):/backup busybox tar cvf /backup/backup.tar /data

5)可以把一个本地主机的目录当做数据卷挂载在容器上,同样是在docker run后面跟-v参数,不过-v后面跟的不再是单独的目录了,它是[host-dir]:[container-dir]:[rw|ro]这样格式的,其中host-dir是一个绝对路径的地址,如果host-dir不存在,则docker会创建一个新的数据卷,如果host-dir存在,但是指向的是一个不存在的目录,则docker也会创建该目录,然后使用该目录做数据源。

9.3.1. Docker Volume数据卷可以实现:

  • 绕过“拷贝写”系统,以达到本地磁盘IO的性能,(比如运行一个容器,在容器中对数据卷修改内容,会直接改变宿主机上的数据卷中的内容,所以是本地磁盘IO的性能,而不是先在容器中写一份,最后还要将容器中的修改的内容拷贝出来进行同步。)
  • 绕过“拷贝写”系统,有些文件不需要在docker commit打包进镜像文件。
  • 数据卷可以在容器间共享和重用数据
  • 数据卷可以在宿主和容器间共享数据
  • 数据卷数据改变是直接修改的
  • 数据卷是持续性的,直到没有容器使用它们。即便是初始的数据卷容器或中间层的数据卷容器删除了,只要还有其他的容器使用数据卷,那么里面的数据都不会丢失。

9.3.2. Docker数据持久化:

容器在运行期间产生的数据是不会写在镜像里面的,重新用此镜像启动新的容器就会初始化镜像,会加一个全新的读写入层来保存数据。如果想做到数据持久化,Docker提供数据卷(Data volume)或者数据容器卷来解决问题,另外还可以通过commit提交一个新的镜像来保存产生的数据。

docker容器不保持任何数据

重要数据请使用外部卷存储(数据持久化)

容器可以挂载真实机目录或共享存储为卷

9.3.3. 主机卷的映射

9.3.3.1. 示例1 主机卷映射

[root@docker1 ~]# mkdir /var/data
[root@docker1 ~]# docker run -it -v /var/data:/abc myos
[root@f1fb58b85671 /]# cd /abc/
[root@f1fb58b85671 abc]# touch f1
[root@f1fb58b85671 abc]# ls
f1 zhy [root@docker1 ~]# cd /var/data/
[root@docker1 data]# ls
f1
[root@docker1 data]# touch zhy

9.3.3.2. 示例2 创建一个数据卷

如下为容器添加一个数据卷,并将容器名改为data。这个数据卷在容器里的目录是/opt/data

[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/ubuntu latest 0ef2e08ed3fa 2 weeks ago 130 MB [root@localhost ~]# docker run --name data -v /opt/data -t -i docker.io/ubuntu /bin/bash
root@2b9aebcf6ce8:/# cd /opt/data/
root@2b9aebcf6ce8:/opt/data# ls
root@2b9aebcf6ce8:/opt/data# echo "123" > 123
root@2b9aebcf6ce8:/opt/data# echo "123123" > 123123
root@2b9aebcf6ce8:/opt/data# ls
123 123123 [root@localhost volumes]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2b9aebcf6ce8 docker.io/ubuntu "/bin/bash" 49 seconds ago Up 48 seconds data 在宿主机上,查看对应上面的那个数据卷的目录路径:
[root@localhost ~]# docker inspect data|grep /var/lib/docker/volumes
"Source": "/var/lib/docker/volumes/89d6562b9c1fe10dd21707cb697a5d481b3c1b000a69b762f540fa826a16972a/_data",
[root@localhost ~]# ls /var/lib/docker/volumes/89d6562b9c1fe10dd21707cb697a5d481b3c1b000a69b762f540fa826a16972a/_data
123 123123
[root@localhost ~]# echo "asdhfjashdfjk" >> /var/lib/docker/volumes/89d6562b9c1fe10dd21707cb697a5d481b3c1b000a69b762f540fa826a16972a/_data/123
[root@localhost ~]# root@2b9aebcf6ce8:/opt/data# ls
123 123123
root@2b9aebcf6ce8:/opt/data# cat 123
123
asdhfjashdfjk

9.3.3.3. 示例3 挂载宿主机文件到容器上

可以直接挂载宿主机文件或目录到容器里,可以理解为目录映射,这样就可以让所有的容器共享宿主机数据,从而只需要改变宿主机的数据源就能够影响到所有的容器数据。

注意:

-v后面的映射关系是"宿主机文件/目录:容器里对应的文件/目录",其中,宿主机上的文件/目录是要提前存在的,容器里对应的文件/目录会自动创建。

数据卷权限:

挂载的数据默认为可读写权限。

但也可以根据自己的需求,将容器里挂载共享的数据设置为只读,这样数据修改就只能在宿主机上操作。如下实例:

1)挂载宿主机文件到容器上
[root@localhost ~]# cat /etc/web.list
192.168.1.100
192.168.1.101
192.168.1.103
[root@localhost ~]# docker run -t -i --name test -v /etc/web.list:/etc/web.list:ro docker.io/centos /bin/bash
[root@e21a3fefa3ae /]# cat /etc/web.list
192.168.1.100
192.168.1.101
192.168.1.103
[root@e21a3fefa3ae /]# echo "192.168.1.115" >> /etc/web.list
bash: /etc/web.list: Read-only file system
[root@e21a3fefa3ae /]# 在宿主机上修改共享数据
[root@localhost ~]# echo "192.168.1.115" >> /etc/web.list
[root@localhost ~]# [root@e21a3fefa3ae /]# cat /etc/web.list
192.168.1.100
192.168.1.101
192.168.1.103
192.168.1.115 2)挂载宿主机目录到容器上
[root@localhost ~]# mkdir /var/huanqiupc
[root@localhost ~]# echo "test" > /var/huanqiupc/test
[root@localhost ~]# echo "test1" > /var/huanqiupc/test1
[root@localhost ~]# docker run -t -i --name hqsb -v /var/huanqiupc:/opt/huantime docker.io/centos /bin/bash
[root@87cf93ce46a9 /]# cd /opt/huantime/
[root@87cf93ce46a9 huantime]# ls
test test1
[root@87cf93ce46a9 huantime]# cat test
test
[root@87cf93ce46a9 huantime]# cat test1
test1
[root@87cf93ce46a9 huantime]# echo "1231" >>test
[root@87cf93ce46a9 huantime]# echo "44444" >>test1 宿主机上查看
[root@localhost ~]# cat /var/huanqiupc/test
test
1231
[root@localhost ~]# cat /var/huanqiupc/test1
test1
44444

9.3.3.4. 示例4 挂载宿主机目录到容器上

[root@localhost ~]# mkdir /var/huanqiupc
[root@localhost ~]# echo "test" > /var/huanqiupc/test
[root@localhost ~]# echo "test1" > /var/huanqiupc/test1
[root@localhost ~]# docker run -t -i --name hqsb -v /var/huanqiupc:/opt/huantime docker.io/centos /bin/bash
[root@87cf93ce46a9 /]# cd /opt/huantime/
[root@87cf93ce46a9 huantime]# ls
test test1
[root@87cf93ce46a9 huantime]# cat test
test
[root@87cf93ce46a9 huantime]# cat test1
test1
[root@87cf93ce46a9 huantime]# echo "1231" >>test
[root@87cf93ce46a9 huantime]# echo "44444" >>test1 宿主机上查看
[root@localhost ~]# cat /var/huanqiupc/test
test
1231
[root@localhost ~]# cat /var/huanqiupc/test1
test1
44444

9.3.3.5. 示例4 创建数据卷容器

启动一个名为xqsj_Container容器,此容器包含两个数据卷/var/volume1和/var/volume2(这两个数据卷目录是在容器里的,容器创建的时候会自动生成这两目录)

注意一个细节:

下面的创建命令中,没有加-t和-i参数,所以这个容器创建好之后是登陆不了的!

-i:表示以“交互模式”运行容器

-t:表示容器启动后会进入其命令行

[root@linux-node2 ~]# docker run -v /var/volume1 -v /var/volume2 --name xqsj_Container centos /bin/bash
[root@linux-node2 ~]# 所以要想创建容器后能正常登陆,就需要添加上面两个参数
[root@localhost ~]# docker run -t -i -v /var/volume1 -v /var/volume2 --name xqsj_Container centos /bin/bash
[root@73a34f3c1cd9 /]#

查看宿主机上与数据卷对应的目录路径:

[root@localhost ~]# docker inspect xqsj_Container|grep /var/lib/docker/volumes
"Source": "/var/lib/docker/volumes/b8d2e5bcadf2550abd36ff5aa544c721a45464a4406fb50979815de773086627/_data",
"Source": "/var/lib/docker/volumes/a34fa3a0a7a2f126b0d30a32b1034f20917ca7bd0dda346014d768b5ebb68f6b/_data",
由上面命令结果可以查到,两个数据卷/var/volume1和/var/volume2下的数据在/var/lib/docker/volumes/下对于的两个目录的_data下面

创建App_Container容器,挂载xqsj_Container容器中的数据卷

[root@linux-node2 ~]# docker run -t -i --rm --volumes-from xqsj_Container --name App_Container centos /bin/bash
[root@b9891bcdfed0 /]# ls /var/volume1 //发现这两个数据卷都存在
[root@b9891bcdfed0 /]# ls /var/volume2
[root@b9891bcdfed0 /]# echo "this is volume1" > /var/volume1/test1
[root@b9891bcdfed0 /]# echo "this is volume2" > /var/volume1/test2

可以再创建一个容器,挂载App_Container中从xqsj_Container挂载的数据卷。当然也可以直接挂载初始的xqsj_Container容器数据卷

[root@linux-node2 ~]# docker run -t -i --rm --volumes-from App_Container --name LastApp_Container centos /bin/bash
[root@b4c27e360614 /]# ls /var/volume1
test1
[root@b4c27e360614 /]# ls /var/volume2
test2
[root@b4c27e360614 /]# cat /var/volume1/test1
this is volume1
[root@b4c27e360614 /]# cat /var/volume2/test2
this is volume2

即便是删除了初始的数据卷容器xqsj_Container,或是删除了其它容器,但只要是有容器在使用该数据卷,那么它里面的数据就不会丢失!(除非是没有容器在使用它们)

9.3.4. 使用共享存储的映射

思路:将一台主机做为nfs主机, 创建相应的文件夹,并将其共享给docker的两台主机,两台docker主机将分享的文件夹映射到容器中,使得对应的容器可以共享到nfs主机的内容。可以将http等服务器的相应的页面文件夹使用这种形式,从而实现多个容器跑一个业务。

nfs主机配置【192.168.6.77】

[root@nfs ~]# yum -y install nfs-utils
[root@nfs ~]# vim /etc/exports
/public *(rw)
[root@nfs ~]# systemctl restart nfs-server
Failed to restart nfs-serve.service: Unit not found
[root@nfs ~]# mkdir /public
[root@nfs ~]# cd /public/
[root@nfs public]# touch nfs.txt
[root@nfs public]# ls
nfs.txt docker1主机配置
[root@docker1 ~]# vim /etc/fstab
192.168.6.77:/public /mnt/nfs nfs defaults,_netdev 0 0
[root@docker1 ~]# mkdir /mnt/nfs
[root@docker1 ~]# systemctl restart nfs-server
[root@docker1 ~]# mount -a
[root@docker1 ~]# df -h
192.168.6.77:/public 17G 3.2G 14G 19% /mnt/nfs
[root@docker1 ~]# docker run -it -v /mnt/nfs/:/zhuhaiyan 192.168.6.153:5000/myos
[root@c7c376e3755a /]# cd /zhuhaiyan
[root@c7c376e3755a zhuhaiyan]# ls
nfs.txt docker2主机配置
[root@docker2 ~]# vim /etc/fstab
192.168.6.77:/public /mnt/nfs nfs defaults,_netdev 0 0
[root@docker2 ~]# mkdir /mnt/nfs
[root@docker2 ~]# systemctl restart nfs-server
[root@docker2 ~]# mount -a
[root@docker2 ~]# df -h
192.168.6.77:/public 17G 3.2G 14G 19% /mnt/nfs
[root@docker2 ~]# docker run -it -v /mnt/nfs/:/zhuhaiyan 192.168.6.153:5000/myos
[root@cdd805771d07 /]# cd /zhuhaiyan/
[root@cdd805771d07 zhuhaiyan]# ls
nfs.txt

9.4. 备份数据卷

$ sudo docker run --rm --volumes-from test -v $(pwd):/backup ubuntu:14.04 tar cvf /backup/test.tar /test
tar: Removing leading `/' from member names
/test/
/test/b
/test/d
/test/c
/test/a

以上命令表示:

启动一个新的容器并且从test容器中挂载卷,然后挂载当前目录到容器中为backup,并备份test卷中所有的数据为test.tar,执行完成之后删除容器--rm,此时备份就在当前的目录下,名为test.tar。

注意:后面的/test是数据卷的目录路径(即数据卷创建时在容器里的路径)

$ ls

宿主机当前目录下产生了test卷的备份文件test.tar

---------------------------------------------看看下面的一个实例---------------------------------------------

先创建一个容器wang,包含两个数据卷/var/volume1和/var/volume2(这两个目录是在容器里的数据卷路径)

[root@localhost ~]# docker run -t -i -v /var/volume1 -v /var/volume2 --name wang docker.io/centos /bin/bash
[root@83eb43492ae7 /]# 根据Docker的数据持久化之数据卷容器可知,上面创建的wang数据卷容器挂载了/var/volume1和/var/volume2两个目录
然后在数据卷里写些数据,以供测试。
[root@83eb43492ae7 /]# cd /var/volume1
[root@83eb43492ae7 volume1]# echo "test1" > test1
[root@83eb43492ae7 volume1]# echo "test11" > test11
[root@83eb43492ae7 volume1]# echo "test111" > test111
[root@83eb43492ae7 volume1]# ls
test1 test11 test111
[root@83eb43492ae7 volume1]# cd ../volume2
[root@83eb43492ae7 volume2]# echo "test2" > test2
[root@83eb43492ae7 volume2]# echo "test22" > test22
[root@83eb43492ae7 volume2]# echo "test222" > test222
[root@83eb43492ae7 volume2]# ls
test2 test22 test222
[root@83eb43492ae7 volume2]# 然后进行这两个数据卷的备份
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
83eb43492ae7 docker.io/centos "/bin/bash" 2 minutes ago Up 2 minutes wang

现在开始进行数据卷的备份操作:

为了利用数据卷容器备份,使用--volumes-from标记来创建一个加载wang容器卷的容器,并从主机挂载当前目录到容器的/backup目录。并备份wang卷中的数据,执行完成之后删除容器--rm,此时备份就在当前的目录下了。

1)备份wang容器中的/var/volume1数据卷数据<strong>(注意下面:命令中的-i和-t这两个参数加不加都可以;--rm加上,备份后就会自动删除这个容器,如果不加这个--rm参数,那么备份后的容器就会保留,docker ps -a就会查看到)</strong>
[root@localhost ~]# docker run -i -t --rm --volumes-from wang -v $(pwd):/backup docker.io/centos tar cvf /backup/backup1.tar /var/volume1
tar: Removing leading `/' from member names
/var/volume1/
/var/volume1/test1
/var/volume1/test11
/var/volume1/test111 2)备份wang容器中的/var/volume2数据卷数据
[root@localhost ~]# docker run -i -t --rm --volumes-from wang -v $(pwd):/backup docker.io/centos tar cvf /backup/backup2.tar /var/volume2
tar: Removing leading `/' from member names
/var/volume2/
/var/volume2/test2
/var/volume2/test22
/var/volume2/test222 3)备份wang容器中的/var/volume1和/var/volume2数据卷数据
[root@localhost ~]# docker run -i -t --rm --volumes-from wang -v $(pwd):/backup docker.io/centos tar cvf /backup/backup.tar /var/volume1 /var/volume2
tar: Removing leading `/' from member names
/var/volume1/
/var/volume1/test1
/var/volume1/test11
/var/volume1/test111
/var/volume2/
/var/volume2/test2
/var/volume2/test22
/var/volume2/test222
[root@localhost ~]# ls
anaconda-ks.cfg a.py backup1.tar backup2.tar backup.tar mkimage-yum.sh pipework var wang.tar 这样,数据卷容器中的数据就备份完成了. 简言之就是:
先创建一个容器,并挂载要备份的容器数据卷,再挂载数据卷(pwd):/backup目录到容器/bakcup,在容器中执行备份/data目录到/backup,也就是备份到宿主机$(pwd):/backup目录。

7.5. 恢复或迁移数据卷

可以恢复给同一个容器或者另外的容器,新建容器并解压备份文件到新的容器数据卷
$ sudo docker run -t -i -d -v /test --name test4 ubuntu:14.04 /bin/bash
$ sudo docker run --rm --volumes-from test4 -v $(pwd):/backup ubuntu:14.04 tar xvf /backup/test.tar -C /
恢复之前的文件到新建卷中,执行完后自动删除容器 test/ test/b test/d test/c test/a -----------------------------接着上面的实例进行数据卷恢复操作--------------------------
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
531c9d8adf4c docker.io/centos "/bin/bash" 2 minutes ago Up 44 seconds wang 1)恢复数据给同一个容器
测了测试效果,先删除数据卷(注意:数据卷目录删除不了,只能删除其中的数据。)
[root@localhost ~]# docker attach wang
[root@531c9d8adf4c ~]# ls /var/volume1
test1 test11 test111
[root@531c9d8adf4c ~]# ls /var/volume2
test2 test22 test222
[root@531c9d8adf4c ~]# rm -rf /var/volume1 /var/volume2
rm: cannot remove '/var/volume1': Device or resource busy
rm: cannot remove '/var/volume2': Device or resource busy
[root@531c9d8adf4c ~]# ls /var/volume2
[root@531c9d8adf4c ~]# ls /var/volume1 现在进行数据卷恢复,恢复数据卷中的所有数据:
[root@localhost ~]# ls
anaconda-ks.cfg a.py backup1.tar backup2.tar backup.tar mkimage-yum.sh pipework var wang.tar 注意-C后面的路径,这个路径表示将数据恢复到容器里的路径。
命令中用"/",即表示将backup.tar中的数据解压到容器的/路径下。后面跟什么路径,就解压到这个路径下。因此这里用"/"
[root@localhost ~]# docker run --rm --volumes-from wang -v $(pwd):/backup docker.io/centos tar xvf /backup/backup.tar -C /
var/volume1/
var/volume1/test1
var/volume1/test11
var/volume1/test111
var/volume2/
var/volume2/test2
var/volume2/test22
var/volume2/test222 再次到容器里查看,发现数据卷里的数据已经恢复了
[root@531c9d8adf4c ~]# ls /var/volume1
test1 test11 test111
[root@531c9d8adf4c ~]# ls /var/volume2
test2 test22 test222 2)恢复数据给另外的容器,新建容器并解压备份文件到新的容器数据卷
即新建一个容器huihui,将上面备份的数据卷数据恢复到这个新容器里。
[root@localhost ~]# docker run -t -i -v /var/volume1 -v /var/volume2 --name huihui docker.io/centos /bin/bash
[root@f6ff380e0b7f var]# ls /var/volume1
[root@f6ff380e0b7f var]# ls /var/volume2 [root@localhost ~]# ls
anaconda-ks.cfg a.py backup1.tar backup2.tar backup.tar mkimage-yum.sh pipework var wang.tar [root@localhost ~]# docker run --rm --volumes-from huihui -v $(pwd):/backup docker.io/centos tar xvf /backup/backup.tar -C /
var/volume1/
var/volume1/test1
var/volume1/test11
var/volume1/test111
var/volume2/
var/volume2/test2
var/volume2/test22
var/volume2/test222 [root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
813afe297b60 docker.io/centos "/bin/bash" 17 seconds ago Up 16 seconds huihui 这里注意一下:
新容器创建时挂载的数据卷路径最好是和之前备份的数据卷路径一致
如下:
1)新建容器挂载的数据卷只是备份数据卷的一部分,那么恢复的时候也只是恢复一部分数据。如下,新容器创建时只挂载/var/volume1
[root@localhost ~]# docker run -t -i -v /var/volume1 --name huihui docker.io/centos /bin/bash
[root@12dd8d742259 /]# ls /var/volume1/
[root@12dd8d742259 /]# ls /var/volume2
ls: cannot access /var/volume2: No such file or directory [root@localhost ~]# docker run --rm --volumes-from huihui -v $(pwd):/backup docker.io/centos tar xvf /backup/backup.tar -C /
var/volume1/
var/volume1/test1
var/volume1/test11
var/volume1/test111
var/volume2/
var/volume2/test2
var/volume2/test22
var/volume2/test222
[root@localhost ~]# 查看容器,发现只恢复了/var/volume1的数据,/var/volume2数据没有恢复,因为没有容器创建时没有挂载这个。
[root@localhost ~]# docker run -t -i -v /var/volume1 --name huihui docker.io/centos /bin/bash
[root@12dd8d742259 /]# ls /var/volume1/
[root@12dd8d742259 /]# ls /var/volume2
ls: cannot access /var/volume2: No such file or directory 2)新容器创建时只挂载/var/volume2
[root@localhost ~]# docker run -t -i -v /var/volume2 --name huihui docker.io/centos /bin/bash
[root@da3a3d2c95e0 /]# ls /var/volume2/
[root@da3a3d2c95e0 /]# ls /var/volume1
ls: cannot access /var/volume1: No such file or directory [root@localhost ~]# docker run --rm --volumes-from huihui -v $(pwd):/backup docker.io/centos tar xvf /backup/backup.tar -C /
var/volume1/
var/volume1/test1
var/volume1/test11
var/volume1/test111
var/volume2/
var/volume2/test2
var/volume2/test22
var/volume2/test222
[root@localhost ~]# [root@da3a3d2c95e0 /]# ls /var/volume1
ls: cannot access /var/volume1: No such file or directory
[root@da3a3d2c95e0 /]# ls /var/volume2/
test2 test22 test222 3)如果新容器创建时挂载的数据卷目录跟之前备份的路径不一致
[root@localhost ~]# docker run -t -i -v /var/huihui --name huihui docker.io/centos /bin/bash
[root@9bad9b3bde71 /]# ls /var/huihui/
[root@9bad9b3bde71 /]# 如果解压时-C后面跟的路径不是容器挂载的容器,那么数据恢复不了,如下
[root@localhost ~]# docker run --rm --volumes-from huihui -v $(pwd):/backup docker.io/centos tar xvf /backup/backup.tar -C /
var/volume1/
var/volume1/test1
var/volume1/test11
var/volume1/test111
var/volume2/
var/volume2/test2
var/volume2/test22
var/volume2/test222 发现容器内数据没有恢复
[root@9bad9b3bde71 /]# ls /var/huihui/
[root@9bad9b3bde71 /]# 但是如果解压时-C后面跟的是容器挂载的路径,数据就能正常恢复
[root@localhost ~]# docker run --rm --volumes-from huihui -v $(pwd):/backup docker.io/centos tar xvf /backup/backup.tar -C /var/huihui
var/volume1/
var/volume1/test1
var/volume1/test11
var/volume1/test111
var/volume2/
var/volume2/test2
var/volume2/test22
var/volume2/test222
[root@localhost ~]# 发现容器内数据已经恢复了
[root@9bad9b3bde71 /]# ls /var/huihui/
var
[root@9bad9b3bde71 /]# ls /var/huihui/var/
volume1 volume2
[root@9bad9b3bde71 /]# ls /var/huihui/var/volume1
test1 test11 test111
[root@9bad9b3bde71 /]# ls /var/huihui/var/volume2
test2 test22 test222

9.5. 删除数据卷

Volume 只有在下列情况下才能被删除:

1)docker rm -v删除容器时添加了-v选项

2)docker run --rm运行容器时添加了--rm选项

否则,会在/var/lib/docker/volumes目录中遗留很多不明目录。

可以使用下面方式找出,然后删除_data目录下的数据文件

[root@localhost volumes]# docker inspect huihui|grep /var/lib/docker/volumes
"Source": "/var/lib/docker/volumes/97aa95420e66de20abbe618fad8d0c1da31c54ce97e32a3892fa921c7942d42b/_data",

可以使用 docker rm -v 命令在删除容器时删除该容器的卷。示例如下:

[root@localhost volumes]# docker run -d -P --name huihui -v /www docker.io/centos
69199905a74cb360935e32f4e99f7f11319f6aa36033a920aa0bae25874f5c69 [root@localhost volumes]# docker volume ls
DRIVER VOLUME NAME
local 5341c03f3b94f13f4c86d88ccb0f3b63487adf30dea7ae6b2d06e947235e7330
local 97aa95420e66de20abbe618fad8d0c1da31c54ce97e32a3892fa921c7942d42b
local data_volume [root@localhost volumes]# docker rm -vf huihui
huihui
[root@localhost volumes]# docker volume ls
DRIVER VOLUME NAME
local 5341c03f3b94f13f4c86d88ccb0f3b63487adf30dea7ae6b2d06e947235e7330
local data_volume

Docker 新版本中引入了 docker volume 命令来管理 Docker volume。

使用默认的 'local' driver 创建一个volume数据卷

[root@localhost ~]# docker volume create --name kevin
kevin [root@localhost ~]# docker volume ls
DRIVER VOLUME NAME
local kevin [root@localhost ~]# ll /var/lib/docker/volumes
total 24
drwxr-xr-x 3 root root 19 Oct 28 00:32 kevin
-rw------- 1 root root 32768 Oct 28 00:32 metadata.db

使用这个名为kevin的数据卷

[root@localhost ~]# docker run -d -P --name test1 -v kevin:/volume docker.io/centos
375ef74722404f5c52fde9f2ea7ea322c57e07fbac0b0e69825f077328fdb363 [root@localhost ~]# docker inspect test1
.........
"Mounts": [
{
"Type": "volume",
"Name": "kevin",
"Source": "/var/lib/docker/volumes/kevin/_data",
"Destination": "/volume",
"Driver": "local",
"Mode": "z",
"RW": true,
"Propagation": ""
}

即将kevin数据卷对应在本机上的目录/var/lib/docker/volumes/kevin/_data挂载给容器内的 /volume 目录。

9.6. dockerfile

dockerfile是一个文本文件,包含一条条指令,每条指令都会构建一层镜,一般分为四部分:基础镜像信息、维护者信息、镜像操作指令和容器启动时执行指令,#为 Dockerfile 中的注释。

docker build 基于dockerfile制作镜像
docker build [OPTIONS] PATH | URL | -
OPTIONS参数
-t:给镜像打标签
-c:-cpu-shares int:CPU份额
-m:-memory bytes:内存限制
--build-arg:设置构建时变量(构建时候修改ARG指令的参数)

9.6.1. dockerfile指令

9.6.1.1. FROM

1、 FROM
FROM指令必须是Dockerfile中非注释行的第一个指令,为镜像文件构建过程指定基础镜像,后续的指令运行于
此基础镜像所提供的运行环境 FROM <repository>[:<tag>]

FROM <repository>@<digest>
<repository>:指定作为base image的名称
<tag>:base image的标签,省略时候默认latest
<digest>:镜像的哈希码 示例:
FROM busybox:latest

9.6.1.2. MAINTAINER

    用于让dockerfile制作者提供本人的详细信息

    MAINTAINER <authtor's detail>

    示例:
FROM busybox:latest
MAINTAINER "Along <along@along.com>"

9.6.1.3. COPY

    用于从docker 主机复制新文件或者目录至创建的新镜像指定路径中
COPY <src>... <dest> <src>:要复制的源文件或目录
<dest>:目标路径,即正在创建的镜像的文件系统路径

9.6.1.4. ADD

    指令类似于COPY指令,ADD支持使用TAR文件和URL路径
ADD <src> .. <dest> 1、拷贝单个文件
ADD ./a.txt WORKDIR/b 2、拷贝多个文件
ADD指令支持通配符,常用的示例如下:
#拷贝当前目录下的bin文件夹的所有sh文件到/usr/bin目录下
ADD ./bin/*.sh /usr/bin/ #拷贝当前目录下的bin文件夹的所有带后缀的文件到/usr/bin目录下
ADD ./bin/*.* /usr/bin/ #拷贝当前目录下的bin文件夹的所有不带后缀的文件到/usr/bin目录下
ADD ./bin/* /usr/bin/ #拷贝当前目录下的bin文件夹的所有文件到/usr/bin目录下(/usr/bin目录原有的文件会保留)
ADD ./bin/ /usr/bin/ 3、拷贝文件夹
ADD ./config /usr/bin/config

9.6.1.5. WORKDIR

    用于为Dockerfile中所有的RUN、CMD、ENTRYPOINT、COPY和ADD指定设定工作目录
WORKDIR <dirpath>

9.6.1.6. VOLUME

    用于在image中创建一个挂载点目录
VOLUME <mountpoint>

9.6.1.7. EXPOSE

用于为容器打开指定要监听的端口以实现与外部通信
EXPOSE <port>[/ <protocol>] [<port>[/ <protocol>] <protocol>用于指定传输层协议,可为tcp或udp二者之一,默认为TCP协议
EXPOSE指令可一次指定多个端口,例如:EXPOSE 11211/udp 11211/tcp

9.6.1.8. ENV

    用于为镜像定义所需的环境变量,并可被Dockerfile文件中位于其后的其它指令(如ENV、ADD、COPY等)所调用
调用格式为$variable_ name 或 ${variable_ name}
ENV <key> <value> 一次只能设置一个

ENV <key>=<value> 一次可以设置多个键值对

9.6.1.9. RUN

    用于指定docker build过程中运行的程序,其可以是任何命令
RUN <command>

RUN ["<executable>", "<param1>", "<param2>"]
第一种格式中,<command>通常是一个shell命令, 且以“/bin/sh -c”来运行它,这意味着此进程在容器中的PID不为1,
不能接收Unix信号,因此,当使用docker stop <container>命令停止容器时,此进程接收不到SIGTERM信号; 第二种语法格式中的参数是一个JSON格式的数组,其中<executable>为要运行的命令,后面的 <paramN>为传递给命令
的选项或参数;
然而,此种格式指定的命令不会以“/bin/sh -c”来发起,因此常见的shell操作如变量替换以及通配符(?,*等)替换将不会进行;
不过, 如果要运行的命令依赖于此shell特性的话,可以将其替换为类似下面的格式。
RUN ["/bin/bash", "-c", "<executable>", "<param1>"]

9.6.1.10. CMD

    类似于RUN指令,CMD指令也可用于运行任何命令或应用程序
RUN指令运行于映像文件构建过程中,而CMD指令运行于基于Dockerfile构建出的新映像文件启动一个容器时 CMD指令的首要目的在于为启动的容器指定默认要运行的程序,且其运行结束后,容器也将终止;不过,
CMD指定的命令其可以被docker run的命令行选项所覆盖 Dockerfile中可以存在多个CMD指令,但仅最后一个会生效 CMD <command>

CMD ["<executable>","<param1>","<param2>"]

CMD ["<param1>","<param2>"] 前两种语法格式的意义同RUN
第三种则用于为ENTRYPOINT指令提供默认参数
json数组中,要使用双引号,单引号会出错

9.6.1.11. ENTRYPOINT

    类似CMD指令的功能,用于为容器指定默认运行程序,从而使得容器像是一个单独的可执行程序
与CMD不同的是,由ENTRYPOINT启动的程序不会被docker run命令行指定的参数所覆盖,而且,
这些命令行参数会被当作参数传递给ENTRYPOINT指定指定的程序
不过,docker run命令的 --entrypoint选项的参数可覆盖ENTRYPOINT指令指定的程序 ENTRYPOINT <command>

ENTRYPOINT ["<executable>", "<param1>", "<param2>"] docker run命令传入的命令参数会覆盖CMD指令的内容并且附加到ENTRYPOINT命令最后做为其参数使用
Dockerfile文件中也可以存在多个ENTRYPOINT指令,但仅有最后一个会生效

9.6.1.12. HEALTHCHECK

HEALTHCHECK指令告诉Docker如何测试容器以检查它是否仍在工作。
即使服务器进程仍在运行,这也可以检测出陷入无限循环且无法处理新连接的Web服务器等情况 HEALTHCHECK [OPTIONS] CMD command (通过在容器内运行命令来检查容器运行状况)
HEALTHCHECK NONE (禁用从基础映像继承的任何运行状况检查) OPTIONS 选项:
--interval=DURATION (default: 30s):每隔多长时间探测一次,默认30秒
-- timeout= DURATION (default: 30s):服务响应超时时长,默认30秒
--start-period= DURATION (default: 0s):服务启动多久后开始探测,默认0秒
--retries=N (default: 3):认为检测失败几次为宕机,默认3次 返回值:
0:容器成功是健康的,随时可以使用
1:不健康的容器无法正常工作
2:保留不使用此退出代码

9.6.1.13. ONBUILD

    用于在Dockerfile中定义一个触发器
Dockerfile用于build映像文件,此映像文件亦可作为base image被另一个Dockerfile用作FROM指令的参数,
并以之构建新的映像文件
在后面的这个Dockerfile中的FROM指令在build过程中被执行时,将会“触发”创建其base image的Dockerfile文件
中的ONBUILD指令定义的触发器 ONBUILD < Instruction>
尽管任何指令都可注册成为触发器指令,但ONBUILD不能自我嵌套,且不会触发FROM和MAINTAINER指令
使用包含ONBUILD指令的Dockerfile构建的镜像应该使用特殊的标签,例如ruby:2.0-onbuil
在ONBUILD指令中使用ADD或COPY指令应该格外小心,因为新构建过程的上下文在缺少指定的源文件时会失败

9.6.1.14. USER

    用于指定运行image时的或运行Dockerfile中任何RUN、CMD或EntRyPoInT指令指定的程序时的用户名或UID
默认情况下,container的运行身份为root用户 USER <UID>| <U JserName >
需要注意的是,<UID>可以为任意数字,但实践中其必须为/etc/passwd中某用户的有效UID,否则,docker run命令将运行失败

9.6.1.15. ARG

    ARG指令类似ENV,定义了一个变量;区别于ENV:用户可以在构建时docker build --build-arg <varname> = <value>
进行对变量的修改;ENV不可以
如果用户指定了未在Dockerfile中定义的构建参数,那么构建输出警告 ARG <name>[= <default value>]
Dockerfile可以包含一个或多个ARG指令

9.6.1.16. SHELL

    SHELL指令允许覆盖用于shell命令形式的默认shell。
Linux上的默认shell是[“/ bin / sh”,“c”],在Windows上是[“cmd”,“/ S”,“/ C”]
SHELL指令必须以JSON格式写入Dockerfile。
SHELL ["executable", "parameters"] SHELL指令可以多次出现。
每个SHELL指令都会覆盖所有先前的SHELL指令,并影响所有后续指令。

9.6.1.17. STOPSIGNAL

STOPSIGNAL指令设置将发送到容器出口的系统调用信号
此信号可以是与内核的系统调用表中的位置匹配的有效无符号数,例如9,或者SIGNAME格式的信号名,例如SIGKILL。 STOPSIGNAL signal

9.7. dockerfile示例

9.7.1. 概述

Dockerfile是docker中镜像文件的的描述文件,说的直白点就是镜像文件到底是由什么东西一步步构成的。

 例如:你在淘宝上买了一个衣架,但是卖家并没有给你发一个完整的衣架,而是一些组件和一张图纸,你按照这个图纸一步一步将衣架组装起来,就成了你所需要的样子。那么 Dockerfile 就是这张图纸,镜像文件就是你需要的这个衣架,Dockerfile 不建议随便命名,就用 Dockerfile。

 因此,Dockerfile其内部包含了一条条的指令,每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。

9.7.2. 大概执行流程

(1)docker从基础镜像运行一个容器;

(2)执行一条指令并对容器作出修改;

(3)执行类似docker commit的操作提交一个新的镜像层;

(4)docker再基于刚提交的镜像运行一个新容器;

(5)执行dockerfile中的下一条指令直到所有指令都执行完成。

9.7.3. 不同阶段

1、Dockerfile :是软件的原材料,需要定义一个Dockerfile,Dockerfile定义了进程需要的一切东西。Dockerfile涉及的内容包括执行代码或者是文件、环境变量、依赖包、运行时环境、动态链接库等等;

2、Docker镜像 :是软件的交付品,用Dockerfile定义一个文件之后,docker build时会产生一个Docker镜像,当运行 Docker镜像时,会真正开始提供服务;

3、Docker容器 :则可以认为是软件的运行态,容器是直接提供服务的

9.7.4. 各参数详解

FROM:指明构建的新镜像是来自于哪个基础镜像;

MAINTAINER:指明镜像维护者及其联系方式;

RUN:执行什么命令;

CMD:指定一个容器启动时要运行的命令,Dockerfile 中可以有多个 CMD 指令,但只有最后一个生效,CMD 会被 docker run 之后的参数替换;

EXPOSE:声明容器运行的服务端口;

ENV:构建镜像过程中设置环境变量;

ADD:将宿主机上的目录或者文件拷贝到镜像中(会帮你自动解压,无需额外操作);

COPY:作用与ADD类似,但是不支持自动下载和解压;

ENTRYPOINT:指定一个容器启动时要运行的命令,用法类似于CMD,只是有由ENTRYPOINT启动的程序不会被docker run命令行指定的参数所覆盖,而且,这些命令行参数会被当作参数传递给ENTRYPOINT指定的程序;

VOLUME:容器数据卷,指定容器挂载点到宿主机自动生成的目录或者其他容器(数据保存和持久化工作,但是一般不会在 Dockerfile 中用到,更常见的还是命令 docker run 的时候指定 -v 数据卷。);

WORKDIR:相当于cd命令,切换目录路径;

9.7.5. 示例1 构建sshd镜像

[root@localhost ~]# cd /opt/
[root@localhost opt]# mkdir sshd ##创建目录
[root@localhost opt]# cd sshd/
[root@localhost sshd]# vim Dockerfile ##编写dockerfile文件 FROM centos ##下载镜像
MAINTAINER this is sshd <xu> ##描述信息
RUN yum -y update
RUN yum -y install openssh* net-tools lsof telnet passwd
RUN echo '123456' | passwd --stdin root
RUN sed -i 's/UsePAM yes/UsePAM no/g' /etc/ssh/sshd_config
RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key
RUN sed -i '/^session\s\+required\s\+pam_loginuid.so/s/^/#/' /etc/pam.d/sshd
RUN mkdir -p /root/.ssh && chown root.root /root && chmod 700 /root/.ssh
EXPOSE 22 ##端口
CMD ["/usr/sbin/sshd" , "-D"]
[root@localhost sshd]# docker build -t sshd:new . ##创建镜像
89432272695ab560b18de75a064428e4a7c4a52dfce223afd2e85132ae6c3c72
[root@localhost sshd]# docker run -d -P sshd:new ##创建映射和容器
[root@localhost sshd]# docker ps -a ##查看容器状态
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
89432272695a sshd:new "/usr/sbin/sshd -D" 7 seconds ago Up 6 seconds 0.0.0.0:32768->22/tcp sad_fermi
[root@localhost sshd]# ssh localhost -p 32768 ##用ssh登录本地

9.7.6. 示例2 构建systemctl镜像

[root@localhost ~]# cd /opt/
[root@localhost opt]# mkdir systemctl ##创建目录
[root@localhost opt]# cd systemctl/
[root@localhost systemctl]# vim Dockerfile ##编写dockerfile文件 FROM sshd:new
ENV container docker ##环境
RUN (cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ $i == systemd-tmpfiles-setup.service ] || rm -f $i; done); \
rm -f /lib/systemd/system/multi-user.target.wants/*; \
rm -f /etc/systemd/system/*.wants/*; \
rm -f /lib/systemd/system/local-fs.target.wants/*; \
rm -f /lib/systemd/system/sockets.target.wants/*udev*; \
rm -f /lib/systemd/system/sockets.target.wants/*initctl*; \
rm -f /lib/systemd/system/basic.target.wants/*; \
rm -f /lib/systemd/system/anaconda.target.wants/*;
VOLUME [ "/sys/fs/cgroup" ]
CMD ["/usr/sbin/init"]
[root@localhost systemctl]# docker build -t systemd:lasted . ##创建镜像
[root@localhost systemctl]# docker run --privileged -it -v /sys/fs/cgroup/:/sys/fs/cgroup:ro systemd:lasted /sbin/init
##privateged container 内的root拥有真正的root权限,否则,container内的root只是外部的一个普通用户权限。
[root@localhost ~]# docker exec -it 23a50d568c75 bash ##进入容器
[root@23a50d568c75 /]# systemctl status sshd ##查看状态

9.7.7. 示例3 构建Nginx镜像

[root@localhost ~]# cd /opt/
[root@localhost opt]# mkdir nginx ##创建Nginx目录
[root@localhost opt]# cd nginx/
[root@localhost nginx]# vim Dockerfile FROM centos:7
MAINTAINER The is nginx <xu>
RUN yum install -y proc-devel gcc gcc-c++ zlib zlib-devel make openssl-devel wget
ADD nginx-1.12.2.tar.gz /usr/local
WORKDIR /usr/local/nginx-1.12.2/
RUN ./configure --prefix=/usr/local/nginx && make && make install
EXPOSE 80
EXPOSE 443
RUN echo "daemon off;">>/usr/local/nginx/conf/nginx.conf
WORKDIR /root/nginx
ADD run.sh /run.sh
RUN chmod 755 /run.sh
CMD ["/run.sh"]
[root@localhost nginx]# vim run.sh #!/bin/bash
/usr/local/nginx/sbin/nginx ##开启Nginx服务
[root@localhost nginx]# mount.cifs //192.168.100.3/LNMP-C7 /mnt/ ##挂载镜像
Password for root@//192.168.100.3/LNMP-C7:
[root@localhost nginx]# cp /mnt/nginx-1.12.2.tar.gz ./ ##复制到当前目录下
[root@localhost nginx]# docker build -t nginx:new . ##创建镜像
[root@localhost nginx]# docker run -d -P nginx:new ##创建容器
228c1f5b8070d52c6f19d03159ad93a60d682a586c0b1f944dc651ee40576a3e
[root@localhost nginx]# docker ps -a ##查看容器
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
228c1f5b8070 nginx:new "/run.sh" 9 seconds ago Up 8 seconds 0.0.0.0:32770->80/tcp, 0.0.0.0:32769->443/tcp busy_booth
##用浏览器访问网页

9.7.8. 示例4 构建Tomcat镜像

[root@localhost opt]# mkdir tomcat
[root@localhost opt]# cd tomcat
[root@localhost tomcat]# cp /mnt/tomcat/jdk-8u91-linux-x64.tar.gz ./ ##复制到当前目录
[root@localhost tomcat]# cp /mnt/Tomcat1/tomcat/apache-tomcat-9.0.16.tar.gz ./
[root@localhost tomcat]# vim Dockerfile
FROM centos:7
MAINTAINER this is tomcat
ADD jdk-8u91-linux-x64.tar.gz /usr/local
WORKDIR /usr/local
RUN mv jdk1.8.0_91 /usr/local/java
ENV JAVA_HOME /usr/local/java ##设置环境变量
ENV JAVA_BIN /usr/local/java/bin
ENV JRE_HOME /usr/local/java/jre
ENV PATH $PATH:/usr/local/java/bin:/usr/local/java/jre/bin
ENV CLASSPATH /usr/local/java/jre/bin:/usr/local/java/lib:/usr/local/java/jre/lib/charsets.jar
ADD apache-tomcat-8.5.16.tar.gz /usr/local
WORKDIR /usr/local
RUN mv apache-tomcat-8.5.16 /usr/local/tomcat8
EXPOSE 8080
ENTRYPOINT ["/usr/local/tomcat8/bin/catalina.sh","run"]
[root@localhost tomcat]# docker build -t tomcat:centos . ##创建镜像
[root@localhost tomcat]# docker run --name tomcat01 -p 1234:8080 -it tomcat:centos /bin/bash
##创建容器 ##利用浏览器访问

9.7.9. 示例5 构建MySQL镜像

[root@localhost opt]# mkdir mysql
[root@localhost opt]# cd mysql
[root@localhost mysql]# cp /mnt/mysql-boost-5.7.20.tar.gz ./ ##将压缩包复制到当前目录下
[root@localhost mysql]# vim my.cnf ##在当前目录下创建配置文件模板 [client]
port = 3306
default-character-set=utf8
socket = /usr/local/mysql/mysql.sock [mysql]
port = 3306
default-character-set=utf8
socket = /usr/local/mysql/mysql.sock [mysqld]
user = mysql
basedir = /usr/local/mysql
datadir = /usr/local/mysql/data
port = 3306
character_set_server=utf8
pid-file = /usr/local/mysql/mysqld.pid
socket = /usr/local/mysql/mysql.sock
server-id = 1 sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_AUTO_VALUE_ON_ZERO,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,PIPES_AS_CONCAT,ANSI_QUOTES
[root@localhost mysql]# vim Dockerfile ##编写dockerfile文件
FROM centos:7
RUN yum -y install \
ncurses \
ncurses-devel \
bison \
cmake \
make \
gcc \
gcc-c++
RUN useradd -s /sbin/nologin mysql
ADD mysql-boost-5.7.20.tar.gz /usr/local/src
WORKDIR /usr/local/src/mysql-5.7.20/
RUN cmake \
-DCMAKE_INSTALL_PREFIX=/usr/local/mysql \
-DMYSQL_UNIX_ADDR=/usr/local/mysql/mysql.sock \
-DSYSCONFDIR=/etc \
-DSYSTEMD_PID_DIR=/usr/local/mysql \
-DDEFAULT_CHARSET=utf8 \
-DDEFAULT_COLLATION=utf8_general_ci \
-DWITH_INNOBASE_STORAGE_ENGINE=1 \
-DWITH_ARCHIVE_STORAGE_ENGINE=1 \
-DWITH_BLACKHOLE_STORAGE_ENGINE=1 \
-DWITH_PERFSCHEMA_STORAGE_ENGINE=1 \
-DMYSQL_DATADIR=/usr/local/mysql/data \
-DWITH_BOOST=boost \
-DWITH_SYSTEMD=1 && make && make install
RUN chown -R mysql:mysql /usr/local/mysql/
RUN rm -rf /etc/my.cnf
ADD my.cnf /etc
RUN chown mysql:mysql /etc/my.cnf
ENV PATH=/usr/local/mysql/bin:/usr/local/mysql/lib:$PATH
WORKDIR /usr/local/mysql/
RUN bin/mysqld \
--initialize-insecure \
--user=mysql \
--basedir=/usr/local/mysql \
--datadir=/usr/local/mysql/data
RUN cp /usr/local/mysql/usr/lib/systemd/system/mysqld.service /usr/lib/systemd/system/
EXPOSE 3306
RUN echo -e "#!/bin/sh \nsystemctl enable mysqld" > /run.sh
RUN chmod 755 /run.sh
RUN sh /run.sh
CMD ["init"]
[root@localhost mysql]# docker build -t centos:mysql . ##创建镜像
[root@localhost mysql]# docker run --name=mysql_server -d -P --privileged centos:mysql
##创建容器
[root@localhost mysql]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
998dc9797102 centos:mysql "init" About a minute ago Up About a minute 0.0.0.0:32768->3306/tcp mysql_server
[root@localhost mysql]# docker exec -it 998dc9797102 /bin/bash [root@998dc9797102 mysql]# mysql
mysql> grant all privileges on *.* to 'root'@'%' identified by 'abc123';
mysql> grant all privileges on *.* to 'root'@'localhost' identified by 'abc123';
[root@localhost ~]# mysql -h 192.168.13.128 -u root -P 32768 -pabc123
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 4
Server version: 5.7.20 Source distribution Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. MySQL [(none)]>

10. kubectl命令

IPVS: IP virtual Server

IPVS 采用的是hash存放规则,查询、执行速度快

iptables 线性读取

ipvs为大型集群提供更好的可扩展性和性能

Linux命令示例记录-20230313【持续更新中】的更多相关文章

  1. Linux 命令备忘(持续更新中……)

    Linux命令 grep 1. 使用grep 筛选内容,多条件筛选用 grep - E "条件1|条件2" (满足条件1或条件2的均展示) 2. grep '条件3'|grep - ...

  2. 常用linux命令合集(持续更新中)

    我的博客:www.while0.com 开发调试 readelf-a 查看elf文件中的内容 hexdump -C 用16进制查看文件 objdump -d 反汇编目标文件 nm 查看目标文件或者可执 ...

  3. .NET6中一些常用组件的配置及使用记录,持续更新中。。。

    NET6App 介绍 .NET 6的CoreApp框架,用来学习.NET6的一些变动和新特性,使用EFCore,等一系列组件的运用,每个用单独的文档篇章记录,持续更新文档哦. 如果对您有帮助,点击右上 ...

  4. Atom使用记录(持续更新中)

    部分内容取自:http://www.jianshu.com/p/dd97cbb3c22d,我自己也在使用,持续更新中 Atom安装插件在窗口中File---Setting---install 在里面进 ...

  5. oracle数据库学习记录(持续更新中...)

    --------------------------------------------day1------------------------------------------------- 1. ...

  6. SharePoint 命令使用集锦 (持续更新中...)

    首先要定位到 cd "Program Files\Common Files\Microsoft Shared\web server extensions\14\BIN" 下面   ...

  7. 开发常用Git/Linux/idea命令快捷键总结(持续更新)

    在开发过程中,会使用越来越多的命令,或快捷键,来帮助我们提高工作效率.本文记录了我在平时积累的常用命令,分享给大家. git命令 基本命令 set LESSCHARSET=utf-8 --idea T ...

  8. git常用命令(持续更新中)

    git常用命令(持续更新中) 本地仓库操作git int                                 初始化本地仓库git add .                       ...

  9. 【github&&git】4、git常用命令(持续更新中)

    git常用命令(持续更新中) 本地仓库操作git int                                 初始化本地仓库git add .                       ...

  10. 史上最全的spark面试题——持续更新中

    史上最全的spark面试题——持续更新中 2018年09月09日 16:34:10 为了九亿少女的期待 阅读数 13696更多 分类专栏: Spark 面试题   版权声明:本文为博主原创文章,遵循C ...

随机推荐

  1. Windows D3D渲染到纹理

    D3D渲染到纹理 1 #include <d3dx9.h> 2 3 //---------------------------------------------------------- ...

  2. CSS中Position几种属性的总结

    定位position 定位方向:left  right  top  bottom 静态定位:static  默认值,就是文档流 绝对定位:absolute    特点: 1.不占据原来的位置(脱标) ...

  3. 浏览器垃圾回收机制:栈垃圾回收、堆垃圾回收、新生区老生区、Scavenge算法、标记-清除算法、标记-整理算法、全停顿、增量标记

    浏览器垃圾回收机制根据数据的存储方式分为栈垃圾回收和堆垃圾回收. 栈垃圾回收的方式非常简便,当一个函数执行结束之后,JavaScript 引擎会通过向下移动 ESP 来销毁该函数保存在栈中的执行上下文 ...

  4. Java中String,JSON对象,java实体类(Bean)之间的相互转换

    FastJson对于json格式字符串的解析主要用到了一下三个类: (1)JSON:fastJson的解析器,用于JSON格式字符串与JSON对象及javaBean之间的转换. (2)JSONObje ...

  5. Ubuntu linux下gcc、g++不同版本的安装和切换

    讲解linux下gcc.g++不同版本的安装和切换 Ubuntu 18.04预装GCC版本为7.3,但有时在编译是需要用的不同gcc版本,下面介绍,如何安装不同的gcc 和g++,并设置根据不同的需要 ...

  6. Python turtle print TaiChi

    import turtle turtle.pensize(20) turtle.pencolor("black") turtle.penup() turtle.goto(0,300 ...

  7. centos7.6镜像

    centos7.6镜像 https://archive.kernel.org/centos-vault/7.6.1810/isos/x86_64/

  8. spring-security-oauth2使用遇到的坑

    异常信息为 2021-08-22 14:24:11.086 WARN 17812 --- [ main] ConfigServletWebServerApplicationContext : Exce ...

  9. 09 Hive安装与操作

    一.安装Hive 下载解压重命名权限 配置环境变量 修改Hive配置文件 修改/usr/local/hive/conf下的hive-site.xml 1 2 3 4 5 6 7 8 9 10 11 1 ...

  10. jmeter性能测试小小实践

    一.测试步骤 测试计划 / 线程组 / http请求 / 监听器 / 运行脚本 / 查看报告 二.线程组 线程组:虚拟用户数 ramp up period:设置虚拟用户数需要多长的时间全部启动,如果线 ...