当前位置: 首页 > news >正文

使用Cilium/eBPF实现大规模云原生网络和安全

大家读完觉得有帮助记得关注和点赞!!!

目录

抽象

1 Trip.com 云基础设施

1.1 分层架构

1.2 更多细节

2 纤毛在 Trip.com

2.1 推出时间表

2.2 自定义

2.3 优化和调整

2.3.1 解耦安装

2.3.2 避免重试/重启风暴

2.3.3 稳定性优先

2.3.4 规划规模

2.3.5 性能调优

2.3.6 可观察性和警报

2.3.7 其他选项

2.4 多集群解决方案

2.4.1 集群网格

2.4.2 KVStoreMesh

3 高级故障排除技巧

3.1 使用delve/dlv

3.2 使用bpftrace

3.2.1 使用绝对路径

2.3.2 带 PID/proc/

3.3 操作 BPF 映射bpftool

3.4 使用 API 操作 kvstore 内容etcdctl

4 总结


抽象

Trip.com 年,我们将第一个 Cilium 节点(裸机)投入生产 在 2019 年。从那时起,我们几乎所有的 Kubernetes 集群 - 都是本地的 公共云中的裸机和自我管理的集群 - 已切换到 Cilium。

现在有 ~10K 个节点,~300K Pod 在 Kubernetes 上运行, Cilium 为我们的关键业务服务提供支持,例如酒店 搜索引擎、金融/支付服务、内存数据库、数据存储 服务,其中涵盖了延迟方面的广泛要求, 吞吐量等

根据我们 4 年的经验,观众将学习 Cilium 的云原生网络和安全性,包括:

  1. 如何使用 CiliumNetworkPolicy 进行 L3/L4 访问控制,包括将安全模型扩展到 BM/VM 实例;
  2. 我们名为 KVStoreMesh 的新多集群解决方案作为 ClusterMesh 的替代方案,以及我们如何使其与社区兼容以便轻松升级;
  3. 大规模构建稳定性,例如管理控制平面和多集群中断,以及我们因此对 Cilium 所做的改进。

1 Trip.com 云基础设施

1.1 分层架构

Trip.com 云团队负责公司在全球的基础设施,如下所示:

  • 在底部,我们有数据中心和几个公共云供应商;
  • 底部上方是我们用于 BM、VM 和容器的编排系统;
  • 再上一层是内部开发的持续交付平台 (CI/CD);
  • 顶部是我们的业务服务和相应的中间件;
  • 在垂直方向上,我们在不同级别都有安全和管理工具。

云范围是图中所示的框。

1.2 更多细节

有关我们基础设施的更多具体信息:

  • 我们的大部分工作负载现在都在 Kubernetes 上运行,我们有 3 个大型 集群和几个小型集群,具有总节点和 pod;~10k~300k
  • 大多数 Kubernetes 节点都是刀片服务器;哪
  • 使用内部维护的 4.19/5.10 内核运行;
  • 对于主机间网络,我们将 BGP 用于本地集群和 ENI 适用于云上的自建集群。

2 纤毛在 Trip.com

2.1 推出时间表

以下是我们推出流程的简单时间表:

  1. 我们从 2018 年开始研究云原生网络解决方案 [9],当然,Cilium 胜出;
  2. 我们的第一个纤毛节点于 2019 年投入生产 [10];
  3. 从那时起,我们的各种业务和基础设施服务开始透明地迁移到 Cilium。

2021 年,随着大多数在线业务已经在 Cilium 中, 我们启动了一个基于 Cilium 网络策略的安全项目 [8]。

我们使用的功能:

  • 服务负载均衡 (eBPF/XDP)
  • CiliumNetworkPolicy (CNP)
  • eBPF 主机路由
  • eBPF 带宽管理器
  • 哈勃(部分)
  • Rsyslog 驱动程序
  • 性能提升选项,如 sockops、eBPF 重定向

2.2 自定义

首先,此处显示了两个 Kubernetes 集群,

我们基于上述拓扑的一些自定义:

  1. 使用 docker-compose 部署 cilium 以去除 kubernetes 依赖 [1];
  2. 为每个代理分配一个用于 Kubernetes 身份验证的专用证书,而不是所有代理共享的 seviceaccount;
  3. 我们已经帮助完善了 Cilium 的 rsyslog 驱动程序,并已将所有代理日志发送到 ClickHouse 进行故障排除;
  4. 添加了一些补丁来促进业务迁移,但这并不是那么通用,所以我们没有将它们上游化;
  5. 使用 BIRD 作为 BGP 代理,而不是建议的 kube-router,我们已经为 Cilium 文档贡献了 BGP+Cilium 指南;
  6. 我们开发了一种新的多集群解决方案,称为 KVStoreMesh [4]。更多关于这个 lader 的信息。

2.3 优化和调整

现在是优化和调整部分。

2.3.1 解耦安装

刚才说的,我们做的第一件事就是解耦 Cilium 从 Kubernetes 部署/安装:没有 daemonset,没有 configmap。所有 代理所需的配置位于节点上。

这使得代理受 Kubernetes 中断的影响较小,但更重要的是,每个代理现在在配置和升级方面都是完全独立的

2.3.2 避免重试/重启风暴

第二个考虑因素是避免重试风暴和突发启动, 因为请求将激增两个数量级甚至更高 当发生中断时,这很容易崩溃或卡住中央组件 如 Kubernetes apiserver/etcd 和 kvstore 一样。

我们使用内部开发的重启回退 (jitter+backoff) 机制来避免此类情况。 抖动窗口是根据 Cluster Scale 计算的。 如

  • 对于具有 1000 个节点的集群,抖动窗口可能是 20 分钟,在此期间,每个代理只能启动一次,然后退出。
  • 对于具有 5000 个节点的集群,抖动窗口可能为 60 分钟。
  • 退避机制作为 bash 脚本实现(所有状态都保存在本地文件中),使用 在 docker-compose 中作为 “pre-start hook” 时,Cilium 代码没有变化

