Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RFC] Network policies #3611

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions pkg/apis/config/v1alpha4/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,8 @@ type Networking struct {
// If DisableDefaultCNI is true, kind will not install the default CNI setup.
// Instead the user should install their own CNI after creating the cluster.
DisableDefaultCNI bool `yaml:"disableDefaultCNI,omitempty" json:"disableDefaultCNI,omitempty"`
// If NetworkPolicies is true, kind will install the default Network Policy setup.
NetworkPolicies bool `yaml:"networkPolicies,omitempty" json:"networkPolicies,omitempty"`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

given this is a bool i would put a verb in front of it, same as DisasbleDefaultCNI above.
e.g. InstallNetworkPolicies

// KubeProxyMode defines if kube-proxy should operate in iptables, ipvs or nftables mode
// Defaults to 'iptables' mode
KubeProxyMode ProxyMode `yaml:"kubeProxyMode,omitempty" json:"kubeProxyMode,omitempty"`
Expand Down
8 changes: 8 additions & 0 deletions pkg/build/nodeimage/buildcontext.go
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,14 @@ func (c *buildContext) prePullImagesAndWriteManifests(bits kube.Bits, parsedVers
// all builds should install the default storage driver images currently
requiredImages = append(requiredImages, defaultStorageImages...)

// write the default Network Policy manifest
if err := createFile(cmder, defaultNetworkPolicyManifestLocation, defaultNetworkPolicyManifest); err != nil {
c.logger.Errorf("Image build Failed! Failed write default Network Policy Manifest: %v", err)
return nil, err
}
// all builds should install the default network policies images currently
requiredImages = append(requiredImages, defaultNetworkPolicyImage...)

// setup image importer
importer := newContainerdImporter(cmder)
if err := importer.Prepare(); err != nil {
Expand Down
7 changes: 4 additions & 3 deletions pkg/build/nodeimage/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ package nodeimage
// these are well known paths within the node image
const (
// TODO: refactor kubernetesVersionLocation to a common internal package
kubernetesVersionLocation = "/kind/version"
defaultCNIManifestLocation = "/kind/manifests/default-cni.yaml"
defaultStorageManifestLocation = "/kind/manifests/default-storage.yaml"
kubernetesVersionLocation = "/kind/version"
defaultCNIManifestLocation = "/kind/manifests/default-cni.yaml"
defaultStorageManifestLocation = "/kind/manifests/default-storage.yaml"
defaultNetworkPolicyManifestLocation = "/kind/manifests/default-network-policy.yaml"
)
121 changes: 121 additions & 0 deletions pkg/build/nodeimage/const_network_policy.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
/*
Copyright 2024 The Kubernetes Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package nodeimage

/*
The default network policy manifest and images are https://github.com/kubernetes-sigs/kube-network-policies
*/

const networkPolicyImage = "registry.k8s.io/networking/kube-network-policies:v0.2.0"

var defaultNetworkPolicyImage = []string{networkPolicyImage}

const defaultNetworkPolicyManifest = `
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: kube-network-policies
rules:
- apiGroups:
- ""
resources:
- pods
- namespaces
verbs:
- list
- watch
- apiGroups:
- "networking.k8s.io"
resources:
- networkpolicies
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: ` + networkPolicyImage + `
args:
- /bin/netpol
- -v
- "2"
volumeMounts:
- name: lib-modules
mountPath: /lib/modules
readOnly: true
resources:
requests:
cpu: "100m"
memory: "50Mi"
securityContext:
privileged: true
capabilities:
add: ["NET_ADMIN"]
Comment on lines +113 to +115
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

doesn't privileged=true make the NET_ADMIN cap redundant, i think it should be privileged=false and only the required caps should be added.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, I think I started to get granularity and gave up :)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think, it's fine to leave it privileged and remove the NET_ADMIN cap. maybe leave a TODO comment if someone wishes to experiment with caps and limit the access scope.

volumes:
- name: lib-modules
hostPath:
path: /lib/modules
---
`
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*
Copyright 2019 The Kubernetes Authors.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Copyright 2019 The Kubernetes Authors.
Copyright 2024 The Kubernetes Authors.


Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

// Package installnetworkpolicies implements the install Network Policy action
package installnetworkpolicies

import (
"bytes"
"strings"

"sigs.k8s.io/kind/pkg/errors"

"sigs.k8s.io/kind/pkg/cluster/internal/create/actions"
"sigs.k8s.io/kind/pkg/cluster/nodeutils"
)

type action struct{}

// NewAction returns a new action for installing storage
func NewAction() actions.Action {
return &action{}
}

// Execute runs the action
func (a *action) Execute(ctx *actions.ActionContext) error {
ctx.Status.Start("Installing Network Policies πŸ”’")
defer ctx.Status.End(false)

allNodes, err := ctx.Nodes()
if err != nil {
return err
}

// get the target node for this task
controlPlanes, err := nodeutils.ControlPlaneNodes(allNodes)
if err != nil {
return err
}
node := controlPlanes[0] // kind expects at least one always
Comment on lines +47 to +52
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// get the target node for this task
controlPlanes, err := nodeutils.ControlPlaneNodes(allNodes)
if err != nil {
return err
}
node := controlPlanes[0] // kind expects at least one always
// get the target node for this task
node, err := nodeutils.BootstrapControlPlaneNode(allNodes)
if err != nil {
return err
}


// read the manifest from the node
var raw bytes.Buffer
if err := node.Command("cat", "/kind/manifests/default-network-policy.yaml").SetStdout(&raw).Run(); err != nil {
return errors.Wrap(err, "failed to read Network Policies manifest")
}
manifest := raw.String()

// apply the manifest
in := strings.NewReader(manifest)
cmd := node.Command(
"kubectl",
"--kubeconfig=/etc/kubernetes/admin.conf", "apply", "-f", "-",
)
cmd.SetStdin(in)
if err := cmd.Run(); err != nil {
return err
}

// mark success
ctx.Status.End(true)
return nil
}
6 changes: 6 additions & 0 deletions pkg/cluster/internal/create/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import (
"sigs.k8s.io/kind/pkg/cluster/internal/create/actions"
configaction "sigs.k8s.io/kind/pkg/cluster/internal/create/actions/config"
"sigs.k8s.io/kind/pkg/cluster/internal/create/actions/installcni"
"sigs.k8s.io/kind/pkg/cluster/internal/create/actions/installnetworkpolicies"
"sigs.k8s.io/kind/pkg/cluster/internal/create/actions/installstorage"
"sigs.k8s.io/kind/pkg/cluster/internal/create/actions/kubeadminit"
"sigs.k8s.io/kind/pkg/cluster/internal/create/actions/kubeadmjoin"
Expand Down Expand Up @@ -121,6 +122,11 @@ func Cluster(logger log.Logger, p providers.Provider, opts *ClusterOptions) erro
installcni.NewAction(), // install CNI
)
}
if opts.Config.Networking.NetworkPolicies {
actionsToRun = append(actionsToRun,
installnetworkpolicies.NewAction(), // install Network Policies
)
}
// add remaining steps
actionsToRun = append(actionsToRun,
installstorage.NewAction(), // install StorageClass
Expand Down
1 change: 1 addition & 0 deletions pkg/internal/apis/config/convert_v1alpha4.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ func convertv1alpha4Networking(in *v1alpha4.Networking, out *Networking) {
out.KubeProxyMode = ProxyMode(in.KubeProxyMode)
out.ServiceSubnet = in.ServiceSubnet
out.DisableDefaultCNI = in.DisableDefaultCNI
out.NetworkPolicies = in.NetworkPolicies
out.DNSSearch = in.DNSSearch
}

Expand Down
2 changes: 2 additions & 0 deletions pkg/internal/apis/config/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,8 @@ type Networking struct {
// If DisableDefaultCNI is true, kind will not install the default CNI setup.
// Instead the user should install their own CNI after creating the cluster.
DisableDefaultCNI bool
// If NetworkPolicies is true, kind will install the default Network Policy setup.
NetworkPolicies bool
// KubeProxyMode defines if kube-proxy should operate in iptables, ipvs or nftables mode
KubeProxyMode ProxyMode
// DNSSearch defines the DNS search domain to use for nodes. If not set, this will be inherited from the host.
Expand Down
14 changes: 14 additions & 0 deletions site/content/docs/user/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,20 @@ networking:
disableDefaultCNI: true
{{< /codeFromInline >}}

#### Network Policies

KIND ships with an implementation of Kubernetes Network Policies
[kube-network-policies](https://github.com/kubernetes-sigs/kube-network-policies) that
is disabled by default.

You may enable this option by setting the corresponding configuration.
{{< codeFromInline lang="yaml" >}}
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
networking:
networkPolicies: true
{{< /codeFromInline >}}


#### kube-proxy mode

Expand Down
Loading