Series MapLesson 23 / 35
Focus mode active/Press Alt+Shift+R to toggle/Esc to exit
Deepen PracticeOrdered learning track

NGINX in Kubernetes

NGINX in Kubernetes Fundamentals

Memahami Service, ClusterIP, NodePort, LoadBalancer, Ingress, IngressClass, controller pod, admission webhook, ConfigMap, annotation, TLS secret, dan deployment model.

8 min read1593 words
PrevNext
Lesson 2335 lesson track20–29 Deepen Practice
#kubernetes#ingress#ingressclass#service+2 more

Part 023 — NGINX in Kubernetes Fundamentals

1. Tujuan Part Ini

Part ini membangun mental model dasar NGINX ketika berjalan di Kubernetes.

Fokusnya bukan sekadar membuat resource Ingress, tetapi memahami hubungan antar komponen berikut:

external client
  -> DNS
  -> cloud/on-prem load balancer
  -> NGINX Ingress Controller Service
  -> NGINX Ingress Controller Pod
  -> generated NGINX configuration
  -> Kubernetes Service
  -> EndpointSlice
  -> Pod
  -> Java/JAX-RS endpoint

Dalam production system, banyak engineer salah memahami Ingress sebagai “routing rule saja”. Padahal Ingress hanyalah deklarasi intent. Yang benar-benar menerima traffic adalah Ingress Controller.

Untuk konteks enterprise Java/JAX-RS system, perbedaan ini penting karena banyak failure muncul bukan di aplikasi Java, tetapi di layer:

Ingress resource
IngressClass
Ingress Controller
Service
EndpointSlice
Pod readiness
TLS Secret
ConfigMap
annotation
load balancer integration
network policy

Part ini menjadi fondasi sebelum masuk ke routing deep dive, annotation strategy, AWS/EKS, Azure/AKS, on-prem, DNS, GitOps, dan debugging playbook.


2. Core Mental Model: Ingress Is Declarative, Controller Is Operational

Kubernetes Ingress adalah resource API.

Ia mendeskripsikan aturan seperti:

host example.company.com
path /api/orders
backend service quote-order-api:8080
TLS secret example-company-tls

Tetapi Ingress tidak bekerja sendiri.

Agar traffic benar-benar dirutekan, cluster membutuhkan Ingress Controller.

Ingress Controller bertugas:

watch Ingress resources
watch Service resources
watch EndpointSlice/Endpoints
watch Secret resources
watch ConfigMap resources
translate desired state into NGINX runtime config
reload/update NGINX safely
serve traffic
emit logs/metrics/events

Jadi modelnya:

Ingress = desired routing state
Ingress Controller = runtime implementation
NGINX = data plane that handles actual request

Konsekuensi production-nya:

Salah PahamModel yang Benar
Ingress adalah load balancerIngress adalah rule; controller/load balancer yang menerima traffic
Membuat Ingress cukup untuk expose serviceHarus ada controller yang sesuai IngressClass
Semua controller membaca semua IngressController biasanya filter berdasarkan class
Annotation bersifat universalAnnotation tergantung implementation controller
Path matching selalu samaPath behavior bisa berbeda antar controller
TLS Secret cukup dibuatController harus bisa membaca Secret dan mengikatnya ke host
Service ready berarti traffic pasti jalanPod readiness, EndpointSlice, network, dan controller config juga menentukan

3. Kubernetes Networking Building Blocks

Sebelum membahas NGINX Ingress, pahami komponen Kubernetes dasar.

3.1 Pod

Pod adalah unit runtime tempat container berjalan.

Untuk Java/JAX-RS service:

