《云原生网络数据面可观测性最佳实践》—— 一、容器网络内核原理——3.tc子系统(上)

简介: 《云原生网络数据面可观测性最佳实践》—— 一、容器网络内核原理——3.tc子系统(上)

Linux Traffic Control (TC) 子系统是Linux操作系统中用于对从网络设备驱动进出的流量进行分配,整形,调度以及其他修改操作的子系统,借助对数据包比较直接的处理,可以实现流量控制,过滤,行为模拟和带宽限制等功能。

 

1) Linux Traffic Control的核心原理

对于网络数据报文,网络设备驱动通过将二层的以太网数据报文按照Linux内核定义的网络设备驱动规范,以sk_buff结构体的方式进行接收或者发送,即通常我们所描述的报文的最小单元skb。

 

内核通过将网络设备缓冲区环形队列中skb取出,并按照以太网层,网络层,传输层顺序处理后,将报文数据放置到对应Socket缓冲区中,通知用户程序进行读取,从而完成收包

内核为Socket缓冲区待发送数据封装为skb,经过传输层,网络层和以太网层依次填充对应报头后,调用网络设备驱动方法将skb发送到网络上,从而完成发包

 

TC子系统通过工作在网络设备驱动操作和内核真正进行每一层的收包与发包动作之间,按照不同的模式对数据包进行处理,实现复杂的功能。

 

TC子系统比较常见的作用是对需要发送的数据包进行操作,由于作为收包一侧的Linux内核,无法控制所有发送方的行为,因此TC子系统主要的功能实现都是围绕着发送方向,以下介绍也都是基于发送方向的TC子系统进行。

TC子系统的关键概念

TC子系统与netfilter框架工作在内核网络数据处理流程的不同位置,相比于netfilter,TC子系统工作的实际更加靠近网络设备,因此,在TC子系统的设计中,是与网络设备密不可分,在TC子系统中,有三个关键的概念用于对TC子系统的工作流程进行描述:

 

Qdisc是queueing discipline简写,与我们理解网卡队列(queue)不同,qdisc是sk_buff报文进行排队等待处理队列,不同类型qdisc有着不同排队规则,TC子系统会为每个网卡默认创建一个根队列,在跟队列基础上,可以通过Class来创建不同子队列,用于对流量进行分类处理

Class,如下图所示,class将流量进行分类,不同分类流量会进入不同qdisc进行处理

Filter,如下图所示,filter通过指定匹配规则来实现将流量进行分类作用,filter与class配合之后就可以将流量按照特征,采用不同qdisc进行处理

 image.png

 

不同的qdisc之间的主要差别就是他们对排队的数据包进行调度的算法的区别,你可以通过一下命令查看网卡的qdisc信息:

# 查看eth0的class为2的流量的默认qdisc,其中handle指代qdisc id, parent指代class id
tc qdisc show dev eth0 handle 0 parent 2

常见的qdisc包含以下几种:

 

mq(Multi Queue),即默认有多个qdisc

fq_codel(Fair Queuing Controlled Delay),一种公平和随机分配流量带宽算法,会根据数据包大小,五元组等信息,尽量公平得分配不同流之间带宽

pfifo_fast,一种不分类常见先进先出队列,但是默认有三个不同band,可以支持简单tos优先级

netem,network emulator队列,常见依赖TC子系统进行延迟,乱序和丢包模拟,都是通过netem来实现

clsact,这是TC子系统专门为了支持eBPF功能而提供一种qdisc队列,在通过class分配到这个qdisc之后,流量会触发已经挂载到TC子系统上对应eBPF程序处理流程

htb,一种通过令牌桶算法对流量进行带宽控制常用qdisc,用于在单个往卡上对不同用户,场景流量进行独立带宽限流

报文在TC子系统的处理

在egress方向,当以太网层完成数据报文skb的报头封装后,一个skb就可以直接调用网卡的方法进行发送了,而在Linux内核中,当以太网层完成封装并调用__dev_queue_xmit时,会将skb放入他所在网络设备的TC队列中:

