기반 가이드 7단계로 실험대를 철거하고 다시 세운 뒤 virtualization setup 9편과 keycloak-session-store 26편을 순서대로 밟았다. 24편은 끝까지, 11편은 되는 데까지 밟았고 밟은 범위를 편마다 적었다. 명령이 못 도는 것을 고쳤다. - kubectl 을 `kc-lab-1` 에서 치라고 적었는데 그 기계에 kubeconfig 가 없다. 라벨 639개와 각 편의 「어디서 치는가」를 `[lab host]` 로 옮겼다 - `-o custom-columns=…[0]…` 이 zsh 에서 글로브로 읽혀 안 돈다. 28곳에 따옴표 - busybox `sed` 가 끝 개행을 안 붙여 A-3 의 측정이 언제나 0 이었다 - `--token-file ~/node-token` 뒤에 그 파일을 지우면 k3s agent 가 재부팅을 못 견딘다. `/etc/rancher/node-token` 으로 옮기는 처방을 재서 넣었다 - 게스트에 없는 도구를 전제로 한 명령 넷 — `conntrack`·`dig`·`strings`·`nginx -v` - `echo` 와 JWT 헤더가 `"이름" : [ 값 ]` 으로 찍는데 문서는 공백 없이 옮겨 적어 그 실측으로 만든 grep·sed 가 한 줄도 못 잡는다 - B-0 이 `directAccessGrantsEnabled` 와 계정 완성을 빠뜨려 B-3 이 못 돈다 - D-4·D-4a 가 `test-server` 와 `certbot-renew.*` 를 가리키는데 실제로는 `kc-lab-edge` 의 `certbot.service` 다 - `virsh setmaxmem --config` 를 `dominfo` 로 판정하면 틀린다. `--inactive` 로 - `LIBVIRT_DEFAULT_URI` 를 rc 에만 넣으면 `ssh host '명령'` 에서 안 먹는다 결과가 조건부인 것을 갈랐다. - readiness 는 즉시 안 뒤집힌다. A-1·A-2 의 60초 창을 적었다 - 03 의 층 ②③ `301` 은 04 이후의 값이고 그 단계에서는 `404` 다 - A-0 의 로그 필터를 요청 직후에 치면 정반대 결론이 나온다 - A-5 의 한 방향 차단은 잠깐 `1` 이었다 `2` 로 돌아온다 증거는 두 프로젝트의 `evidence/raw/` 에 99벌을 README 와 함께 남겼다. 비밀은 길이만 적었고 화면에 찍힌 토큰은 가렸다. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
51 lines
2.2 KiB
Plaintext
51 lines
2.2 KiB
Plaintext
=== a1 주입 1-① 매니페스트를 먼저 읽는다 ===
|
|
# 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.
|
|
=== a1 주입 1-② 적용하고 시각 ===
|
|
networkpolicy.networking.k8s.io/a1-block-jgroups-transport created
|
|
13:53:51 적용
|