[Daily morning study] Kubernetes ๋„คํŠธ์›Œํ‚น - Service, Ingress, NetworkPolicy

#daily morning study

Image


Kubernetes ๋„คํŠธ์›Œํ‚น ๊ธฐ์ดˆ

Kubernetes ํด๋Ÿฌ์Šคํ„ฐ ์•ˆ์—์„œ Pod๋ผ๋ฆฌ, ๊ทธ๋ฆฌ๊ณ  ์™ธ๋ถ€์—์„œ Pod๋กœ์˜ ํ†ต์‹ ์€ ์—ฌ๋Ÿฌ ๊ณ„์ธต์˜ ๋„คํŠธ์›Œํ‚น ์ถ”์ƒํ™”๋กœ ์ด๋ฃจ์–ด์ง„๋‹ค. ํ•ต์‹ฌ์€ ์„ธ ๊ฐ€์ง€๋‹ค: Service, Ingress, NetworkPolicy.


Service

Pod๋Š” ์žฌ์ƒ์„ฑ๋  ๋•Œ๋งˆ๋‹ค IP๊ฐ€ ๋ฐ”๋€๋‹ค. Service๋Š” Pod ์ง‘ํ•ฉ ์•ž์—์„œ ๊ณ ์ •๋œ DNS ์ด๋ฆ„๊ณผ IP๋ฅผ ์ œ๊ณตํ•˜๋Š” ์ถ”์ƒ ๊ณ„์ธต์ด๋‹ค. ๋ ˆ์ด๋ธ” ์…€๋ ‰ํ„ฐ๋กœ ๋Œ€์ƒ Pod๋ฅผ ์„ ํƒํ•œ๋‹ค.

Service ์ข…๋ฅ˜

ํƒ€์ž…์„ค๋ช…์™ธ๋ถ€ ์ ‘๊ทผ
ClusterIPํด๋Ÿฌ์Šคํ„ฐ ๋‚ด๋ถ€์—์„œ๋งŒ ์ ‘๊ทผ ๊ฐ€๋Šฅ (๊ธฐ๋ณธ๊ฐ’)๋ถˆ๊ฐ€
NodePort๊ฐ ๋…ธ๋“œ์˜ ํŠน์ • ํฌํŠธ๋ฅผ ์—ด์–ด ์™ธ๋ถ€ ์ ‘๊ทผ ํ—ˆ์šฉ (30000-32767)๊ฐ€๋Šฅ
LoadBalancerํด๋ผ์šฐ๋“œ ํ”„๋กœ๋ฐ”์ด๋”์˜ LB๋ฅผ ํ”„๋กœ๋น„์ €๋‹๊ฐ€๋Šฅ
ExternalName์™ธ๋ถ€ DNS ์ด๋ฆ„์œผ๋กœ CNAME ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ-

ClusterIP (๊ธฐ๋ณธ๊ฐ’)

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: my-app
  ports:
    - port: 80
      targetPort: 8080

ํด๋Ÿฌ์Šคํ„ฐ ๋‚ด๋ถ€ ๋‹ค๋ฅธ Pod์—์„œ my-service:80์œผ๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค. kube-dns๊ฐ€ my-service.namespace.svc.cluster.local๋กœ ์ด๋ฆ„์„ ํ•ด์„ํ•ด ์ค€๋‹ค.

NodePort

spec:
  type: NodePort
  ports:
    - port: 80
      targetPort: 8080
      nodePort: 30080

<๋…ธ๋“œ-IP>:30080์œผ๋กœ ์™ธ๋ถ€์—์„œ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•˜๋‹ค. ๊ฐœ๋ฐœ/ํ…Œ์ŠคํŠธ ํ™˜๊ฒฝ์—์„œ ์‚ฌ์šฉํ•˜๊ณ  ํ”„๋กœ๋•์…˜์—์„œ๋Š” LoadBalancer๋‚˜ Ingress๋ฅผ ์“ฐ๋Š” ๊ฒŒ ์ผ๋ฐ˜์ ์ด๋‹ค.

LoadBalancer