Pod
  -> container JVM
  -> listens on port 8080/8443
  -> exposes /health, /ready, /api/*

Pod IP bersifat ephemeral. Jangan treat Pod IP sebagai alamat stabil untuk routing jangka panjang.

Failure mode:

pod recreated
pod IP changes
readiness false
container port mismatch
network policy blocks traffic
application listens on localhost only

Internal verification checklist:

kubectl get pod -n <namespace> -o wide
kubectl describe pod <pod> -n <namespace>
kubectl logs <pod> -n <namespace>
containerPort matches service targetPort
readinessProbe matches actual Java endpoint

3.2 Service

Kubernetes Service memberikan alamat stabil untuk satu set Pod.

Ingress biasanya tidak langsung mengarah ke Pod. Ingress mengarah ke Service.

apiVersion: v1
kind: Service
metadata:
  name: quote-order-api
spec:
  selector:
    app: quote-order-api
  ports:
    - name: http
      port: 80
      targetPort: 8080

Modelnya:

Ingress backend servicePort 80
  -> Service port 80
  -> targetPort 8080
  -> Pod container port 8080

Failure yang sering terjadi:

Ingress points to wrong Service name
Ingress uses wrong Service port
Service selector does not match Pods
Service targetPort wrong
Pods not ready, so EndpointSlice empty
application listens on different port

Debug command:

kubectl get svc quote-order-api -n quote
kubectl describe svc quote-order-api -n quote
kubectl get endpointslice -n quote -l kubernetes.io/service-name=quote-order-api
kubectl get endpoints quote-order-api -n quote

3.3 EndpointSlice

EndpointSlice adalah representasi backend endpoint aktual di balik Service.

Service bisa ada, tetapi kalau EndpointSlice kosong, NGINX tidak punya target sehat.

Service exists
but no ready endpoints
=> Ingress may return 503

Untuk Java/JAX-RS backend, penyebab umum EndpointSlice kosong:

label selector mismatch
readiness probe failing
container crash loop
port name mismatch
namespace mismatch
rollout not complete

Checklist:

kubectl get endpointslice -n <namespace>
kubectl describe endpointslice <name> -n <namespace>
kubectl get pod -n <namespace> --show-labels
kubectl describe deploy <deployment> -n <namespace>

4. Service Types: ClusterIP, NodePort, LoadBalancer

NGINX Ingress Controller sendiri biasanya diexpose melalui Service.

4.1 ClusterIP

ClusterIP hanya bisa diakses dari dalam cluster.

Cocok untuk backend Java/JAX-RS service.

spec:
  type: ClusterIP

Model:

NGINX Ingress Controller Pod
  -> ClusterIP Service
  -> Java/JAX-RS Pods

Untuk backend application service, ClusterIP biasanya default dan paling aman.


4.2 NodePort

NodePort membuka port pada setiap node.

Model:

external load balancer
  -> nodeIP:nodePort
  -> ingress controller Service
  -> ingress controller Pod

Digunakan pada beberapa on-prem atau cloud integration pattern.

Risiko:

node exposure lebih luas
firewall rule harus presisi
source IP preservation bisa tricky
port range operational overhead

4.3 LoadBalancer

LoadBalancer meminta cloud provider membuat external/internal load balancer.

Model umum di cloud:

DNS
  -> AWS NLB / Azure Load Balancer / cloud LB
  -> Service type LoadBalancer
  -> NGINX Ingress Controller Pods

Bukan semua load balancer sama:

Load BalancerLayerTypical Role
AWS NLBL4TCP/TLS pass-through to ingress
AWS ALBL7HTTP routing, sometimes instead of NGINX Ingress
Azure Load BalancerL4TCP forwarding
Azure Application GatewayL7HTTP/TLS edge, may replace or sit before ingress
On-prem F5/AVI/HAProxyL4/L7Enterprise edge/routing layer

Internal verification checklist:

Is ingress controller exposed using LoadBalancer, NodePort, or hostNetwork?
Is the cloud load balancer public or internal?
Is TLS terminated at cloud LB, NGINX, or both?
Is source IP preserved?
Is proxy protocol enabled?

5. What Kubernetes Ingress Actually Represents

Ingress defines HTTP/S routing rules.

Simplified example:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: quote-order-api
  namespace: quote
spec:
  ingressClassName: nginx
  tls:
    - hosts:
        - quote.example.company.com
      secretName: quote-example-company-tls
  rules:
    - host: quote.example.company.com
      http:
        paths:
          - path: /api/quotes
            pathType: Prefix
            backend:
              service:
                name: quote-order-api
                port:
                  number: 80

This means:

For HTTPS request with Host quote.example.company.com
and path beginning with /api/quotes
route to Service quote-order-api port 80
using TLS material from Secret quote-example-company-tls
handled by controller for IngressClass nginx

It does not mean:

Kubernetes itself becomes a reverse proxy
Ingress independently opens public endpoint
all controllers will automatically use this rule
path behavior is identical across controllers

6. IngressClass

IngressClass tells Kubernetes and controllers which controller should implement an Ingress.

Example:

apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
  name: nginx
spec:
  controller: k8s.io/ingress-nginx

An Ingress can reference it:

spec:
  ingressClassName: nginx

Why this matters:

one cluster can have multiple ingress controllers
public and internal ingress can be separate
NGINX and cloud-native ingress can coexist
migration between controllers becomes possible
wrong class can make ingress ignored

Common patterns:

PatternMeaning
nginx-publicPublic internet-facing NGINX ingress
nginx-internalInternal/private NGINX ingress
albAWS ALB controller handles Ingress
agicAzure Application Gateway Ingress Controller
nginx-plusF5 NGINX/NGINX Plus controller

Failure mode:

Ingress exists but no ADDRESS assigned
controller ignores resource
wrong load balancer receives traffic
internal route accidentally exposed publicly

Debug:

kubectl get ingressclass
kubectl describe ingressclass nginx
kubectl get ingress -A -o wide
kubectl describe ingress <name> -n <namespace>

Internal verification checklist:

What IngressClass names exist?
Which one is default?
Which class is public vs internal?
Are application teams allowed to choose class freely?
Is class enforced by policy?

7. NGINX Ingress Controller: Control Plane and Data Plane

NGINX Ingress Controller has two roles:

control plane: watches Kubernetes API and generates config
 data plane: NGINX process handles traffic

Mermaid model:

graph TD A[Kubernetes API Server] -->|watch Ingress| B[NGINX Ingress Controller] A -->|watch Service| B A -->|watch EndpointSlice| B A -->|watch Secret| B A -->|watch ConfigMap| B B -->|render/reload| C[NGINX Runtime] D[Client Traffic] --> E[Cloud or On-Prem Load Balancer] E --> C C --> F[Kubernetes Service] F --> G[Ready Pods] G --> H[Java/JAX-RS Endpoint]

This means an Ingress Controller failure can appear as:

routing stale
new Ingress not applied
TLS Secret update not reflected
Service endpoint change not picked up
config reload failed
controller pod restarted
admission webhook blocks bad config

8. ingress-nginx vs F5 NGINX Ingress Controller

Do not assume every NGINX-based controller behaves the same.

Two commonly encountered ecosystems:

AreaKubernetes community ingress-nginxF5 NGINX Ingress Controller
Project originKubernetes communityF5/NGINX
Data planeNGINX OSS-basedNGINX OSS or NGINX Plus depending edition
Config modelIngress + annotations + ConfigMapIngress + annotations + ConfigMap + NGINX-specific CRDs/features
Annotation prefixUsually nginx.ingress.kubernetes.io/*Usually nginx.org/* or related F5 NGINX annotations
Enterprise supportCommunity supportCommercial support available depending license
Feature parityNot identicalNot identical

Important principle:

Annotation names, defaults, generated config, health behavior, canary behavior, snippets, and NGINX Plus features can differ.

Internal verification checklist:

Which ingress controller implementation is installed?
What image repository and tag are used?
What Helm chart is used?
Is it community ingress-nginx or F5 NGINX Ingress Controller?
Is NGINX Plus enabled?
Which annotation prefix is valid?
What controller version is deployed in each environment?

9. Controller Pod Anatomy

A controller pod usually contains:

controller process
NGINX master process
NGINX worker processes
mounted service account token
mounted ConfigMap/Secret data or generated config
logs to stdout/stderr
metrics endpoint
health endpoint

Typical things to inspect:

kubectl get pod -n ingress-nginx
kubectl describe pod <controller-pod> -n ingress-nginx
kubectl logs <controller-pod> -n ingress-nginx
kubectl exec -n ingress-nginx <controller-pod> -- nginx -T

nginx -T is especially useful because it shows the effective generated configuration. Use it carefully in restricted environments because it may expose sensitive routing details.

Failure modes:

controller cannot watch API due to RBAC issue
controller cannot read TLS Secret across namespace
controller cannot render config due to invalid annotation
NGINX reload fails
controller pod OOMKilled
controller pod CPU throttled
controller has stale generated config

10. Admission Webhook

Many ingress controller installations include an admission webhook.

Its job:

validate Ingress resources before Kubernetes accepts them
reject invalid annotations or dangerous config
prevent broken generated NGINX config

This is good for safety, but it can surprise application teams.

Symptoms:

kubectl apply fails
GitOps sync fails
Argo CD shows admission webhook denial
Helm upgrade fails
Ingress not created

Example failure pattern:

Error from server: admission webhook "validate.nginx.ingress.kubernetes.io" denied the request

Operational meaning:

The failure happened before runtime traffic path.
The controller is refusing a configuration shape.
Do not debug Java service first.
Debug Ingress manifest/annotation/class first.

Internal verification checklist:

Is validating webhook enabled?
Which annotations are denied?
Are snippets allowed?
Does CI run the same validation before merge?
Are webhook failures visible in GitOps dashboard?

11. ConfigMap: Global Controller Behavior

Ingress controller ConfigMap usually defines global behavior.

Examples:

proxy timeout defaults
body size defaults
log format
real IP behavior
TLS defaults
server tokens
proxy buffers
gzip
allow/deny snippet usage

Mental model:

ConfigMap = platform-level defaults
Annotation = per-Ingress override
Helm values = deployment-time controller configuration

A risky pattern:

global ConfigMap says timeout 30s
one team adds annotation timeout 600s
another layer has cloud LB idle timeout 60s
result: confusing 504/499 behavior

Internal verification checklist:

kubectl get configmap -n <ingress-namespace>
kubectl describe configmap <controller-configmap> -n <ingress-namespace>
helm get values <release> -n <ingress-namespace>

Questions to ask:

Which ConfigMap controls global NGINX behavior?
Who owns it?
Are changes reviewed by platform/SRE?
Which settings may application teams override?
Are defaults different across dev/staging/prod?

12. Annotation: Per-Ingress Behavior

Annotations customize behavior for one Ingress.

Common categories:

rewrite behavior
timeout behavior
body size behavior
rate limiting
CORS
auth
TLS redirect
backend protocol
proxy buffering
canary
whitelist/allowlist
custom snippets

Example:

metadata:
  annotations:
    nginx.ingress.kubernetes.io/proxy-read-timeout: "60"
    nginx.ingress.kubernetes.io/proxy-body-size: "10m"

Production warning:

Annotations are not portable across controllers.
Annotation semantics can change across controller versions.
Some annotations can bypass platform defaults.
Snippet annotations can become code execution at proxy configuration layer.

For senior engineers, annotations must be treated like production code, not metadata decoration.

Internal verification checklist:

List all annotations on the Ingress.
Confirm the annotation prefix matches the installed controller.
Confirm the annotation is supported in the deployed version.
Confirm whether it overrides platform defaults.
Confirm whether it changes security, timeout, buffering, or auth behavior.
Confirm whether it needs platform approval.

13. TLS Secret

Ingress TLS usually references a Kubernetes Secret:

spec:
  tls:
    - hosts:
        - quote.example.company.com
      secretName: quote-example-company-tls

The Secret typically contains:

tls.crt
tls.key

Mental model:

Ingress declares host -> TLS Secret binding
Controller reads Secret
NGINX serves certificate for matching SNI/Host

Failure modes:

Secret missing
Secret in wrong namespace
certificate expired
private key mismatch
certificate SAN does not include host
intermediate certificate missing
controller lacks permission to read Secret
TLS terminated before NGINX so Secret unused

Debug:

kubectl get secret quote-example-company-tls -n quote
kubectl describe ingress quote-order-api -n quote
openssl s_client -connect quote.example.company.com:443 -servername quote.example.company.com

Internal verification checklist:

Is TLS terminated at NGINX or upstream cloud LB?
Is cert-manager used?
Is certificate source ACM, Azure Key Vault, internal CA, or Kubernetes Secret?
Is certificate rotation automated?
Is expiry alert configured?

14. Backend Service and Port Resolution

Ingress backend points to a Service, not directly to a Deployment.

Example:

backend:
  service:
    name: quote-order-api
    port:
      number: 80

The Service maps to Pod targetPort:

ports:
  - name: http
    port: 80
    targetPort: 8080

The Java/JAX-RS container listens on 8080.

Common bug:

Ingress backend port: 8080
Service port: 80
targetPort: 8080

If Ingress references Service port 8080 but the Service only exposes port 80, routing fails.

Checklist:

kubectl describe ingress <ingress> -n <namespace>
kubectl describe svc <service> -n <namespace>
kubectl get endpointslice -n <namespace> -l kubernetes.io/service-name=<service>

15. Default Backend

A default backend handles requests that do not match any Ingress rule.

Symptoms of default backend:

404 from ingress controller
unexpected default page
request reaches NGINX but no host/path match
wrong Host header
missing Ingress rule
IngressClass mismatch

Do not confuse:

SymptomLikely Layer
NGINX default backend 404Ingress routing mismatch
Java application 404Backend route/resource not found
Cloud LB 404Cloud L7 load balancer rule mismatch
503 no endpointsService/Pod readiness issue

Debug steps:

curl -vk https://host.example.com/path
curl -vk -H 'Host: host.example.com' https://lb-address/path
kubectl describe ingress -A | grep -A20 host.example.com
kubectl logs -n <ingress-ns> <controller-pod>

16. Health Endpoint and Readiness

There are multiple health concepts:

cloud LB health check against ingress controller
Kubernetes readiness probe for ingress controller pod
Kubernetes readiness probe for Java backend pod
NGINX passive upstream failure behavior
application-level /health or /ready endpoint

Do not collapse them into one thing.

Example traffic health path:

AWS NLB health checks ingress controller node/pod
Kubernetes checks ingress controller readiness
NGINX proxies to Service
Service only includes ready Java pods
Java readiness depends on DB/Kafka/config/cache

A backend may be alive but not ready.

A Pod may be ready but unable to serve a specific tenant because downstream dependency fails.

Internal verification checklist:

What does cloud LB health check?
What does ingress controller readiness check?
What does Java service readiness check?
Are readiness probes too shallow or too deep?
Are dependency failures reflected in readiness or only in request errors?

17. Deployment Model: Deployment vs DaemonSet

NGINX Ingress Controller can be deployed as Deployment or DaemonSet.

Deployment

Typical cloud pattern:

cloud load balancer
  -> ingress controller Service
  -> selected controller pods

Advantages:

easier HPA
fewer pods
standard rolling update

Considerations:

pod placement matters
anti-affinity matters
PDB matters
node failure can reduce ingress capacity

DaemonSet

Common in some on-prem or bare-metal patterns.

one ingress pod per node
external LB sends traffic to nodes

Advantages:

predictable node-level presence
useful with hostNetwork/hostPort patterns

Considerations:

more pods
node exposure
rollout across many nodes
resource usage per node

Internal verification checklist:

Is controller deployed as Deployment or DaemonSet?
How many replicas?
Is anti-affinity configured?
Is PDB configured?
Does HPA exist?
What happens during node drain?

18. Horizontal Scaling and Capacity

Ingress controller capacity depends on:

number of replicas
CPU limit/request
memory limit/request
worker_processes
worker_connections
TLS workload
logging volume
buffering/temp file usage
connection count
long-lived WebSocket/SSE connections
cloud LB distribution

Scaling replicas helps only if traffic is distributed correctly.

Potential bottlenecks:

single NGINX pod overloaded
cloud LB uneven distribution
node-level connection tracking pressure
CPU throttling
log output bottleneck
Prometheus scraping overhead
TLS handshake spike
long-lived connection exhaustion

Internal verification checklist:

Ingress controller HPA metric: CPU, memory, custom metric, or none?
Replica count per environment?
PDB minimum available?
Resource requests/limits?
Worker connection setting?
Dashboard for active connections and 5xx?

19. Java/JAX-RS Backend Impact

NGINX Ingress can affect Java/JAX-RS service behavior in subtle ways.

19.1 Scheme Detection

If NGINX terminates TLS and sends HTTP to backend, Java sees HTTP unless forwarded headers are trusted.

Required headers often include:

X-Forwarded-Proto: https
X-Forwarded-Host: quote.example.company.com
X-Forwarded-Port: 443
Forwarded: proto=https;host=quote.example.company.com

Impact:

wrong redirect URL
wrong absolute link generation
wrong OpenAPI server URL
wrong callback URL
wrong cookie Secure behavior

19.2 Base Path and Context Path

Public path may differ from internal path.

public: /quote-order/api/v1/quotes
backend: /api/v1/quotes

If rewrite is wrong:

NGINX 404
Java 404
wrong JAX-RS resource matched
redirect loses prefix
OpenAPI docs incorrect

19.3 Real Client IP

Backend may need real client IP for:

audit
fraud detection
rate limiting
tenant policy
security investigation

But trusting X-Forwarded-For blindly is dangerous.

Internal verification checklist:

Does Java framework trust forwarded headers?
Which proxy IP ranges are trusted?
Is external client allowed to inject X-Forwarded-*?
Does NGINX overwrite or append these headers?
Is client IP logged consistently in NGINX and Java logs?

20. AWS, Azure, On-Prem, and Hybrid Impact

Same Kubernetes Ingress resource can behave differently depending on platform edge.

AWS/EKS

Common patterns:

Route 53 -> NLB -> NGINX Ingress Controller -> Service -> Pod
Route 53 -> ALB -> NGINX Ingress Controller -> Service -> Pod
Route 53 -> ALB directly to Service/Pod via AWS LB Controller

Verify:

NLB vs ALB
proxy protocol
source IP preservation
security group
target type instance vs IP
ACM vs Kubernetes Secret

Azure/AKS

Common patterns:

Azure DNS -> Azure Load Balancer -> NGINX Ingress -> Service -> Pod
Azure Front Door -> Application Gateway -> NGINX Ingress -> Service -> Pod
Azure Application Gateway Ingress Controller instead of NGINX

Verify:

Front Door/Application Gateway position
TLS termination point
NSG rules
Private Link/Private Endpoint
certificate store
source IP headers

On-Prem/Hybrid

Common patterns:

enterprise DNS -> firewall -> L4/L7 load balancer -> NGINX Ingress -> Service -> Pod
enterprise DNS -> corporate reverse proxy -> Kubernetes ingress -> Java service

Verify:

DMZ boundary
internal CA
proxy chaining
firewall allowlist
split-horizon DNS
hybrid connectivity

21. Common Failure Modes

SymptomLikely Root CauseFirst Check
Ingress has no addressController/class/LB issuekubectl get ingress -o wide
404 from ingressHost/path mismatchIngress rules and Host header
503 from ingressNo ready endpointsService/EndpointSlice/Pod readiness
502Upstream connection/protocol issueService port, backend protocol, pod logs
504Timeout chainingress timeout, backend latency, LB timeout
TLS wrong certSNI/default cert mismatchTLS Secret, host, certificate SAN
Request reaches wrong serviceoverlapping rules/conflictall Ingresses for same host
Java sees HTTP not HTTPSforwarded headers missingproxy headers and app config
client IP wrongsource IP/proxy protocol configreal IP settings and LB mode
GitOps sync failsadmission webhook denialIngress validation error

22. Debugging Flow

Start broad, then narrow.

1. Does DNS resolve to expected load balancer?
2. Does load balancer route to ingress controller?
3. Is the Ingress assigned to the correct IngressClass?
4. Does host/path match the Ingress rule?
5. Does the backend Service exist?
6. Does the Service have ready endpoints?
7. Does the backend protocol/port match?
8. Does Java/JAX-RS service receive the request?
9. Do NGINX and application logs share a correlation ID?

Useful commands:

kubectl get ingress -A -o wide
kubectl describe ingress <name> -n <namespace>
kubectl get ingressclass
kubectl get svc -A
kubectl describe svc <service> -n <namespace>
kubectl get endpointslice -n <namespace>
kubectl get pod -n <namespace> -o wide
kubectl logs -n <ingress-ns> <controller-pod>
kubectl exec -n <ingress-ns> <controller-pod> -- nginx -T
curl -vk https://host/path
curl -vk -H 'Host: host.example.com' https://lb-address/path

23. Observability Concerns

Ingress visibility should answer:

Which host was requested?
Which path was requested?
Which ingress/service/upstream handled it?
What was the response status?
Was it NGINX-generated or backend-generated?
How long did the total request take?
How long did upstream take?
Which upstream address was used?
Was the request terminated by client, proxy, or backend?

Minimum useful log fields:

request_id
traceparent
remote_addr
real_client_ip
host
request_method
request_uri
status
request_time
upstream_response_time
upstream_status
upstream_addr
bytes_sent
request_length
user_agent

Without upstream timing, many 502/503/504 investigations become guesswork.


24. Security Concerns

Ingress is a security boundary.

Review these areas:

public vs internal class
TLS termination point
default backend exposure
admin path exposure
snippet annotation allowance
CORS annotation usage
auth annotation usage
source IP trust
X-Forwarded-* trust
body size limits
rate limits
WAF integration
log redaction
namespace isolation

Key principle:

Application teams should not be able to bypass platform security defaults through arbitrary annotations without review.

25. Performance Concerns

Ingress performance is shaped by:

controller replica count
CPU/memory limits
worker_connections
TLS handshake rate
upstream keepalive
body buffering
response buffering
large uploads/downloads
WebSocket/SSE long-lived connections
log volume
cloud LB behavior

For Java/JAX-RS systems, ingress tuning should be aligned with application capacity:

NGINX can accept more connections than Java can process.
NGINX can hide backend slowness until queues build up.
NGINX buffering can protect backend or increase latency/disk use.
Timeouts can fail requests before Java completes work.

26. PR Review Checklist

When reviewing Kubernetes Ingress changes, check:

IngressClass is correct.
Host is correct.
Path and pathType are intentional.
Backend Service name and port are correct.
TLS Secret is correct and in same namespace.
Annotations are supported by installed controller.
Annotations do not bypass platform defaults unexpectedly.
Timeout/body size/rewrite behavior is reviewed.
Auth/CORS/rate limit behavior is reviewed.
Public/internal exposure is correct.
Service has ready endpoints.
Java/JAX-RS base path and forwarded headers are compatible.
Observability fields remain available.
Rollback plan exists.

27. Internal Verification Checklist

Use this checklist in your CSG/team environment without assuming internal architecture.

Identify ingress controller implementation:
  - community ingress-nginx?
  - F5 NGINX Ingress Controller?
  - NGINX Plus?
  - cloud-native controller instead?

Identify exposure path:
  - public load balancer?
  - internal load balancer?
  - on-prem L4/L7 appliance?
  - API gateway before ingress?

Identify controller ownership:
  - application team?
  - platform team?
  - SRE/DevOps?
  - network/security team?

Inspect Kubernetes resources:
  - IngressClass
  - Ingress
  - Service
  - EndpointSlice
  - Secret
  - ConfigMap
  - Deployment/DaemonSet
  - HPA
  - PDB
  - NetworkPolicy

Inspect GitOps/CI/CD:
  - Helm chart
  - Kustomize overlay
  - rendered manifests
  - policy validation
  - admission webhook
  - rollout strategy
  - rollback process

Inspect observability:
  - access log format
  - controller metrics
  - cloud LB metrics
  - error dashboards
  - 499/502/503/504 alerts
  - trace correlation

28. Senior Engineer Summary

Kubernetes Ingress with NGINX is not “just YAML routing”. It is a full traffic management subsystem.

The correct mental model is:

Ingress resource declares desired HTTP/S routing.
IngressClass selects the controller implementation.
Controller watches Kubernetes resources.
Controller generates and reloads NGINX configuration.
NGINX handles actual request traffic.
Service and EndpointSlice determine available backend pods.
Java/JAX-RS service sees the result of all proxy decisions before it.

When debugging, avoid jumping directly to application code.

Always first locate the failing layer:

DNS?
cloud/on-prem load balancer?
IngressClass?
Ingress host/path?
NGINX generated config?
Service?
EndpointSlice?
Pod readiness?
Java/JAX-RS route?
Downstream dependency?

For production architecture review, the most important questions are:

Who owns the ingress layer?
What are the platform defaults?
What can application teams override?
How are risky annotations governed?
How is TLS managed?
How are source IP and forwarded headers trusted?
How are ingress failures observed?
How is rollback performed?
Lesson Recap

You just completed lesson 23 in deepen practice. Use the series map if you want to review the broader track, or continue directly into the next lesson while the context is still warm.

Continue The Track

Keep the momentum while the lesson is still fresh. Move backward for review or continue forward into the next concept.