Gitea #143. Additive, default false, so the render is byte-identical to the previous release - proven by diffing both renders against origin/main rather than asserted. Switched on it adds 15008/TCP, ztunnel's HBONE tunnel, to the rule carrying the probe port, and - inside that rule's source-restricted branch - 169.254.7.127/32, the address the kubelet's probes arrive from once the pod is in the mesh. Ambient does not bypass NetworkPolicy enforcement, so without the port a pod whose namespace has joined the mesh is unreachable. The two halves are one value because the second is the one nobody thinks of: 15008 added by hand leaves a policy that passes review and drops every probe the first time probeSources is narrowed, and a pod that never becomes Ready reads as a broken application rather than as a policy. Minor, not major: additive value, unchanged default, unchanged render. Port half only: this chart offers no networkPolicy.probeSources - its probes put no packet on the network - so there is no redirected probe to allow and an ipBlock for one would match nothing while making the rule look like it did something. ci/run-networkpolicy-test.sh ties that exemption to the absence of probeSources, not to a chart name.
114 lines
5.9 KiB
YAML
114 lines
5.9 KiB
YAML
{{- /*
|
|
NetworkPolicy for valkey (Gitea #5).
|
|
|
|
THIS CHART AND stalwart ARE THE TWO THAT HAD A POLICY BEFORE #5, so the
|
|
convention was derived from them rather than imposed on them. What changed here
|
|
is the FORM and not a single rule: the reasoning moved out of "#" comments,
|
|
which are part of the rendered object and travel into the cluster, into template
|
|
comments, which render nothing. ci/run-networkpolicy-test.sh now fails on a
|
|
rendered "#", and this file was one of the two that failed it.
|
|
|
|
TWO THINGS THAT DELIBERATELY DID NOT CHANGE, because they are right and the
|
|
convention was written to accommodate them:
|
|
|
|
1. INGRESS ONLY. This instance opens no outbound connection of its own - no
|
|
replication, no cluster bus - so an egress rule here would constrain nothing
|
|
while making the object look stricter than it is. policyTypes names only
|
|
what there is something to restrict. homeassistant and satisfactory invoke
|
|
the same rule in the other direction, for outbound traffic nobody can
|
|
enumerate.
|
|
|
|
2. 6379 IS RESTRICTED BY SOURCE, with no probeSources value anywhere in this
|
|
chart - and that combination is only safe because of a detail worth knowing:
|
|
ALL THREE PROBES HERE ARE EXEC PROBES. An exec probe runs inside the
|
|
container through the kubelet's runtime and puts no packet on the network, so
|
|
there is no kubelet traffic to let through and nothing to accommodate. A
|
|
chart with an httpGet or tcpSocket probe on this port could NOT restrict it
|
|
this way - it would need the worker node's IP, which no chart can know, and
|
|
the pod would never become Ready without it. minecraft-server is tight for
|
|
the same reason; every web app in the sweep is not.
|
|
|
|
So this policy is what the rest of the rollout aims at and mostly cannot reach:
|
|
a port that is genuinely closed to everything but the namespaces named below.
|
|
*/ -}}
|
|
{{- if .Values.networkPolicy.enabled }}
|
|
{{- /* networkPolicy.ingress - the policy's INBOUND side, and not the same
|
|
thing as the top-level .Values.ingress (the Ingress object) - both match
|
|
a search for "ingress". */}}
|
|
{{- $npIngress := .Values.networkPolicy.ingress | default dict }}
|
|
{{- $ambientMesh := $npIngress.ambientMesh }}
|
|
apiVersion: networking.k8s.io/v1
|
|
kind: NetworkPolicy
|
|
metadata:
|
|
name: {{ .Release.Name }}-{{ .Chart.Name }}-networkpolicy
|
|
labels:
|
|
app: {{ .Release.Name }}-{{ .Chart.Name }}-networkpolicy
|
|
spec:
|
|
podSelector:
|
|
matchLabels:
|
|
app: {{ .Release.Name }}-{{ .Chart.Name }}-sfs
|
|
policyTypes:
|
|
- Ingress
|
|
ingress:
|
|
{{- /*
|
|
One rule with a list of sources. Note the shape: an empty "from" would allow
|
|
EVERYTHING, so the namespaces are always spelled out - the release's own
|
|
namespace first, then whatever networkPolicy.allowedNamespaces adds. An
|
|
empty "from: []" is worse still, because it allows everything while reading
|
|
as a restriction; ci/run-networkpolicy-test.sh rejects that form outright.
|
|
*/}}
|
|
- from:
|
|
- namespaceSelector:
|
|
matchLabels:
|
|
{{- /*
|
|
Set by Kubernetes itself on every namespace (>= 1.21), so this
|
|
needs no labelling work on the target namespaces.
|
|
*/}}
|
|
kubernetes.io/metadata.name: {{ .Release.Namespace }}
|
|
{{- range .Values.networkPolicy.allowedNamespaces }}
|
|
- namespaceSelector:
|
|
matchLabels:
|
|
kubernetes.io/metadata.name: {{ . | quote }}
|
|
{{- end }}
|
|
ports:
|
|
- protocol: TCP
|
|
port: 6379
|
|
{{- if $ambientMesh }}
|
|
{{- /* networkPolicy.ingress.ambientMesh (Gitea #143). 15008/TCP is ztunnel's
|
|
HBONE tunnel, the port every inbound connection arrives on once the
|
|
namespace carries istio.io/dataplane-mode - ambient "does not and will
|
|
never bypass Kubernetes NetworkPolicy enforcement", so without it a pod
|
|
in the mesh is unreachable.
|
|
|
|
It is the one port here that is NOT a containerPort of the selected pod
|
|
spec: ztunnel terminates it, not the application. ci/run-networkpolicy-
|
|
test.sh holds a NAMED exception for exactly this number, gated on exactly
|
|
this value, and proves on a second render that it stays the only such
|
|
port and that it is absent while the value is false.
|
|
|
|
THE PORT HALF ONLY, and that is not an omission. Elsewhere this switch
|
|
also adds 169.254.7.127/32 as a probe source, because inside the mesh the
|
|
kubelet's probes are redirected away from the worker node's address.
|
|
This chart offers no networkPolicy.probeSources at all, so the rule
|
|
carrying the probe port is never restricted by source - and an
|
|
unrestricted rule needs no probe address. Measured in the render: three
|
|
exec probes, which run inside the container through the kubelet's
|
|
runtime and put no packet on the network at all.
|
|
WHICH RULE IT JOINS:
|
|
the only rule this policy has, the one carrying 6379. That rule is
|
|
ALWAYS restricted to the release's own namespace plus allowedNamespaces,
|
|
so 15008 is restricted with it - and whether ztunnel is reached by those
|
|
peers is the open question of #143. ztunnel runs with its own pod IPs in
|
|
istio-system (measured 2026-10-19: no hostNetwork on the DaemonSet,
|
|
Istio 1.30.6), so if a peer of its own proves necessary it is
|
|
expressible as a namespaceSelector plus podSelector and not as an
|
|
unknowable node CIDR. It cannot be settled before a namespace joins the
|
|
mesh, and none has.
|
|
NOT MEASURED: that 15008 alone suffices comes from Istio's
|
|
documentation. Measured on this cluster is only which listeners ztunnel
|
|
opens. Provable at the first namespace to join the mesh; none has. */}}
|
|
- protocol: TCP
|
|
port: 15008
|
|
{{- end }}
|
|
{{- end }}
|