[Daily morning study] Kubernetes ๋คํธ์ํน - Service, Ingress, NetworkPolicy
#daily morning study
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๋ก ์์ํ๋ ๊ฒฝ๋ก ๋ชจ๋ ๋งค์นญ |
| ImplementationSpecific | Ingress 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/ํธ์คํธ ๊ธฐ๋ฐ ๋ผ์ฐํ |
| NetworkPolicy | Pod ๊ฐ ํธ๋ํฝ ํ์ดํธ๋ฆฌ์คํธ ๋ฐฉํ๋ฒฝ |
| kube-proxy | Service IP โ Pod IP ํจํท ๋ณํ |
- Service๋ Pod ์งํฉ์ ์์ ์ ์ธ ์ ๊ทผ์ ์ ์ ๊ณตํ๊ณ , Ingress๋ HTTP(S) ํธ๋ํฝ์ ๊ฒฝ์ ์ ์ผ๋ก ์ธ๋ถ์ ๋ ธ์ถํ๋ค.
- NetworkPolicy๋ ๊ธฐ๋ณธ๊ฐ์ด ์ ์ฒด ํ์ฉ์ด๋ฏ๋ก ๋ฏผ๊ฐํ ํ๊ฒฝ์์๋
default-deny์ ์ฑ ์ ๋จผ์ ์ ์ฉํ๊ณ ํ์ํ ํต์ ๋ง ์ด์ด์ผ ํ๋ค.