此外,我们还为每个代理分配了一个不同的证书(每个代理都有一个 专用用户名,但属于公共用户组),这将启用 Kubernetes 使用 APF(API 优先级和公平性)对 Cilium 代理执行速率限制。也没有更改 Cilium 代码来实现这一点。

如果您想了解有关 Kubernetes AuthN/AuthZ 模型的更多信息,请参阅我们之前的博客 [2,3]。

2.3.3 稳定性优先

Trip.com 7x24 小时在全球范围内提供在线预订服务,因此随时 在任何一天,业务服务中断都会导致 公司。因此,我们不能冒险让网络等基础服务通过简单的 “快速故障” 规则自行重启,而倾向于必要的人工干预和决策。

当失败出现时,我们希望像 Cilium 这样的服务能更有耐心,只是 在那里等待并保持当前业务不中断,让系统开发人员和 维护者决定做什么;快速失败和自动重试 在这种情况下,让事情变得更糟

一些特定选项(带有示例配置)来调整此行为:

  • --allocator-list-timeout=3h
  • --kvstore-lease-ttl=86400s
  • --k8s-syn-timeout=600s
  • --k8s-heartbeat-timeout=60s

请参阅 Cilium 文档或源代码以找出每个选项的内容 确切的含义,并根据您的需要自定义它们。

2.3.4 规划规模

根据您的集群规模,某些内容需要提前规划。 例如,身份相关标签 () 直接确定 集群中的最大 pod:一组标签映射到 在 Cilium 中只有一个身份,所以在它的设计中,所有具有相同标签的 Pod 都共享相同的身份。 但是,如果你的 Bean 太细粒度(不幸的是,这是默认的 case),这可能会导致每个 Pod 都有不同的身份,在最坏的情况下,你的集群规模为 上限为 64K pod,因为表示身份 替换为整数。有关更多信息,请参阅 [8]。--labels--labels=<labels>16bit

此外,还有一些参数需要根据 您的工作负载吞吐量,例如 Identity Allocation Mode、Connection Tracking Table。

选项:

  • --cluster-id/--cluster-name:避免多集群场景中的身份冲突;
  • --labels=<labellist>Identity Relevent 标签
  • --identity-allocation-mode和 kvstore 基准测试(如果使用 kvstore 模式)

    我们使用模式,并在大型集群的专用刀片服务器上运行 kvstore (cilium etcd)。kvstore

  • --bpf-ct-*
  • --api-rate-limit
  • 用于减少可观测性数据量的 Monitor 聚合选项

2.3.5 性能调优

Cilium 包含许多高性能选项,例如 sockops 和 BPF 主机 routing,当然,所有这些功能都需要特定的内核版本 支持。

  • --socops-enable
  • --bpf-lb-sock-hostns-only

此外,禁用一些调试级别选项也是必要的:

  • --disable-cnp-status-updates

2.3.6 可观察性和警报

我们要讨论的最后一个方面是可观测性。

  • 度量
  • 伐木
  • 描图

除了来自 Cilium agent/operator 的指标数据外,我们还 还收集了所有代理/操作员日志(日志记录数据)并发送 到 ClickHouse 进行分析,这样,我们就可以对异常指标进行告警,以及 错误/警告日志、

此外,跟踪也很有帮助,稍后会详细介绍。

2.3.7 其他选项

  • --enable-hubble
  • --keep-config
  • --log-drivers
  • --policy-audit-mode

2.4 多集群解决方案

现在我们来看一下多集群问题。

由于历史原因,我们的业务部署在不同的 数据中心和 Kubernetes 集群。 因此,存在没有 L4/L7 边界网关的集群间通信。 这对访问控制来说是一个问题,因为 Cilium 身份是一个集群范围的对象

2.4.1 集群网格

这个问题的社区解决方案是 ClusterMesh,如下所示,

ClusterMesh 要求每个 agent 连接到所有集群中的每个 kvstore, 有效地产生点对点网格。虽然这个解决方案是直接的 向前,它遇到了稳定性和可扩展性问题,尤其是对于大型 集群。

简而言之,当单个集群宕机时,故障很快就会传播到所有集群 网格中的其他集群, 最终,所有集群可能会同时崩溃,如下所示:

从本质上讲,这是因为 ClusterMesh 中的集群耦合得太紧密了。

2.4.2 KVStoreMesh

我们解决这个问题的概念非常简单: 从所有远程 KVSache 中提取元数据,并在筛选后推送到本地 KVSares。

三集群案例更清楚地显示了这个概念:只涉及 kvstores,

在 ClusterMesh 中,代理从远程 kvstores 获取远程元数据;在 KVStoreMesh 中,它们从本地获取。

感谢 cilium 的良好设计,这只需要对代理和操作符 [4] 进行一些改进和/或错误修复,我们已经 他们中的一些人被上游。kvstoremesh-operator 是新引入的,目前在内部维护; 我们也会在下一个版本投入更多精力将其上游化。

此外,我们还开发了一个简单的解决方案,让 Cilium 注意我们的遗留工作负载,例如 OpenStack 中的虚拟机, the-solultion 称为 CiliumExeternalResource。请看我们之前的 博客 [8] 如果你感兴趣的话。

3 高级故障排除技巧

现在让我们回到一些方便的东西。

第一个是调试。

3.1 使用delve/dlv

Delve 是一个好朋友,我们的 docker-compose 方式使调试更加容易。 由于每个代理程序都是独立部署的,因此命令可以 在节点上执行以启动/停止/重新配置代理。

