云计算:OVN 集群分布式交换机部署指南

在云计算环境下,网络虚拟化是实现多租户隔离、动态拓扑调整以及 SDN(软件定义网络)能力的关键。OVN(Open Virtual Network)作为 Open vSwitch(OVS)的网络控制平面,能够提供分布式虚拟交换机(Distributed Virtual Switch)和路由(Distributed Logical Router)功能。本文将从概念、架构、部署步骤、代码示例和拓扑图解等多方面入手,帮助你系统掌握 OVN 集群分布式交换机的部署要点。


目录

  1. OVN 基础概念与架构概述
    1.1. OVN 组成组件
    1.2. OVN 与 OVS 的关系
    1.3. 逻辑交换机与物理物理节点映射
  2. 部署准备与环境要求
    2.1. 操作系统与软件依赖
    2.2. 主机列表与角色分配
    2.3. 网络及端口说明
  3. OVN 数据库集群配置
    3.1. OVSDB Server 集群(Northbound / Southbound)
    3.2. 数据库高可用与复制模式
    3.3. 启动 OVSDB Server 示例代码
  4. OVN 控制平面组件部署
    4.1. ovn-northd 服务部署与配置
    4.2. ovn-controller 部署到计算节点
    4.3. OVN Southbound 与 OVSDB 的连接
  5. 构建逻辑网络:Logical Switch 与 Logical Router
    5.1. 创建 Logical Switch
    5.2. 创建 Logical Router 与路由规则
    5.3. 逻辑端口绑定到物理接口
    5.4. 图解:逻辑网络数据平面流向
  6. 部署案例:三节点 OVN 集群
    6.1. 节点角色与 IP 拓扑
    6.2. 步骤详解:从零搭建
    6.3. 配置脚本与代码示例
    6.4. 拓扑图解(ASCII 或流程图)
  7. 动态扩容与故障切换
    7.1. 新加入 OVN 控制节点示例
    7.2. OVN 数据库 Leader 选举与故障恢复
    7.3. OVN Controller 动态下线/上线示例
  8. 运维与调试要点
    8.1. 常用 ovn-nbctl / ovn-sbctl 命令
    8.2. 日志与诊断:ovn-northd、ovn-controller 日志级别
    8.3. 性能优化建议
  9. 总结与最佳实践

1. OVN 基础概念与架构概述

1.1 OVN 组成组件

OVN(Open Virtual Network)是一套基于 OVS (Open vSwitch)的网络控制平台,主要包含以下核心组件:

  • OVN Northbound Database(NB\_DB)
    存储高层逻辑网络模型,例如 Logical Switch、Logical Router、ACL、DHCP 选项等。上层管理工具(如 Kubernetes CNI、OpenStack Neutron OVN 驱动)通过 ovn-nbctl 或 API 将网络需求写入 NB\_DB。
  • OVN Southbound Database(SB\_DB)
    存储将逻辑模型转化后的“下发”配置,用于各个 OVN Controller 在底层实现。由 ovn-northd 将 NB\_DB 的内容同步并转换到 SB\_DB。
  • ovn-northd
    Northd 轮询读取 NB\_DB 中的逻辑网络信息,将其转换为 SB\_DB 可识别的表项(如 Logical Flow、Chassis 绑定),并写入 SB\_DB。是整个控制平面的“大脑”。
  • ovn-controller
    部署在每台物理(或虚拟)宿主机(也称 Chassis)上,与本机的 OVS 数据平面对接,监听 SB\_DB 中下发的 Logical Flow、Security Group、ACL、DHCP 等信息,并通过 OpenFlow 将其下发给 OVS。
  • OVSDB Server
    每个 OVN 数据库(NB\_DB、SB\_DB)本质上是一个 OVSDB(Open vSwitch Database)实例,提供集群复制和多客户端并发访问能力。
  • OVS (Open vSwitch)
    部署在每个 Chassis 上,负责实际转发数据包。OVN Controller 通过 OVSDB 与 OVS 通信,下发 OpenFlow 规则,完成数据路径的构建。

1.2 OVN 与 OVS 的关系

┌───────────────────────────────┐
│        上层管理/编排系统       │  (如 Kubernetes CNI、OpenStack Neutron OVN)
│ nbctl / REST API / gRPC 调用   │
└───────────────┬───────────────┘
                │ 写入/读取 Northbound DB
                ▼
┌───────────────────────────────┐
│    OVN Northbound Database    │ (OVSDB Server 集群)
└───────────────┬───────────────┘
                │  ovn-northd 转换
                ▼
┌───────────────────────────────┐
│    OVN Southbound Database    │ (OVSDB Server 集群)
└───────────────┬───────────────┘
                │  OVN Controller 轮询监听
                ▼
┌───────────────────────────────┐
│     OVN Controller (Chassis)  │
│  OpenFlow 下发 Logical Flow   │
└───────────────┬───────────────┘
                │
                ▼
┌───────────────────────────────┐
│      OVS 数据平面 (Kernel)     │
└───────────────────────────────┘
  • Northbound DB:上层系统定义逻辑网络(LS、LR、ACL、DHCP、LB 等)。
  • ovn-northd:将逻辑模型转换为“物理可执行”规则,写入 Southbound DB。
  • Southbound DB:各 OVN Controller 轮询,找到自己节点相关的配置,最终下发 OpenFlow 规则到 OVS。
  • OVS:真正负责数据包转发的 Linux kernel 模块。

1.3 逻辑交换机与物理节点映射

OVN 中的 Logical Switch (LS)Logical Router (LR) 是虚拟拓扑中的抽象,所有逻辑交换机/路由器并不存在于物理硬件上,而是通过下发的 OpenFlow 覆盖实际网络接口和隧道端点,实现跨主机的二层转发和三层路由。底层通过 Geneve 隧道(默认 6081 端口) 在主机之间封装虚拟网络。

                          ┌────────────────┐
                          │    LS1 (逻辑)   │
                          └──────┬─────────┘
                                 │ 通过 Geneve 隧道
                                 ▼
┌───────────────┐          ┌───────────────┐          ┌───────────────┐
│ Chassis A_OVS │◀────────▶│ Chassis B_OVS │◀────────▶│ Chassis C_OVS │
│   192.168.1.1 │ Geneve   │   192.168.1.2 │ Geneve   │   192.168.1.3 │
└───────────────┘ Tunnel   └───────────────┘ Tunnel   └───────────────┘
      │                            │                         │
   VM1 eth0                     VM2 eth0                  VM3 eth0
  • 在 Chassis A、B、C 上,OVN Controller 将为 LS1 下发对应的隧道端点配置(如 Geneve 隧道,VNI ID),使 VM1/VM2/VM3 虚拟接口如同在同一交换机中。

2. 部署准备与环境要求

本文示例通过三台主机部署 OVN 集群:两台作为 OVN 数据库高可用节点,三台作为 Chassis(运行 ovn-controller 和 OVS)。如需生产环境部署,建议奇数台 OVSDB Server,以保证 etcd 或 Raft 一致性。