static inline int c(struct sk_buff *skb, struct Qdisc *q,
         struct net_device *dev,
         struct netdev_queue *txq)
{
  if (q->flags & TCQ_F_NOLOCK) {
    if (unlikely(test_bit(__QDISC_STATE_DEACTIVATED, &q->state))) {
      __qdisc_drop(skb, &to_free);
      rc = NET_XMIT_DROP;
    } else {
            // 对于大多数数据包,都会从这里进入qdisc进行排队
      rc = q->enqueue(skb, q, &to_free) & NET_XMIT_MASK;
      qdisc_run(q);
    }
    if (unlikely(to_free))
      kfree_skb_list(to_free);
    return rc;
  }
}

在入队动作发生后,内核一般都会直接进行一次qdisc的发包操作,将队列进行排序并按照规则发送符合条件的数据包:

void __qdisc_run(struct Qdisc *q)
{
  int quota = dev_tx_weight;
  int packets;
  // 每次restart都会发送数据包,直到发送完成,这并不意味着所有数据都发送完了,只是这次发送完成了
  while (qdisc_restart(q, &packets)) {
    quota -= packets;
    if (quota <= 0 || need_resched()) {
      __netif_schedule(q);
      break;
    }
  }
}

qdisc每次被触发执行,都会将已经进入qdisc的数据进行入队操作,同时选择符合发送条件的数据包进行出队动作,也就是调用网卡的操作方法进行数据的发送,以pfifo_fast为例:

static int pfifo_fast_enqueue(struct sk_buff *skb, struct Qdisc *qdisc)
{
    // 检测 Qdisc 队列数据包数量是否达到 dev 预定的最大值
    if (skb_queue_len(&qdisc->q) < qdisc_dev(qdisc)->tx_queue_len) {
        // 确定数据包需要进入哪个通道
        int band = prio2band[skb->priority & TC_PRIO_MAX];
        struct pfifo_fast_priv *priv = qdisc_priv(qdisc);
        // 获取通道列表的head
        struct sk_buff_head *list = band2list(priv, band);
        priv->bitmap |= (1 << band);
        qdisc->q.qlen++;
        // 添加到通道队尾
        return __qdisc_enqueue_tail(skb, qdisc, list);
    }
    return qdisc_drop(skb, qdisc);
}
static struct sk_buff *pfifo_fast_dequeue(struct Qdisc *qdisc)
{
    struct pfifo_fast_priv *priv = qdisc_priv(qdisc);
    int band = bitmap2band[priv->bitmap];
    if (likely(band >= 0)) {
        struct sk_buff_head *list = band2list(priv, band);
        struct sk_buff *skb = __qdisc_dequeue_head(qdisc, list);
        qdisc->q.qlen--;
        if (skb_queue_empty(list))
            priv->bitmap &= ~(1 << band);
        return skb;
    }
    return NULL;
}

 qdisc流量控制由于设计非常复杂,所以很难简单概括其特性,通常在排查网络问题的过程中,我们需要了解的就是常见的qdisc的算法的大致工作原理,以及查看qdisc统计信息。

 

更多精彩内容,欢迎观看:

《云原生网络数据面可观测性最佳实践》—— 一、容器网络内核原理——3.tc子系统(下):https://developer.aliyun.com/article/1221713?groupCode=supportservice

