# Experiment A-1 — cut the JGroups transport (TCP 7800) while leaving discovery alone. # # The point is to separate two things that are easy to conflate: # # discovery how the nodes FIND each other -> PostgreSQL JGROUPS_PING table # transport how they actually TALK -> TCP 7800 # # Blocking only the transport produces a state that cannot happen on a single # node: both members stay registered in the database, so each believes the other # exists, yet no message gets through. # # kubectl apply -f deploy/lab/k8s/a1-block-jgroups-transport.yaml # kubectl -n keycloak-lab delete networkpolicy a1-block-jgroups-transport # # NetworkPolicy is an ALLOWLIST, not a firewall with deny rules. There is no way # to write "deny 7800". The moment a pod is selected by a policy carrying # policyTypes: [Ingress], every inbound port is denied unless a rule permits it. # So 7800 is blocked by *omission*: 8080 and 9000 are listed, 7800 is not. # # That makes the two allow rules load-bearing — get them wrong and the experiment # measures a dead Keycloak instead of a partitioned cluster: # # 8080 the HTTP endpoint. Traefik, the other pod's REST calls, and the probe # traffic all arrive here. # 9000 the management port: /health/started, /health/ready, /health/live and # /metrics. Losing it means the kubelet fails the readiness probe and # kills the pod — the cluster would break for the wrong reason. # # Both rules deliberately omit `from:`, which allows those ports from any source. # Narrowing the source is not the subject here; the 2-hop experiment already # established how to do that by label when it matters. apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: a1-block-jgroups-transport namespace: keycloak-lab spec: podSelector: matchLabels: app: keycloak policyTypes: [Ingress] ingress: - ports: - { port: 8080, protocol: TCP } # HTTP — must stay open - { port: 9000, protocol: TCP } # health + metrics — must stay open # 7800 is absent on purpose. That is the whole experiment.