kubernetes-sigs/kube-network-policies
GitHub: kubernetes-sigs/kube-network-policies
Kubernetes 官方网络策略参考实现,用于测试和验证 K8s Network Policy 及 Admin Network Policy 的合规性与功能正确性。
Stars: 72 | Forks: 28
# Kubernetes 网络策略
Kubernetes Network Policies 的实现:
- [Network Policies](https://kubernetes.io/docs/concepts/services-networking/network-policies/)
- [Admin Network Policies and Baseline Admin Network Policies](https://network-policy-api.sigs.k8s.io/)
## 架构概览
kube-network-policies 项目旨在通过在 userspace 中拦截和评估网络数据包来强制执行 Kubernetes network policies。这是通过使用 NFQUEUE 将数据包重定向到 controller 来实现的,controller 随后根据一组 policy evaluators 决定允许或拒绝它们。
### 数据包流
下图展示了网络数据包从内核到 userspace controller 再返回的流程:
[](https://mermaid.live/edit#pako:eNp1UlFvmzAQ_iuWnzaJsEADATpVSgppp25dljZ7GPDg4EuC6tjImHVZlP8-Y6KgpZsfwHz3fXf3HXfAhaCAI7yRpNqi5zjjSJ-6WXXAA0gODD1VpIAu1B5aSihUKTj6vOjRSfoI6lXIFzQnxQso9HElb9BcUDTJ0WBwg6YHvlZkxaBGi6Z9GkJMFKkY4YBuBVdSMAbyeN2nnWotgroVlvUW6AcJjCigJmWcThgTr28qTvNTBuA04xemljXI-n-Onqc92o-hWcHg5G4wF6wsSt1-328vaU-SGsoeJXxTcujMz87gT8IaooRETn79t3BmmHdvme4l884w71PbtvM-YsxeuDbje5x9WybLxIiSU6r7NvAdJC0LFaFJUUClupn-kxAD35vwp3dpvPg6z99rGrbwDuSOlFSv0KGVZVhtYQcZjvSVwpo0TGU440dNJY0ST3te4EjJBizcVFT_yLgkesg7HK0Jq89oQktt_AyC-fzS7apZWQtXhOPogH_hyPFCOwxG-hW4fnjl-p6F9zhyg6Htjv3A930ndN3x1dHCv4XQpYa27wzdcOQFw5EXeuFobGEpms32XFAn_2GoXasb2Vrs7lJPF-StaLjCke8c_wB98vpd)
### 核心组件
架构的关键组件包括:
* **Dataplane Controller**:`dataplane/controller.go` 文件包含主要的 controller,它负责设置 NFQUEUE、拦截数据包并编排策略评估过程。它负责创建必要的 nftables 规则来重定向流量。为了避免将所有数据包发送到 userspace 带来的性能损失,该 controller 包含逻辑,仅捕获至少被一个 network policy 定向的 Pod 的数据包。
* **Policy Engine**:`networkpolicy/engine.go` 文件定义了 `PolicyEngine`,它管理着一个 `PolicyEvaluator` 插件管道。该 engine 负责将每个数据包通过管道运行,并根据 evaluators 返回的 verdicts 做出最终决定。
* **Pod Info Provider**:`podinfo/podinfo.go` 文件提供了一个用于检索 Pod 信息的接口。它将数据包的 IP 地址解析为 PodInfo protobuf 类型(`pkg/api/kubenetworkpolicies.proto`)。这个 `PodInfo` 对象包含了 evaluator 匹配策略所需的所有信息,包括 Pod 的名称、labels、namespace 和关联的 node 信息。
* **Policy Evaluators**:这些是实现 PolicyEvaluator 接口的插件,包含特定类型 network policy 的逻辑。该项目目前包括 AdminNetworkPolicy、BaselineAdminNetworkPolicy 和标准 Kubernetes NetworkPolicy 的 evaluator。
下图展示了这些组件之间的交互:
[](https://mermaid.live/edit#pako:eNpNkdtum0AQhl9lNFeNhB2bGAykipTYVLKqVDSHXiTkYgtjjIp30bJYcS2_e4eFkO7Nzs7OfP8cTpipnDDCQot6B0_rVAKf29cU18KIuhKSYKWk0aqqSH_9rS9vJvBIpoG2hh_ffj7Hz_HgfaCMygM1UIvsD0ek-AaTCST2xdYN3DE2UVWZHSGWRSlpyLwXUhScSAdRtcKoXgegLmuqOIxJ131hdx2RIZbpQKLyjdyqFC1-9R_-g_SluRhEBhfBRhaamuYyttdYvGm1hF-k8zIzn4IrS15bcg6dGCRaHcp8HMYDNarq2t4kYNRHScPnbZaxBn9-Dxqbrfeku8lco4Ns7kWZ8_RPnViKZkd7bjZiM6etaCsuJJVnDhWtUY9HmWFkdEsOtnXOraxLwXvbY7QVVTN647zkxkcn2ed9v2a7bQdrITE64TtGcy-chsGCr8D1wyvX9xw8YuQGs6m79APf9-eh6y6vzg7-VYqlZlN_PnPDhRfMFl7ohYulg1q1xW4UZPiLDe1LLXTXYm9rkjy4lWqlwcj3zv8A6-vK3A)
### PolicyEvaluator 接口
PolicyEvaluator 接口是策略评估管道的核心。每个 evaluator 负责确定是允许、拒绝数据包,还是将其传递给管道中的下一个 evaluator。
该接口在 `pkg/networkpolicy/engine.go` 中定义如下:
```
type PolicyEvaluator interface {
Name() string
EvaluateIngress(ctx context.Context, p \*network.Packet, srcPod, dstPod \*api.PodInfo) (Verdict, error)
EvaluateEgress(ctx context.Context, p \*network.Packet, srcPod, dstPod \*api.PodInfo) (Verdict, error)
}
```
每个 evaluator 返回的 Verdict 可以是以下之一:
* `VerdictAccept`:允许数据包,不再咨询后续的 evaluator。
* `VerdictDeny`:拒绝数据包,不再咨询后续的 evaluator。
* `VerdictNext`:将数据包传递给管道中的下一个 evaluator。
### 如何添加新的 PolicyEvaluator
添加一个新的 `PolicyEvaluator` 非常简单,包括以下步骤:
1. 在 `pkg/networkpolicy` 目录中为你的 evaluator **创建一个新文件**。
2. 为你的 evaluator **定义一个结构体**,实现 `PolicyEvaluator` 接口。
3. **实现 Name 方法**以返回 evaluator 的唯一名称。
4. **实现 EvaluateIngress 和 EvaluateEgress 方法**以定义策略的逻辑。
5. 在 `cmd/main.go` 的 PolicyEngine 中**注册你的新 evaluator**。
#### 示例:创建 AllowListPolicy
让我们创建一个简单的 `AllowListPolicy`,它只允许来自预定义 IP 地址列表的流量。
1. **创建文件** pkg/networkpolicy/allowlistpolicy.go:
```
package networkpolicy
import (
"context"
"net"
"sigs.k8s.io/kube-network-policies/pkg/api"
"sigs.k8s.io/kube-network-policies/pkg/network"
)
// AllowListPolicy is a simple policy that allows traffic only from a predefined list of IP addresses.
type AllowListPolicy struct {
allowedIPs []net.IP
}
// NewAllowListPolicy creates a new AllowListPolicy.
func NewAllowListPolicy(allowedIPs []net.IP) *AllowListPolicy {
return &AllowListPolicy{
allowedIPs: allowedIPs,
}
}
func (a *AllowListPolicy) Name() string {
return "AllowListPolicy"
}
func (a *AllowListPolicy) EvaluateIngress(ctx context.Context, p *network.Packet, srcPod, dstPod *api.PodInfo) (Verdict, error) {
for \_, ip := range a.allowedIPs {
if ip.Equal(p.SrcIP) {
return VerdictAccept, nil
}
}
return VerdictDeny, nil
}
func (a *AllowListPolicy) EvaluateEgress(ctx context.Context, p *network.Packet, srcPod, dstPod *api.PodInfo) (Verdict, error) {
// This policy only applies to ingress traffic.
return VerdictNext, nil
}
```
2. 在 `cmd/main.go` 中**注册新的 evaluator**:
```
// ... (imports)
func main() {
// ... (existing setup)
// Create the evaluators for the Pipeline to process the packets
// and take a network policy action. The evaluators are processed
// by the order in the array.
evaluators := []networkpolicy.PolicyEvaluator{}
// Add the new AllowListPolicy evaluator
allowedIPs := []net.IP{net.ParseIP("10.0.0.1"), net.ParseIP("10.0.0.2")}
evaluators = append(evaluators, networkpolicy.NewAllowListPolicy(allowedIPs))
// ... (rest of the evaluators)
// Create the controller that enforces the network policies on the data plane
networkPolicyController, err := dataplane.NewController(
clientset,
networkPolicyInfomer,
nsInformer,
podInformer,
networkpolicy.NewPolicyEngine(podInfoProvider, evaluators),
cfg,
)
// ... (rest of the main function)
}
```
按照这些步骤,你可以轻松地用自己的自定义 policy evaluator 扩展 kube-network-policies 的功能。
### 未来改进
* **Programmable Traffic Capture**:目前,controller 根据一个 Pod 是否被任何 network policy 选中来决定将哪些流量发送到 userspace。一个潜在的改进是使其更具可编程性,允许单个 PolicyEvaluator 插件指定它们感兴趣的确切流量。这将通过减少发送到 userspace 的流量来进一步优化性能。
## 安装
### 手动安装
当前仓库中有两个 manifest:
1. 对于“传统”的 Kubernetes Network policies,只需执行:
```
kubectl apply -f install.yaml
```
2. 对于 Admin Network Policies 和 Baseline Admin Network Policies,必须先安装 CRD:
```
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/network-policy-api/v0.1.5/config/crd/experimental/policy.networking.k8s.io_adminnetworkpolicies.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/network-policy-api/v0.1.5/config/crd/experimental/policy.networking.k8s.io_baselineadminnetworkpolicies.yaml
```
然后安装 daemonset 并使用相应的标志启用功能:
```
kubectl apply -f install-anp.yaml
```
### Helm
要通过 Helm 安装 kube-network-policies,请运行:
```
helm install kube-network-policies -n kube-system charts/kube-network-policies
```
Admin Network Policies 和 Baseline Admin Network Policies 功能由 `Values.adminNetworkPolicy` 控制,并且
默认启用。如果需要,可以在 values.yaml 中禁用它们,或者在运行
`helm install` 命令时使用 `--set adminNetworkPolicy=false`。
注意:必须先安装相应的 CRD。
## 卸载
### 手动卸载
要卸载手动安装的组件:
1. 删除“传统”的 Kubernetes Network Policies:
```
kubectl delete -f install.yaml
```
2. 对于 Admin Network Policies 和 Baseline Admin Network Policies,删除 CRD 和 daemonset:
```
kubectl delete -f https://raw.githubusercontent.com/kubernetes-sigs/network-policy-api/v0.1.5/config/crd/experimental/policy.networking.k8s.io_adminnetworkpolicies.yaml
kubectl delete -f https://raw.githubusercontent.com/kubernetes-sigs/network-policy-api/v0.1.5/config/crd/experimental/policy.networking.k8s.io_baselineadminnetworkpolicies.yaml
```
### Helm 卸载
如果是通过 Helm 安装的,要卸载 kube-network-policies:
```
helm uninstall kube-network-policies -n kube-system
```
## 指标
Prometheus metrics 在由标志定义的地址上公开
```
-metrics-bind-address string
The IP address and port for the metrics server to serve on (default ":9080")
```
当前实现的 metrics 包括:
* packet_process_time: 处理每个数据包所用的时间 (microseconds)
* packet_process_duration_microseconds: 数据包处理持续时间(以 microseconds 为单位)的摘要
* packet_count: 数据包数量
* nfqueue_queue_total: 当前排队等待应用程序处理的数据包数量
* nfqueue_queue_dropped: 内核不得不丢弃的数据包数量,因为已有太多数据包在等待 user space 发回强制性的 accept/drop verdicts
* nfqueue_user_dropped: 在 netlink 子系统内丢弃的数据包数量。这种丢弃通常发生在相应的 socket 缓冲区已满时;也就是说,user space 无法足够快地读取消息
* nfqueue_packet_id: 最近排队的数据包的 ID
## 测试
参见 [TESTING](docs/testing/README.md)
有两个 github workflows,它们针对 Kubernetes/Kubernetes Network Policy 测试和 Network Policy API Working Group conformance 测试运行 e2e 测试。
## 项目范围
该项目是为了填补 Network Policies 领域测试覆盖率的空白而创建的。
现有的解决方案有限,而且那些方案特定于个别网络提供商,
需要安装额外的功能,增加了复杂性和调试难度,
并且不允许在开发新功能期间快速迭代。
参考:https://github.com/kubernetes/org/issues/4856
这是一个由社区维护的开源项目,采用尽力而为的支持模式,非常欢迎
符合当前项目范围的贡献、反馈和错误报告。
### 目标
P0: Support Testing Kubernetes
利益相关者:SIG Network, SIG Testing, SIG Scalability, SIG Release, Network Policy API Working Group
覆盖工作:e2e testing, scalability, performance and reliability
P0: Provide Early Feedback
利益相关者:SIG Network, Network Policy API Working Group
覆盖范围:在 feature gates 下实现的新功能,以便快速迭代
### 非目标
实现不属于官方或提议的 Kubernetes network policy API 的功能
## 参考
* https://home.regit.org/netfilter-en/using-nfqueue-and-libnetfilter_queue/
* https://netfilter.org/projects/libnetfilter_queue/doxygen/html/
## 社区、讨论、贡献与支持
了解如何参与 Kubernetes 社区,请访问 [community page](http://kubernetes.io/community/)。
你可以通过以下方式联系该项目的维护者:
- [Slack](https://kubernetes.slack.com/messages/sig-network)
- [Mailing List](https://groups.google.com/a/kubernetes.io/g/sig-network)
### 行为准则
参与 Kubernetes 社区受 [Kubernetes Code of Conduct](code-of-conduct.md) 管理。
标签:Admin Network Policies, CISA项目, CNI, EVTX分析, Iptables, JSONLines, Kube-network-policies, MacOS取证, Netfilter, Network Policies, NFQUEUE, Streamlit, 参考实现, 子域名突变, 微隔离, 数据包过滤, 日志审计, 流量控制, 用户态, 网络安全, 网络插件, 网络策略, 网络隔离, 自定义请求头, 访问控制, 防火墙, 隐私保护, 零信任