相关文章
|
16天前
|
人工智能 弹性计算 运维
ACK Edge与IDC:高效容器网络通信新突破
本文介绍如何基于ACK Edge以及高效的容器网络插件管理IDC进行容器化。
|
5天前
|
存储 Kubernetes 开发者
容器化时代的领航者:Docker 和 Kubernetes 云原生时代的黄金搭档
Docker 是一种开源的应用容器引擎,允许开发者将应用程序及其依赖打包成可移植的镜像,并在任何支持 Docker 的平台上运行。其核心概念包括镜像、容器和仓库。镜像是只读的文件系统,容器是镜像的运行实例,仓库用于存储和分发镜像。Kubernetes(k8s)则是容器集群管理系统,提供自动化部署、扩展和维护等功能,支持服务发现、负载均衡、自动伸缩等特性。两者结合使用,可以实现高效的容器化应用管理和运维。Docker 主要用于单主机上的容器管理,而 Kubernetes 则专注于跨多主机的容器编排与调度。尽管 k8s 逐渐减少了对 Docker 作为容器运行时的支持,但 Doc
48 5
容器化时代的领航者:Docker 和 Kubernetes 云原生时代的黄金搭档
|
1天前
|
容灾 网络协议 数据库
云卓越架构:云上网络稳定性建设和应用稳定性治理最佳实践
本文介绍了云上网络稳定性体系建设的关键内容,包括面向失败的架构设计、可观测性与应急恢复、客户案例及阿里巴巴的核心电商架构演进。首先强调了网络稳定性的挑战及其应对策略,如责任共担模型和冗余设计。接着详细探讨了多可用区部署、弹性架构规划及跨地域容灾设计的最佳实践,特别是阿里云的产品和技术如何助力实现高可用性和快速故障恢复。最后通过具体案例展示了秒级故障转移的效果,以及同城多活架构下的实际应用。这些措施共同确保了业务在面对网络故障时的持续稳定运行。
|
17天前
|
供应链 安全 Cloud Native
阿里云容器服务助力企业构建云原生软件供应链安全
本文基于2024云栖大会演讲,探讨了软件供应链攻击的快速增长趋势及对企业安全的挑战。文中介绍了如何利用阿里云容器服务ACK、ACR和ASM构建云原生软件供应链安全,涵盖容器镜像的可信生产、管理和分发,以及服务网格ASM实现应用无感的零信任安全,确保企业在软件开发和部署过程中的安全性。
|
17天前
|
人工智能 Kubernetes Cloud Native
阿里云容器服务,智算时代云原生操作系统
2024云栖大会,阿里巴巴研究员易立分享了阿里云容器服务的最新进展。容器技术已成为云原生操作系统的基石,支持多样化的应用场景,如自动驾驶、AI训练等。阿里云容器服务覆盖公共云、边缘云、IDC,提供统一的基础设施,助力客户实现数字化转型和技术创新。今年,阿里云在弹性计算、网络优化、存储解决方案等方面进行了多项重要升级,进一步提升了性能和可靠性。
|
27天前
|
存储 缓存 监控
Docker容器性能调优的关键技巧,涵盖CPU、内存、网络及磁盘I/O的优化策略,结合实战案例,旨在帮助读者有效提升Docker容器的性能与稳定性。
本文介绍了Docker容器性能调优的关键技巧,涵盖CPU、内存、网络及磁盘I/O的优化策略,结合实战案例,旨在帮助读者有效提升Docker容器的性能与稳定性。
67 7
|
1月前
|
Kubernetes Cloud Native Docker
云原生之旅:从传统架构到容器化服务的演变
随着技术的快速发展,云计算已经从简单的虚拟化服务演进到了更加灵活和高效的云原生时代。本文将带你了解云原生的概念、优势以及如何通过容器化技术实现应用的快速部署和扩展。我们将以一个简单的Python Web应用为例,展示如何利用Docker容器进行打包和部署,进而探索Kubernetes如何管理这些容器,确保服务的高可用性和弹性伸缩。
|
29天前
|
Kubernetes Cloud Native 开发者
云原生入门:从容器到微服务
本文将带你走进云原生的世界,从容器技术开始,逐步深入到微服务架构。我们将通过实际代码示例,展示如何利用云原生技术构建和部署应用。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的信息和启示。
|
1月前
|
运维 Cloud Native 云计算
云原生之旅:Docker容器化实战
本文将带你走进云原生的世界,深入理解Docker技术如何改变应用部署与运维。我们将通过实际案例,展示如何利用Docker简化开发流程,提升应用的可移植性和伸缩性。文章不仅介绍基础概念,还提供操作指南和最佳实践,帮助你快速上手Docker,开启云原生的第一步。
|
1月前
|
安全 网络安全 数据安全/隐私保护
利用Docker的网络安全功能来保护容器化应用
通过综合运用这些 Docker 网络安全功能和策略,可以有效地保护容器化应用,降低安全风险,确保应用在安全的环境中运行。同时,随着安全威胁的不断变化,还需要持续关注和研究新的网络安全技术和方法,不断完善和强化网络安全保护措施,以适应日益复杂的安全挑战。
45 5

热门文章

最新文章