2.1 操作系统与软件依赖

  • 操作系统:Ubuntu 20.04 LTS(其他基于 systemd 的 Linux 发行版类似)。
  • 所需软件包:

    sudo apt-get update
    sudo apt-get install -y \
      openvswitch-switch \
      openvswitch-common \
      ovn-central \
      ovn-host \
      ovn-common \
      python3-pip \
      python3-venv
    • openvswitch-switch/openvswitch-common:安装 OVS 数据平面与管理工具。
    • ovn-central:包含 OVN Northbound/Southbound OVSDB Server 和 ovn-northd
    • ovn-host:包含 ovn-controller 与相关脚本。
    • ovn-common:OVN 公共文件。
  • 注意:部分发行版的包名可能为 ovn-gitovs-ovn,请根据对应仓库替换。

2.2 主机列表与角色分配

假设我们有以下三台服务器:

主机名IP 地址角色
db1192.168.1.10OVN NB/SB OVSDB Server 节点
db2192.168.1.11OVN NB/SB OVSDB Server 节点
chx1192.168.1.21OVN Controller + OVS(Chassis)
chx2192.168.1.22OVN Controller + OVS(Chassis)
chx3192.168.1.23OVN Controller + OVS(Chassis)
  • db1db2:作为 OVN 数据库高可用的 Raft 集群;
  • chx1chx2chx3:部署 ovn-controller,作为数据平面转发节点。

2.3 网络及端口说明

  • OVSDB Server 端口

    • 6641/TCP:OVS 本地 OVSDB Server(管理本机 OVS);
    • 6642/TCP:OVN NB\_DB 监听端口;
    • 6643/TCP:OVN SB\_DB 监听端口。
  • Geneve 隧道端口

    • 6081/UDP(默认):Chassis 之间封装 Geneve 隧道,用于二层转发。
  • Control Plane 端口

    • 6644/TCP(可选):ovn-northd 与管理工具通信;
    • 6645/TCP(可选):基于 SSL 的 OVSDB 连接。
  • 防火墙:请确保上述端口在主机之间互通,例如:

    sudo ufw allow 6642/tcp
    sudo ufw allow 6643/tcp
    sudo ufw allow 6081/udp
    sudo ufw reload

3. OVN 数据库集群配置

3.1 OVSDB Server 集群(Northbound / Southbound)

OVN 使用 OVSDB(基于 OVSDB 协议)存储其 Northbound(NB)和 Southbound(SB)数据库。为了高可用,我们需要在多台主机上运行 OVSDB Server 并采用 Raft 或 Standalone 模式互为备份。

  • Northbound DB:存放高层逻辑网络拓扑。
  • Southbound DB:存放下发到各 Chassis 的逻辑 Flow、Chassis Binding 信息。

db1db2 上分别启动两个 OVSDB Server 实例,用于 NB、SB 数据库的 HA。

3.2 数据库高可用与复制模式

OVN 官方支持三种模式:

  1. 集群模式(Ovsdb Cluster Mode):通过内置 Raft 协议实现三节点以上的强一致性。
  2. Standalone + Keepalived 虚拟 IP:两个节点分别运行 OVSDB,Keepalived 提供 VIP,只有 Master 节点对外开放。
  3. etcd + Ovsdb Client:将 OVN DB 存于 etcd,但较少使用。

本文以两节点 OVN DB Standalone 模式 + Keepalived 提供 VIP为例,实现简易高可用。(生产建议至少 3 节点 Raft 模式)

3.3 启动 OVSDB Server 示例代码

3.3.1 配置 Northbound 数据库

db1db2 上的 /etc/ovn/ovn-nb.conf 中指定数据库侦听地址和辅助备份。

db1 上执行:

# 初始化 /etc/openvswitch/conf.db,确保 OVS 已初始化
sudo ovsdb-tool create /etc/openvswitch/ovnnb_db.db \
    /usr/share/ovs/ovnnb_db.ovsschema

# 启动 ovnnb-server(Northbound OVSDB)并监听在 6642
sudo ovsdb-server --remote=ptcp:6642:0 \
                 --pidfile --detach \
                 /etc/openvswitch/ovnnb_db.db \
                 --no-chdir \
                 --log-file=/var/log/ovn/ovnnb-server.log \
                 --remote=punix:/var/run/openvswitch/ovnnb_db.sock \
                 --private-key=db1-privkey.pem \
                 --certificate=db1-cert.pem \
                 --bootstrap-ca-cert=ca-cert.pem \
                 --ca-cert=ca-cert.pem

db2 上执行相同命令,并将数据库文件改为 /etc/openvswitch/ovnnb_db.db,保持路径一致。然后使用 Keepalived 配置 VIP(如 192.168.1.100:6642)浮动在两节点之间。

3.3.2 配置 Southbound 数据库

同理,在 db1db2 上各创建并启动 OVN SB OVSDB:

sudo ovsdb-tool create /etc/openvswitch/ovnsb_db.db \
    /usr/share/ovs/ovnsb_db.ovsschema

sudo ovsdb-server --remote=ptcp:6643:0 \
                 --pidfile --detach \
                 /etc/openvswitch/ovnsb_db.db \
                 --no-chdir \
                 --log-file=/var/log/ovn/ovnsb-server.log \
                 --remote=punix:/var/run/openvswitch/ovnsb_db.sock \
                 --private-key=db1-privkey.pem \
                 --certificate=db1-cert.pem \
                 --bootstrap-ca-cert=ca-cert.pem \
                 --ca-cert=ca-cert.pem

同样使用 Keepalived 将 192.168.1.100:6643 VIP 浮动在两节点间。这样,OVN 控制平面组件(ovn-northd、ovn-controller)可以统一通过 VIP 访问 NB\_DB/SB\_DB。

:示例中用到了 SSL 证书和私钥(db1-privkey.pemdb1-cert.pemca-cert.pem),用于 OVSDB 加密通信。如果环境不需要加密,可省略 --private-key--certificate--ca-cert--bootstrap-ca-cert 参数。

4. OVN 控制平面组件部署

4.1 ovn-northd 服务部署与配置

ovn-northd 是 OVN 控制平面的核心进程,它会监听 NB\_DB,并将逻辑网络翻译为 SB\_DB 所需的格式。通常部署在 DB 节点或者单独的控制节点上。

4.1.1 ovn-northd 启动命令示例

假设 NB VIP 为 192.168.1.100:6642,SB VIP 为 192.168.1.100:6643,可在任意一台控制节点(或 db1db2 随机选一)执行:

sudo ovsdb-client set connection:ovnnb \
    . external_ids:ovn-remote="ptcp:6642:192.168.1.100" \
    external_ids:ovn-nb \
    external_ids:ovn-cacert="/etc/ovn/ca-cert.pem" \
    external_ids:ovn-cert="/etc/ovn/controller-cert.pem" \
    external_ids:ovn-privkey="/etc/ovn/controller-privkey.pem"

sudo ovsdb-client set connection:ovnsb \
    . external_ids:ovn-remote="ptcp:6643:192.168.1.100" \
    external_ids:ovn-sb \
    external_ids:ovn-cacert="/etc/ovn/ca-cert.pem" \
    external_ids:ovn-cert="/etc/ovn/controller-cert.pem" \
    external_ids:ovn-privkey="/etc/ovn/controller-privkey.pem"