spec:
  type: LoadBalancer
  ports:
    - port: 80
      targetPort: 8080

AWS ELB, GCP CLB ๊ฐ™์€ ํด๋ผ์šฐ๋“œ ์ œ๊ณต ๋กœ๋“œ๋ฐธ๋Ÿฐ์„œ๊ฐ€ ์ž๋™์œผ๋กœ ์ƒ์„ฑ๋œ๋‹ค. kubectl get svc๋กœ EXTERNAL-IP๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. ์„œ๋น„์Šค๋งˆ๋‹ค LB๊ฐ€ ํ•˜๋‚˜์”ฉ ์ƒ์„ฑ๋˜๋ฏ€๋กœ ๋น„์šฉ์ด ๋ฐœ์ƒํ•œ๋‹ค.

Headless Service

ClusterIP๋ฅผ None์œผ๋กœ ์„ค์ •ํ•˜๋ฉด ํ”„๋ก์‹œ ์—†์ด Pod IP๋ฅผ ์ง์ ‘ DNS ๋ ˆ์ฝ”๋“œ๋กœ ๋ฐ˜ํ™˜ํ•œ๋‹ค. StatefulSet์—์„œ ๊ฐ Pod์— ๊ฐœ๋ณ„ DNS๋กœ ์ ‘๊ทผํ•ด์•ผ ํ•  ๋•Œ (์˜ˆ: Kafka, Cassandra ํด๋Ÿฌ์Šคํ„ฐ) ์‚ฌ์šฉํ•œ๋‹ค.

spec:
  clusterIP: None
  selector:
    app: kafka

Ingress

Service์˜ LoadBalancer ํƒ€์ž…์€ ์„œ๋น„์Šค๋งˆ๋‹ค ์™ธ๋ถ€ LB๋ฅผ ์ƒ์„ฑํ•ด ๋น„์šฉ์ด ํฌ๋‹ค. Ingress๋Š” ํด๋Ÿฌ์Šคํ„ฐ ์ง„์ž…์ ์„ ํ•˜๋‚˜๋กœ ํ†ตํ•ฉํ•˜๊ณ  ํ˜ธ์ŠคํŠธ ์ด๋ฆ„์ด๋‚˜ URL ๊ฒฝ๋กœ ๊ธฐ๋ฐ˜์œผ๋กœ ํŠธ๋ž˜ํ”ฝ์„ ๋‚ด๋ถ€ Service๋กœ ๋ผ์šฐํŒ…ํ•œ๋‹ค.

์ธํ„ฐ๋„ท โ†’ Ingress Controller (nginx, traefik, etc.)
              โ†“          โ†“            โ†“
         api-service  web-service  admin-service

Ingress ๋ฆฌ์†Œ์Šค

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx
  rules:
    - host: api.example.com
      http:
        paths:
          - path: /v1
            pathType: Prefix
            backend:
              service:
                name: api-service
                port:
                  number: 80
    - host: www.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: web-service
                port:
                  number: 80
  tls:
    - hosts:
        - api.example.com
        - www.example.com
      secretName: tls-secret

Ingress ๋ฆฌ์†Œ์Šค๋งŒ์œผ๋กœ๋Š” ๋™์ž‘ํ•˜์ง€ ์•Š๋Š”๋‹ค. ํด๋Ÿฌ์Šคํ„ฐ์— Ingress Controller๊ฐ€ ๋ณ„๋„๋กœ ๋ฐฐํฌ๋ผ ์žˆ์–ด์•ผ ํ•œ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ ingress-nginx๋‚˜ Traefik์„ ์‚ฌ์šฉํ•œ๋‹ค.

pathType ์ข…๋ฅ˜

๊ฐ’์„ค๋ช…
Exact๊ฒฝ๋กœ๊ฐ€ ์ •ํ™•ํžˆ ์ผ์น˜ํ•ด์•ผ ํ•จ
Prefixํ•ด๋‹น prefix๋กœ ์‹œ์ž‘ํ•˜๋Š” ๊ฒฝ๋กœ ๋ชจ๋‘ ๋งค์นญ
ImplementationSpecificIngress Controller๊ฐ€ ์ •์˜

