# Header echo workload for the two-hop proxy contract measurement. # # browser -> host nginx (TLS termination) -> Traefik -> this pod # # The image is built from backend/ and imported straight into each node's # containerd, so imagePullPolicy must stay Never. See scripts/build-and-import.sh. apiVersion: v1 kind: Namespace metadata: name: header-lab --- apiVersion: apps/v1 kind: Deployment metadata: name: echo namespace: header-lab spec: replicas: 2 selector: matchLabels: app: echo template: metadata: labels: app: echo spec: # One replica per node so the sticky-session switch on the host nginx # upstream has something observable to route between. topologySpreadConstraints: - maxSkew: 1 topologyKey: kubernetes.io/hostname whenUnsatisfiable: ScheduleAnyway labelSelector: matchLabels: app: echo containers: - name: echo image: keycloak-pattern-api:lab imagePullPolicy: Never ports: - containerPort: 8081 name: http env: - name: SERVER_PORT value: "8081" # "none" makes the app report the raw connection, so scheme/secure/ # requestUrl show what arrives without any forwarded-header handling. # Set to "native" and redeploy to see the same request interpreted # with X-Forwarded-* honoured. Keycloak's KC_PROXY_HEADERS is the # same opt-in, which is why measuring both sides matters here. - name: SERVER_FORWARD_HEADERS_STRATEGY value: "native" # The JVM sizes its heap from the container limit, not the host. - name: JAVA_TOOL_OPTIONS value: "-XX:MaxRAMPercentage=70" # /api/echo is permitAll, so the JWT decoder is never exercised. # These stay pointed at the future Keycloak service name. - name: SPRING_SECURITY_OAUTH2_RESOURCESERVER_JWT_ISSUER_URI value: "https://auth.hyeonworks.com/realms/keycloak-patterns" - name: SPRING_SECURITY_OAUTH2_RESOURCESERVER_JWT_JWK_SET_URI value: "https://auth.hyeonworks.com/realms/keycloak-patterns/protocol/openid-connect/certs" readinessProbe: httpGet: path: /actuator/health/readiness port: http initialDelaySeconds: 15 periodSeconds: 5 livenessProbe: httpGet: path: /actuator/health/liveness port: http initialDelaySeconds: 45 periodSeconds: 15 resources: requests: memory: 320Mi cpu: 100m limits: memory: 512Mi --- apiVersion: v1 kind: Service metadata: name: echo namespace: header-lab spec: selector: app: echo ports: - port: 8081 targetPort: http name: http --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: echo namespace: header-lab spec: # k3s ships Traefik as the default ingress controller. Keeping it is what # makes this lab a faithful two-hop replica. ingressClassName: traefik rules: - host: app1.hyeonworks.com http: paths: - path: /api pathType: Prefix backend: service: name: echo port: number: 8081