# 启动 ovn-northd
sudo ovn-northd \
    --log-file=/var/log/ovn/ovn-northd.log \
    --pidfile \
    --ovnnb-db ptcp:6642:192.168.1.100 \
    --ovnsb-db ptcp:6643:192.168.1.100 \
    --ovnnb-private-key=/etc/ovn/controller-privkey.pem \
    --ovnnb-certificate=/etc/ovn/controller-cert.pem \
    --ovnnb-cacert=/etc/ovn/ca-cert.pem \
    --ovnsb-private-key=/etc/ovn/controller-privkey.pem \
    --ovnsb-certificate=/etc/ovn/controller-cert.pem \
    --ovnsb-cacert=/etc/ovn/ca-cert.pem
  • --ovnnb-db--ovnsb-db:指向 NB/SB 数据库的访问地址(可以使用 VIP)。
  • external_ids:用于 OVSDB 客户端指定 OVN 相关参数。

4.1.2 验证 ovn-northd 是否正常工作

查看 Northbound DB 表是否被填充:

ovn-nbctl --db=tcp:192.168.1.100:6642 show

应能看到如下输出(如果尚未创建任何逻辑网络,可看到空表):

A global
    is_uuid ver
    ...

4.2 ovn-controller 部署到计算节点

在每台 Chassis (chx1chx2chx3) 上,需要安装并运行 ovn-controller 以将 Southbound DB 中的下发规则同步到本机 OVS。

4.2.1 安装 OVS 与 OVN Host

在每台 Chassis 上执行:

sudo apt-get install -y openvswitch-switch openvswitch-common ovn-host ovn-common

4.2.2 配置 OVSDB 连接

OVN Controller 启动前,需要设置 OVS 与 OVN Southbound 数据库的关联。假设 SB VIP 为 192.168.1.100:6643,执行:

# 配置本机 OVSDB 连接 Southbound DB
sudo ovs-vsctl set open . external_ids:ovn-remote="ptcp:6643:192.168.1.100" 
sudo ovs-vsctl set open . external_ids:ovn-external-ids="ovn-sb"
sudo ovs-vsctl set open . external_ids:ovn-cacert="/etc/ovn/ca-cert.pem"
sudo ovs-vsctl set open . external_ids:ovn-cert="/etc/ovn/chassis-cert.pem"
sudo ovs-vsctl set open . external_ids:ovn-privkey="/etc/ovn/chassis-privkey.pem"
  • external_ids:ovn-remote:指定 SB\_DB 的访问地址。
  • ovn-cacertovn-certovn-privkey:指定 SSL 证书,以保证 OVSDB 对 SB\_DB 的安全访问。如果不使用加密,可省略证书配置。

4.2.3 启动 ovn-controller

sudo systemctl enable ovn-controller
sudo systemctl start ovn-controller

或者直接手动:

sudo ovn-controller \
    --pidfile \
    --log-file=/var/log/ovn/ovn-controller.log \
    --no-chdir \
    --db=tcp:192.168.1.100:6643 \
    --ovn-controller-chassis-id=$(hostname)
  • --db:SB DB 地址。
  • --ovn-controller-chassis-id:本机作为 OVN Chassis 的唯一标识,一般取主机名或 IP。

4.2.4 验证 ovn-controller 连接状态

在 Chassis 上执行:

ovs-vsctl get open . external_ids:ovn-chassis-id
ovs-vsctl get open . external_ids:ovn-remote

应能看到已配置的 chassis-idovn-remote。同时查看日志 /var/log/ovn/ovn-controller.log,确认 Chassis 已成功注册到 SB\_DB。


5. 构建逻辑网络:Logical Switch 与 Logical Router

完成 OVN 控制平面部署后,就可以开始在 OVN NB\_DB 中创建逻辑网络,ovn-northd 会将其下发到 SB\_DB,再由 ovn-controller 传播到各 Chassis。

5.1 创建 Logical Switch

假设要创建一个名为 ls_sw1 的虚拟交换机,并在其中添加两个逻辑端口(对应虚拟机网卡)lsw1-port1lsw1-port2

# 创建逻辑交换机
ovn-nbctl ls-add ls_sw1

# 添加逻辑端口
ovn-nbctl lsp-add ls_sw1 lsw1-port1
ovn-nbctl lsp-add ls_sw1 lsw1-port2

# 为端口分配 DHCP 或固定 IP(可选)
# 例如为 lsw1-port1 分配固定 IP 192.168.100.10/24
ovn-nbctl lsp-set-addresses lsw1-port1 "00:00:00:00:00:01 192.168.100.10"

# 也可不指定地址,由 DHCP 服务分配
  • ls-add <logical-switch>:创建名为 logical-switch 的逻辑交换机;
  • lsp-add <logical-switch> <logical-port>:向交换机添加一个逻辑端口;
  • lsp-set-addresses <logical-port> "<MAC> <IP>":为逻辑端口分配 MAC 和 IP。

5.2 创建 Logical Router 与路由规则

若需要 Layer-3 路由,可创建一个逻辑路由器 lr_router1,并为其添加北向(外部网)接口和南向(逻辑交换机)接口。

# 创建逻辑路由器
ovn-nbctl lr-add lr_router1

# 添加路由器端口,连接到 ls_sw1
ovn-nbctl lrp-add lr_router1 ls1-to-lr1 00:00:aa:aa:aa:01 192.168.100.1/24

# 让交换机 ls_sw1 中的端口 lsw1-port1、lsw1-port2 都连接到路由器
# 需要为交换机添加一个“Router Port(RP)”端口
ovn-nbctl lsp-add ls_sw1 ls1-to-lr1
ovn-nbctl lsp-set-type ls1-to-lr1 router
ovn-nbctl lsp-set-options ls1-to-lr1 router-port=ls1-to-lr1

# 添加北向连接到外部网的 Router Port
# 假设外部网为 10.0.0.0/24,接口名为 ls-router-port-ext1
ovn-nbctl lrp-add lr_router1 lr1-to-ext 00:00:bb:bb:bb:01 10.0.0.1/24

# 添加允许的路由规则(北向网关)
ovn-nbctl lr-route-add lr_router1 0.0.0.0/0 10.0.0.254
  • lr-add <logical-router>:创建逻辑路由器;
  • lrp-add <logical-router> <port-name> <MAC> <IP/mask>:在逻辑路由器上添加一个端口;
  • lsp-add <logical-switch> <port-name>:在逻辑交换机上添加对应的端口;
  • lsp-set-type <port-name> router + lsp-set-options router-port=<router-port>:将逻辑交换机端口类型设为 router,并挂接到所属路由器;
  • lr-route-add <logical-router> <destination-cidr> <next-hop>:为逻辑路由器添加静态路由;

5.3 逻辑端口绑定到物理接口

当 VM 要接入逻辑网络时,需要在 OVS 数据平面创建对应的 internal 接口,并将其与 OVN 逻辑端口绑定。假设在 chx1 上有一个 QEMU/KVM 虚拟机网卡 tapvm1,需要将其加入逻辑交换机 ls_sw1

