ЁЯПл The SchoolтА║тШ╕я╕П KubernetesтА║ЁЯПл рдзрдбрд╛ 10 тАФ Ingress: рдореБрдЦреНрдп рдлрд╛рдЯрдХ рдЖрдгрд┐ рддреНрдпрд╛рд╡рд░рдЪрд╛ рдлрд▓рдХ
ЁЯЦ╝я╕П See the drawing + lab ЁЯПа Course home ЁЯМ┐ Branch on GitHub тЬПя╕П View source
ЁЯЦ╝я╕П рдЖрдХреГрддреА рдЖрдгрд┐ labThe drawing + lab рдкреВрд░реНрдг рдкрд╛рдирд╛рд╡рд░ рдЙрдШрдбрд╛ тЖЧOpen full page тЖЧ

ЁЯПл рдзрдбрд╛ 10 тАФ Ingress: рдореБрдЦреНрдп рдлрд╛рдЯрдХ рдЖрдгрд┐ рддреНрдпрд╛рд╡рд░рдЪрд╛ рдлрд▓рдХ

ЁЯУН рддреБрдореНрд╣реА рдЗрдереЗ рдЖрд╣рд╛рдд: 13 рдкреИрдХреА рдзрдбрд╛ 10 ┬╖ рдорд╛рдЧрдЪрд╛: lesson-09-autoscaling ┬╖ рдкреБрдврдЪрд╛: lesson-11-rollouts


ЁЯУж рдпрд╛ рдмреНрд░рдБрдЪрдордзреНрдпреЗ рдХрд╛рдп рдЖрд╣реЗ

рдзрдбреЗ 01тАУ09, рдЖрдгрд┐: Ingress тАФ internet рд╡рд░реВрди рдпреЛрдЧреНрдп Service рдкрд░реНрдпрдВрдд рдпреЗрдгрд╛рд░реЗ HTTP traffic. рдЦрд░реА file:

ЁЯзТ 5 рд╡рд░реНрд╖рд╛рдВрдЪреНрдпрд╛ рдореБрд▓рд╛рд▓рд╛ рд╕рдордЬрд╛рд╡рд▓реНрдпрд╛рд╕рд╛рд░рдЦреЗ

рд╢рд╛рд│реЗрд▓рд╛ рдПрдХрдЪ рдореБрдЦреНрдп рдлрд╛рдЯрдХ ЁЯПл рдЕрд╕рддреЗ тАФ рдкреНрд░рддреНрдпреЗрдХ рд╡рд░реНрдЧрдЦреЛрд▓реАрд╕рд╛рдареА рд╡реЗрдЧрд│реЗ рдлрд╛рдЯрдХ рдирд╛рд╣реА (30 рдлрд╛рдЯрдХрд╛рдВрд╕рд╛рдареА 30 рдкрд╣рд╛рд░реЗрдХрд▒реНрдпрд╛рдВрдЪрд╛ рдкрдЧрд╛рд░ рдХрд▓реНрдкрдирд╛ рдХрд░рд╛! ЁЯТ╕). рдлрд╛рдЯрдХрд╛рд╡рд░ рдПрдХ рдкрд╣рд╛рд░реЗрдХрд░реА рдлрд▓рдХ рдШреЗрдКрди рдЙрднрд╛ рдЕрд╕рддреЛ:

ЁЯкз "рдХреНрд░реАрдбрд╛ рджрд┐рдирд╛рд╕рд╛рдареА рдЖрд▓рд╛рдд? тЖТ рдбрд╛рд╡реАрдХрдбреЗ рдореИрджрд╛рдирд╛рдХрдбреЗ рдЬрд╛. рдмрд╛рдХреА рдХрд╛рд╣реАрд╣реА? тЖТ рд╕рд░рд│ рдХрд╛рд░реНрдпрд╛рд▓рдпрд╛рдХрдбреЗ рдЬрд╛."

