feat(template-chart): the reference NetworkPolicy, on by default
The reference implementation for Gitea #5: one NetworkPolicy per workload, networkPolicy.enabled defaulting to true, plus the values block, the schema entry and the NOTES.txt section that go with it. The shape is taken from the two charts that already had one - valkey and stalwart - rather than invented, because they carry the expensive lessons: policyTypes only where there is something to restrict, namespaces always spelled out because an empty "from" allows everything, kubernetes.io/metadata.name so no foreign namespace needs labelling, POD ports and never NodePorts, egress by port because the object cannot express a hostname, and the probe path left open by default because the kubelet probes from the node's own IP. Three things are written down rather than assumed. The ingress source is measured on the cluster and is NOT what the issue body assumes: ingress-nginx is gone, the only IngressClass is traefik, and the controller is the DaemonSet rke2-traefik in kube-system - which also serves the Gateway API here, so one source covers both the Ingress and the HTTPRoute path. Egress stays coarse: with Canal (Flannel plus Calico) there is no FQDN rule, and Calico's GlobalNetworkSet would bind every chart to Calico, the same argument that kept implementation-specific objects out of #114. And a policy is only a boundary where the CNI enforces one - unenforced, it is accepted and filters nothing. All reasoning sits in Go template comments, not in "#" comments: those are part of the rendered object and travel into the cluster. Writing this header also found the second-order trap, which is now in the header itself - prose inside a template comment must not spell out the comment's own closing delimiter, or the parser ends the comment early and the remaining prose is emitted as manifest content. Part of #5
This commit is contained in:
4 files changed
+388
No files matched your search
@@ -182,6 +182,57 @@ THIS CHART IS A SCAFFOLD — IT IS NOT MEANT TO RUN
|
||||
"{{ .Release.Name }}-{{ .Chart.Name }}-config-map" while the ConfigMap this chart creates is
|
||||
"{{ .Release.Name }}-{{ .Chart.Name }}-configmap": replace the whole block with your app's real
|
||||
variables rather than repairing the example.
|
||||
{{- if .Values.networkPolicy.enabled }}
|
||||
|
||||
NETWORKPOLICY IS ACTIVE — WHAT IT CAPS, AND WHAT IT DOES NOT
|
||||
{{ .Release.Name }}-{{ .Chart.Name }}-networkpolicy selects this workload's pods. Only the
|
||||
container ports this chart declares are reachable at all; anything else the
|
||||
process binds is blocked without anyone having to notice it exists. Outbound
|
||||
traffic is capped at DNS{{ with .Values.networkPolicy.egress }}{{ with .extraPorts }} plus TCP {{ join ", " . }}{{ end }}{{ end }}.
|
||||
|
||||
Three limits belong in the same breath, because none of them is visible in
|
||||
the object:
|
||||
|
||||
- EGRESS IS BY PORT, NEVER BY DESTINATION. A NetworkPolicy matches CIDRs and
|
||||
selectors and cannot express a hostname, so every rule above permits its
|
||||
port to ANY address. This is a limit of the object, not a shortcut — and
|
||||
with this cluster's CNI (Canal: Flannel plus Calico) there is no FQDN rule
|
||||
to reach for. An outbound port the chart does not know about is blocked:
|
||||
add it to networkPolicy.egress.extraPorts, and expect to find out through
|
||||
an application-level connection error rather than through this object.
|
||||
{{- if .Values.networkPolicy.probeSources }}
|
||||
- THE PROBE PATH IS RESTRICTED in this release, because
|
||||
networkPolicy.probeSources is set to
|
||||
{{ join ", " .Values.networkPolicy.probeSources }}
|
||||
Probes come from the IP of the WORKER NODE running the pod. If none of
|
||||
those CIDRs covers the node this pod lands on, the kubelet's probes are
|
||||
dropped and THE POD NEVER BECOMES READY — the rollout then times out and
|
||||
the symptom looks like a broken application. Check with
|
||||
|
||||
kubectl -n {{ .Release.Namespace }} describe pod -l app={{ .Release.Name }}-{{ .Chart.Name }}-deployment
|
||||
|
||||
and compare "Readiness probe failed" against `kubectl get node -o wide`.
|
||||
{{- else }}
|
||||
- THE PROBED PORT IS OPEN INSIDE THE CLUSTER. networkPolicy.probeSources is
|
||||
empty, so the rule for that port carries no source selector at all: any
|
||||
pod the CNI routes to can reach it. Not from the internet — the port has no
|
||||
NodePort — but this is NOT pod-level isolation. Narrowing it means listing
|
||||
the worker node IPs in networkPolicy.probeSources, because the kubelet
|
||||
probes from the node's own address and the chart cannot know it; a wrong
|
||||
guess there leaves the pod permanently un-Ready.
|
||||
{{- end }}
|
||||
- IT IS ONLY A BOUNDARY WHERE THE CNI ENFORCES POLICIES. Where it does not,
|
||||
this object is accepted and filters nothing, so everything reads as
|
||||
configured while nothing is filtered. Prove it rather than assume it:
|
||||
|
||||
kubectl -n {{ .Release.Namespace }} get networkpolicy {{ .Release.Name }}-{{ .Chart.Name }}-networkpolicy
|
||||
|
||||
shows the object exists; only a connection attempt from an unrelated
|
||||
namespace shows that it bites.
|
||||
|
||||
Switch it off with networkPolicy.enabled: false{{ if .Values.networkPolicy.allowedNamespaces }}; the namespaces currently
|
||||
allowed in addition to {{ .Release.Namespace }} are {{ join ", " .Values.networkPolicy.allowedNamespaces }}{{ end }}.
|
||||
{{- end }}
|
||||
{{- if .Values.ingress.enabled }}
|
||||
{{- with .Values.ingress.annotations }}
|
||||
|
||||
|
||||
Reference in new issue
Block a user