Skip to content

Commit

Permalink
Add networkpolices to protect metrics endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
camilamacedo86 committed May 17, 2024
1 parent a6600a1 commit ea8629e
Show file tree
Hide file tree
Showing 50 changed files with 906 additions and 3 deletions.
7 changes: 4 additions & 3 deletions .github/workflows/test-sample-go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,10 @@ jobs:
KUSTOMIZATION_FILE_PATH="testdata/project-v4/config/default/kustomization.yaml"
sed -i '25s/^#//' $KUSTOMIZATION_FILE_PATH
sed -i '27s/^#//' $KUSTOMIZATION_FILE_PATH
sed -i '42s/^#//' $KUSTOMIZATION_FILE_PATH
sed -i '46,142s/^#//' $KUSTOMIZATION_FILE_PATH
sed -i '38s/^#//' $KUSTOMIZATION_FILE_PATH
sed -i '48s/^#//' $KUSTOMIZATION_FILE_PATH
sed -i '52,148s/^#//' $KUSTOMIZATION_FILE_PATH
- name: Test
run: |
cd testdata/project-v4
Expand Down
21 changes: 21 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,27 @@ Following the targets that can be used to test your changes locally.

**NOTE** To use the `make lint` is required to install `golangci-lint` locally. More info: https://github.com/golangci/golangci-lint#install

### Running e2e tests locally

See that you can run `test-e2e-local` to setup Kind and run e2e tests locally.
Another option is by manually starting up Kind and configuring it and then,
you can for example via your IDEA debug the e2e tests.

To manually setup run:

```shell
# To generate an Kubebuilder local binary with your changes
make install
# To create the cluster and configure a CNI which supports NetworkPolicy
kind create cluster --config ./test/e2e/kind-config.yaml
kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml
```

Now, you can for example, run in debug mode the `test/e2e/v4/e2e_suite_test.go`:

