[Daily morning study] Kubernetes StatefulSet vs Deployment ๋น๊ต
#daily morning study
Deployment vs StatefulSet โ ์ธ์ ๋ฌด์์ ์จ์ผ ํ๋
Kubernetes์์ ํ๋(Pod)๋ฅผ ์ฌ๋ฌ ๊ฐ ์คํํ ๋ ๋ณดํต Deployment๋ฅผ ์ด๋ค. ๊ทธ๋ฐ๋ฐ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ๋ฉ์์ง ํ์ฒ๋ผ ์ํ(state)๋ฅผ ๊ฐ์ง๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฌ๋ฆฌ๋ ค ํ๋ฉด Deployment๋ง์ผ๋ก๋ ๋ถ์กฑํ๋ค๋ ๊ฑธ ๊ธ๋ฐฉ ์๊ฒ ๋๋ค. ์ด ์ฐจ์ด๋ฅผ ์ ๋ฆฌํด ๋๋ฉด ์ค๊ณํ ๋ ํท๊ฐ๋ฆฌ์ง ์๋๋ค.
Deployment
Deployment๋ ๋ฌด์ํ(stateless) ์ํฌ๋ก๋๋ฅผ ์ํด ์ค๊ณ๋๋ค. ํต์ฌ ํน์ฑ์ ๋ค์๊ณผ ๊ฐ๋ค.
- ํ๋ ์ด๋ฆ์ด
{deployment-name}-{replicaset-hash}-{random-suffix}ํํ๋ก ๋ฌด์์ ์์ฑ๋จ - ํ๋๋ผ๋ฆฌ ๋๋ฑ(interchangeable)ํ๋ค โ ์ด๋ ํ๋๊ฐ ์์ฒญ์ ์ฒ๋ฆฌํด๋ ์๊ด์์
- ํ๋๊ฐ ์ฃฝ์ผ๋ฉด ์๋ก์ด ์ด๋ฆ์ผ๋ก ์ฌ์์ฑ๋จ
- ๋ณผ๋ฅจ์ ๋ถ์ฌ๋ ํ๋๊ฐ ๋ฐ๋๋ฉด ๊ฐ์ ๋ณผ๋ฅจ์ ๋ณด์ฅํ์ง ์์
- ๋กค๋ง ์ ๋ฐ์ดํธ ์ ์์ ๋ณด์ฅ ์์ด ๋ณ๋ ฌ๋ก ๊ต์ฒด ๊ฐ๋ฅ
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: app
image: my-app:v2
์น ์๋ฒ, API ์๋ฒ์ฒ๋ผ ์์ฒญ๋ง๋ค ๋ ๋ฆฝ์ ์ผ๋ก ์ฒ๋ฆฌํ ์ ์๋ ์๋น์ค์ ์ ํฉํ๋ค.
StatefulSet
StatefulSet์ ์ํ๋ฅผ ๊ฐ์ง๋ ์ํฌ๋ก๋๋ฅผ ์ํด ๋ง๋ค์ด์ก๋ค. Deployment์ ๊ฒฐ์ ์ ์ผ๋ก ๋ค๋ฅธ ์ ๋ค์ด ์๋ค.
์์ ์ ์ธ ๋คํธ์ํฌ ID
ํ๋ ์ด๋ฆ์ด {statefulset-name}-0, {statefulset-name}-1, {statefulset-name}-2 ์ฒ๋ผ ์์๊ฐ ์๋ ๊ณ ์ ์ด๋ฆ์ผ๋ก ์์ฑ๋๋ค. ํ๋๊ฐ ์ฌ์์๋์ด๋ ์ด๋ฆ์ด ์ ์ง๋๋ค.
mysql-0 โ ํญ์ ์ด ์ด๋ฆ
mysql-1
mysql-2
Headless Service์ DNS
StatefulSet์ ๋ณดํต Headless Service(.spec.clusterIP: None)์ ํจ๊ป ์ด๋ค. ๊ฐ ํ๋์ ๋ค์๊ณผ ๊ฐ์ DNS ์ฃผ์๊ฐ ์๋์ผ๋ก ๋ถ์ฌ๋๋ค.
{pod-name}.{service-name}.{namespace}.svc.cluster.local
# ์์
mysql-0.mysql.default.svc.cluster.local
mysql-1.mysql.default.svc.cluster.local
ํด๋ผ์ด์ธํธ๊ฐ ํน์ ํ๋๋ฅผ ์ง์ ์ง์ ํด์ ์ ๊ทผํ ์ ์๋ค. Primary DB์๋ง ์ฐ๊ธฐ๋ฅผ ๋ณด๋ด์ผ ํ๋ ๊ฒฝ์ฐ ์ด๊ฒ ํ์๋ค.
์์๊ฐ ๋ณด์ฅ๋ ๋ฐฐํฌ ๋ฐ ์ญ์
- ์์ฑ: 0 โ 1 โ 2 ์์๋ก ํ๋์ฉ ์ฌ๋ผ์ด (์ด์ ํ๋๊ฐ Running์ด ๋ผ์ผ ๋ค์ ๊ฒ ์์ฑ)
- ์ญ์ : 2 โ 1 โ 0 ์์๋ก ์ญ์ ์ญ์
- ์ ๋ฐ์ดํธ: ๊ธฐ๋ณธ์ ์ผ๋ก ์ญ์(๊ฐ์ฅ ๋์ ๋ฒํธ๋ถํฐ)์ผ๋ก ๋กค๋ง ์ ๋ฐ์ดํธ
์ด ์์ ๋ณด์ฅ ๋๋ถ์ ํด๋ฌ์คํฐ ๋ฉค๋ฒ์ญ ๊ด๋ฆฌ๊ฐ ์์ ํด์ง๋ค.
์์ ์ ์ธ ์คํ ๋ฆฌ์ง (PVC ๋ณด์ฅ)
StatefulSet์ volumeClaimTemplates์ ํตํด ํ๋๋ง๋ค ๊ณ ์ ํ PVC(PersistentVolumeClaim)๋ฅผ ์๋์ผ๋ก ๋ง๋ค์ด ์ค๋ค.
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
spec:
serviceName: mysql
replicas: 3
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:8.0
volumeMounts:
- name: data
mountPath: /var/lib/mysql
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 10Gi
์ ์ค์ ์ด๋ฉด data-mysql-0, data-mysql-1, data-mysql-2 PVC๊ฐ ์๋ ์์ฑ๋๋ค. ํ๋๊ฐ ์ฌ์ค์ผ์ค๋์ด๋ ๊ฐ์ PVC์ ๋ค์ ๋ถ๋๋ค. Deployment์์๋ ์ด๊ฒ ์ ๋๋ค.
๋ ๊ฐ์ง๋ฅผ ํ๋์ ๋น๊ต
| ํญ๋ชฉ | Deployment | StatefulSet |
|---|---|---|
| ํ๋ ์ด๋ฆ | ๋๋ค suffix | ์์ ์๋ ๊ณ ์ ์ด๋ฆ (-0, -1) |
| ๋คํธ์ํฌ ID | ํ๋ ์ฌ์์ ์ ๋ณ๊ฒฝ | ์ฌ์์ํด๋ ๋์ผ |
| ์คํ ๋ฆฌ์ง | ํ๋๋ง๋ค ๋ณด์ฅ ์์ | ํ๋๋ง๋ค ์ ์ฉ PVC |
| ๋ฐฐํฌ/์ญ์ ์์ | ์์ ์์ด ๋ณ๋ ฌ ๊ฐ๋ฅ | ์์ ๋ณด์ฅ |
| ์ฃผ์ ์ฌ์ฉ์ฒ | ์น์๋ฒ, API์๋ฒ | DB, ๋ฉ์์ง ํ, ZooKeeper |
์ค์ ๋ก ์ด๋ค ์ํฉ์์ ์ฐ๋
StatefulSet์ ์จ์ผ ํ๋ ๊ฒฝ์ฐ
- MySQL, PostgreSQL Replication (Primary/Replica ๊ตฌ๋ถ์ด ํ์)
- Kafka, RabbitMQ (๋ธ๋ก์ปค ID๊ฐ ๊ณ ์ ์ด์ด์ผ ํด๋ฌ์คํฐ๊ฐ ์ ์ง๋จ)
- Elasticsearch, Cassandra (ํด๋ฌ์คํฐ ๋ ธ๋ ๊ฐ ํต์ ์ ์์ ์ ์ธ ์ฃผ์ ํ์)
- ZooKeeper (์ฟผ๋ผ ๊ตฌ์ฑ์ ์ํด ๊ฐ ๋ ธ๋ ์๋ณ ํ์)
Deployment๋ก ์ถฉ๋ถํ ๊ฒฝ์ฐ
- Nginx, Apache ๋ฑ ์น ์๋ฒ
- ์ธ๋ถ DB๋ฅผ ์ฐ๋ REST API ์๋ฒ
- ์คํ ์ดํธ๋ฆฌ์ค ์์ปค ํ๋ก์ธ์ค
StatefulSet์ ์ฃผ์์
PVC๋ ์๋์ผ๋ก ์ญ์ ๋์ง ์๋๋ค. StatefulSet์ kubectl delete ํด๋ PVC๋ ๋จ๋๋ค. ๋ฐ์ดํฐ ๋ณดํธ๋ฅผ ์ํ ์๋์ ์ธ ์ค๊ณ์ธ๋ฐ, ์ง์ PVC๋ฅผ ์ญ์ ํด์ผ ์์ ํ ์ ๋ฆฌ๋๋ค.
# StatefulSet ์ญ์ ํ์๋ PVC๊ฐ ๋จ์ ์์
kubectl get pvc
# data-mysql-0 Bound ...
# data-mysql-1 Bound ...
# data-mysql-2 Bound ...
# ์ง์ ์ญ์ ํด์ผ ํจ
kubectl delete pvc data-mysql-0 data-mysql-1 data-mysql-2
์ค์ผ์ผ ๋ค์ด ์ ๋ฐ์ดํฐ ์์ค ์ํ
replicas๋ฅผ 3 โ 1๋ก ์ค์ด๋ฉด mysql-1, mysql-2 ํ๋๊ฐ ์ญ์ ๋์ง๋ง PVC๋ ๋จ๋๋ค. ๋ค์ ์ค์ผ์ผ ์
ํ๋ฉด ๊ฐ์ PVC์ ๋ค์ ์ฐ๊ฒฐ๋๋ค. ํ์ง๋ง ์ ํ๋ฆฌ์ผ์ด์
๋ ๋ฒจ์์ ํด๋ฌ์คํฐ ๋ฉค๋ฒ ์ ๊ฑฐ ์ฒ๋ฆฌ๋ฅผ ๋จผ์ ํด์ค์ผ ํ๋ ๊ฒฝ์ฐ๊ฐ ์์ผ๋ ์ฃผ์ํด์ผ ํ๋ค.
์ ๋ฆฌ
Deployment์ StatefulSet์ ๋ณธ์ง์ ์ธ ์ฐจ์ด๋ ํ๋์ ์ ์ฒด์ฑ(identity)์ ๋ณด์ฅํ๋๋ ์๋๋๋ค.
- ์ด๋ค ํ๋๊ฐ ์์ฒญ์ ์ฒ๋ฆฌํด๋ ์๊ด์๋ค โ Deployment
- ๊ฐ ํ๋๊ฐ ๊ณ ์ ํ ์ญํ ์ ๋งก๊ณ , ์ฌ์์ํด๋ ๊ฐ์ ์ด๋ฆยท๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ์ ์งํด์ผ ํ๋ค โ StatefulSet
๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ๋ถ์ฐ ์์คํ ์ Kubernetes ์์ ์ฌ๋ฆด ๋ StatefulSet์ ์ดํดํ์ง ์์ผ๋ฉด ํด๋ฌ์คํฐ๊ฐ ์ ๋๋ก ๋์ํ์ง ์๋ ์ํฉ์ ๋ง๋๊ฒ ๋๋ค. ๊ฐ๋ ์ ์ก์๋๋ฉด Helm Chart๋ฅผ ์ฝ์ ๋๋ ์ค๊ณ ์๋๊ฐ ๋ฐ๋ก ๋ณด์ธ๋ค.