рдкрд╛рд╣реБрдгреЗ рдлрдХреНрдд рддреНрдпрд╛ рдПрдХрд╛ рдлрд╛рдЯрдХрд╛рдХрдбреЗ рдпреЗрддрд╛рдд; рдкрд╣рд╛рд░реЗрдХрд░реА рддреНрдпрд╛рдВрдирд╛ рдХреБрдареЗ рдЬрд╛рдпрдЪреЗ рдЖрд╣реЗ рддреЗ рд╡рд╛рдЪрддреЛ рдЖрдгрд┐ рддреНрдпрд╛рдВрдирд╛ рдпреЛрдЧреНрдп рдЦреЛрд▓реАрдХрдбреЗ рдкрд╛рдард╡рддреЛ.

Ingress рдореНрд╣рдгрдЬреЗ рд╣реЗрдЪ рдлрд╛рдЯрдХ + рдлрд▓рдХ:

ЁЯЧ║я╕П рдЖрдХреГрддреА

flowchart LR
    U["ЁЯМН Internet<br/>parent's browser"]
    ALB["ЁЯПл Main gate<br/>AWS ALB - created by<br/>the Ingress controller"]
    R{"ЁЯкз signboard<br/>which path?"}
    S1["тШОя╕П Service school-api"]
    S2["тШОя╕П Service school-analytics"]
    P1["ЁЯкС node pods"]
    P2["ЁЯкС python pods"]
    U -->|"http://gate/students"| ALB --> R
    R -->|"/analytics/*"| S2 --> P2
    R -->|"/* everything else"| S1 --> P1

тЭУ рдХрд╛рдп

ЁЯдФ рдХрд╛

рдзрдбрд╛ 04 рдордзрд▓реНрдпрд╛ Services ClusterIP рдЖрд╣реЗрдд тАФ рдореБрджреНрджрд╛рдо рдлрдХреНрдд рдЕрдВрддрд░реНрдЧрдд. рддреБрдореНрд╣реА рдкреНрд░рддреНрдпреЗрдХ service рддрд┐рдЪреНрдпрд╛ рд╕реНрд╡рддрдГрдЪреНрдпрд╛ cloud LoadBalancer рдиреЗ рдмрд╛рд╣реЗрд░ рдЙрдШрдбреВ рд╢рдХрддрд╛, рдкрдг рдкреНрд░рддреНрдпреЗрдХ LB рд▓рд╛ рдЦрд░реЗ рдкреИрд╕реЗ рд▓рд╛рдЧрддрд╛рдд рдЖрдгрд┐ TLS, domains рдЖрдгрд┐ routing рддреБрдореНрд╣рд╛рд▓рд╛ N рд╡реЗрд│рд╛ рд╕рд╛рдВрднрд╛рд│рд╛рд╡реЗ рд▓рд╛рдЧреЗрд▓. рдПрдХ Ingress = рдПрдХ рдлрд╛рдЯрдХ, рдПрдХ рдмрд┐рд▓, рдПрдХ рдЬрд╛рдЧрд╛ HTTPS certificates рдЖрдгрд┐ path рдирд┐рдпрдорд╛рдВрд╕рд╛рдареА тАФ рдЖрдгрд┐ рдкреБрдвреЗ рдХрдзреА рддрд┐рд╕рд░реА service рдЬреЛрдбрд╛рдпрдЪреА рдЭрд╛рд▓реА рддрд░ рдлрд▓рдХрд╛рд╡рд░ рдлрдХреНрдд рдПрдХ рдУрд│ рд╡рд╛рдврддреЗ.

ЁЯФз рдХрд╕реЗ (рдпрд╛ repo рдордзреНрдпреЗ)

k8s/ingress.yaml, рддреНрдпрд╛рддрд▓реЗ рд░рдВрдЬрдХ рднрд╛рдЧ:

metadata:
  annotations:
    alb.ingress.kubernetes.io/scheme: internet-facing   # public gate
    alb.ingress.kubernetes.io/target-type: ip           # straight to pod IPs
    alb.ingress.kubernetes.io/healthcheck-path: /healthz
spec:
  ingressClassName: alb
  rules:
    - http:
        paths:
          - path: /analytics    # specific first!
            backend: { service: { name: school-analytics, port: { number: 80 } } }
          - path: /             # catch-all last
            backend: { service: { name: school-api, port: { number: 80 } } }