<span style="color:#333333"><span style="background-color:#f8f8f8"><span style="background-color:#f6f8fa"><code><span style="color:#999988"><em># Start cilium-agent agent container with entrypoint `sleep 10d`, then enter the container</em></span>
<span style="color:#000000"><strong>(</strong></span>node<span style="color:#000000"><strong>)</strong></span> <span style="color:#008080">$ </span>docker <span style="color:#0086b3">exec</span> <span style="color:#000080">-it</span> cilium-agent bash<span style="color:#000000"><strong>(</strong></span>cilium-agent ctn<span style="color:#000000"><strong>)</strong></span> <span style="color:#008080">$ </span>dlv <span style="color:#0086b3">exec</span> /usr/bin/cilium-agent <span style="color:#000080">--</span> <span style="color:#000080">--config-dir</span><span style="color:#000000"><strong>=</strong></span>/tmp/cilium/config-map
Type <span style="color:#dd1144">'help'</span> <span style="color:#000000"><strong>for </strong></span>list of commands.
<span style="color:#000000"><strong>(</strong></span>dlv<span style="color:#000000"><strong>)</strong></span><span style="color:#000000"><strong>(</strong></span>dlv<span style="color:#000000"><strong>)</strong></span> <span style="color:#0086b3">break </span>github.com/cilium/cilium/pkg/endpoint.<span style="color:#000000"><strong>(</strong></span><span style="color:#000000"><strong>*</strong></span>Endpoint<span style="color:#000000"><strong>)</strong></span>.regenerateBPF
Breakpoint 3 <span style="color:#0086b3">set </span>at 0x1e84a3b <span style="color:#000000"><strong>for </strong></span>github.com/cilium/cilium/pkg/endpoint.<span style="color:#000000"><strong>(</strong></span><span style="color:#000000"><strong>*</strong></span>Endpoint<span style="color:#000000"><strong>)</strong></span>.regenerateBPF<span style="color:#000000"><strong>()</strong></span> /go/src/github.com/cilium/cilium/pkg/endpoint/bpf.go:591
<span style="color:#000000"><strong>(</strong></span>dlv<span style="color:#000000"><strong>)</strong></span> <span style="color:#0086b3">break </span>github.com/cilium/cilium/pkg/endpoint/bpf.go:1387
Breakpoint 4 <span style="color:#0086b3">set </span>at 0x1e8c27b <span style="color:#000000"><strong>for </strong></span>github.com/cilium/cilium/pkg/endpoint.<span style="color:#000000"><strong>(</strong></span><span style="color:#000000"><strong>*</strong></span>Endpoint<span style="color:#000000"><strong>)</strong></span>.syncPolicyMapWithDump<span style="color:#000000"><strong>()</strong></span> /go/src/github.com/cilium/cilium/pkg/endpoint/bpf.go:1387
<span style="color:#000000"><strong>(</strong></span>dlv<span style="color:#000000"><strong>)</strong></span> <span style="color:#000000"><strong>continue</strong></span>
...<span style="color:#000000"><strong>(</strong></span>dlv<span style="color:#000000"><strong>)</strong></span> clear 1
Breakpoint 1 cleared at 0x1e84a3b <span style="color:#000000"><strong>for </strong></span>github.com/cilium/cilium/pkg/endpoint.<span style="color:#000000"><strong>(</strong></span><span style="color:#000000"><strong>*</strong></span>Endpoint<span style="color:#000000"><strong>)</strong></span>.regenerateBPF<span style="color:#000000"><strong>()</strong></span> /go/src/github.com/cilium/cilium/pkg/endpoint/bpf.go:591
<span style="color:#000000"><strong>(</strong></span>dlv<span style="color:#000000"><strong>)</strong></span> clear 2
Breakpoint 2 cleared at 0x1e8c27b <span style="color:#000000"><strong>for </strong></span>github.com/cilium/cilium/pkg/endpoint.<span style="color:#000000"><strong>(</strong></span><span style="color:#000000"><strong>*</strong></span>Endpoint<span style="color:#000000"><strong>)</strong></span>.syncPolicyMapWithDump<span style="color:#000000"><strong>()</strong></span> /go/src/github.com/cilium/cilium/pkg/endpoint/bpf.go:1387
</code></span></span></span>

我们以这种方式跟踪了几个 bug。

3.2 使用bpftrace

另一个有用的工具是用于实时跟踪的 bpftrace。

但请注意,跟踪容器进程存在一些差异。 您需要在节点上找到 cilium-agent 二进制文件的 PID 命名空间或绝对路径。

3.2.1 使用绝对路径

<span style="color:#333333"><span style="background-color:#f8f8f8"><span style="background-color:#f6f8fa"><code><span style="color:#999988"><em># Check cilium-agent container</em></span>
<span style="color:#008080">$ </span>docker ps | <span style="color:#0086b3">grep </span>cilium-agent
0eb2e76384b3        cilium:20220516   <span style="color:#dd1144">"/usr/bin/cilium-agent ..."</span>   4 hours ago    Up 4 hours   cilium-agent<span style="color:#999988"><em># Find the merged path for cilium-agent container</em></span>
<span style="color:#008080">$ </span>docker inspect <span style="color:#000080">--format</span> <span style="color:#dd1144">"{{.GraphDriver.Data.MergedDir}}"</span> 0eb2e76384b3
/var/lib/docker/overlay2/0a26c6/merged <span style="color:#999988"><em># 0a26c6.. is shortened for better viewing</em></span>
<span style="color:#999988"><em># The object file we are going to trace</em></span>
<span style="color:#008080">$ </span><span style="color:#0086b3">ls</span> <span style="color:#000080">-ahl</span> /var/lib/docker/overlay2/0a26c6/merged/usr/bin/cilium-agent
/var/lib/docker/overlay2/0a26c6/merged/usr/bin/cilium-agent <span style="color:#999988"><em># absolute path</em></span><span style="color:#999988"><em># Or you can find it bruteforcelly if there are no performance (e.g. IO spikes) concerns:</em></span>
<span style="color:#008080">$ </span>find /var/lib/docker/overlay2/ <span style="color:#000080">-name</span> cilium-agent
/var/lib/docker/overlay2/0a26c6/merged/usr/bin/cilium-agent <span style="color:#999988"><em># absolute path</em></span>
</code></span></span></span>

