Cilium 基于磁盘文件的 Network Policystatic-cnp-path 实现策略即文件与实时热更新【免费下载链接】ciliumeBPF-based Networking, Security, and Observability项目地址: https://gitcode.com/GitHub_Trending/ci/ciliumCilium 的 Network Policy 通常通过 Kubernetes CRDCiliumNetworkPolicy、CiliumClusterwideNetworkPolicy下发到集群。而磁盘文件驱动的策略Disk based Cilium Network Policies提供了一条不依赖 K8s API Server 的路径把策略 YAML 文件直接放到节点的文件系统目录中Cilium agent 会自动读取、解析并加载进策略引擎同时持续监听该目录对新增、修改、删除的文件做出实时响应。本文以当前仓库 Documentation/security/policy/disk-based.rst 为核心骨架结合pkg/policy/directory的源码实现完整讲解该特性的原理、配置、验证与已知限制。功能定位策略 YAML 即文件绕过 CRD 下发该特性允许用户将网络策略 YAML 文件直接放置在节点文件系统中无需通过 Kubernetes CRD 进行定义。通过设置配置字段static-cnp-path用户可以指定策略加载目录Cilium agent 会处理该目录下的所有策略 YAML 文件将其转换为规则并纳入策略引擎。除此之外Cilium agent 还会持续监控该目录新出现的策略 YAML 文件会被加载已存在文件的更新与删除也会同步反映到策略引擎的规则中。需要明确该特性的边界——它只支持CiliumNetworkPolicy和CiliumClusterwideNetworkPolicy两种类型普通 Kubernetes NetworkPolicy 不在其处理范围内。从源码实现看目录监视器Directory policy watcher读取文件后统一反序列化为cilium_v2.CiliumNetworkPolicy对象watcher.go再调用cnp.Parse()转换为规则因此文件内的kind决定了其作用域命名空间级CiliumNetworkPolicy或集群级CiliumClusterwideNetworkPolicy。配置方式static-cnp-path 与 Helm 挂载static-cnp-path是 Cilium agent 的启动参数定义在 pkg/policy/directory/cell.go 中type Config struct { StaticCNPPath string } const ( // StaticCNPPath defines the directory path for static cilium network policy yaml files. staticCNPPath static-cnp-path ) var defaultConfig Config{ StaticCNPPath: , // Disabled } func (cfg Config) Flags(flags *pflag.FlagSet) { flags.String(staticCNPPath, defaultConfig.StaticCNPPath, Directory path to watch and load static cilium network policy yaml files.) }默认值为空字符串即默认关闭该功能一旦设置了非空路径agent 启动后即开始监视该目录。该参数同样会出现在cilium-agent --help的完整输出中对应--static-cnp-path选项参见 Documentation/cmdref/cilium-agent.md--static-cnp-path string Directory path to watch and load static cilium network policy yaml files.Helm values 配置示例Cilium agent 需要监视的目录必须通过卷挂载volume mount从宿主机挂载进来。对于使用 Helm 部署的用户可以通过extraArgs与extraHostPathMounts开启完整示例如下extraArgs: - --static-cnp-path/policies extraHostPathMounts: - name: static-policies mountPath: /policies hostPath: /policies hostPathType: Directory参数说明字段取值示例含义extraArgs--static-cnp-path/policies以 agent 命令行参数形式启用目录监视/policies为容器内策略目录extraHostPathMounts[].namestatic-policies挂载项名称便于在 Pod 中标识extraHostPathMounts[].mountPath/policies容器内挂载路径须与--static-cnp-path一致extraHostPathMounts[].hostPath/policies宿主机上的策略目录路径extraHostPathMounts[].hostPathTypeDirectory宿主机路径类型明确声明为目录extraHostPathMounts是 Cilium Helm Chart 为 agent DaemonSet 提供的标准扩展入口在 Documentation/helm-values.rst 中亦有收录因此无需修改 Chart 本身即可将宿主机目录以 HostPath 形式挂载进 agent 容器。部署完成后向宿主机/policies目录放置或修改策略 YAMLagent 即会自动感知。策略文件的要求与目录监视机制从源码 watcher.go 可以看出目录监视器对文件名的校验非常明确func (p *policyWatcher) isValidCNPFileName(filePath string) bool { if filepath.Ext(filePath) ! .yaml { return false } if reasons : validation.IsDNS1123Subdomain(filepath.Base(filePath)); len(reasons) 0 { p.log.Error( CNP name parse validation failed, logfields.Name, filepath.Base(filePath), logfields.Reasons, reasons, ) return false } return true }即文件必须满足扩展名为.yaml.yml、无扩展名等均会被忽略文件名必须符合 DNS-1123 子域名规范仅含小写字母、数字、-、.且以字母数字开头/结尾命名不合法会直接打印错误日志并跳过。文件的解析流程为os.ReadFile读取 →yaml.YAMLToJSON转 JSON →json.Unmarshal为cilium_v2.CiliumNetworkPolicy对象watcher.go。这意味着文件必须是合法的 Cilium Network Policy YAML任何语法错误或字段不合法都会导致翻译失败agent 会记录Failed to translate policy yaml file to cnp object之类的错误日志。目录监视本身基于 fsnotify完整生命周期如下agent 启动时通过fsnotify.NewWatcher()创建监视器并watcher.Add(dir)注册目录先扫描目录中已存在的文件逐个合法文件加载进策略引擎保证 agent 重启后策略不丢失随后进入事件监听循环Create/Write事件 → 读取并解析文件新增或更新策略Remove/Rename事件 → 从策略引擎删除对应策略。cell.go中通过 Hive 生命周期将监视器注册为 agent 启动钩子cell.goOnStart时启动watchDirectoryOnStop时通过context.WithCancel取消监听而StaticCNPPath为空时直接返回一个空的sync.WaitGroup即完全禁用该能力。文件 → 策略引擎的数据流加载与删除的核心实现如下watcher.go// addToPolicyEngine读取 yaml 文件并转换为策略对象然后加入策略引擎。 func (p *policyWatcher) addToPolicyEngine(cnp *cilium_v2.CiliumNetworkPolicy, cnpFilePath string) error { fileName : filepath.Base(cnpFilePath) resourceID : ipcacheTypes.NewResourceID( ipcacheTypes.ResourceKindFile, p.config.StaticCNPPath, fileName, ) // convert to rules rules, err : cnp.Parse(p.log, p.clusterName) if err ! nil { return err } // update labels lbls : getLabels(fileName, cnp) for _, r : range rules { r.Labels lbls } dc : make(chan uint64, 1) // add to policy engine p.policyImporter.UpdatePolicy(policytypes.PolicyUpdate{ Rules: policyutils.RulesToPolicyEntries(rules), Source: source.Directory, Resource: resourceID, ProcessingStartTime: time.Now(), DoneChan: dc, }) -dc // wait for policy to be applied p.fileNameToCnpCache[fileName] cnp return err }关键点每个策略文件会携带由filename、命名空间若有与policy-derived-from值为CiliumNetworkPolicy或CiliumClusterwideNetworkPolicy组成的标签集来源统一标记为source.Directorywatcher.go通过PolicyImporter.UpdatePolicy()提交策略更新policy_importer.go提交至异步队列后由 importer 批量处理DoneChan用于等待策略真正应用到策略引擎fileNameToCnpCache缓存「文件名 → CNP 对象」映射用于删除操作时反查对应的策略内容watcher.go删除时提交Rules: nil的更新即删除该文件对应的全部规则。源码级测试对这条链路有完整覆盖watcher_test.goTestTranslateToCNPObject验证合法 YAML 能成功转为 CNP 对象、非法 YAML 返回错误TestAddToPolicyEngine验证策略加载后写入缓存且同名文件重复加载即为更新覆盖同一缓存条目TestDeleteFromPolicyEngine验证删除后缓存清空且删除不存在的条目会返回fileNameToCnp map entry doesnt exist错误。测试中使用的策略 YAML 可以作为放置到目录中的真实样例以 CiliumClusterwideNetworkPolicy 为例apiVersion: cilium.io/v2 kind: CiliumClusterWideNetworkPolicy metadata: name: deny-egress-to-ip spec: endpointSelector: {} egressDeny: - toCIDR: - 11.1.0.4/32 enableDefaultDeny: egress: false策略来源验证source 字段与 endpoint 关联要确定某条策略是通过 Kubernetes CRD 建立还是直接来自目录文件可以执行cilium policy get并检查策略中的source属性。来自目录的策略其source字段为directory。此外cilium endpoint get endpoint_id的输出中也包含与该 endpoint 关联策略的来源字段可用于排查某端点究竟被哪一类来源的策略所约束。从底层看directory来源在 pkg/source/source.go 中定义// Directory is the source used for watching and reading // cilium network policy files from specific directory. Directory Source directory同时defaultSources按优先级从高到低排列了所有来源source.goAllowOverwrite()依据该顺序决定新状态能否覆盖旧状态source.go。从源码结构看Directory的优先级介于ClusterMesh与LocalAPI之间且 source_test.go 显示Directory来源的新状态可以覆盖Kubernetes、CustomResource、KVStore、Local、KubeAPIServer、ClusterMesh等既有来源而LocalAPI、Generated、Restored则不可被覆盖。因此可以推断当同一策略同时以多种来源定义时最终生效的规则由来源优先级裁决这也是排查「为什么目录中的策略与 CRD 中的策略行为不一致」时需要留意的点。已知限制与版本注意点对于Cilium 1.14 之前的版本针对集群外部对端的 deny 策略deny-policies for peers outside the cluster有时无法生效相关历史问题为 issue #15198。因此如果依赖 deny 策略来管理发往集群的外部流量请确保使用 1.14 或更高版本。结合源码还可补充以下使用注意点目录中不合法无法解析的 YAML 文件会导致 agent 记录致命错误logging.Fatal需保证放置的文件始终合法文件名的合规性直接决定策略是否被加载命名不符合 DNS-1123 的文件会被静默跳过该特性仅处理CiliumNetworkPolicy/CiliumClusterwideNetworkPolicy其他类型如标准 Kubernetes NetworkPolicy的文件即使放入目录也不会被转换为规则目录必须通过卷挂载从宿主机映射进 agent 容器Helm 下使用extraHostPathMounts且挂载路径需与--static-cnp-path保持一致否则 agent 启动时会因无法访问目录而失败并记录Failed to watch policy directory。小结基于磁盘文件的 Network Policy 为 Cilium 提供了一条去 CRD 化的策略下发路径写入即加载、修改即更新、删除即卸载配合 agent 的目录监视能力实现策略的热变更。其核心实现位于 pkg/policy/directory/配置入口为static-cnp-pathcell.go完整监视与导入逻辑见 watcher.go并通过 watcher_test.go 得到行为验证。在需要绕过 Kubernetes API 进行策略管理、或希望在节点本地直接维护策略文件的场景下该特性提供了简单而可靠的选择使用时注意版本1.14与文件名、文件格式的合规性即可。【免费下载链接】ciliumeBPF-based Networking, Security, and Observability项目地址: https://gitcode.com/GitHub_Trending/ci/cilium创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考