ЁЯзк рдХрд░реВрди рдкрд╛рд╣рд╛

# LOCAL (minikube):
minikube addons enable ingress                # hire the local guard company
# use a local-friendly ingress (no ALB annotations needed):
sed '/alb.ingress/d; s/ingressClassName: alb/ingressClassName: nginx/' \
  k8s/ingress.yaml | kubectl apply -f -
kubectl -n school get ingress                 # note the ADDRESS
minikube tunnel                               # then browse http://127.0.0.1/

# ON EKS (after terraform apply + installing the AWS LB Controller):
kubectl apply -f k8s/ingress.yaml
kubectl -n school get ingress -w              # ADDRESS becomes a real ALB DNS name
curl http://<ALB-address>/students            # тЖТ Node API
curl http://<ALB-address>/analytics/summary   # тЖТ Python API

ЁЯФз рдпрд╛ рдзрдбреНрдпрд╛рд╕рд╛рдареА kubectl

kubectl get ingress ┬╖ kubectl describe ingress

ЁЯФЧ рдпрд╛рд╡рд░ рдЖрдзрд╛рд░рд┐рдд: ЁЯкк AWS L15 (ALB) ┬╖ L16 (Route 53)

тЬЕ рддрдкрд╛рд╕рд╛ тАФ рддреБрдореНрд╣рд╛рд▓рд╛ рдХрд╛рдп рджрд┐рд╕рд╛рдпрд▓рд╛ рд╣рд╡реЗ

curl -H 'Host: school.local' http://INGRESS_IP/analytics/ Python service рдкрд░реНрдпрдВрдд рдкреЛрд╣реЛрдЪрддреЗ; / Node рдкрд░реНрдпрдВрдд рдкреЛрд╣реЛрдЪрддреЗ тАФ рдПрдХ рдкрддреНрддрд╛, path рдиреБрд╕рд╛рд░ route.

ЁЯз╣ рд╕рд╛рдлрд╕рдлрд╛рдИ

local cluster: kubectl delete -f k8s/ (рдХрд┐рдВрд╡рд╛ рддреБрдореНрд╣реА apply рдХреЗрд▓реЗрд▓реА file) тАФ EKS рд╡рд░ рдЪрд╛рд▓реВ рд░рд╛рд╣рд┐рд▓реЗрд▓реНрдпрд╛ рдкреНрд░рддреНрдпреЗрдХ рдЧреЛрд╖реНрдЯреАрдЪреЗ рддрд╛рд╕рд╛рдкреНрд░рдорд╛рдгреЗ рдмрд┐рд▓ рд▓рд╛рдЧрддреЗ; EKS рд╡рд░ рддреНрдпрд╛рдиреЗ рдмрдирд╡рд▓реЗрд▓реНрдпрд╛ ALB рдЪреЗ рджрд░ рддрд╛рд╕рд╛рд▓рд╛ рдмрд┐рд▓ рд▓рд╛рдЧрддреЗ

тЪая╕П рдиреЗрд╣рдореАрдЪреНрдпрд╛ рдЪреБрдХрд╛

тПня╕П рдкреБрдвреЗ

Traffic рд╡рд╛рд╣рддреЗ рдЖрд╣реЗ! рдЖрддрд╛: рдПрдХрд╛ рд╕реЗрдХрдВрджрд╛рдЪрд╛рд╣реА downtime рди рд╣реЛрддрд╛ version 2 рдХрд╕реЗ рдкрд╛рдард╡рд╛рдпрдЪреЗ тАФ рдЖрдгрд┐ рдЦрд░рд╛рдм release рдорд╛рдЧреЗ рдХрд╕рд╛ рдШреНрдпрд╛рдпрдЪрд╛? Rollouts рдЖрдгрд┐ rollbacks.

git checkout lesson-11-rollouts

ЁЯПл Lesson 10 тАФ Ingress: the main gate and its signboard

ЁЯУН You are here: Lesson 10 of 13 ┬╖ Previous: lesson-09-autoscaling ┬╖ Next: lesson-11-rollouts