无论如何,在找到目标文件并检出其中的符号后,

<span style="color:#333333"><span style="background-color:#f8f8f8"><span style="background-color:#f6f8fa"><code><span style="color:#008080">$ </span>nm /var/lib/docker/overlay2/0a26c6/merged/usr/bin/cilium-agent
0000000001d3e940 T type..hash.github.com/cilium/cilium/pkg/k8s.ServiceID
0000000001f32300 T type..hash.github.com/cilium/cilium/pkg/node/types.Identity
0000000001d05620 T type..hash.github.com/cilium/cilium/pkg/policy/api.FQDNSelector
0000000001d05e80 T type..hash.github.com/cilium/cilium/pkg/policy.PortProto
...
</code></span></span></span>

您可以像下面这样启动用户空间探测,打印您希望看到的内容:

<span style="color:#333333"><span style="background-color:#f8f8f8"><span style="background-color:#f6f8fa"><code><span style="color:#008080">$ </span>bpftrace <span style="color:#000080">-e</span> <span style="color:#dd1144">\</span><span style="color:#dd1144">'uprobe:/var/lib/docker/overlay2/0a26c6/merged/usr/bin/cilium-agent:"github.com/cilium/cilium/pkg/endpoint.(*Endpoint).regenerateBPF" {printf("%s\n", ustack);}'</span>
Attaching 1 probe...github.com/cilium/cilium/pkg/endpoint.<span style="color:#000000"><strong>(</strong></span><span style="color:#000000"><strong>*</strong></span>Endpoint<span style="color:#000000"><strong>)</strong></span>.regenerateBPF+0github.com/cilium/cilium/pkg/endpoint.<span style="color:#000000"><strong>(</strong></span><span style="color:#000000"><strong>*</strong></span>EndpointRegenerationEvent<span style="color:#000000"><strong>)</strong></span>.Handle+1180github.com/cilium/cilium/pkg/eventqueue.<span style="color:#000000"><strong>(</strong></span><span style="color:#000000"><strong>*</strong></span>EventQueue<span style="color:#000000"><strong>)</strong></span>.run.func1+363sync.<span style="color:#000000"><strong>(</strong></span><span style="color:#000000"><strong>*</strong></span>Once<span style="color:#000000"><strong>)</strong></span>.doSlow+236github.com/cilium/cilium/pkg/eventqueue.<span style="color:#000000"><strong>(</strong></span><span style="color:#000000"><strong>*</strong></span>EventQueue<span style="color:#000000"><strong>)</strong></span>.run+101runtime.goexit+1
</code></span></span></span>

2.3.2 带 PID/proc/<PID>

更方便、更简洁的方法是找到 PID 命名空间并将其传递给 ,这将使命令更短:bpftrace

<span style="color:#333333"><span style="background-color:#f8f8f8"><span style="background-color:#f6f8fa"><code><span style="color:#008080">$ </span><span style="color:#0086b3">sudo </span>docker inspect <span style="color:#000080">-f</span> <span style="color:#dd1144">'{{.State.Pid}}'</span> cilium-agent
109997
<span style="color:#008080">$ </span>bpftrace <span style="color:#000080">-e</span> <span style="color:#dd1144">'uprobe:/proc/109997/root/usr/bin/cilium-agent:"github.com/cilium/cilium/pkg/endpoint.(*Endpoint).regenerate" {printf("%s\n", ustack); }'</span>
</code></span></span></span>

<span style="color:#333333"><span style="background-color:#f8f8f8"><span style="background-color:#f6f8fa"><code><span style="color:#008080">$ </span>bpftrace <span style="color:#000080">-p</span> 109997 <span style="color:#000080">-e</span> <span style="color:#dd1144">'uprobe:/usr/bin/cilium-agent:"github.com/cilium/cilium/pkg/endpoint.(*Endpoint).regenerate" {printf("%s\n", ustack); }'</span>
</code></span></span></span>

3.3 操作 BPF 映射bpftool

现在考虑一个具体问题:如何确定 CNP 是否真的生效?有几种方法:

<span style="color:#333333"><span style="background-color:#f8f8f8"><span style="background-color:#f6f8fa"><code><span style="color:#008080">$ </span>kubectl get cnp <span style="color:#000080">-n</span> <ns> <cnp> <span style="color:#000080">-o</span> yaml       <span style="color:#999988"><em># spec & status in k8s</em></span>
<span style="color:#008080">$ </span>cilium endpoint get <ep <span style="color:#0086b3">id</span><span style="color:#000000"><strong>></strong></span>                 <span style="color:#999988"><em># spec & status in cilium userspace</em></span>
<span style="color:#008080">$ </span>cilium bpf policy get <ep <span style="color:#0086b3">id</span><span style="color:#000000"><strong>></strong></span>               <span style="color:#999988"><em># summary of kernel bpf policy status</em></span>
</code></span></span></span>
  • 查询 Kubernetes?不,这太高了;
  • 查看终端节点状态?不,这是一个用户空间状态,仍然太高级别了;
  • 使用 cilium 命令检查 bpf 策略?嗯,这确实是一个总结 的 BPF 策略,但摘要代码本身也可能有 bug;

最底层的策略状态是内核中的 BPF 策略映射,我们可以通过 bpftool 查看它:

<span style="color:#333333"><span style="background-color:#f8f8f8"><span style="background-color:#f6f8fa"><code><span style="color:#008080">$ </span>bpftool map dump pinned cilium_policy_00794 <span style="color:#999988"><em># REAL & ULTIMATE policies in the kernel!</em></span>
</code></span></span></span>

但是要使用此工具,您首先需要熟悉一些 Cilium 数据结构。 比如,IP 地址如何对应一个身份,以及如何组合 身份、端口、协议、流量方向在 BPF 策略映射中形成一个键。

