Skip to content

Commit 9bb5910

Browse files
committed
ClusterNetworkPolicy
Network Policy API v1alpha2
1 parent a900dfd commit 9bb5910

File tree

8 files changed

+974
-10
lines changed

8 files changed

+974
-10
lines changed

Makefile

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ REGISTRY?=gcr.io/k8s-staging-networking
1212
TAG?=$(shell echo "$$(date +v%Y%m%d)-$$(git describe --always --dirty)")
1313
PLATFORMS?=linux/amd64,linux/arm64
1414

15-
.PHONY: all build build-standard build-npa-v1alpha1 build-iptracker build-kube-ip-tracker
15+
.PHONY: all build build-standard build-npa-v1alpha1 build-npa-v1alpha2 build-iptracker build-kube-ip-tracker
1616

17-
build: build-standard build-npa-v1alpha1 build-iptracker build-kube-ip-tracker
17+
build: build-standard build-npa-v1alpha1 build-npa-v1alpha2 build-iptracker build-kube-ip-tracker
1818

1919
build-standard:
2020
@echo "Building standard binary..."
@@ -24,6 +24,10 @@ build-npa-v1alpha1:
2424
@echo "Building npa-v1alpha1 binary..."
2525
go build -o ./bin/kube-network-policies-npa-v1alpha1 ./cmd/kube-network-policies/npa-v1alpha1
2626

27+
build-npa-v1alpha2:
28+
@echo "Building npa-v1alpha2 binary..."
29+
go build -o ./bin/kube-network-policies-npa-v1alpha2 ./cmd/kube-network-policies/npa-v1alpha2
30+
2731
build-iptracker:
2832
@echo "Building iptracker binary..."
2933
go build -o ./bin/kube-network-policies-iptracker ./cmd/kube-network-policies/iptracker
@@ -32,7 +36,6 @@ build-kube-ip-tracker:
3236
@echo "Building kube-ip-tracker binary..."
3337
go build -o ./bin/kube-ip-tracker ./cmd/kube-ip-tracker
3438

35-
3639
clean:
3740
rm -rf "$(OUT_DIR)/"
3841

@@ -65,6 +68,12 @@ image-build-npa-v1alpha1: build-npa-v1alpha1
6568
--tag="${REGISTRY}/$(IMAGE_NAME):$(TAG)-npa-v1alpha1" \
6669
--load
6770

71+
image-build-npa-v1alpha2: build-npa-v1alpha2
72+
docker buildx build . \
73+
--build-arg TARGET_BUILD=npa-v1alpha2 \
74+
--tag="${REGISTRY}/$(IMAGE_NAME):$(TAG)-npa-v1alpha2" \
75+
--load
76+
6877
image-build-iptracker: build-iptracker
6978
docker buildx build . \
7079
--build-arg TARGET_BUILD=iptracker \
@@ -91,6 +100,13 @@ image-push-npa-v1alpha1: build-npa-v1alpha1
91100
--tag="${REGISTRY}/$(IMAGE_NAME):$(TAG)-npa-v1alpha1" \
92101
--push
93102

103+
image-push-npa-v1alpha2: build-npa-v1alpha2
104+
docker buildx build . \
105+
--build-arg TARGET_BUILD=npa-v1alpha2 \
106+
--platform="${PLATFORMS}" \
107+
--tag="${REGISTRY}/$(IMAGE_NAME):$(TAG)-npa-v1alpha2" \
108+
--push
109+
94110
image-push-iptracker: build-iptracker
95111
docker buildx build . \
96112
--build-arg TARGET_BUILD=iptracker \
@@ -103,15 +119,15 @@ image-push-kube-ip-tracker: build-kube-ip-tracker
103119
--tag="${REGISTRY}/kube-ip-tracker:$(TAG)" \
104120
--push
105121

106-
107122
# --- Aggregate Targets ---
108123
.PHONY: images-build images-push release
109124