ЁЯУж What's in this branch

Lessons 01тАУ09, plus: the Ingress тАФ HTTP traffic from the internet into the right Service. Real file:

ЁЯзТ Explain like I'm 5

A school has ONE main gate ЁЯПл тАФ not a separate gate for every classroom (imagine paying a guard for 30 gates! ЁЯТ╕). At the gate stands a guard with a signboard:

ЁЯкз "Here for sports day? тЖТ go LEFT to the playground. Everything else? тЖТ go STRAIGHT to the office."

Visitors just walk to the one gate; the guard reads where they want to go and points them to the right room.

The Ingress is that gate + signboard:

ЁЯЧ║я╕П Diagram

flowchart LR
    U["ЁЯМН Internet<br/>parent's browser"]
    ALB["ЁЯПл Main gate<br/>AWS ALB - created by<br/>the Ingress controller"]
    R{"ЁЯкз signboard<br/>which path?"}
    S1["тШОя╕П Service school-api"]
    S2["тШОя╕П Service school-analytics"]
    P1["ЁЯкС node pods"]
    P2["ЁЯкС python pods"]
    U -->|"http://gate/students"| ALB --> R
    R -->|"/analytics/*"| S2 --> P2
    R -->|"/* everything else"| S1 --> P1

тЭУ What

ЁЯдФ Why

Lesson 04's Services are ClusterIP тАФ internal only, on purpose. You could expose each service with its own cloud LoadBalancer, but every LB costs real money and you'd manage TLS, domains and routing N times. One Ingress = one gate, one bill, one place for HTTPS certificates and path rules тАФ and adding a third service someday is just one more line on the signboard.

ЁЯФз How (in this repo)

k8s/ingress.yaml, the interesting bits:

metadata:
  annotations:
    alb.ingress.kubernetes.io/scheme: internet-facing   # public gate
    alb.ingress.kubernetes.io/target-type: ip           # straight to pod IPs
    alb.ingress.kubernetes.io/healthcheck-path: /healthz
spec:
  ingressClassName: alb
  rules:
    - http:
        paths:
          - path: /analytics    # specific first!
            backend: { service: { name: school-analytics, port: { number: 80 } } }
          - path: /             # catch-all last
            backend: { service: { name: school-api, port: { number: 80 } } }

ЁЯзк Try it

# LOCAL (minikube):
minikube addons enable ingress                # hire the local guard company
# use a local-friendly ingress (no ALB annotations needed):
sed '/alb.ingress/d; s/ingressClassName: alb/ingressClassName: nginx/' \
  k8s/ingress.yaml | kubectl apply -f -
kubectl -n school get ingress                 # note the ADDRESS
minikube tunnel                               # then browse http://127.0.0.1/

# ON EKS (after terraform apply + installing the AWS LB Controller):
kubectl apply -f k8s/ingress.yaml
kubectl -n school get ingress -w              # ADDRESS becomes a real ALB DNS name
curl http://<ALB-address>/students            # тЖТ Node API
curl http://<ALB-address>/analytics/summary   # тЖТ Python API

ЁЯФз kubectl for this lesson

kubectl get ingress ┬╖ kubectl describe ingress

ЁЯФЧ Builds on: ЁЯкк AWS L15 (ALB) ┬╖ L16 (Route 53)

тЬЕ Verify тАФ what you should see

curl -H 'Host: school.local' http://INGRESS_IP/analytics/ reaches the Python service; / reaches Node тАФ one address, routed by path.

ЁЯз╣ Clean up

local cluster: kubectl delete -f k8s/ (or the file you applied) тАФ on EKS, anything left running bills by the hour; on EKS the ALB it created bills hourly

тЪая╕П Common mistakes

тПня╕П Next

Traffic flows! Now: how do you ship version 2 without a second of downtime тАФ and how do you undo a bad release? Rollouts & rollbacks.

git checkout lesson-11-rollouts
тЖР PreviousautoscalingNext тЖТrollouts

This page is the lesson's README from the lesson-10-ingress branch, shown here so the whole School stays on one site. Code files open on GitHub at the same branch.