<span style="color:#333333"><span style="background-color:#f8f8f8"><span style="background-color:#f6f8fa"><code><span style="color:#999988"><em># Get the corresponding identity of an (client) IP address</em></span>
<span style="color:#008080">$ </span>cilium bpf ipcache get 10.2.6.113
10.2.6.113 maps to identity 298951 0 0.0.0.0<span style="color:#999988"><em># Convert a numeric identity to its hex representation</em></span>
<span style="color:#008080">$ </span><span style="color:#0086b3">printf</span> <span style="color:#dd1144">'%08x'</span> 298951
00048fc7<span style="color:#999988"><em># Search if there exists any policy related to this identity</em></span>
<span style="color:#999988"><em>#</em></span>
<span style="color:#999988"><em># Key format: identity(4B) + port(2B) + proto(1B) + direction(1B)</em></span>
<span style="color:#999988"><em># For endpoint 794's TCP/80 ingress, check if allow traffic from identity 298951</em></span>
<span style="color:#008080">$ </span>bpftool map dump pinned cilium_policy_00794 | <span style="color:#0086b3">grep</span> <span style="color:#dd1144">"c7 8f 04 00"</span> <span style="color:#000080">-B</span> 1 <span style="color:#000080">-A</span> 3
key:
c7 8f 04 00 00 50 06 00 <span style="color:#999988"><em># 4B identity + 2B port(80) + 1B L4Proto(TCP) + direction(ingress)</em></span>
value:
00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
</code></span></span></span>

键和值数据结构:

<span style="color:#333333"><span style="background-color:#f8f8f8"><span style="background-color:#f6f8fa"><code><span style="color:#999988"><em>// PolicyKey represents a key in the BPF policy map for an endpoint. It must</em></span>
<span style="color:#999988"><em>// match the layout of policy_key in bpf/lib/common.h.</em></span>
<span style="color:#999988"><em>// +k8s:deepcopy-gen:interfaces=github.com/cilium/cilium/pkg/bpf.MapKey</em></span>
<span style="color:#000000"><strong>type</strong></span> PolicyKey <span style="color:#000000"><strong>struct</strong></span> {Identity         <span style="color:#445588"><strong>uint32</strong></span> <span style="color:#dd1144">`align:"sec_label"`</span>DestPort         <span style="color:#445588"><strong>uint16</strong></span> <span style="color:#dd1144">`align:"dport"`</span> <span style="color:#999988"><em>// In network byte-order</em></span>Nexthdr          <span style="color:#445588"><strong>uint8</strong></span>  <span style="color:#dd1144">`align:"protocol"`</span>TrafficDirection <span style="color:#445588"><strong>uint8</strong></span>  <span style="color:#dd1144">`align:"egress"`</span>
}<span style="color:#999988"><em>// PolicyEntry represents an entry in the BPF policy map for an endpoint. It must</em></span>
<span style="color:#999988"><em>// match the layout of policy_entry in bpf/lib/common.h.</em></span>
<span style="color:#999988"><em>// +k8s:deepcopy-gen:interfaces=github.com/cilium/cilium/pkg/bpf.MapValue</em></span>
<span style="color:#000000"><strong>type</strong></span> PolicyEntry <span style="color:#000000"><strong>struct</strong></span> {ProxyPort <span style="color:#445588"><strong>uint16</strong></span> <span style="color:#dd1144">`align:"proxy_port"`</span> <span style="color:#999988"><em>// In network byte-order</em></span>Flags     <span style="color:#445588"><strong>uint8</strong></span>  <span style="color:#dd1144">`align:"deny"`</span>Pad0      <span style="color:#445588"><strong>uint8</strong></span>  <span style="color:#dd1144">`align:"pad0"`</span>Pad1      <span style="color:#445588"><strong>uint16</strong></span> <span style="color:#dd1144">`align:"pad1"`</span>Pad2      <span style="color:#445588"><strong>uint16</strong></span> <span style="color:#dd1144">`align:"pad2"`</span>Packets   <span style="color:#445588"><strong>uint64</strong></span> <span style="color:#dd1144">`align:"packets"`</span>Bytes     <span style="color:#445588"><strong>uint64</strong></span> <span style="color:#dd1144">`align:"bytes"`</span>
}<span style="color:#999988"><em>// pkg/maps/policymap/policymap.go</em></span><span style="color:#999988"><em>// Allow pushes an entry into the PolicyMap to allow traffic in the given</em></span>
<span style="color:#999988"><em>// `trafficDirection` for identity `id` with destination port `dport` over</em></span>
<span style="color:#999988"><em>// protocol `proto`. It is assumed that `dport` and `proxyPort` are in host byte-order.</em></span>
<span style="color:#000000"><strong>func</strong></span> (pm <span style="color:#000000"><strong>*</strong></span>PolicyMap) Allow(id <span style="color:#445588"><strong>uint32</strong></span>, dport <span style="color:#445588"><strong>uint16</strong></span>, proto u8proto<span style="color:#000000"><strong>.</strong></span>U8proto, trafficDirection trafficdirection<span style="color:#000000"><strong>.</strong></span>TrafficDirection, proxyPort <span style="color:#445588"><strong>uint16</strong></span>) <span style="color:#445588"><strong>error</strong></span> {key <span style="color:#000000"><strong>:=</strong></span> newKey(id, dport, proto, trafficDirection)pef <span style="color:#000000"><strong>:=</strong></span> NewPolicyEntryFlag(<span style="color:#000000"><strong>&</strong></span>PolicyEntryFlagParam{})entry <span style="color:#000000"><strong>:=</strong></span> newEntry(proxyPort, pef)<span style="color:#000000"><strong>return</strong></span> pm<span style="color:#000000"><strong>.</strong></span>Update(<span style="color:#000000"><strong>&</strong></span>key, <span style="color:#000000"><strong>&</strong></span>entry)
}
</code></span></span></span>