110125
# Build all image variants and load them into the local Docker daemon
111-
images-build: ensure-buildx image-build-standard image-build-npa-v1alpha1
126+
images-build: ensure-buildx image-build-standard image-build-npa-v1alpha1 image-build-npa-v1alpha2 image-build-iptracker image-build-kube-ip-tracker
127+
112128

113129
# Build and push all multi-platform image variants to the registry
114-
images-push: ensure-buildx image-push-standard image-push-npa-v1alpha1
130+
images-push: ensure-buildx image-push-standard image-push-npa-v1alpha1 image-build-npa-v1alpha2 image-push-iptracker image-push-kube-ip-tracker
115131

116132
# The main release target, which pushes all images
117133
release: images-push
Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
1+
package main
2+
3+
import (
4+
"context"
5+
"flag"
6+
"fmt"
7+
"net"
8+
"os"
9+
"os/signal"
10+
"syscall"
11+
"time"
12+
13+
"sigs.k8s.io/kube-network-policies/pkg/api"
14+
"sigs.k8s.io/kube-network-policies/pkg/cmd"
15+
"sigs.k8s.io/kube-network-policies/pkg/dataplane"
16+
"sigs.k8s.io/kube-network-policies/pkg/dns"
17+
"sigs.k8s.io/kube-network-policies/pkg/networkpolicy"
18+
"sigs.k8s.io/kube-network-policies/pkg/podinfo"
19+
pluginsnpav1alpha2 "sigs.k8s.io/kube-network-policies/plugins/npa-v1alpha2"
20+
npav1alpha2 "sigs.k8s.io/network-policy-api/apis/v1alpha2"
21+
npaclient "sigs.k8s.io/network-policy-api/pkg/client/clientset/versioned"
22+
npainformers "sigs.k8s.io/network-policy-api/pkg/client/informers/externalversions"
23+
24+
"k8s.io/apimachinery/pkg/api/meta"
25+
"k8s.io/client-go/informers"
26+
"k8s.io/client-go/tools/clientcmd"
27+
28+
"k8s.io/client-go/kubernetes"
29+
"k8s.io/client-go/rest"
30+
"k8s.io/component-base/logs"
31+
logsapi "k8s.io/component-base/logs/api/v1"
32+
_ "k8s.io/component-base/logs/json/register"
33+
nodeutil "k8s.io/component-helpers/node/util"
34+
"k8s.io/klog/v2"
35+
)
36+
37+
// This is a pattern to ensure that deferred functions executes before os.Exit
38+
func main() {
39+
os.Exit(run())
40+
}
41+
42+
func run() int {
43+
// Setup logging
44+
logCfg := logsapi.NewLoggingConfiguration()
45+
logsapi.AddGoFlags(logCfg, flag.CommandLine)
46+
47+
// Setup flags
48+
opts := cmd.NewOptions()
49+
opts.AddFlags(flag.CommandLine)
50+
51+
flag.Parse()
52+
53+
// init logging
54+
logs.InitLogs()
55+
if err := logsapi.ValidateAndApply(logCfg, nil); err != nil {
56+
fmt.Fprintf(os.Stderr, "%v\n", err)
57+
return 1
58+
}
59+
60+
// Create a context for structured logging, and catch termination signals
61+
ctx, cancel := signal.NotifyContext(
62+
context.Background(), os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
63+
defer cancel()
64+
65+
logger := klog.FromContext(ctx)
66+
logger.Info("called", "args", flag.Args())
67+
68+
flag.VisitAll(func(flag *flag.Flag) {
69+
logger.Info("flag", "name", flag.Name, "value", flag.Value)
70+
})
71+
72+
if _, _, err := net.SplitHostPort(opts.MetricsBindAddress); err != nil {
73+
logger.Error(err, "parsing metrics bind address", "address", opts.MetricsBindAddress)
74+
return 1
75+
}
76+
77+
nodeName, err := nodeutil.GetHostname(opts.HostnameOverride)
78+
if err != nil {
79+
klog.Fatalf("can not obtain the node name, use the hostname-override flag if you want to set it to a specific value: %v", err)
80+
}
81+
82+
dpCfg := dataplane.Config{
83+
FailOpen: opts.FailOpen,
84+
QueueID: opts.QueueID,
85+
NetfilterBug1766Fix: opts.NetfilterBug1766Fix,
86+
}
87+
88+
var config *rest.Config
89+
if opts.Kubeconfig != "" {
90+
config, err = clientcmd.BuildConfigFromFlags("", opts.Kubeconfig)
91+
} else {
92+
// creates the in-cluster config
93+
config, err = rest.InClusterConfig()
94+
}
95+
if err != nil {
96+
klog.Fatalf("can not create client-go configuration: %v", err)
97+
}
98+
99+
// use protobuf for better performance at scale
100+
// https://kubernetes.io/docs/reference/using-api/api-concepts/#alternate-representations-of-resources
101+
npaConfig := config // shallow copy because CRDs does not support proto
102+
config.AcceptContentTypes = "application/vnd.kubernetes.protobuf,application/json"
103+
config.ContentType = "application/vnd.kubernetes.protobuf"
104+
105+
// creates the clientset
106+
clientset, err := kubernetes.NewForConfig(config)
107+
if err != nil {
108+
panic(err.Error())
109+
}
110+
111+
informersFactory := informers.NewSharedInformerFactory(clientset, 0)
112+
nsInformer := informersFactory.Core().V1().Namespaces()
113+
networkPolicyInfomer := informersFactory.Networking().V1().NetworkPolicies()
114+
podInformer := informersFactory.Core().V1().Pods()
115+
nodeInformer := informersFactory.Core().V1().Nodes()
116+
117+
// Set the memory-saving transform function on the pod informer.
118+
err = podInformer.Informer().SetTransform(func(obj interface{}) (interface{}, error) {
119+
if accessor, err := meta.Accessor(obj); err == nil {
120+
accessor.SetManagedFields(nil)
121+
}
122+
return obj, nil
123+
})
124+
if err != nil {
125+
klog.Fatalf("Failed to set pod informer transform: %v", err)
126+
}
127+
128+
npaClient, err := npaclient.NewForConfig(npaConfig)
129+
if err != nil {
130+
klog.Fatalf("Failed to create Network client: %v", err)
131+
}
132+
npaInformerFactory := npainformers.NewSharedInformerFactory(npaClient, 0)
133+
cnpInformer := npaInformerFactory.Policy().V1alpha2().ClusterNetworkPolicies()
134+
135+
// Create the Pod IP resolvers.
136+
// First, given an IP address they return the Pod name/namespace.
137+
informerResolver, err := podinfo.NewInformerResolver(podInformer.Informer())
138+
if err != nil {
139+
klog.Fatalf("Failed to create informer resolver: %v", err)
140+
}
141+
resolvers := []podinfo.IPResolver{informerResolver}
142+
143+
// Create an NRI Pod IP resolver if enabled, since NRI connects to the container runtime
144+
// the Pod and IP information is provided at the time the Pod Sandbox is created and before
145+
// the containers start running, so policies can be enforced without race conditions.
146+
if !opts.DisableNRI {
147+
nriIPResolver, err := podinfo.NewNRIResolver(ctx)
148+
if err != nil {
149+
klog.Infof("failed to create NRI plugin, using apiserver information only: %v", err)
150+
}
151+
resolvers = append(resolvers, nriIPResolver)
152+
}
153+
154+
// Create the pod info provider to obtain the Pod information
155+
// necessary for the network policy evaluation, it uses the resolvers
156+
// to obtain the key (Pod name and namespace) and use the informers to obtain
157+
// the labels that are necessary to match the network policies.
158+
podInfoProvider := podinfo.NewInformerProvider(
159+
podInformer,
160+
nsInformer,
161+
nodeInformer,
162+
resolvers)
163+
164+
// Create the evaluators for the Pipeline to process the packets
165+
// and take a network policy action. The evaluators are processed
166+
// by the order in the array.
167+
evaluators := []api.PolicyEvaluator{}
168+
169+
// Logging evaluator must go first if enabled.
170+
if klog.V(2).Enabled() {
171+
evaluators = append(evaluators, networkpolicy.NewLoggingPolicy())
172+
}
173+
174+
// Admin Network Policy need to associate IP addresses to Domains
175+
// NewDomainCache implements the interface DomainResolver using
176+
// nftables to create a cache with the resolved IP addresses from the
177+
// Pod domain queries.
178+
domainResolver := dns.NewDomainCache(opts.QueueID + 1)
179+
go func() {
180+
err := domainResolver.Run(ctx)
181+
if err != nil {
182+
klog.Infof("domain cache controller exited: %v", err)
183+
}
184+
}()
185+
186+
evaluators = append(evaluators, pluginsnpav1alpha2.NewClusterNetworkPolicy(
187+
npav1alpha2.AdminTier,
188+
cnpInformer,
189+
domainResolver,
190+
))
191+
192+
// Standard Network Policy goes after AdminNetworkPolicy and before BaselineAdminNetworkPolicy
193+
evaluators = append(evaluators, networkpolicy.NewStandardNetworkPolicy(
194+
nodeName,
195+
nsInformer,
196+
podInformer,
197+
networkPolicyInfomer,
198+
))
199+
200+
evaluators = append(evaluators, pluginsnpav1alpha2.NewClusterNetworkPolicy(
201+
npav1alpha2.BaselineTier,
202+
cnpInformer,
203+
domainResolver,
204+
))
205+
206+
informersFactory.Start(ctx.Done())
207+
npaInformerFactory.Start(ctx.Done())
208+
209+
cmd.Start(ctx, networkpolicy.NewPolicyEngine(podInfoProvider, evaluators), dpCfg, opts.MetricsBindAddress)
210+
211+
<-ctx.Done()
212+
logger.Info("Received termination signal, starting cleanup...")
213+
// grace period to cleanup resources
214+
time.Sleep(5 * time.Second)
215+
logger.Info("Cleanup completed, exiting...")
216+
return 0
217+
}

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ require (
2727
k8s.io/component-helpers v0.33.4
2828
k8s.io/klog/v2 v2.130.1
2929
k8s.io/utils v0.0.0-20250604170112-4c0f3b243397
30-
sigs.k8s.io/network-policy-api v0.1.6-0.20250401132235-45061d10895e
30+
sigs.k8s.io/network-policy-api v0.1.8-0.20250826165010-d5cee02b3c1c
3131
)
3232

3333
require (

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -304,8 +304,8 @@ k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 h1:hwvWFiBzdWw1FhfY1FooPn3kzWuJ8
304304
k8s.io/utils v0.0.0-20250604170112-4c0f3b243397/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
305305
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE=
306306
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg=
307-
sigs.k8s.io/network-policy-api v0.1.6-0.20250401132235-45061d10895e h1:b5Vm5aa0I37gToQmFhQ+gQMZVsPsxSiJzxZWtSCs99w=
308-
sigs.k8s.io/network-policy-api v0.1.6-0.20250401132235-45061d10895e/go.mod h1:8J+z3UB9HgeqbmYprl6OKIobEDv27A3KRHPcteJ61rw=
307+
sigs.k8s.io/network-policy-api v0.1.8-0.20250826165010-d5cee02b3c1c h1:ySTDTqw3flKypZ4OnU2Q1lY/MzCBbONPVL6Rmx4BRAQ=
308+
sigs.k8s.io/network-policy-api v0.1.8-0.20250826165010-d5cee02b3c1c/go.mod h1:QIWX6Th2h0SmCwOwa1+9Urs0W+WDJGL5rujAPUemdkk=
309309
sigs.k8s.io/randfill v0.0.0-20250304075658-069ef1bbf016/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
310310
sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU=
311311
sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=

0 commit comments

Comments
 (0)