NetworkPolicy

๊ธฐ๋ณธ์ ์œผ๋กœ Kubernetes ํด๋Ÿฌ์Šคํ„ฐ ๋‚ด ๋ชจ๋“  Pod๋Š” ์„œ๋กœ ํ†ต์‹ ํ•  ์ˆ˜ ์žˆ๋‹ค. NetworkPolicy๋Š” Pod ๊ฐ„ ๋„คํŠธ์›Œํฌ ํŠธ๋ž˜ํ”ฝ์„ ํ—ˆ์šฉ/์ฐจ๋‹จํ•˜๋Š” ๋ฐฉํ™”๋ฒฝ ๊ทœ์น™์ด๋‹ค.

NetworkPolicy๊ฐ€ ์ ์šฉ๋˜๋ ค๋ฉด CNI ํ”Œ๋Ÿฌ๊ทธ์ธ์ด NetworkPolicy๋ฅผ ์ง€์›ํ•ด์•ผ ํ•œ๋‹ค (Calico, Cilium, Weave Net ๋“ฑ). Flannel์€ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ง€์›ํ•˜์ง€ ์•Š๋Š”๋‹ค.

๊ธฐ๋ณธ ๊ฒฉ๋ฆฌ ์ •์ฑ…

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-all
  namespace: production
spec:
  podSelector: {}
  policyTypes:
    - Ingress
    - Egress

์ด ์ •์ฑ…์„ ์ ์šฉํ•˜๋ฉด production ๋„ค์ž„์ŠคํŽ˜์ด์Šค์˜ ๋ชจ๋“  Pod์— ๋Œ€ํ•œ ์ธ๋ฐ”์šด๋“œ/์•„์›ƒ๋ฐ”์šด๋“œ ํŠธ๋ž˜ํ”ฝ์ด ๋ชจ๋‘ ์ฐจ๋‹จ๋œ๋‹ค. ์ดํ›„ ํ•„์š”ํ•œ ํ†ต์‹ ๋งŒ ๋ช…์‹œ์ ์œผ๋กœ ํ—ˆ์šฉํ•œ๋‹ค.

ํŠน์ • Pod ๊ฐ„ ํ†ต์‹  ํ—ˆ์šฉ

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-backend-from-frontend
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: backend
  policyTypes:
    - Ingress
  ingress:
    - from:
        - podSelector:
            matchLabels:
              app: frontend
      ports:
        - protocol: TCP
          port: 8080

๋„ค์ž„์ŠคํŽ˜์ด์Šค ๊ฐ„ ํ—ˆ์šฉ

ingress:
  - from:
      - namespaceSelector:
          matchLabels:
            kubernetes.io/metadata.name: monitoring
        podSelector:
          matchLabels:
            app: prometheus

namespaceSelector์™€ podSelector๋ฅผ ๊ฐ™์€ - ํ•ญ๋ชฉ ์•„๋ž˜ ๋‘๋ฉด AND ์กฐ๊ฑด์ด๋‹ค. ๋ณ„๋„ - ํ•ญ๋ชฉ์œผ๋กœ ๋ถ„๋ฆฌํ•˜๋ฉด OR ์กฐ๊ฑด์ด ๋œ๋‹ค.


kube-proxy์˜ ์—ญํ• 

Service ํŠธ๋ž˜ํ”ฝ์ด ์‹ค์ œ Pod๋กœ ์ „๋‹ฌ๋˜๋Š” ๋ฐฉ์‹์€ ๊ฐ ๋…ธ๋“œ์—์„œ ์‹คํ–‰ ์ค‘์ธ kube-proxy๊ฐ€ ์ฒ˜๋ฆฌํ•œ๋‹ค. kube-proxy๋Š” iptables ๋˜๋Š” IPVS ๊ทœ์น™์„ ์„ค์ •ํ•ด Service IP๋กœ ๋“ค์–ด์˜ค๋Š” ํŒจํ‚ท์„ ์‹ค์ œ Pod IP๋กœ NATํ•œ๋‹ค.