bpftool在紧急情况下也会来救援,例如当 流量被拒绝,但您的 Kubernetes 或 Cilium 代理无法准备就绪, 只需插入一个 allow-any 规则,如下所示:

<span style="color:#333333"><span style="background-color:#f8f8f8"><span style="background-color:#f6f8fa"><code><span style="color:#999988"><em># Add an allow-any rule in emergency cases</em></span>
<span style="color:#008080">$ </span>bpftool map update pinned <map> <span style="color:#dd1144">\</span>key hex 00 00 00 00 00 00 00 00 <span style="color:#dd1144">\</span>value hex 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 noexist
</code></span></span></span>

3.4 使用 API 操作 kvstore 内容etcdctl

我们要分享的最后一个技能是操作 kvstore 内容。

同样,这需要对 Cilium 数据模型有深入的了解。 例如,将以下三个条目插入 kvstore 中,

<span style="color:#333333"><span style="background-color:#f8f8f8"><span style="background-color:#f6f8fa"><code><span style="color:#008080">$ </span>etcdctl put <span style="color:#dd1144">"cilium/state/identities/v1/id/15614229"</span> <span style="color:#dd1144">\</span><span style="color:#dd1144">'k8s:app=app1;k8s:io.cilium.k8s.policy.cluster=cluster1;k8s:io.cilium.k8s.policy.serviceaccount=default;k8s:io.kubernetes.pod.namespace=ns1;'</span><span style="color:#008080">$ </span>etcdctl put <span style="color:#dd1144">'k8s:app=app1;k8s:io.cilium.k8s.policy.cluster=cluster1;k8s:io.cilium.k8s.policy.serviceaccount=default;k8s:io.kubernetes.pod.namespace=ns1;/10.3.9.10'</span> <span style="color:#dd1144">\</span>15614229<span style="color:#008080">$ </span>etcdctl put <span style="color:#dd1144">"cilium/state/ip/v1/cluster1/10.3.192.65"</span> <span style="color:#dd1144">\</span><span style="color:#dd1144">'{"IP":"10.3.192.65","Mask":null,"HostIP":"10.3.9.10","ID":15614299,"Key":0,"Metadata":"cilium-global:cluster1:node1:2404","K8sNamespace":"ns1","K8sPodName":"pod1"}'</span>
</code></span></span></span>

所有 cilium-agents 都会收到通知,在 Kubernetes 、 namespace 中创建了一个 pod,其中包含 PoIP、NodeIP、NodeName、pod 标签和 条目中的身份信息。cluster1default

从本质上讲,这就是我们在 CER 解决方案中将 VM、BM 和非纤毛 pod 注入 Cilium 世界的方式(有关详细信息,请参阅我们之前的帖子 [8]); 它也是 Cilium 网络策略的基础。

警告:操纵 kvstores 和 BPF 映射是危险的, 因此,我们不建议在生产环境中执行这些操作 环境中,除非您知道自己在做什么。

4 总结

我们从 1.4 开始一直在使用 Cilium,现在已经一路升级到 1.10(2022.11 更新)。 它支持我们的业务和基础设施关键服务。 凭借 4 年的经验,我们相信它不仅为大规模生产做好了准备, 而且在性能、功能、社区等方面也是最佳候选人之一。1.11

最后,我想特别感谢 Andre、Denial、Joe、Martynas、Paul、Quentin、Thomas 以及所有 Cilium 的家伙。社区非常好,过去帮了我们很多。

相关文章:

使用Cilium/eBPF实现大规模云原生网络和安全

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 目录 抽象 1 Trip.com 云基础设施 1.1 分层架构 1.2 更多细节 2 纤毛在 Trip.com 2.1 推出时间表 2.2 自定义 2.3 优化和调整 2.3.1 解耦安装 2.3.2 避免重试/重启风暴 2.3.3 稳定性优先 2…...

“深入浅出”系列之C++:(4)回调函数

在写项目的时候遇见一个问题&#xff0c;现在的需求是主项目需要拿到子项目的结果来进行显示&#xff0c;那么如何集成呢&#xff0c;子项目里面有一个MainWindow类&#xff0c;类里 回调函数是一种通过函数指针将函数作为参数传递给另一个函数的编程技术。这种机制允许程序在特…...

Mysql--运维篇--主从复制和集群(主从复制I/O线程,SQL线程,二进制日志,中继日志,集群NDB)

一、主从复制 MySQL的主从复制&#xff08;Master-Slave Replication&#xff09;是一种数据冗余和高可用性的解决方案&#xff0c;它通过将一个或多个从服务器&#xff08;Slave&#xff09;与主服务器&#xff08;Master&#xff09;同步来实现。主从复制的基本原理是&#…...

设计模式 行为型 状态模式(State Pattern)与 常见技术框架应用 解析

状态模式&#xff08;State Pattern&#xff09;是一种行为型设计模式&#xff0c;它允许对象在内部状态改变时改变其行为&#xff0c;使得对象看起来好像修改了它的类。这种设计模式的核心思想是将对象的状态和行为封装成不同的状态类&#xff0c;通过状态对象的行为改变来避免…...

计算机网络 (38)TCP的拥塞控制

前言 TCP拥塞控制是传输控制协议&#xff08;Transmission Control Protocol&#xff0c;TCP&#xff09;避免网络拥塞的算法&#xff0c;是互联网上主要的一个拥塞控制措施。 一、目的 TCP拥塞控制的主要目的是防止过多的数据注入到网络中&#xff0c;使网络能够承受现有的网络…...

鸿蒙面试 2025-01-09

鸿蒙分布式理念&#xff1f;&#xff08;个人认为理解就好&#xff09; 鸿蒙操作系统的分布式理念主要体现在其独特的“流转”能力和相关的分布式操作上。在鸿蒙系统中&#xff0c;“流转”是指涉多端的分布式操作&#xff0c;它打破了设备之间的界限&#xff0c;实现了多设备…...