# 在 chx1 的 OVS 上创建一个 OVS 内部接口 ovs-dp-port1
sudo ovs-vsctl add-port br-int enp3s0 -- set interface enp3s0 type=internal

# 或者直接:
sudo ovs-vsctl add-port br-int veth-vm1 -- set interface veth-vm1 type=internal

# 将物理接口与逻辑端口绑定:让 OVN Controller 识别本地逻辑端口
sudo ovs-vsctl set interface enp3s0 external-ids:iface-id=lsw1-port1
sudo ovs-vsctl set interface enp3s0 external-ids:iface-status=active
sudo ovs-vsctl set interface enp3s0 external-ids:attached-mac=02:00:00:00:00:01

# 以上命令实现:
#  1) 在 br-int 上创建名为 enp3s0 的内部端口
#  2) 告诉 OVN Controller 该内部端口对应的逻辑端口 iface-id=lsw1-port1
#  3) 通知 Controller 该逻辑端口已激活
#  4) 指定该端口的实际 MAC 地址

# 重复上述步骤,为 lsw1-port2 在 chx2、chx3 上绑定相应的接口
  • external-ids:iface-id=<logical-port>:告知 OVN Controller,将本地 OVS 接口与 OVN 逻辑端口绑定;
  • iface-status=active:告知 Controller 该端口激活,可参与流量转发;
  • attached-mac=<MAC>:VM 网卡的实际 MAC,用于 OVN Controller 下发 DHCP、NAT、ACL 等规则。

5.4 图解:逻辑网络数据平面流向

以下用 ASCII 图展示在三个 Chassis 上,通过 Geneve 隧道实现逻辑交换机跨主机二层转发的简要流程。

+------------------------+         +------------------------+         +------------------------+
|        Chassis 1       |         |        Chassis 2       |         |        Chassis 3       |
|    IP: 192.168.1.21    |         |    IP: 192.168.1.22    |         |    IP: 192.168.1.23    |
|    OVN Controller      |         |    OVN Controller      |         |    OVN Controller      |
|                        |         |                        |         |                        |
|  OVS br-int            |         |  OVS br-int            |         |  OVS br-int            |
|   +----------------+   |         |   +----------------+   |         |   +----------------+   |
|   | enp3s0 (VM1)   |   |         |   | enp4s0 (VM2)   |   |         |   | enp5s0 (VM3)   |   |
|   +----------------+   |         |   +----------------+   |         |   +----------------+   |
|         │                |         |         │                |         |         │                |
|         ▼                | Geneve   |         ▼                | Geneve   |         ▼                |
|   +-------------------------------------+    +-------------------------------------+    +-------------------------------------+
|   |   Geneve Tunnel to 192.168.1.22     |    |   Geneve Tunnel to 192.168.1.23     |    |   Geneve Tunnel to 192.168.1.21     |
|   +-------------------------------------+    +-------------------------------------+    +-------------------------------------+
|         ▲                |         ▲                |         ▲                |         ▲                |
|         │                |         │                |         │                |         │                |
+------------------------+         +------------------------+         +------------------------+
  • VM1 的流量发送到本机 enp3s0 (iface-id=lsw1-port1),OVS 会根据 OpenFlow 规则封装为 Geneve 隧道报文,发往目标 Chassis。
  • 目标 Chassis 解封装后转发到对应本地 VM。

6. 部署案例:三节点 OVN 集群

下面以更具体的三节点示例,将上述零散步骤串联起来,展示一个自底向上的完整部署流程。

6.1 节点角色与 IP 拓扑

节点名IP 地址角色
db1192.168.1.10OVN NB\_DB/SB\_DB OVSDB Server 节点 (Master)
db2192.168.1.11OVN NB\_DB/SB\_DB OVSDB Server 节点 (Slave)
chx1192.168.1.21OVN Controller + OVS (Chassis)
chx2192.168.1.22OVN Controller + OVS (Chassis)
chx3192.168.1.23OVN Controller + OVS (Chassis)
  • OVN NB VIP192.168.1.100:6642(Keepalived VIP)
  • OVN SB VIP192.168.1.100:6643(Keepalived VIP)

6.2 步骤详解:从零搭建

6.2.1 安装基础软件

在所有节点(db1db2chx1chx2chx3)执行:

sudo apt-get update
sudo apt-get install -y openvswitch-switch openvswitch-common ovn-central ovn-host ovn-common
  • db1db2:主要运行 ovn-central(包含 NB/SB DB、ovn-northd)。
  • chx1chx2chx3:运行 ovn-host(包含 ovn-controller 和 OVS 数据平面)。

6.2.2 配置 OVN 数据库 OVSDB Server

db1db2 上执行以下脚本(以 db1 为例,db2 同理):

# 1. 创建北向数据库文件
sudo ovsdb-tool create /etc/openvswitch/ovnnb_db.db /usr/share/ovn/ovnnb_db.ovsschema

# 2. 启动 OVN NB OVSDB Server
sudo ovsdb-server --remote=ptcp:6642:0 \
                 --pidfile --detach \
                 /etc/openvswitch/ovnnb_db.db \
                 --no-chdir \
                 --log-file=/var/log/ovn/ovnnb-server.log

# 3. 创建南向数据库文件
sudo ovsdb-tool create /etc/openvswitch/ovnsb_db.db /usr/share/ovn/ovnsb_db.ovsschema

# 4. 启动 OVN SB OVSDB Server
sudo ovsdb-server --remote=ptcp:6643:0 \
                 --pidfile --detach \
                 /etc/openvswitch/ovnsb_db.db \
                 --no-chdir \
                 --log-file=/var/log/ovn/ovnsb-server.log
说明:此处暂未使用 SSL、Keepalived,可以先验证单节点正常工作,再后续添加高可用。

6.2.3 部署 ovn-northd

db1 上执行:

sudo ovs-vsctl set open . external_ids:ovn-remote="ptcp:6642:192.168.1.10"    # NB DB 连接
sudo ovs-vsctl set open . external_ids:ovn-external-ids="ovn-nb"

sudo ovs-vsctl set open . external_ids:ovn-remote="ptcp:6643:192.168.1.10"    # SB DB 连接
sudo ovs-vsctl set open . external_ids:ovn-external-ids="ovn-sb"

sudo ovn-northd \
    --log-file=/var/log/ovn/ovn-northd.log \
    --pidfile \
    --ovnnb-db ptcp:6642:192.168.1.10 \
    --ovnsb-db ptcp:6643:192.168.1.10
  • 检查 db1 上是否已生成 /var/log/ovn/ovn-northd.log,并无错误。

6.2.4 配置 Chassis (ovn-controller + OVS)

chx1chx2chx3 上执行以下命令,以 chx1 为例:

# 1. 配置 OVSDB 连接 OVN Southbound DB
sudo ovs-vsctl set open . external_ids:ovn-remote="ptcp:6643:192.168.1.10"
sudo ovs-vsctl set open . external_ids:ovn-external-ids="ovn-sb"

# 2. 启动 ovn-controller
sudo systemctl enable ovn-controller
sudo systemctl start ovn-controller
  • 同时可查看日志 /var/log/ovn/ovn-controller.log,应看到类似 “ovn-controller (chassis “chx1”) connecting to southbound database” 的输出。

