Skip to content

Commit

Permalink
Merge pull request #9 from aojea/admin
Browse files Browse the repository at this point in the history
add admin and baseline network policy
  • Loading branch information
aojea committed Apr 25, 2024
2 parents c7fc563 + 729b384 commit c677550
Show file tree
Hide file tree
Showing 12 changed files with 1,682 additions and 129 deletions.
153 changes: 153 additions & 0 deletions .github/workflows/npa.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@

name: e2e_npa

on:
push:
branches:
- 'main'
tags:
- 'v*'
pull_request:
branches: [ main ]
workflow_dispatch:

env:
GO_VERSION: "1.22.0"
K8S_VERSION: "v1.29.2"
KIND_VERSION: "v0.22.0"
IMAGE_NAME: registry.k8s.io/networking/kube-network-policies
KIND_CLUSTER_NAME: kind

permissions: write-all

jobs:
build:
name: build
runs-on: ubuntu-latest
steps:
- name: Set up Go
uses: actions/setup-go@v2
with:
go-version: ${{ env.GO_VERSION }}
id: go

- name: Check out code
uses: actions/checkout@v2

- name: Build
run: |
docker build -t registry.k8s.io/networking/kube-network-policies:test -f Dockerfile .
mkdir _output
docker save registry.k8s.io/networking/kube-network-policies:test > _output/kube-network-policies-image.tar
- uses: actions/upload-artifact@v2
with:
name: test-image
path: _output/kube-network-policies-image.tar

e2e_npa:
name: e2e_npa
runs-on: ubuntu-22.04
timeout-minutes: 100
needs:
- build
strategy:
fail-fast: false
matrix:
# TODO add "dual", waiting on KEP https://github.com/kubernetes/enhancements/tree/master/keps/sig-network/3705-cloud-node-ips
ipFamily: ["ipv4", "ipv6"]
env:
JOB_NAME: "kube-network-policies-${{ matrix.ipFamily }}"
IP_FAMILY: ${{ matrix.ipFamily }}
steps:
- name: Check out code
uses: actions/checkout@v2