![example](https://github.com/kubernetes-sigs/kubebuilder/assets/7708031/277d26d5-c94d-41f0-8f02-1381458ef750)


### Test Plugin

If your intended PR creates a new plugin, make sure the PR also provides test cases. Testing should include:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ resources:
- ../certmanager
# [PROMETHEUS] To enable prometheus monitor, uncomment all sections with 'PROMETHEUS'.
- ../prometheus
# [NETWORK POLICY] Protect the /metrics endpoint with NetworkPolicy. If you want your controller-manager to
# expose the /metrics, it is recommended uncomment the following line. Therefore, only Pod(s) running a namespace
# with the label 'monitoring: enabled' will be able to gather the metrics.
# Be aware that NetworkPolicy alone does not ensure fully protection. Please, ensure that you check the Metrics
# documentation: https://kubebuilder.io/reference/metrics
- ../policy

patches:
# [METRICS] The following patch will enable the metrics endpoint. Ensure that you also protect this endpoint.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Allow CertManager have communication across the cluster
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-cert-manager
namespace: cert-manager
spec:
podSelector: {} # This applies to all pods within the cert-manager namespace
policyTypes:
- Ingress
- Egress
ingress:
# Allow ingress from all pods in the same namespace
- from:
- podSelector: {} # This effectively allows all pods within the namespace
egress:
# Allow egress to all destinations
- {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Allow webhooks usage in the manager namespace
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
labels:
app.kubernetes.io/name: project
app.kubernetes.io/managed-by: kustomize
name: allow-webhooks
namespace: system
spec:
podSelector:
matchLabels:
control-plane: controller-manager
policyTypes:
- Ingress
ingress:
- from:
ports:
- protocol: TCP
port: 443
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
resources:
- protect-metrics.yaml
- allow-webhook.yaml
- allow-cert-manager.yaml

Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# NetworkPolicy to protect metrics endpoint
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
labels:
app.kubernetes.io/name: project
app.kubernetes.io/managed-by: kustomize
name: protect-metrics
namespace: system
spec:
podSelector:
matchLabels:
control-plane: controller-manager
policyTypes:
- Egress
- Ingress
egress:
- {}
ingress:
- from:
- namespaceSelector:
matchLabels:
monitoring: enabled # Only from namespaces with this label
ports:
- protocol: TCP
port: 8080 # TCP port for metrics
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ resources:
#- ../certmanager
# [PROMETHEUS] To enable prometheus monitor, uncomment all sections with 'PROMETHEUS'.
#- ../prometheus
# [NETWORK POLICY] Protect the /metrics endpoint with NetworkPolicy. If you want your controller-manager to
# expose the /metrics, it is recommended uncomment the following line. Therefore, only Pod(s) running a namespace
# with the label 'monitoring: enabled' will be able to gather the metrics.
# Be aware that NetworkPolicy alone does not ensure fully protection. Please, ensure that you check the Metrics
# documentation: https://kubebuilder.io/reference/metrics
#- ../policy

patches:
# [METRICS] The following patch will enable the metrics endpoint. Ensure that you also protect this endpoint.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Allow CertManager have communication across the cluster
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-cert-manager
namespace: cert-manager
spec:
podSelector: {} # This applies to all pods within the cert-manager namespace
policyTypes:
- Ingress
- Egress
ingress:
# Allow ingress from all pods in the same namespace
- from:
- podSelector: {} # This effectively allows all pods within the namespace
egress:
# Allow egress to all destinations
- {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
resources:
- protect-metrics.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# NetworkPolicy to protect metrics endpoint
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
labels:
app.kubernetes.io/name: project
app.kubernetes.io/managed-by: kustomize
name: protect-metrics
namespace: system
spec:
podSelector:
matchLabels:
control-plane: controller-manager
policyTypes:
- Egress
- Ingress
egress:
- {}
ingress:
- from:
- namespaceSelector:
matchLabels:
monitoring: enabled # Only from namespaces with this label
ports:
- protocol: TCP
port: 8080 # TCP port for metrics
11 changes: 11 additions & 0 deletions docs/book/src/reference/metrics.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,17 @@ NetworkPolicy acts as a basic firewall for pods within a Kubernetes cluster, con
flow at the IP address or port level. However, it doesn't handle authentication (authn), authorization (authz),
or encryption directly like [kube-rbac-proxy](https://github.com/brancz/kube-rbac-proxy) solution.

Uncomment the following line in the `config/default/kustomization.yaml`:

```
# [NETWORK POLICY FOR METRICS] Protect the /metrics endpoint with NetworkPolicy. If you want your controller-manager to
# expose the /metrics, it is recommended uncomment the following line. Therefore, only Pod(s) with the label
# 'allow-metrics' which are running in a namespace which also has the same label will be able to gather the metrics.
# Be aware that NetworkPolicy alone does not ensure fully protection. Please, ensure that you check the Metrics
# documentation: https://kubebuilder.io/reference/metrics
#- ../policy
```

### By exposing the metrics endpoint using HTTPS and CertManager

Integrating `cert-manager` with your metrics service can secure the endpoint via TLS encryption.
Expand Down
5 changes: 5 additions & 0 deletions hack/docs/internal/cronjob-tutorial/generate_cronjob.go
Original file line number Diff line number Diff line change
Expand Up @@ -559,6 +559,11 @@ func updateKustomization(sp *Sample) {
`#- ../prometheus`, `#`)
CheckError("fixing default/kustomization", err)

err = pluginutil.UncommentCode(
filepath.Join(sp.ctx.Dir, "config/default/kustomization.yaml"),
`#- ../policy`, `#`)
CheckError("uncomment policy in the default/kustomization", err)

err = pluginutil.UncommentCode(
filepath.Join(sp.ctx.Dir, "config/default/kustomization.yaml"),
DefaultKustomization, `#`)
Expand Down
4 changes: 4 additions & 0 deletions pkg/plugins/common/kustomize/v2/scaffolds/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"sigs.k8s.io/kubebuilder/v3/pkg/plugins"
"sigs.k8s.io/kubebuilder/v3/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/kdefault"
"sigs.k8s.io/kubebuilder/v3/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/manager"
"sigs.k8s.io/kubebuilder/v3/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/policy"
"sigs.k8s.io/kubebuilder/v3/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/prometheus"
"sigs.k8s.io/kubebuilder/v3/pkg/plugins/common/kustomize/v2/scaffolds/internal/templates/config/rbac"
)
Expand Down Expand Up @@ -76,6 +77,9 @@ func (s *initScaffolder) Scaffold() error {
&kdefault.ManagerMetricsPatch{},
&manager.Config{Image: imageName},
&kdefault.Kustomization{},
&policy.Kustomization{},
&policy.ProtectMetricsNetworkPolicy{},
&policy.AllowCertManagerNetworkPolicy{},
&prometheus.Kustomization{},
&prometheus.Monitor{},
}
Expand Down
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,12 @@ resources:
#- ../certmanager
# [PROMETHEUS] To enable prometheus monitor, uncomment all sections with 'PROMETHEUS'.
#- ../prometheus
# [NETWORK POLICY] Protect the /metrics endpoint with NetworkPolicy. If you want your controller-manager to
# expose the /metrics, it is recommended uncomment the following line. Therefore, only Pod(s) running a namespace
# with the label 'monitoring: enabled' will be able to gather the metrics.
# Be aware that NetworkPolicy alone does not ensure fully protection. Please, ensure that you check the Metrics
# documentation: https://kubebuilder.io/reference/metrics
#- ../policy
patches:
# [METRICS] The following patch will enable the metrics endpoint. Ensure that you also protect this endpoint.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
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 policy

import (
"path/filepath"

"sigs.k8s.io/kubebuilder/v3/pkg/machinery"
)

var _ machinery.Template = &AllowCertManagerNetworkPolicy{}

// AllowWebhookNetworkPolicy scaffolds a file that defines the NetworkPolicy to allow access to webhook service
type AllowCertManagerNetworkPolicy struct {
machinery.TemplateMixin
machinery.ProjectNameMixin
}

// SetTemplateDefaults implements file.Template
func (f *AllowCertManagerNetworkPolicy) SetTemplateDefaults() error {
if f.Path == "" {
f.Path = filepath.Join("config", "policy", "allow-cert-manager.yaml")
}

f.TemplateBody = certmanagerNetworkPolicyTemplate

return nil
}

const certmanagerNetworkPolicyTemplate = `# Allow CertManager have communication across the cluster
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-cert-manager
namespace: cert-manager
spec:
podSelector: {} # This applies to all pods within the cert-manager namespace
policyTypes:
- Ingress
- Egress
ingress:
# Allow ingress from all pods in the same namespace
- from:
- podSelector: {} # This effectively allows all pods within the namespace
egress:
# Allow egress to all destinations
- {}
`
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
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 policy

import (
"path/filepath"

"sigs.k8s.io/kubebuilder/v3/pkg/machinery"
)

var _ machinery.Template = &AllowWebhookNetworkPolicy{}

// AllowWebhookNetworkPolicy scaffolds a file that defines the NetworkPolicy to allow access to webhook service
type AllowWebhookNetworkPolicy struct {
machinery.TemplateMixin
machinery.ProjectNameMixin
}

// SetTemplateDefaults implements file.Template
func (f *AllowWebhookNetworkPolicy) SetTemplateDefaults() error {
if f.Path == "" {
f.Path = filepath.Join("config", "policy", "allow-webhook.yaml")
}

f.TemplateBody = webhookNetworkPolicyTemplate

return nil
}

const webhookNetworkPolicyTemplate = `# Allow webhooks usage in the manager namespace
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
labels:
app.kubernetes.io/name: {{ .ProjectName }}
app.kubernetes.io/managed-by: kustomize
name: allow-webhooks
namespace: system
spec:
podSelector:
matchLabels:
control-plane: controller-manager
policyTypes:
- Ingress
ingress:
- from:
ports:
- protocol: TCP
port: 443
`
Loading

0 comments on commit ea8629e

Please sign in to comment.