【关于for循环的几种写法】

关于for循环的几种写法 在 C 中&#xff0c;for(int i 0; i < n; i) 是一种常见的循环写法&#xff0c;用于遍历从 0 到 n-1 的索引。如果你希望简化这种写法&#xff0c;可以使用以下几种方法&#xff1a; 1. 使用范围 for 循环 如果你需要遍历一个容器&#xff08;如数…...

Apache和PHP:构建动态网站的黄金组合

在当今的互联网世界&#xff0c;网站已经成为了企业、个人和机构展示自己、与用户互动的重要平台。而在这些动态网站的背后&#xff0c;Apache和PHP无疑是最受开发者青睐的技术组合之一。这一组合提供了高效、灵活且可扩展的解决方案&#xff0c;帮助您快速搭建出强大的网站&am…...

免费开源的下载工具Xdown

软件介绍 Xdown是一款功能强大的开源免费下载工具&#xff0c;专为PC端用户设计&#xff0c;支持多种协议和下载方式。 1、多线程下载 Xdown支持最高128线程的并发下载&#xff0c;能够将文件分割成多个部分同时下载&#xff0c;从而显著提升下载速度。 2、多种协议支持 该…...

Three.js 数学工具:构建精确3D世界的基石

文章目录 前言一、向量&#xff08;Vectors&#xff09;二、矩阵&#xff08;Matrices&#xff09;三、四元数&#xff08;Quaternions&#xff09;四、欧拉角&#xff08;Euler Angles&#xff09;五、颜色&#xff08;Colors&#xff09;六、几何体生成器&#xff08;Geometr…...

如何明智地提问

如何明智地提问的重要总结&#xff0c;让我为主要观点添加一些具体的实践建议&#xff1a; 提问前的准备工作 尝试在 Google、Stack Overflow 等平台搜索相似问题阅读相关文档和错误日志尝试自己调试和排查问题记录下已尝试过的解决方案 选择合适的提问平台 Stack Overflow…...

Microsoft Sql Server 2019 函数理解

说到函数&#xff0c;首先和存储过程作个比较吧&#xff0c;两者有一个共同点都是预编译优化后存储在磁盘中&#xff0c;所以效率 要比T-SQL高一点点。值得注意的是&#xff0c;存储过程可以创建或访问临时表&#xff0c;而函数不可以&#xff1b; 同时函数不可 以修改表中的数…...

自定义日期转换配置

文章目录 1.日期问题出现原因以及解决方案概述1.图示2.三种解决方案概述1.对于表单数据 application/x-www-form-urlencoded2.对于JSON数据1.使用JsonFormat注解2.自定义Jackson日期转换配置 2.解决方案common-web-starter1.目录2.BaseController.java 使用InitBinder解决表单数…...

“AI智能服务平台系统,让生活更便捷、更智能

大家好&#xff0c;我是资深产品经理老王&#xff0c;今天咱们来聊聊一个让生活变得越来越方便的高科技产品——AI智能服务平台系统。这个系统可是现代服务业的一颗璀璨明珠&#xff0c;它究竟有哪些魅力呢&#xff1f;下面我就跟大家伙儿闲聊一下。 一、什么是AI智能服务平台系…...

SQL美化器优化

文章目录 1.目录2.代码 1.目录 2.代码 package com.sunxiansheng.mybatis.plus.inteceptor;import org.apache.ibatis.executor.statement.StatementHandler; import org.apache.ibatis.mapping.*; import org.apache.ibatis.plugin.*; import org.apache.ibatis.reflection.*…...

我的128天创作之路:回顾与展望

大家好呀&#xff01;今天来和你们分享一下我的创作历程&#x1f601;。 一、机缘 最开始创作呢&#xff0c;是因为在学习 C 的 STL 时&#xff0c;像 string、list、vector 这些模板可把我折腾得够呛&#xff0c;但也让我学到了超多东西&#xff01;我就想&#xff0c;要是把我…...

内核配置参数整理

#参考网页 linux5.2 &#xff1c;.config&#xff1e;文件注释 详细解释 CONFIG_ARMy&#xff1a;启用ARM架构支持&#xff0c;这是ARM处理器专用的内核配置选项。 CONFIG_ARM_HAS_SG_CHAINy&#xff1a;启用对散列表&#xff08;scatter-gather&#xff09;链的支持&#xf…...

SpringBoot整合Easy-es

一.什么是Easy-Es Easy-Es&#xff08;简称EE&#xff09;是一款基于ElasticSearch(简称Es)官方提供的RestHighLevelClient打造的ORM开发框架&#xff0c;在 RestHighLevelClient 的基础上,只做增强不做改变&#xff0c;为简化开发、提高效率而生,您如果有用过Mybatis-Plus(简称…...

于交错的路径间:分支结构与逻辑判断的思维协奏

大家好啊&#xff0c;我是小象٩(๑ω๑)۶ 我的博客&#xff1a;Xiao Xiangζั͡ޓއއ 很高兴见到大家&#xff0c;希望能够和大家一起交流学习&#xff0c;共同进步。* 这一节内容很多&#xff0c;文章字数达到了史无前例的一万一&#xff0c;我们要来学习分支与循环结构中…...

Linux之读者写者模型与特殊锁的学习

目录 读者写者模型 特殊锁 悲观锁 自旋锁 在前几期&#xff0c;我们学习了多线程的生产者和消费者模型&#xff0c;生产者和消费者模型中&#xff0c;有三种关系&#xff0c;两个角色&#xff0c;一个场所&#xff0c;那么读者写者模型和生产者消费者模型有什么关联吗&…...

回溯专题 记录

回溯的题目按照这套模板进行&#xff1b; 我感觉整体逻辑还是递归&#xff0c;只不过有了pop_back才是回溯概念&#xff1b; class Solution {public:vector<int> path;vector<vector<int>> ans;void backtracking(int n,int k,int startindex){if(path.…...