- name: Enable ipv4 and ipv6 forwarding
run: |
sudo sysctl -w net.ipv6.conf.all.forwarding=1
sudo sysctl -w net.ipv4.ip_forward=1
- name: Set up environment (download dependencies)
run: |
TMP_DIR=$(mktemp -d)
# kubectl
curl -L https://dl.k8s.io/${{ env.K8S_VERSION }}/bin/linux/amd64/kubectl -o ${TMP_DIR}/kubectl
# kind
curl -Lo ${TMP_DIR}/kind https://kind.sigs.k8s.io/dl/${{ env.KIND_VERSION }}/kind-linux-amd64
# Install
sudo cp ${TMP_DIR}/kubectl /usr/local/bin/kubectl
sudo cp ${TMP_DIR}/kind /usr/local/bin/kind
sudo chmod +x /usr/local/bin/*
- name: Create multi node cluster
run: |
# output_dir
mkdir -p _artifacts
# create cluster
cat <<EOF | /usr/local/bin/kind create cluster \
--name ${{ env.KIND_CLUSTER_NAME}} \
--image kindest/node:${{ env.K8S_VERSION }} \
-v7 --wait 1m --retain --config=-
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
networking:
ipFamily: ${IP_FAMILY}
nodes:
- role: control-plane
- role: worker
- role: worker
EOF
# dump the kubeconfig for later
/usr/local/bin/kind get kubeconfig --name ${{ env.KIND_CLUSTER_NAME}} > _artifacts/kubeconfig.conf
- uses: actions/download-artifact@v2
with:
name: test-image

- name: Install kube-network-policies
run: |
/usr/local/bin/kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/network-policy-api/main/config/crd/experimental/policy.networking.k8s.io_adminnetworkpolicies.yaml
/usr/local/bin/kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/network-policy-api/main/config/crd/experimental/policy.networking.k8s.io_baselineadminnetworkpolicies.yaml
# preload kube-network-policies image
docker load --input kube-network-policies-image.tar
/usr/local/bin/kind load docker-image registry.k8s.io/networking/kube-network-policies:test --name ${{ env.KIND_CLUSTER_NAME}}
sed -i s#registry.k8s.io/networking/kube-network-policies.*#registry.k8s.io/networking/kube-network-policies:test# install-anp.yaml
/usr/local/bin/kubectl apply -f ./install-anp.yaml
- name: Get Cluster status
run: |
# wait network is ready
sleep 5
/usr/local/bin/kubectl get nodes -o wide
/usr/local/bin/kubectl get pods -A
/usr/local/bin/kubectl wait --timeout=1m --for=condition=ready pods --namespace=kube-system -l k8s-app=kube-dns
/usr/local/bin/kubectl wait --timeout=1m --for=condition=ready pods --namespace=kube-system -l app=kube-network-policies
- name: Run tests
run: |
# https://network-policy-api.sigs.k8s.io/npeps/npep-137-conformance-profiles/#integration
git clone https://github.com/kubernetes-sigs/network-policy-api.git
cd network-policy-api/
go mod download
go test -v ./conformance -run TestConformanceProfiles -args --conformance-profiles=AdminNetworkPolicy,BaselineAdminNetworkPolicy --organization=kubernetes --project=kube-network-policies --url=https://github.com/kubernetes-sigs/kube-network-policies --version=0.1.1 [email protected] --additional-info=https://github.com/kubernetes-sigs/kube-network-policies
cd -
- name: Upload Junit Reports
if: always()
uses: actions/upload-artifact@v2
with:
name: kind-junit-${{ env.JOB_NAME }}-${{ github.run_id }}
path: './_artifacts/*.xml'

- name: Export logs
if: always()
run: |
/usr/local/bin/kind export logs --name ${KIND_CLUSTER_NAME} --loglevel=debug ./_artifacts/logs
- name: Upload logs
if: always()
uses: actions/upload-artifact@v2
with:
name: kind-logs-${{ env.JOB_NAME }}-${{ github.run_id }}
path: ./_artifacts/logs
50 changes: 45 additions & 5 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,13 @@ import (
"github.com/prometheus/client_golang/prometheus/promhttp"
"sigs.k8s.io/knftables"
"sigs.k8s.io/kube-network-policies/pkg/networkpolicy"
npaclient "sigs.k8s.io/network-policy-api/pkg/client/clientset/versioned"
npainformers "sigs.k8s.io/network-policy-api/pkg/client/informers/externalversions"
"sigs.k8s.io/network-policy-api/pkg/client/informers/externalversions/apis/v1alpha1"

utilruntime "k8s.io/apimachinery/pkg/util/runtime"
"k8s.io/client-go/informers"
v1 "k8s.io/client-go/informers/core/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
"k8s.io/klog/v2"
Expand All @@ -24,13 +28,17 @@ import (
)

var (
failOpen bool
queueID int
metricsBindAddress string
failOpen bool
adminNetworkPolicy bool // AdminNetworkPolicy is alpha so keep it feature gated behind a flag
baselineAdminNetworkPolicy bool // BaselineAdminNetworkPolicy is alpha so keep it feature gated behind a flag
queueID int
metricsBindAddress string
)

func init() {
flag.BoolVar(&failOpen, "fail-open", false, "If set, don't drop packets if the controller is not running")
flag.BoolVar(&adminNetworkPolicy, "admin-network-policy", false, "If set, enable Admin Network Policy API")
flag.BoolVar(&baselineAdminNetworkPolicy, "baseline-admin-network-policy", false, "If set, enable Baseline Admin Network Policy API")
flag.IntVar(&queueID, "nfqueue-id", 100, "Number of the nfqueue used")
flag.StringVar(&metricsBindAddress, "metrics-bind-address", ":9080", "The IP address and port for the metrics server to serve on")

Expand All @@ -45,6 +53,8 @@ func main() {
klog.InitFlags(nil)
flag.Parse()

klog.Infof("flags: %v", flag.Args())

nft, err := knftables.New(knftables.InetFamily, "kube-network-policies")
if err != nil {
klog.Fatalf("Error initializing nftables: %v", err)
Expand All @@ -55,8 +65,10 @@ func main() {
}

cfg := networkpolicy.Config{
FailOpen: failOpen,
QueueID: queueID,
AdminNetworkPolicy: adminNetworkPolicy,
BaselineAdminNetworkPolicy: baselineAdminNetworkPolicy,
FailOpen: failOpen,
QueueID: queueID,
}
// creates the in-cluster config
config, err := rest.InClusterConfig()
Expand All @@ -83,6 +95,27 @@ func main() {

informersFactory := informers.NewSharedInformerFactory(clientset, 0)

var npaClient *npaclient.Clientset
var npaInformerFactory npainformers.SharedInformerFactory
var nodeInformer v1.NodeInformer
if adminNetworkPolicy || baselineAdminNetworkPolicy {
nodeInformer = informersFactory.Core().V1().Nodes()
npaClient, err = npaclient.NewForConfig(config)
if err != nil {
klog.Fatalf("Failed to create Network client: %v", err)
}
npaInformerFactory = npainformers.NewSharedInformerFactory(npaClient, 0)
}

var anpInformer v1alpha1.AdminNetworkPolicyInformer
if adminNetworkPolicy {
anpInformer = npaInformerFactory.Policy().V1alpha1().AdminNetworkPolicies()
}
var banpInformer v1alpha1.BaselineAdminNetworkPolicyInformer
if baselineAdminNetworkPolicy {
banpInformer = npaInformerFactory.Policy().V1alpha1().BaselineAdminNetworkPolicies()
}

http.Handle("/metrics", promhttp.Handler())
go func() {
err := http.ListenAndServe(metricsBindAddress, nil)
Expand All @@ -95,6 +128,10 @@ func main() {
informersFactory.Networking().V1().NetworkPolicies(),
informersFactory.Core().V1().Namespaces(),
informersFactory.Core().V1().Pods(),
nodeInformer,
npaClient,
anpInformer,
banpInformer,
cfg,
)
go func() {
Expand All @@ -103,6 +140,9 @@ func main() {
}()

informersFactory.Start(ctx.Done())
if adminNetworkPolicy || baselineAdminNetworkPolicy {
npaInformerFactory.Start(ctx.Done())
}

select {
case <-signalCh:
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ require (
k8s.io/klog/v2 v2.120.1
k8s.io/utils v0.0.0-20240310230437-4693a0247e57
sigs.k8s.io/knftables v0.0.16
sigs.k8s.io/network-policy-api v0.1.5
)

require (
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,8 @@ sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMm
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
sigs.k8s.io/knftables v0.0.16 h1:ZpTfNsjnidgoXdxxzcZLdSctqkpSO3QB3jo3zQ4PXqM=
sigs.k8s.io/knftables v0.0.16/go.mod h1:f/5ZLKYEUPUhVjUCg6l80ACdL7CIIyeL0DxfgojGRTk=
sigs.k8s.io/network-policy-api v0.1.5 h1:xyS7VAaM9EfyB428oFk7WjWaCK6B129i+ILUF4C8l6E=
sigs.k8s.io/network-policy-api v0.1.5/go.mod h1:D7Nkr43VLNd7iYryemnj8qf0N/WjBzTZDxYA+g4u1/Y=
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4=
sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08=
sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
Expand Down
100 changes: 100 additions & 0 deletions install-anp.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: kube-network-policies
rules:
- apiGroups:
- ""
resources:
- pods
- namespaces
- nodes
verbs:
- list
- watch
- apiGroups:
- "networking.k8s.io"
resources:
- networkpolicies
verbs:
- list
- watch
- apiGroups:
- "policy.networking.k8s.io"
resources:
- adminnetworkpolicies
- baselineadminnetworkpolicies
verbs:
- list
- watch
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: kube-network-policies
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: kube-network-policies
subjects:
- kind: ServiceAccount
name: kube-network-policies
namespace: kube-system
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: kube-network-policies
namespace: kube-system
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: kube-network-policies
namespace: kube-system
labels:
tier: node
app: kube-network-policies
k8s-app: kube-network-policies
spec:
selector:
matchLabels:
app: kube-network-policies
template:
metadata:
labels:
tier: node
app: kube-network-policies
k8s-app: kube-network-policies
spec:
hostNetwork: true
dnsPolicy: ClusterFirst
nodeSelector:
kubernetes.io/os: linux
tolerations:
- operator: Exists
effect: NoSchedule
serviceAccountName: kube-network-policies
containers:
- name: kube-network-policies
image: registry.k8s.io/networking/kube-network-policies:v0.1.0
command: ["/bin/netpol"]
args: ["-v=2", "-admin-network-policy=true", "-baseline-admin-network-policy=true"]
volumeMounts:
- name: lib-modules
mountPath: /lib/modules
readOnly: true
resources:
requests:
cpu: "100m"
memory: "50Mi"
securityContext:
privileged: true
capabilities:
add: ["NET_ADMIN"]
volumes:
- name: lib-modules
hostPath:
path: /lib/modules
---
Loading

0 comments on commit c677550

Please sign in to comment.