frozenprocess/telepathy

GitHub: frozenprocess/telepathy

Telepathy 是一款无需集群即可在 CI 中评估 Kubernetes 和 Calico 网络策略连通性的离线测试工具。

Stars: 1 | Forks: 0

# Telepathy **在合并之前了解 NetworkPolicy 的作用 —— 无需集群。** Telepathy 通过针对拓扑结构运行 [Calico](https://github.com/projectcalico) **自己的策略引擎** 来评估 Kubernetes 和 Calico NetworkPolicies。它可以在几毫秒内,无需 Kubernetes、无需 CNI、也无需节点的情况下,告诉你哪个 pod 可以与哪个 pod 进行通信。 因为它复用了 Felix(Calico 的大脑)的真实代码,而不是重新实现策略语义,因此其判定结果与你的集群实际执行的效果完全一致,Telepathy 甚至可以为你展示 Felix 针对相同策略会下发的 **iptables/nftables 链、eBPF 程序以及 Windows HNS ACL**。 ## 用途 - **像测试代码一样测试你的策略** —— 断言 `frontend → backend = allow`、`attacker → backend = deny`,并在断言被破坏时让构建失败。 - **查看 PR 的影响范围** —— 一个 base 分支与 PR 分支的连通性差异对比,以评论的形式发布,展示该变更 *打开* 或 *关闭* 的每一个流量。 - **检查 dataplane** —— 无需集群即可渲染出策略编译后的实际 iptables/nftables/eBPF/HNS 规则。 ## 快速开始 ``` make build # clones the pinned Calico tree, builds bin/telepathy make test # evaluate the sample topology + policy -> connectivity matrix make verify # run the sample assertions (the CI gate) make diff-demo # diff a base policy vs a PR that loosens it ``` 该引擎是一个 stdin 到 stdout 的过滤器:输入一个拓扑 Request,输出一个 JSON 格式的连通性矩阵。 ``` ./bin/telepathy -policy testdata/sample-policy.yaml < testdata/sample-topology.yaml ``` ``` { "matrix": { "demo/frontend->demo/backend": "allow", "demo/attacker->demo/backend": "deny" } } ``` ## 三种模式 ### 1. `evaluate`(默认) —— 连通性矩阵 探测特定 port/protocol 下的每一个有序 pod 对。只有当一对 pod 同时通过源端的 egress 和目的端的 ingress 时,才会判定为 `allow` —— 这与真实数据包必须通过的方式完全一致。 ### 2. `test` —— 作为 CI gate 的断言 在你的策略旁边写下你的期望,让 Telepathy 去执行它们。当任何断言失败时,退出码将不为零。 ``` # telepathy.tests.yaml assertions: - name: frontend may reach backend from: demo/frontend to: demo/backend expect: allow - name: attacker must not reach backend from: demo/attacker to: demo/backend expect: deny # port/protocol optional — inherit the probe ``` ``` telepathy test -assert telepathy.tests.yaml -policy ./policies < topology.yaml # PASS frontend 可达 backend (demo/frontend -> demo/backend) expect=allow got=allow # PASS attacker 不可达 backend (demo/attacker -> demo/backend) expect=deny got=deny # 2 个通过,0 个失败 ``` ### 3. `diff` —— 这个变更打开或关闭了什么? 评估两个修订版本(例如两个 git checkout)上的矩阵,并仅报告发生移动的部分: ``` telepathy -policy ./policies < topology.yaml > base.json # on the base branch telepathy -policy ./policies < topology.yaml > head.json # on the PR branch telepathy diff -format markdown base.json head.json ``` 生成 PR 评论如下: `opened`(deny→allow)是一种新的暴露;`closed`(allow→deny)是一种可能的服务中断。使用 `-format json` 获取机器可读输出,或使用 `-exit-code` 在发生任何变化时判定为失败。 ## 在 CI/CD 中使用 GitHub Action 封装了这两个 gate。在每一个 PR 上,它会运行你的断言,**并且**将 base 分支与 PR 分支的连通性差异对比作为一条置顶评论发布出来: ``` # .github/workflows/networkpolicy.yml on: pull_request permissions: contents: read pull-requests: write jobs: telepathy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: { fetch-depth: 0 } # the diff needs git history - uses: frozenprocess/telepathy@v1 with: topology: path/to/topology.yaml policy: path/to/policies/ # file or directory assertions: path/to/telepathy.tests.yaml ``` 有关所有输入参数,请参见 [`examples/github-actions.yml`](examples/github-actions.yml)。该引擎是 `scratch` 镜像中的一个单一静态二进制文件,因此任何运行容器的 CI(如 GitLab、Tekton、Argo、Jenkins)都可以用相同的方式调用它: ``` docker run --rm -i ghcr.io/frozenprocess/telepathy:latest \ test -assert /w/telepathy.tests.yaml -policy /w/policies < /w/topology.yaml ``` ## 检查 dataplane 相同的 Request 可以渲染出 Felix 实际会下发的规则 —— 这是一个让你直观了解你的策略 *编译成什么* 的独特窗口: ``` telepathy iptables -policy p.yaml < topology.yaml # iptables / nftables chains telepathy bpf -policy p.yaml < topology.yaml # annotated eBPF policy program telepathy hns -policy p.yaml < topology.yaml # Windows HNS ACL rules ``` ## 输入格式 一个 Request 由一个拓扑(`endpoints`、`namespaces`)加上一个探测(`port`、`protocol`)组成;策略通过 stdin 或 `-policy`(一个文件或包含多个 manifest 的目录)分层输入。支持 Kubernetes `networking.k8s.io/v1` NetworkPolicies 和 Calico `projectcalico.org/v3` (Global)NetworkPolicy、Tier、NetworkSet、HostEndpoint、Service/ServiceAccount 选择器等。有关最小化的端到端示例,请参见 [`testdata/`](testdata/)。 ``` namespaces: - { name: demo, labels: { kubernetes.io/metadata.name: demo } } endpoints: - { id: demo/frontend, namespace: demo, name: frontend, ip: 10.0.0.1, labels: { app: frontend } } - { id: demo/backend, namespace: demo, name: backend, ip: 10.0.0.2, labels: { app: backend } } - { id: demo/attacker, namespace: demo, name: attacker, ip: 10.0.0.3, labels: { app: attacker } } port: 8080 protocol: tcp ``` ## 工作原理 Telepathy 在各 CNI 之间是可插拔的。厂商中立的请求/响应 schema 位于轻量级的 [`api`](api/) 模块中,每个 CNI 的策略引擎都位于 [`provider`](provider/) 的 `Provider` 接口之后,并在运行时通过 `-provider` 进行选择(默认为 `calico`;`telepathy version` 会列出已注册的 provider)。这两种方式都是离线驱动 CNI 自己的代码 —— 无需集群。 至关重要的是,**每个 CNI 引擎都从其自己的 Go module 构建为独立的二进制文件**,因此它们的依赖关系图永远不需要相互妥协(Calico 和 Antrea 锁定了互不兼容的 `network-policy-api`、`controller-runtime` 等版本 —— 如果不进行版本 hack,将它们链接到一个二进制文件中是不可能的)。中立的 `api` JSON 契约就是它们之间的边界: - **`calico`**([`provider/calico`](provider/calico/))被链接到主 `telepathy` 二进制文件中(基于 `third_party/calico` 构建):它根据你的拓扑和策略构建出一个 Felix `CalculationGraph`,通过 `app-policy/checker.Evaluate` 走查每一个有序对的 egress 和 ingress,并且可以渲染出 Felix 会下发的 iptables/nftables/eBPF/HNS dataplane。 - **`antrea`** 是一个独立的二进制文件,名为 `telepathy-engine-antrea`([`engines/antrea`](engines/antrea/),基于 `third_party/antrea` 并使用 Antrea 的原生依赖版本构建)。shell 会通过 JSON 契约将 `-provider antrea` 分发给它(stdin 上的 Request → stdout 上的 Response)。它驱动 Antrea 真实的 `grouping.GroupEntityIndex` 来解析 pod/namespace 选择器,然后对解析出的成员应用 Kubernetes NetworkPolicy 语义。跨进程测试会断言其结果与 Calico 引擎在流量层面完全一致。 `make build` 会同时生成这两个二进制文件;shell 会在其自身同级目录下寻找该引擎(可通过 `TELEPATHY_ANTREA_ENGINE` 覆盖)。 ### 法律声明 上面使用的 Telepathy 卡牌图片是非官方的同人创作内容,根据同人内容政策 (Fan Content Policy) 获得许可。未经 Wizards of the Coast 批准或认可。所使用的部分素材版权归 Wizards of the Coast 所有。©Wizards of the Coast LLC。
标签:Docker镜像, EVTX分析, 日志审计, 网络安全, 网络策略, 请求拦截, 隐私保护