ํด๋ผ์ด์–ธํŠธ โ†’ ClusterIP:80 โ†’ iptables(kube-proxy) โ†’ PodIP:8080

IPVS ๋ชจ๋“œ๋Š” iptables๋ณด๋‹ค ํ™•์žฅ์„ฑ์ด ์ข‹์•„ Pod ์ˆ˜๊ฐ€ ๋งŽ์€ ๋Œ€๊ทœ๋ชจ ํด๋Ÿฌ์Šคํ„ฐ์—์„œ ๊ถŒ์žฅ๋œ๋‹ค.


DNS ๋™์ž‘ ๋ฐฉ์‹

Kubernetes๋Š” CoreDNS๋ฅผ ๊ธฐ๋ณธ ํด๋Ÿฌ์Šคํ„ฐ DNS๋กœ ์‚ฌ์šฉํ•œ๋‹ค. ์„œ๋น„์Šค ์ด๋ฆ„์œผ๋กœ ์ ‘๊ทผํ•  ๋•Œ ๋‹ค์Œ ์ˆœ์„œ๋กœ ์ด๋ฆ„์„ ํ•ด์„ํ•œ๋‹ค.

my-service
โ†’ my-service.default.svc.cluster.local  (๊ฐ™์€ ๋„ค์ž„์ŠคํŽ˜์ด์Šค)
โ†’ my-service.other-ns.svc.cluster.local
โ†’ ...

Pod์˜ /etc/resolv.conf์— ํด๋Ÿฌ์Šคํ„ฐ ๋„๋ฉ”์ธ(cluster.local)์ด search ํ•ญ๋ชฉ์œผ๋กœ ๋“ฑ๋ก๋˜์–ด ์žˆ์–ด ์งง์€ ์ด๋ฆ„์œผ๋กœ๋„ ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.


์ •๋ฆฌ

๊ฐœ๋…์—ญํ• 
ClusterIPํด๋Ÿฌ์Šคํ„ฐ ๋‚ด๋ถ€ ์„œ๋น„์Šค ๋…ธ์ถœ (๊ธฐ๋ณธ๊ฐ’)
NodePort๋…ธ๋“œ ํฌํŠธ๋ฅผ ํ†ตํ•œ ์™ธ๋ถ€ ๋…ธ์ถœ
LoadBalancerํด๋ผ์šฐ๋“œ LB๋ฅผ ํ†ตํ•œ ์™ธ๋ถ€ ๋…ธ์ถœ
Ingress๋‹จ์ผ ์ง„์ž…์ ์—์„œ URL/ํ˜ธ์ŠคํŠธ ๊ธฐ๋ฐ˜ ๋ผ์šฐํŒ…
NetworkPolicyPod ๊ฐ„ ํŠธ๋ž˜ํ”ฝ ํ™”์ดํŠธ๋ฆฌ์ŠคํŠธ ๋ฐฉํ™”๋ฒฝ
kube-proxyService IP โ†’ Pod IP ํŒจํ‚ท ๋ณ€ํ™˜
  • Service๋Š” Pod ์ง‘ํ•ฉ์— ์•ˆ์ •์ ์ธ ์ ‘๊ทผ์ ์„ ์ œ๊ณตํ•˜๊ณ , Ingress๋Š” HTTP(S) ํŠธ๋ž˜ํ”ฝ์„ ๊ฒฝ์ œ์ ์œผ๋กœ ์™ธ๋ถ€์— ๋…ธ์ถœํ•œ๋‹ค.
  • NetworkPolicy๋Š” ๊ธฐ๋ณธ๊ฐ’์ด ์ „์ฒด ํ—ˆ์šฉ์ด๋ฏ€๋กœ ๋ฏผ๊ฐํ•œ ํ™˜๊ฒฝ์—์„œ๋Š” default-deny ์ •์ฑ…์„ ๋จผ์ € ์ ์šฉํ•˜๊ณ  ํ•„์š”ํ•œ ํ†ต์‹ ๋งŒ ์—ด์–ด์•ผ ํ•œ๋‹ค.