使用 Python 实现自动化办公(邮件、Excel)

目录 一、Python 自动化办公的准备工作 1.1 安装必要的库 1.2 设置邮件服务 二、邮件自动化处理 2.1 发送邮件 示例代码 注意事项 2.2 接收和读取邮件 示例代码 三、Excel 自动化处理 3.1 读取和写入 Excel 文件 示例代码 3.2 数据处理和分析 示例代码 四、综合…...

贪心算法笔记

贪心算法笔记 大概内容 贪心就是对于一个问题有很多个步骤,我们在每一个步骤中都选取最优的那一个,最后得出答案。就是在一些函数中可行,但是有些比如二次函数,因为它的转折点不一定最优,就是不可行的。那么如何判断贪心呢?有这么几种 看时间复杂度,一般的就是 O ( n…...

Formality:两种等价状态consistency和equality

相关阅读 Formalityhttps://blog.csdn.net/weixin_45791458/category_12841971.html?spm1001.2014.3001.5482 背景 逻辑锥的等价性检查时&#xff0c;存在两种验证模式&#xff1a;一致(consistency)和等同(equality)&#xff0c;要理解这两点&#xff0c;首先得明白综合工具…...

Java Web开发基础:HTML的深度解析与应用

文章目录 前言&#x1f30d;一.B/S 软件开发架构简述&#x1f30d;二.HTML 介绍❄️2.1 官方文档❄️2.2 网页的组成❄️2.3 HTML 是什么❄️2.4html基本结构 &#x1f30d;三.HTML标签1.html 的标签/元素-说明2. html 标签注意事项和细节3.font 字体标签4.标题标签5.超链接标签…...

第30章 汇编语言--- 性能优化技巧

汇编语言是用于直接编程计算机硬件的低级语言&#xff0c;它几乎是一对一地映射到机器指令。因为汇编代码与特定处理器架构紧密相关&#xff0c;所以在讨论性能优化技巧时&#xff0c;通常需要考虑具体的CPU架构和指令集。 以下是一些通用的汇编语言性能优化技巧&#xff0c;并…...

HTB:Paper[WriteUP]

目录 连接至HTB服务器并启动靶机 信息收集 使用rustscan对靶机TCP端口进行开放扫描 将靶机TCP开放端口号提取并保存 使用nmap对靶机TCP开放端口进行脚本、服务扫描 使用nmap对靶机TCP开放端口进行漏洞、系统扫描 使用nmap对靶机常用UDP端口进行开放扫描 对靶机进行子域…...

数据库中的 DDL、DML 和 DCL

数据库中的 DDL、DML 和 DCL 在数据库的定义与操作中&#xff0c;DDL、DML 和 DCL 是三个核心概念&#xff0c;分别用于不同层面的数据库管理与操作。 1. DDL&#xff08;Data Definition Language&#xff09; - 数据定义语言 定义 DDL 用于定义和管理数据库的结构或模式。…...

OKR 极简史及理解

大家读完觉得有帮助记得点赞和关注&#xff01;&#xff01;&#xff01; 目录 MBO SMART 和 KPI OKR 1. 什么是 OKR&#xff1f; 1.1 Objectives&#xff08;目标&#xff09; 1.2 Key Results&#xff08;关键成果&#xff09; KR 应当是困难的&#xff0c;但并非不可…...

电商项目-基于ElasticSearch实现商品搜索功能(四)

一、 高亮显示 1.1 高亮分析 高亮显示是指根据商品关键字搜索商品的时候&#xff0c;显示的页面对关键字给定了特殊样式&#xff0c;让它显示更加突出&#xff0c;如商品搜索中&#xff0c;关键字变成了红色&#xff0c;其实就是给定了红色样式。 1.2 高亮搜索实现步骤解析 …...

单位内部网站建设调研/网络优化公司排名

面向对象开发的总结与面向对象的技巧 一、对象描述的配置 方法名 __tostring() 可直接打印对象句柄&#xff0c;从而获得该方法的基本信息或其他内容 在类初始化之后&#xff0c;可以直接输出tostring函数中的内容。 二、对象方法的异常处理 方法名 __call($functionname…...

阿里云 wordpress 503/优化优化

基于MATLAB的数字水印技术研究马苗(西安科技学院计算机系硕士研究生&#xff0c;西安710054)摘要&#xff1a;数字水印技术作为数字媒体版权保护的有效办法&#xff0c;近年来在国内外引起了人们极大的兴趣。但是由于数字水印技术涉及到的知识面比较广&#xff0c;即使是专业人…...

互动网站/腾讯竞价广告

日前&#xff0c;位于美国亚特兰大东北部地区的阿尔法利塔市批准了一个更改土地用途的申请&#xff0c;将原先计划建设数据中心的用地改为建设联排别墅。 而通用电气公司&#xff0c;E-Trade金融公司&#xff0c;以及CarterValidus公司的律师代表已经向当地的城市规划委员会致函…...

苗木公司网站模板/seo名词解释

在互联网行业中&#xff0c;基于Java开发地业务类系统&#xff0c;不管是服务端还是客户端&#xff0c;业务逻辑代码的更新往往是非常频繁的&#xff0c;这源于功能的快速迭代特性。在一般公司内部&#xff0c;特别是使用Java web技术构建的平台中&#xff0c;不管是基于模块化…...

建设工程竣工规划局网站/宠物美容师宠物美容培训学校

所有题目均有五种语言实现。C实现目录、C++ 实现目录、Python实现目录、Java实现目录、JavaScript实现目录...

梅州网站建设wlwl/站长工具日本

IOS环境搭建与开发入门 (此博文图片显示不了&#xff0c;请下载图文教程http://download.csdn.net/detail/jingwen3699/4424117) 一、注册APPLE ID 1.在苹果官网上下载iTunes。 官方下载地址&#xff1a;http://www.apple.com/itunes/download/ 2.安装iTunes. 3.启动iTunes…...