NAME
IO::K8s::Role::NetworkPolicy - Role for building network policies (core K8s and Cilium)
VERSION
version 1.110
SYNOPSIS
package My::NetPol;
use IO::K8s::APIObject api_version => 'networking.k8s.io/v1';
with 'IO::K8s::Role::NetworkPolicy';
sub _netpol_format { 'core' } # or 'cilium'
package main;
my $p = My::NetPol->new;
$p->select_pods(app => 'web')
->allow_ingress_from_pods({ app => 'nginx' }, ports => [{ port => 8080 }])
->allow_egress_to_dns
->deny_all_egress;
DESCRIPTION
This role provides the fluent network-policy builders documented in the README's "Network policies" section. The same chain works against both core Kubernetes NetworkPolicy and Cilium CiliumNetworkPolicy CRDs; the role dispatches on a _netpol_format method the consumer must implement, returning either 'core' or 'cilium'.
Core K8s operations build typed IO::K8s::Api::Networking::V1::NetworkPolicySpec objects (with the canonical from/to/ports shape and the policyTypes field maintained automatically); Cilium operations write their rules (fromEndpoints/toEndpoints/fromCIDR/toCIDR) through IO::K8s::Role::SpecBuilder, so a plain-hash Cilium spec gets plain hashrefs and a modeled one gets its declared rule class either way. The two paths live in the same role because most consumers either commit fully to core K8s or fully to Cilium and do not switch mid-flow.
CIDR-accepting methods (allow_ingress_from_cidrs, allow_egress_to_cidrs) validate each input through "IPAddress" in IO::K8s::Types::Net semantics and croak on a malformed value rather than letting the cluster reject the manifest after the fact.
select_pods
$netpol->select_pods(app => 'web', tier => 'frontend');
Sets the policy's podSelector to match pods carrying the given labels. For core Kubernetes NetworkPolicy this writes spec.podSelector.matchLabels; for Cilium CiliumNetworkPolicy it writes the spec.endpointSelector.matchLabels shape. The two formats produce the same selector semantics; the role picks the right shape based on the consuming class's _netpol_format. Returns $self for chaining.
allow_ingress_from_pods
$netpol->allow_ingress_from_pods({ app => 'nginx' }, ports => [{ port => 8080 }]);
Adds an ingress rule allowing traffic from pods matching the given labels. $labels is a hashref (the matchLabels payload); ports is an optional arrayref of { port => $n, protocol => 'TCP' } entries. Core K8s writes spec.ingress[].from[].podSelector; Cilium writes spec.ingress[].fromEndpoints[].matchLabels. Returns $self for chaining.
allow_ingress_from_cidrs
$netpol->allow_ingress_from_cidrs(['10.0.0.0/8', '192.168.0.0/16'], ports => [...]);
Adds an ingress rule allowing traffic from the given CIDR ranges. Each CIDR is validated as having a / and being parseable by Net::IP; croaks otherwise. ports is an optional arrayref of { port => $n, protocol => 'TCP' } entries. Core K8s writes spec.ingress[].from[].ipBlock.cidr; Cilium writes spec.ingress[].fromCIDR. Returns $self for chaining.
allow_ingress_from_namespace
$netpol->allow_ingress_from_namespace('kube-system', ports => [...]);
Adds an ingress rule allowing traffic from any pod in the named namespace. Internally selects on the well-known kubernetes.io/metadata.name => $namespace label (or its Cilium equivalent k8s:io.kubernetes.pod.namespace). ports is optional. Returns $self for chaining.
allow_egress_to_pods
$netpol->allow_egress_to_pods({ app => 'redis' }, ports => [{ port => 6379 }]);
Adds an egress rule allowing traffic to pods matching the given labels. $labels is a hashref of matchLabels; ports is an optional arrayref of port spec entries. Core K8s writes spec.egress[].to[]; Cilium writes spec.egress[].toEndpoints[]. Returns $self for chaining.
allow_egress_to_cidrs
$netpol->allow_egress_to_cidrs(['0.0.0.0/0']);
Adds an egress rule allowing traffic to the given CIDR ranges (most often ['0.0.0.0/0'] for "all external traffic"). Each CIDR is validated as having a / and being parseable by Net::IP; croaks otherwise. Core K8s writes spec.egress[].to[].ipBlock.cidr; Cilium writes spec.egress[].toCIDR. Returns $self for chaining.
allow_egress_to_dns
$netpol->allow_egress_to_dns;
Adds an egress rule that allows DNS lookups: TCP and UDP port 53 to the cluster's CoreDNS pods -- the ones in kube-system carrying k8s-app: kube-dns. This is the common "let pods resolve names" companion to a restrictive egress policy. Returns $self for chaining.
Core Kubernetes writes both selectors into a single to peer, so they intersect rather than union -- the rule reaches pods that are in kube-system and carry the label, not either:
egress:
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- { port: 53, protocol: UDP }
- { port: 53, protocol: TCP }
Cilium writes the same two facts as one toEndpoints match in its own label vocabulary (k8s:io.kubernetes.pod.namespace, k8s:k8s-app).
Changed in 1.108: the core branch used to emit the ports without any to peer, which allows port 53 to every destination -- a policy looser than this documentation described, and one that silently opened egress on port 53 to anything a pod could reach. Manifests regenerated with this version carry the narrower rule. A cluster that relied on the old, wider rule for something other than DNS needs that traffic allowed explicitly.
deny_all_ingress
$netpol->deny_all_ingress;
Replaces the policy's ingress rules with an empty list, the canonical "deny all ingress" shape. Core K8s sets spec.ingress = []; Cilium sets spec.ingress = [] and additionally writes a wildcard spec.ingressDeny = [{}] for consistency with Cilium's deny-first semantics. Returns $self for chaining.
deny_all_egress
$netpol->deny_all_egress;
Replaces the policy's egress rules with an empty list, the canonical "deny all egress" shape. Core K8s sets spec.egress = []; Cilium sets spec.egress = [] and additionally writes a wildcard spec.egressDeny = [{}]. Returns $self for chaining.
REQUIRED METHODS
_netpol_format
Must return 'core' or 'cilium'. The role dispatches all method bodies on this answer; a missing or unknown value is treated as a no-op.
SEE ALSO
IO::K8s::Cilium, IO::K8s::Types::Net, IO::K8s::Api::Networking::V1::NetworkPolicySpec, IO::K8s::APIObject
SUPPORT
Issues
Please report bugs and feature requests on GitHub at https://github.com/pplu/io-k8s-p5/issues.
CONTRIBUTING
Contributions are welcome! Please fork the repository and submit a pull request.
AUTHORS
Torsten Raudssus <getty@cpan.org>
Jose Luis Martinez Torres <jlmartin@cpan.org>
COPYRIGHT AND LICENSE
This software is Copyright (c) 2018-2026 by Jose Luis Martinez Torres <jlmartin@cpan.org>.
This is free software, licensed under:
The Apache License, Version 2.0, January 2004