6.2.5 创建物理交换桥 br-int

在每台 Chassis 上,OVN Controller 会默认使用 br-int 作为集成交换桥。如果不存在,可手动创建并将物理 NIC 加入以便与外部网络互通。

sudo ovs-vsctl add-br br-int
# 将物理网卡 eth0 作为 uplink 接口,供外部网络访问
sudo ovs-vsctl add-port br-int eth0
  • OVN Controller 会向 br-int 下发 OpenFlow 规则,实现逻辑网络与物理网络互通。

6.3 配置脚本与代码示例

一旦集群所有组件启动正常,就可以开始创建逻辑网络。以下示例脚本 deploy-logical-network.shchx1 为控制端执行。

#!/bin/bash
# deploy-logical-network.sh
# 用于在 OVN 集群中创建逻辑交换机、路由器并绑定端口
# 执行前确保 ovn-northd 和 ovn-controller 均已启动

# 1. 创建逻辑交换机 ls1
ovn-nbctl ls-add ls1

# 2. 在 ls1 上创建端口 lsp1、lsp2
ovn-nbctl lsp-add ls1 lsp1
ovn-nbctl lsp-add ls1 lsp2

# 3. 为端口 lsp1 分配静态 MAC/IP
ovn-nbctl lsp-set-addresses lsp1 "00:00:00:00:01:01 192.168.100.10"
ovn-nbctl lsp-set-port-security lsp1 "00:00:00:00:01:01 192.168.100.10"

# 4. 为端口 lsp2 分配静态 MAC/IP
ovn-nbctl lsp-set-addresses lsp2 "00:00:00:00:01:02 192.168.100.11"
ovn-nbctl lsp-set-port-security lsp2 "00:00:00:00:01:02 192.168.100.11"

# 5. 创建逻辑路由器 lr1
ovn-nbctl lr-add lr1

# 6. 创建路由器端口 lr1-ls1,连接到 ls1
ovn-nbctl lrp-add lr1 lr1-ls1 00:00:00:00:aa:01 192.168.100.1/24
ovn-nbctl lsp-add ls1 ls1-lr1
ovn-nbctl lsp-set-type ls1-lr1 router
ovn-nbctl lsp-set-options ls1-lr1 router-port=lr1-ls1

# 7. 创建外部连接路由器端口 lr1-ext
ovn-nbctl lrp-add lr1 lr1-ext 00:00:00:00:bb:01 10.0.0.1/24
ovn-nbctl lrp-set-gateway-chassis lr1-ext chx1

# 8. 配置静态默认路由,下一跳为物理默认网关 10.0.0.254
ovn-nbctl lr-route-add lr1 0.0.0.0/0 10.0.0.254

echo "逻辑网络已创建:交换机 ls1,路由器 lr1,端口配置完成"
  • 以上脚本将:

    1. 在 NB\_DB 中创建了逻辑交换机 ls1
    2. ls1 创建两个逻辑端口 lsp1lsp2,并分配 MAC/IP;
    3. 创建逻辑路由器 lr1,分别创建 lr1-ls1 连接到 ls1,以及外部接口 lr1-ext
    4. 添加默认路由,将所有未知流量导向物理网关。

执行后,ovn-northd 会将这些逻辑配置下发到 SB\_DB,再被每个 OVN Controller “抓取”并下发到 OVS。

6.4 拓扑图解(ASCII 或流程图)

        ┌─────────────────────────────────────────────────────────────────┐
        │                         OVN NB/SB DB Cluster                    │
        │       +----------------------+   +----------------------+       │
        │       |    db1:6642 (NBDB)   |   |  db2:6642 (NBDB)     |       │
        │       +----------------------+   +----------------------+       │
        │       |    db1:6643 (SBDB)   |   |  db2:6643 (SBDB)     |       │
        │       +----------------------+   +----------------------+       │
        └─────────────────────────────────────────────────────────────────┘
                           ▲                         ▲
                 监听 NB/SB |                         | 监听 NB/SB
                           │                         │
        ┌──────────────────┴─────────────────────────┴───────────────────┐
        │                            ovn-northd                              │
        │  (读取 NBDB,转换并写入 SBDB)                                       │
        └──────────────────┬─────────────────────────┬───────────────────┘
                           │                         │
             下发 SB      ▼                         ▼       下发 SB
           ┌──────────┐   ┌──────────────────┐   ┌──────────┐  
           │ chx1     │   │ chx2             │   │ chx3     │  
           │ ovn-ctrl │   │ ovn-ctrl         │   │ ovn-ctrl │  
           │ br-int   │   │ br-int           │   │ br-int   │  
           └────┬─────┘   └──────┬───────────┘   └────┬─────┘  
                │              │                      │        
          隧道 │            隧道                  隧道 │        
       Geneve▼            Geneve                  Geneve▼        
        ┌───────────────┐         ┌───────────────┐         ┌───────────────┐
        │  虚拟交换机 ls1  ├────────▶  虚拟交换机 ls1  ◀────────▶  虚拟交换机 ls1  │
        │   (逻辑拓扑)    │         │   (逻辑拓扑)    │         │   (逻辑拓扑)    │
        └───────────────┘         └───────────────┘         └───────────────┘
            │   ▲                       │   ▲                       │   ▲    
   VM1 │   ▲     │  VM2 │   ▲     │  VM3 │   ▲       
         │ 虚拟接口  │         │ 虚拟接口  │         │ 虚拟接口  │        
        ▼         ▼         ▼         ▼         ▼         ▼        
    +------+  +------+   +------+  +------+   +------+  +------+  
    | VM1  |  | VM2  |   | VM3  |  | VM4  |   | VM5  |  | VM6  |  
    +------+  +------+   +------+  +------+   +------+  +------+  
  • ovn-northd 将 “逻辑交换机 ls1” 下发到所有 Chassis 的 ovn-controller,并由 ovn-controller 在本地 br-int 上创建基于 Geneve 隧道的流表。
  • VM1/VM2/VM3 等虚拟机均挂载到各自 Chassis 的 br-int 上,并通过 Geneve 隧道封装,实现跨主机二层转发。

7. 动态扩容与故障切换

OVN 的分布式设计使得扩容和故障切换相对简单,只需在新的节点上启动 ovn-controller 并加入 Cluster,即可自动同步流表。

7.1 新加入 OVN 控制节点示例

假设新增一台 Chassis chx4(192.168.1.24),只需在该节点上:

sudo apt-get install -y openvswitch-switch openvswitch-common ovn-host ovn-common

# 配置 OVSDB 连接 SB_DB
sudo ovs-vsctl set open . external_ids:ovn-remote="ptcp:6643:192.168.1.10" 
sudo ovs-vsctl set open . external_ids:ovn-external-ids="ovn-sb"

# 启动 ovn-controller
sudo systemctl enable ovn-controller
sudo systemctl start ovn-controller
  • OVN Controller 启动后,会自动注册到 SB\_DB,并从 SB\_DB 拉取所有 ls1lr1 的流表。
  • 新节点即可立刻参与逻辑网络转发,无需重新下发逻辑网络配置。

