使用 Cilium 为 CloudNativePG PostgreSQL 实例实施 Kubernetes Pod 网络隔离

使用 Cilium 为 CloudNativePG PostgreSQL 实例实施 Kubernetes Pod 网络隔离 使用 Cilium 为 CloudNativePG PostgreSQL 实例实施 Kubernetes Pod 网络隔离【免费下载链接】cloudnative-pgThe most popular Kubernetes Operator for PostgreSQL.项目地址: https://gitcode.com/GitHub_Trending/cl/cloudnative-pgCilium 是基于 eBPF 的云原生网络、安全与可观测性方案本文以 CloudNativePG 管理的 PostgreSQL 集群为例讲解如何通过CiliumNetworkPolicy实现 Pod 间精细网络访问控制从默认拒绝策略、允许 Operator 访问 8000 状态端口到将 5432 数据库端口的访问权限精确限制到指定应用 Pod。阅读完本文你将掌握一套可直接复制落地的 Cilium 网络策略模板并理解其与 CloudNativePG Pod 标签体系、实例状态端口之间的底层关联。Cilium 与 CloudNativePG 集成背景Cilium 是什么Cilium 是 CNCF 毕业级Graduated项目2021 年被接纳为 Incubating 项目2023 年正式毕业最初由 Isovalent 创建。它是在 eBPF 技术之上构建的云原生环境高级网络、安全与可观测性解决方案通过将 eBPF 程序动态注入 Linux 内核来管理 Kubernetes 集群内的网络流量实现低延迟、高性能通信并强制实施细粒度的安全策略。Cilium 的关键能力包括面向 L3-L7 的高级安全策略实现细粒度的网络流量控制基于 eBPF 的内核级高效流量管理内置服务网格能力Cilium Service Mesh同时支持 Kubernetes NetworkPolicy 与 CiliumNetworkPolicy依托 Hubble 提供内置的可观测性与监控能力。官方安装指引见 Cilium 文档Kubernetes 默认安装路径这里不再赘述。下文默认你已有一个运行中的 Cilium 集群。为什么 CloudNativePG 需要网络策略Kubernetes 的默认行为是允许集群网络中任意两个 Pod 之间的流量互通。而 PostgreSQL 是承载敏感业务数据的核心服务通常只应允许特定应用访问。CloudNativePG 以 Kubernetes Operator 方式管理 PostgreSQL 集群Pod 的创建、扩缩容、故障切换、备份等全部由控制器编排因此网络策略既要保护数据库 Pod又不能破坏 Operator 自身的管控通道——这正是本文所有策略设计的出发点。Cilium 的默认拒绝行为与 CiliumNetworkPolicy与 Kubernetes NetworkPolicy 的命名空间内一旦存在策略即默认拒绝模型不同Cilium 默认不会拒绝任何流量除非显式配置。Cilium 对默认拒绝行为提供了更灵活的控制。要使用 Cilium 强制实施默认拒绝姿态需要显式创建策略要么在endpointSelector配合下使用空的ingress段要么在 Cilium Agent 级别启用--enable-default-deny做更广范围的强制。一个最小的默认拒绝策略如下apiVersion: cilium.io/v2 kind: CiliumNetworkPolicy metadata: name: default-deny namespace: default spec: description: Default deny all ingress traffic to all Pods in this namespace endpointSelector: {} ingress: []endpointSelector: {}匹配命名空间内的全部 Pod空的ingress: []表示不授予任何入站规则从而实现对default命名空间所有 Pod 的默认拒绝。后续所有策略都在此基础上白名单式放行。让网络策略适配 CloudNativePG Operator8000 状态端口实施任何网络策略无论是 Cilium 还是其他方案的第一步都是确保Operator 能访问目标命名空间中的 Pod。这是因为 Operator 需要对 Pod 执行健康检查与管控动作其中一个关键动作是访问 Pod 上的8000 端口以获取 Pod 内 PostgreSQL 实例的当前状态。从源码可以验证这一结论pkg/management/url/url.go 定义了StatusPort 8000状态 HTTP 请求端口同时定义了PathPgStatus /pg/statusPostgreSQL 状态路径。Operator 通过kubectl插件或控制器执行状态查询时正是构造http://localhost:8000/pg/status请求见 internal/cmd/manager/instance/status/cmd.go其中executeRequest使用url.Build(scheme, localhost, url.PathPgStatus, url.StatusPort)发起对 8000 端口的状态请求。因此第一个策略必须放行 Operator位于cnpg-system命名空间对目标命名空间所有 Pod 的 8000 端口访问apiVersion: cilium.io/v2 kind: CiliumNetworkPolicy metadata: name: cnpg-operator-access namespace: default spec: description: Allow CloudNativePG operator access to any pod in the target namespace endpointSelector: {} ingress: - fromEndpoints: - matchLabels: io.kubernetes.pod.namespace: cnpg-system toPorts: - ports: - port: 8000 protocol: TCP注意cnpg-system是使用 YAML manifests 安装 Operator 时的默认命名空间。如果通过 Helm、OLM 等其他方式安装命名空间可能不同请务必按实际部署调整该值。允许集群内 Pod 之间互通cluster 标签的正确使用由于基准策略是全部拒绝我们还需要显式允许同一命名空间内集群 Pod 之间的流量例如主备之间基于流复制的通信。在上一策略基础上追加 ingress 规则apiVersion: cilium.io/v2 kind: CiliumNetworkPolicy metadata: name: cnpg-cluster-internal-access namespace: default spec: description: Allow CloudNativePG operator access and connection between pods in the same namespace endpointSelector: {} ingress: - fromEndpoints: - matchLabels: io.kubernetes.pod.namespace: cnpg-system - matchLabels: io.kubernetes.pod.namespace: default cnpg.io/cluster: cluster-example toPorts: - ports: - port: 8000 protocol: TCP - port: 5432 protocol: TCP该策略同时放行两类来源cnpg-system命名空间的 PodOperator 控制面访问default命名空间中同时带cnpg.io/cluster: cluster-example标签的 Pod集群实例之间的内部通信。这里用到的cnpg.io/cluster标签正是 CloudNativePG 在所有受管对象上打的核心标签。见 pkg/utils/labels_annotations.goClusterLabelName MetadataNamespace /cluster其中MetadataNamespace cnpg.io。实例 Pod 构建时即携带该标签见 pkg/specs/pods.go 中buildInstance为每个 Pod 设置的 Labels包括cnpg.io/cluster、cnpg.io/instanceName、cnpg.io/podRole等。因此matchLabels中同时给出io.kubernetes.pod.namespace: default与cnpg.io/cluster: cluster-example可以精确命中cluster-example的全部实例 Pod。关键语义matchLabels要求 Pod 具备列出的完整标签集合缺少任何一个标签都不会匹配。这也是为什么第二条fromEndpoints必须同时写命名空间标签与 cluster 标签。将 PostgreSQL 访问限制到指定应用下面的策略只允许default命名空间中带有rolebackend标签的 Pod 连接名为cluster-example的 PostgreSQL 集群其余入站流量默认全部阻断apiVersion: cilium.io/v2 kind: CiliumNetworkPolicy metadata: name: postgres-access-backend-label namespace: default spec: description: Allow PostgreSQL access on port 5432 from Pods with rolebackend endpointSelector: matchLabels: cnpg.io/cluster: cluster-example ingress: - fromEndpoints: - matchLabels: role: backend toPorts: - ports: - port: 5432 protocol: TCP注意这里endpointSelector直接使用cnpg.io/cluster: cluster-example把被保护对象限定为 CloudNativePG 管理的实例 PodfromEndpoints使用应用侧自定义的role: backend标签。该策略确保只有rolebackend的 Pod 能通过 5432 端口访问数据库。放行任意命名空间中的指定标签 Pod如果后端应用分布在多个命名空间可以使用labelSelector组合matchLabels与matchExpressions只要求标签存在而不限定命名空间apiVersion: cilium.io/v2 kind: CiliumNetworkPolicy metadata: name: postgres-access-backend-any-ns namespace: default spec: description: Allow PostgreSQL access on port 5432 from Pods with rolebackend in any namespace endpointSelector: matchLabels: cnpg.io/cluster: cluster-example ingress: - fromEndpoints: - labelSelector: matchLabels: role: backend matchExpressions: - key: io.kubernetes.pod.namespace operator: Exists toPorts: - ports: - port: 5432 protocol: TCP这里通过matchExpressions中的io.kubernetes.pod.namespace且operator: Exists要求来源 Pod 必须处于某个命名空间所有 Pod 都满足同时role: backend限定应用身份从而实现对任意命名空间下带该标签的应用放行。放行整个命名空间如果希望backend命名空间的所有Pod 都能访问default命名空间中cluster-example的 5432 端口只需用命名空间标签作为来源选择器apiVersion: cilium.io/v2 kind: CiliumNetworkPolicy metadata: name: postgres-access-backend-namespace namespace: default spec: description: Allow PostgreSQL access on port 5432 from any Pods in the backend namespace endpointSelector: matchLabels: cnpg.io/cluster: cluster-example ingress: - fromEndpoints: - matchLabels: io.kubernetes.pod.namespace: backend toPorts: - ports: - port: 5432 protocol: TCP放行整个集群内部流量若希望 Kubernetes 集群内任意来源都能访问 5432 端口例如开发/测试环境使用fromEntities的cluster实体apiVersion: cilium.io/v2 kind: CiliumNetworkPolicy metadata: name: postgres-access-cluster-wide namespace: default spec: description: Allow ingress traffic to port 5432 of the cluster-example from any pods within the Kubernetes cluster endpointSelector: matchLabels: cnpg.io/cluster: cluster-example ingress: - fromEntities: - cluster toPorts: - ports: - port: 5432 protocol: TCP策略编写辅助与后续扩展编写 Cilium 网络策略时可以使用网络策略可视化编辑器Network Policy Editor这类交互式工具以图形化方式创建和校验CiliumNetworkPolicy帮助避免误配置并直观理解流量规则。以上述策略为基线你已为 PostgreSQL 建立了基础访问控制。在此基础上还可以进一步扩展使用 Cilium 策略语言叠加**出站egress**规则限制实例 Pod 对外发起连接的方向与目标增加审计规则记录并观察被阻断或放行的流量结合 Cilium Service Mesh / Envoy将策略升级到L7 层按 HTTP 方法、路径或 gRPC 服务粒度实施应用层管控。配套示例与进一步阅读完整的 CloudNativePG 集群配置可参考 docs/src/samples/cluster-example-full.yaml其中包含了cnpg.io相关资源、存储、备份、资源配额等完整定义便于搭建测试环境后验证上述策略。关于 CloudNativePG 的标签体系cnpg.io/cluster、cnpg.io/podRole、cnpg.io/instanceName等的完整说明可参阅 docs/src/labels_annotations.md。实例状态端口与路径的源码定义见 pkg/management/url/url.goOperator 状态请求的调用链见 internal/cmd/manager/instance/status/cmd.go。网络策略与 CloudNativePG 的 CNCF 集成主题还包括 external-secrets 等其他方案见 docs/src/cncf-projects/category.json 所索引的 CNCF Projects Integrations 章节。【免费下载链接】cloudnative-pgThe most popular Kubernetes Operator for PostgreSQL.项目地址: https://gitcode.com/GitHub_Trending/cl/cloudnative-pg创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考