7.2 OVN 数据库 Leader 选举与故障恢复

db1 节点挂掉,Keepalived VIP 会漂移到 db2 上,OVN Controller 访问的 OVSDB VIP 仍然可用。在使用 Raft 模式时,Leader 会自动选举,确保 NBDB/SBDB 的可用性。

7.3 OVN Controller 动态下线/上线示例

  • 下线:直接在某 Chassis 上停掉 ovn-controller 服务即可,该节点上的流表会失效,但业务流转至其他节点不会中断。
  • 上线:重启 ovn-controller,会自动拉取 SBDB 信息,快速恢复转发能力。

8. 运维与调试要点

8.1 常用 ovn-nbctl / ovn-sbctl 命令

  • 列出所有逻辑交换机:

    ovn-nbctl ls-list
  • 查看逻辑路由器:

    ovn-nbctl lr-list
  • 查看 Chassis Binding 信息:

    ovn-sbctl show
  • 查看指定 Logical Switch 的端口信息:

    ovn-nbctl lsp-list ls1
  • 手动清理无效 Logical Flow:

    ovn-sbctl lr-flow-list lr1
    ovn-sbctl delete logical_router_static_route <UUID>

8.2 日志与诊断:ovn-northd、ovn-controller 日志级别

  • 若出现逻辑网络下发异常,首先查看 ovn-northd 日志:

    tail -f /var/log/ovn/ovn-northd.log
  • 如果某 Chassis 收不到流表或流表不正确,查看该节点的 ovn-controller 日志:

    tail -f /var/log/ovn/ovn-controller.log
  • ovn-controller 与 SBDB 连接异常,可通过 ovs-vsctl get open . external_ids:ovn-remote 验证 SBDB 地址是否正确。

8.3 性能优化建议

  1. 合理规划 Geneve 隧道 MTU:避免因隧道封装导致数据包过大而分片,影响性能。
  2. 调整 ovn-northd 同步间隔:对于大型拓扑,可通过 --poll-interval 参数调整同步频率,减少负载。
  3. 监控 OVSDB 连接数与 CPU 使用率:Profiling 时关注 /etc/openvswitch/ovnnb_db.dbovnsb_db.db 的 IOPS 和延迟。
  4. 开启 OpenFlow Controller 性能优化:在 OVS 上启用 datapath 中的 DPDK 或 XDP 支持,以降低转发延迟。

9. 总结与最佳实践

本文从 OVN 的核心概念与组件开始,深入介绍了 OVN NB/SB 数据库的高可用部署、ovn-northd 与 ovn-controller 的安装与配置,以及逻辑网络(Logical Switch、Logical Router)的构建流程。通过脚本示例ASCII 拓扑图解,全面呈现了 OVN 集群分布式交换机如何在物理节点间通过 Geneve 隧道实现跨主机二层和三层网络连接。

最佳实践建议:

  1. 集群 HA

    • 对于生产环境,推荐至少部署 3 个 OVN NB/SB OVSDB Server,以 Raft 模式提供强一致性。
    • 使用 Keepalived 只适合小规模测试或双节点部署;生产务必使用 Raft。
  2. 证书与加密

    • 在多租户或跨机房环境,建议为 NB/SB OVSDB Server、ovn-northd、ovn-controller 配置 mTLS(双向证书),保护控制平面安全。
  3. MTU 与网络性能

    • 确保物理网络 MTU(例如 1500)与 Geneve 隧道 MTU(默认 6081)匹配,或在 OVS 上开启分段协商。
    • 对于数据中心,可考虑使用 DPDK 加速 OVS 数据平面。
  4. 日志与监控

    • 定期监控 /var/log/ovn 中各组件日志,关注错误提示和流表下发失败。
    • 使用 Grafana + Prometheus 监控 OVSDB Replica、ovn-northd 延迟、ovn-controller 的流表数量与 Chassis 链路状态。
  5. 动态扩容

    • OVN Controller 极易扩容,新增 Chassis 后自动拉取逻辑网络配置,无需重启集群。
    • 在逻辑网络设计时,可通过 lflownat 等机制,实现租户隔离和网络多租户策略。

通过本文的学习与操作演示,相信你已经掌握了从零搭建 OVN 集群分布式交换机的全流程。无论是在 Kubernetes、OpenStack、KVM 或裸机虚拟化环境中,OVN 都能提供高性能、高可靠的虚拟网络能力,让你的云计算平台快速实现软件定义网络(SDN)的核心价值。

2024-09-09

Linux 是一种开源的操作系统,有许多相关的指令可以使用。以下是一些常见的 Linux 指令:

  1. ls:列出目录的内容。



ls
  1. cd:改变目录。



cd /path/to/directory
  1. pwd:打印工作目录。



pwd
  1. cat:连接并打印文件内容。



cat filename
  1. grep:在文件中查找匹配的行。



grep "text" filename
  1. find:在文件系统中查找文件。



find /path/to/directory -name filename
  1. cp:复制文件或目录。



cp source destination
  1. mv:移动或重命名文件或目录。



mv source destination
  1. rm:删除文件或目录。



rm filename
  1. touch:创建空文件或更新文件时间。



touch filename
  1. chmod:改变文件或目录的权限。



chmod 755 filename
  1. chown:改变文件或目录的所有者。



chown username filename
  1. ps:查看当前进程状态。



ps aux
  1. kill:发送信号到进程。



kill PID
  1. tar:打包和解压文件。



tar -cvf archive.tar files
tar -xvf archive.tar
  1. wc:计算文件的行数、字数等。



wc -l filename
  1. sort:对文件的行进行排序。



sort filename
  1. uniq:移除重复的行。



uniq filename
  1. diff:比较两个文件的差异。



diff file1 file2
  1. sed:流编辑器,用于替换、插入和删除文本。



sed 's/old/new/' filename
  1. awk:文本处理工具,用于模式扫描和处理语言。



awk '{print $1}' filename
  1. gzip:压缩文件。



gzip filename
  1. curl:传输数据使用的工具。



curl http://example.com
  1. make:执行Makefile文件中的指令。



make
  1. gcc:C语言编译器。



gcc filename -o output
  1. make:编译程序。



make
  1. sudo:以系统管理员的身份运行命令。



sudo command
  1. su:切换用户。



su username
2024-09-09

Linux 是一种开源的操作系统,有许多相关的指令可以使用。以下是一些常见的 Linux 指令:

  1. ls:列出目录的内容。



ls
  1. cd:改变目录。



cd /path/to/directory
  1. pwd:打印工作目录。



pwd
  1. cat:连接并打印文件内容。



cat filename
  1. grep:在文件中查找匹配的行。



grep "text" filename
  1. find:在文件系统中查找文件。



find /path/to/directory -name filename
  1. cp:复制文件或目录。



cp source destination
  1. mv:移动或重命名文件或目录。



mv source destination
  1. rm:删除文件或目录。



rm filename
  1. touch:创建空文件或更新文件时间。



touch filename
  1. chmod:改变文件或目录的权限。



chmod 755 filename
  1. chown:改变文件或目录的所有者。



chown username filename
  1. ps:查看当前进程状态。



ps aux
  1. kill:发送信号到进程。



kill PID
  1. tar:打包和解压文件。



tar -cvf archive.tar files
tar -xvf archive.tar
  1. wc:计算文件的行数、字数等。



wc -l filename
  1. sort:对文件的行进行排序。



sort filename
  1. uniq:移除重复的行。



uniq filename
  1. diff:比较两个文件的差异。



diff file1 file2
  1. sed:流编辑器,用于替换、插入和删除文本。



sed 's/old/new/' filename
  1. awk:文本处理工具,用于模式扫描和处理语言。



awk '{print $1}' filename
  1. gzip:压缩文件。



gzip filename
  1. curl:传输数据使用的工具。



curl http://example.com
  1. make:执行Makefile文件中的指令。



make
  1. gcc:C语言编译器。



gcc filename -o output
  1. make:编译程序。



make
  1. sudo:以系统管理员的身份运行命令。



sudo command
  1. su:切换用户。



su username
2024-09-09

在Linux系统中,用户缓冲区(User Buffer)是内存中的一段区域,用于临时存储输入/输出数据。当程序需要读取数据时,Linux会先将数据从硬盘读入到用户缓冲区,然后再将数据从用户缓冲区拷贝到程序的缓冲区。当程序写入数据时,也会先写入到用户缓冲区,然后再由内核将数据从用户缓冲区写入到硬盘。

在Linux系统中,可以通过各种方式来模拟和实现用户缓冲区的相关操作。以下是一个简单的示例,展示了如何在C语言程序中使用标准I/O库函数来读取和写入用户缓冲区。




#include <stdio.h>
#include <string.h>
 
int main() {
    FILE *fp;
    char msg[] = "Hello, User Buffer!";
 
    // 写入数据到用户缓冲区
    fp = fopen("test.txt", "w");
    if(fp == NULL) {
        printf("Error opening file\n");
        return -1;
    }
    fprintf(fp, "%s", msg);  // fprintf将数据写入用户缓冲区
    fclose(fp);              // 当文件关闭时,用户缓冲区的数据会被写入硬盘
 
    // 从用户缓冲区读取数据
    fp = fopen("test.txt", "r");
    if(fp == NULL) {
        printf("Error opening file\n");
        return -1;
    }
    fscanf(fp, "%s", msg);  // fscanf从用户缓冲区读取数据
    printf("%s\n", msg);   // 打印读取的数据
    fclose(fp);
 
    return 0;
}

在这个示例中,我们首先使用fprintf将消息写入用户缓冲区,然后关闭文件,将缓冲区内容写入硬盘。接着,我们再次打开文件,使用fscanf从用户缓冲区读取数据,并将其输出到控制台。

这只是用户缓冲区操作的一个简单示例,实际上用户缓冲区在操作系统中起着非常重要的作用,影响着数据的读写性能和安全性。

2024-09-06

在Linux中,有许多基本的命令可以用来执行各种任务。以下是一些最常见和最有用的命令:

  1. ls:列出目录中的文件和文件夹。



ls
  1. cd:改变当前工作目录。



cd /path/to/directory
  1. pwd:打印当前工作目录的全路径。



pwd
  1. cat:连接文件并打印到标准输出设备上。



cat filename
  1. touch:改变文件的访问和修改时间。



touch filename
  1. cp:文件或目录。



cp source destination
  1. mv:移动或重命名文件。



mv source destination
  1. rm:删除文件或目录。



rm filename
  1. mkdir:创建目录。



mkdir directoryname
  1. rmdir:删除空目录。



rmdir directoryname
  1. grep:在文件中查找字符串。



grep "string" filename
  1. find:在目录树中查找文件。



find /path/to/directory -name filename
  1. chmod:改变文件或目录的权限。



chmod 755 filename
  1. chown:改变文件或目录的所有者。



chown username:groupname filename
  1. ps:显示当前进程的快照。



ps aux
  1. kill:发送信号到进程。



kill PID
  1. tar:打包和解压文件。



tar -cvf archive.tar files
tar -xvf archive.tar
  1. wc:计算文件中的字数、行数、字符数。



wc filename
  1. man:查看命令手册。



man command
  1. apt-get:在Debian和Ubuntu中用于安装、更新、升级和删除软件包。



sudo apt-get install packagename
  1. yum:在Red Hat和Fedora中用于安装、更新、升级和删除软件包。



sudo yum install packagename
  1. ping:检查网络连接。



ping hostname
  1. ssh:用于安全登录到远程主机。



ssh user@hostname
  1. sudo:以系统管理员的身份运行命令。



sudo command
  1. su:切换用户身份。



su username
  1. passwd:修改用户密码。



passwd username
  1. date:显示和设置系统日期和时间。



date
  1. cal:显示日历。



cal
  1. top:显示当前系统正在运行的进程。



top
  1. free:显示内存和交换区的使用情况。



free -m
  1. df:报告文件系统的磁盘空间使用情况。



df -h
  1. du:查看文件和目录的磁盘使用空间。



du -sh filename
  1. useradd:创建新的用户。



useradd username
  1. userdel:删除用户。



userdel username
  1. groupadd:创建新的用户组。



groupadd groupname
2024-09-06



# 安装一个RPM包
sudo rpm -ivh example.rpm
 
# 卸载一个RPM包
sudo rpm -e example.rpm
 
# 查询一个RPM包是否已安装
rpm -q example
 
# 列出所有已安装的RPM包
rpm -qa
 
# 升级一个RPM包
sudo rpm -Uvh example.rpm
 
# 创建一个SRPM包
rpmbuild -bs example.spec
 
# 安装一个YUM仓库
sudo yum install example-yum-repo.noarch.rpm
 
# 使用YUM安装软件包
sudo yum install example
 
# 使用YUM移除软件包
sudo yum remove example
 
# 使用YUM更新软件包
sudo yum update example
 
# 清理YUM缓存
sudo yum clean all

这些命令提供了使用RPM和YUM包管理器的基本操作,包括安装、卸载、查询、创建和使用SRPM以及安装和管理YUM仓库。这些操作是Linux系统管理员和开发者在日常工作中的常用操作。

2024-09-06

Linux 2.6内核的进程调度器采用了一个新的调度算法,称为O(1)调度程序。这个算法的目标是减少在高负载下调度延迟的影响,同时保持对IO消耗型和其他工作负载的良好支持。

在O(1)调度器中,有一个就绪队列的概念,它是一个entity数组,用于存储可运行的进程。每个CPU都有自己的就绪队列。当一个进程被唤醒或者变成可运行状态时,它会被放入到当前CPU的就绪队列中。

在O(1)调度器中,实现了一个新的数据结构,称为红黑树,用于高效的查找和修改操作。每个CPU的就绪队列都有一个红黑树,进程在树中的位置由其优先级决定。

以下是一个简化的代码示例,描述了如何在就绪队列中插入和删除进程:




// 插入进程到就绪队列
void enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se) {
    if (!se->on_rq) {
        update_entity_load_avg(se);
        /* 将进程插入到红黑树中 */
        __enqueue_entity(cfs_rq, se);
        se->on_rq = 1;
    }
}
 
// 从就绪队列删除进程
void dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se) {
    if (se->on_rq) {
        /* 从红黑树中删除进程 */
        __dequeue_entity(cfs_rq, se);
        se->on_rq = 0;
    }
}

在O(1)调度器中,选择下一个进程运行的算法复杂度为O(log n),这对于大规模的进程数量是有效的。此外,O(1)调度器还包括了对交互性和响应性的改进,以及对能量效率的更好支持。

2024-09-06

在Linux中,有许多常用的命令,这些命令可以帮助用户完成各种任务。以下是45个常用的Linux命令,包括一些示例代码,以帮助你轻松玩转Linux。

  1. ls:列出目录中的文件和文件夹。



ls
  1. cd:改变目录。



cd /path/to/directory
  1. pwd:打印工作目录。



pwd
  1. touch:创建一个空文件。



touch filename
  1. cat:查看文件内容。



cat filename
  1. cp:复制文件或文件夹。



cp source destination
  1. mv:移动或重命名文件或文件夹。



mv source destination
  1. rm:删除文件或文件夹。



rm filename
  1. mkdir:创建新的目录。



mkdir new_directory
  1. rmdir:删除空目录。



rmdir empty_directory
  1. grep:在文件中搜索字符串。



grep "string" filename
  1. find:在系统中搜索文件。



find /path/to/search -name "filename"
  1. chmod:改变文件或文件夹的权限。



chmod 755 filename
  1. chown:改变文件或文件夹的所有者。



chown new_owner filename
  1. passwd:修改用户密码。



passwd
  1. su:切换用户。



su username
  1. whoami:显示当前用户。



whoami
  1. ps:显示当前运行的进程。



ps
  1. kill:结束进程。



kill PID
  1. tar:压缩或解压文件。



tar -cvf archive.tar files
  1. unzip:解压.zip文件。



unzip file.zip
  1. wget:从网络下载文件。



wget http://example.com/file
  1. curl:获取或发送数据。



curl http://example.com
  1. sort:对文件内容排序。



sort filename
  1. awk:在文件中使用脚本处理文本。



awk '{print $1}' filename
  1. sed:对文本文件进行转换。



sed 's/old/new/g' filename
  1. awk:在文件中使用脚本处理文本。



awk '{print $1}' filename
  1. sed:对文本文件进行转换。



sed 's/old/new/g' filename
  1. awk:在文件中使用脚本处理文本。



awk '{print $1}' filename
  1. sed:对文本文件进行转换。



sed 's/old/new/g' filename
  1. gzip:压缩文件。



gzip filename
  1. bzip2:压缩文件。



bzip2 filename
  1. ping:检查网络连接。



ping example.com
  1. netstat:显示网络相关信息。



netstat -tulnp
  1. df:显示磁盘空间。



df -h
  1. top:显示实时运行的进程。



top
2024-09-05

在Linux中,当一个信号被进程捕获并处理后,进程可以选择对信号的行为进行更改。如果在处理信号的过程中再次发生了该信号,那么进程可以选择对信号进行保存,直到信号被适当处理。

在信号被保存的时候,进程需要使用某种机制来记住接收到的信号,并且在合适的时候对这些信号进行处理。在Linux中,这是通过设置一个特殊的数据结构(sigset\_t)来实现的,这个数据结构称为信号集。

以下是一个简单的示例,演示了如何在信号处理函数中保存信号,并在合适的时候处理它们:




#include <stdio.h>
#include <signal.h>
#include <unistd.h>
 
sigset_t signal_set; // 信号集用于保存信号
 
void handle_signal(int sig) {
    sigaddset(&signal_set, sig); // 保存信号
}
 
int main() {
    struct sigaction sa;
    sigemptyset(&sa.sa_mask); // 初始化sa_mask字段,表示信号处理期间不阻塞任何信号
    sa.sa_flags = 0;
    sa.sa_handler = &handle_signal; // 设置信号处理函数
    sigaction(SIGINT, &sa, NULL); // 注册信号处理函数
 
    while(1) {
        sigset_t pending;
        sigpending(0, &pending); // 获取当前的信号集
        if (sigismember(&pending, SIGINT)) { // 检查是否有SIGINT信号待处理
            sigprocmask(SIG_BLOCK, &signal_set, NULL); // 阻塞当前保存的信号集
            // 处理信号...
            printf("Caught SIGINT\n");
            sigprocmask(SIG_UNBLOCK, &signal_set, NULL); // 恢复信号集
            sigemptyset(&signal_set); // 清空信号集
        }
        sleep(1); // 休眠一秒钟
    }
 
    return 0;
}

在这个示例中,我们定义了一个全局的信号集signal_set用于保存信号。我们注册了SIGINT信号的处理函数handle_signal,它将收到的信号加入到signal_set中。在主循环中,我们通过调用sigpending检查是否有待处理的信号,如果有,我们就暂时阻塞当前保存的信号集,处理信号,处理完毕后恢复信号集并清空保存信号的集合。这样就可以在合适的时候处理信号,而不会丢失信号。

2024-09-05

在Linux中,有许多基础操作指令,这些指令可以帮助我们完成从文件操作、用户管理,到系统监控等多种任务。以下是一些常见的基础操作指令:

  1. ls:列出目录中的文件和文件夹。



ls
  1. cd:改变当前工作目录。



cd /path/to/directory
  1. pwd:打印当前工作目录的路径。



pwd
  1. touch:创建一个空文件。



touch filename
  1. cat:查看文件内容。



cat filename
  1. cp:复制文件或目录。



cp source destination
  1. mv:移动或重命名文件或目录。



mv source destination
  1. rm:删除文件或目录。



rm filename
  1. mkdir:创建新的目录。



mkdir new_directory
  1. rmdir:删除空目录。



rmdir empty_directory
  1. chmod:改变文件或目录的权限。



chmod 755 filename
  1. chown:改变文件或目录的所有者。



chown new_owner filename
  1. find:在系统中搜索文件。



find /path/to/search -name filename
  1. grep:在文件中搜索字符串。



grep "search_string" filename
  1. ps:查看当前运行的进程。



ps aux
  1. top:实时显示系统进程。



top
  1. kill:终止进程。



kill PID
  1. df:检查文件系统的磁盘空间占用。



df -h
  1. du:查看文件或目录的磁盘使用情况。



du -sh filename_or_directory
  1. date:显示或设置系统日期和时间。



date
  1. passwd:修改用户密码。



passwd username
  1. useradd:创建新用户。



useradd new_username
  1. usermod:修改用户属性。



usermod -aG groupname username
  1. su:切换用户身份。



su - username
  1. sudo:以其他用户身份执行命令。



sudo command
  1. wget:从网络下载文件。



wget http://example.com/filename
  1. tar:压缩或解压文件。



tar -czvf archive.tar.gz /path/to/directory
  1. ping:检查网络连接。



ping example.com
  1. ssh:远程登录到其他机器。



ssh username@hostname
  1. man:查看命令手册。



man command

这些指令是Linux操作的基础,每个指令都有其特定的选项和参数,可以实现更多的功能。