Information in this document may be out of date
This document has an older update date than the original, so the information it contains may be out of date. If you're able to read English, see the English version for the most up-to-date information: Running ZooKeeper, A Distributed System Coordinator
๋ถ์ฐ ์์คํ ์ฝ๋๋ค์ดํฐ ZooKeeper ์คํํ๊ธฐ
์ด ํํ ๋ฆฌ์ผ์ ์ํ์น ZooKeeper ์ฟ ๋ฒ๋คํฐ์ค์์ ์คํ ์ดํธํ์ ๊ณผ PodDisruptionBudget๊ณผ ํ๋์ํฐ์ดํผ๋ํฐ(PodAntiAffinity)๋ฅผ ์ด์ฉํ Apache Zookeeper ์คํ์ ์ค๋ช ํ๋ค.
์์ํ๊ธฐ ์ ์
์ด ํํ ๋ฆฌ์ผ์ ์์ํ๊ธฐ ์ ์ ๋ค์ ์ฟ ๋ฒ๋คํฐ์ค ๊ฐ๋ ์ ์น์ํด์ผ ํ๋ค.
- ํ๋
- ํด๋ฌ์คํฐ DNS
- ํค๋๋ฆฌ์ค ์๋น์ค
- ํผ์์คํดํธ๋ณผ๋ฅจ
- ํผ์์คํดํธ๋ณผ๋ฅจ ํ๋ก๋น์ ๋
- ์คํ ์ดํธํ์
- PodDisruptionBudget
- ํ๋์ํฐ์ดํผ๋ํฐ
- kubectl CLI
๋ฐ๋์ ์ต์ํ 4๊ฐ์ ๋ ธ๋๊ฐ ์๋ ํด๋ฌ์คํฐ๊ฐ ํ์ํ๋ฉฐ, ๊ฐ ๋ ธ๋๋ ์ ์ด๋ 2 ๊ฐ์ CPU์ 4 GiB ๋ฉ๋ชจ๋ฆฌ๊ฐ ํ์ํ๋ค. ์ด ํํ ๋ฆฌ์ผ์์ ํด๋ฌ์คํฐ ๋ ธ๋๋ฅผ ํต์ (cordon)ํ๊ณ ๋น์ฐ๊ฒ(drain) ํ ๊ฒ์ด๋ค. ์ด๊ฒ์ ํด๋ฌ์คํฐ๋ฅผ ์ข ๋ฃํ์ฌ ๋ ธ๋์ ๋ชจ๋ ํ๋๋ฅผ ์ถ์ถ(evict)ํ๋ ๊ฒ์ผ๋ก, ๋ชจ๋ ํ๋๋ ์์๋ก ์ธ์ค์ผ์ค๋๋ค๋ ์๋ฏธ์ด๋ค. ์ด ํํ ๋ฆฌ์ผ์ ์ํด ์ ์ฉ ํด๋ฌ์คํฐ๋ฅผ ์ด์ฉํ๊ฑฐ๋, ๋ค๋ฅธ ํ ๋ํธ์ ๊ฐ์ญ์ ํ๋ ํผ๋์ด ๋ฐ์ํ์ง ์๋๋ก ํด์ผ ํฉ๋๋ค.
์ด ํํ ๋ฆฌ์ผ์ ํด๋ฌ์คํฐ๊ฐ ๋์ ์ผ๋ก ํผ์์คํดํธ๋ณผ๋ฅจ์ ํ๋ก๋น์ ๋ํ๋๋ก ๊ตฌ์ฑํ๋ค๊ณ ๊ฐ์ ํ๋ค. ๊ทธ๋ ๊ฒ ์ค์ ๋์ด ์์ง ์๋ค๋ฉด ํํ ๋ฆฌ์ผ์ ์์ํ๊ธฐ ์ ์ ์๋์ผ๋ก 3๊ฐ์ 20 GiB ๋ณผ๋ฅจ์ ํ๋ก๋น์ ๋ํด์ผ ํ๋ค.
๋ชฉ์
์ด ํํ ๋ฆฌ์ผ์ ๋ง์น๋ฉด ๋ค์์ ๋ํด ์๊ฒ ๋๋ค.
- ์ด๋ป๊ฒ ์คํ ์ดํธํ์ ์ ์ด์ฉํ์ฌ ZooKeeper ์์๋ธ์ ๋ฐฐํฌํ๋๊ฐ.
- ์ด๋ป๊ฒ ์์๋ธ์ ์ผ๊ด๋๊ฒ ์ค์ ํ๋๊ฐ.
- ์ด๋ป๊ฒ ZooKeeper ์๋ฒ ๋ํ๋ก์ด๋จผํธ๋ฅผ ์์๋ธ ์์์ ํผ๋จ๋ฆฌ๋๊ฐ.
- ์ด๋ป๊ฒ PodDisruptionBudget์ ์ด์ฉํ์ฌ ๊ณํ๋ ์ ๊ฒ ๊ธฐ๊ฐ ๋์ ์๋น์ค ๊ฐ์ฉ์ฑ์ ๋ณด์ฅํ๋๊ฐ.
ZooKeeper
์ํ์น ZooKeeper๋ ๋ถ์ฐ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ํ ๋ถ์ฐ ์คํ ์์ค ์ฝ๋๋ค์ด์ ์๋น์ค์ด๋ค. ZooKeeper๋ ๋ฐ์ดํฐ๋ฅผ ์ฝ๊ณ ์ฐ๊ณ ๊ฐฑ์ ์ ์ง์ผ๋ณด๋๋ก ํ๋ค. ๋ฐ์ดํฐ๋ ํ์ผ์์คํ ์ฒ๋ผ ๊ณ์ธต์ ์ผ๋ก ๊ด๋ฆฌ๋๊ณ ์์๋ธ(ZooKeeper ์๋ฒ์ ์งํฉ) ๋ด์ ๋ชจ๋ ZooKeeper์๋ฒ์ ๋ณต์ ๋๋ค. ๋ฐ์ดํฐ์ ๋ชจ๋ ์ฐ์ฐ์ ์์์ ์ด๊ณ ์์ฒ์ ์ผ๋ก ์ผ๊ด๋๋ค. ZooKeeper๋ Zab ํฉ์ ํ๋กํ ์ฝ์ ์ด์ฉํ์ฌ ์์๋ธ ๋ด์ ๋ชจ๋ ์๋ฒ์ ๊ฑธ์ณ ์ํ ๋จธ์ ์ ๋ณต์ ํ์ฌ ์ด๋ฅผ ๋ณด์ฅํ๋ค.
์์๋ธ์ ๋ฆฌ๋ ์ ์ถ์ ์ํด Zab ํ๋กํ ์ฝ์ ์ฌ์ฉํ๊ณ , ๋ฆฌ๋ ์ ์ถ๊ณผ ์ ๊ฑฐ๊ฐ ์๋ฃ๋๊ธฐ ์ ๊น์ง ์์๋ธ์ ๋ฐ์ดํฐ๋ฅผ ์ธ ์ ์๋ค. ์๋ฃ๋๋ฉด ์์๋ธ์ Zab์ ์ด์ฉํ์ฌ ํ์ธํ๊ณ ํด๋ผ์ด์ธํธ์ ๋ณด์ด๋๋ก ๋ชจ๋ ์ฐ๊ธฐ๋ฅผ ์ฟผ๋ผ(quorum)์ ๋ณต์ ํ๋ค. ๊ฐ์ค์น์๋ ์ฟผ๋ผ๊ณผ ๊ด๋ จ ์์ด, ์ฟผ๋ผ์ ํ์ฌ ๋ฆฌ๋๋ฅผ ํฌํจํ๋ ์์๋ธ์ ๋๋ค์ ์ปดํฌ๋ํธ์ด๋ค. ์๋ฅผ ๋ค์ด ์์๋ธ์ด 3๊ฐ ์๋ฒ์ธ ๊ฒฝ์ฐ, ๋ฆฌ๋์ ๋ค๋ฅธ ์๋ฒ๋ก ์ฟผ๋ผ์ ๊ตฌ์ฑํ๋ค. ์์๋ธ์ด ์ฟผ๋ผ์ ๋ฌ์ฑํ ์ ์๋ค๋ฉด, ์์๋ธ์ ๋ฐ์ดํฐ๋ฅผ ์ธ ์ ์๋ค.
ZooKeeper๋ ์ ์ฒด ์ํ ๋จธ์ ์ ๋ฉ๋ชจ๋ฆฌ์ ๋ณด์กดํ๊ณ ๋ชจ๋ ๋์ฐ๋ณ์ด๋ฅผ ์ ์ฅ ๋ฏธ๋์ด์ ๋ด๊ตฌ์ฑ ์๋ WAL(Write Ahead Log)์ ๊ธฐ๋กํ๋ค. ์๋ฒ ์ฅ์ ์ WAL์ ์ฌ์ํ์ฌ ์ด์ ์ํ๋ฅผ ๋ณต์ํ ์ ์๋ค. WAL์ด ๋ฌด์ ํ์ผ๋ก ์ปค์ง๋ ๊ฒ์ ๋ฐฉ์งํ๊ธฐ ์ํด ZooKeeper๋ ์ฃผ๊ธฐ์ ์ผ๋ก ์ ์ฅ ๋ฏธ๋์ด์ ๋ฉ๋ชจ๋ฆฌ ์ํ์ ์ค๋ ์ท์ ์ ์ฅํ๋ค. ์ด ์ค๋ ์ท์ ๋ฉ๋ชจ๋ฆฌ์ ์ง์ ์ ์ฌํ ์ ์๊ณ ์ค๋ ์ท ์ด์ ์ ๋ชจ๋ WAL ํญ๋ชฉ์ ์ญ์ ๋ ์ ์๋ค.
ZooKeeper ์์๋ธ ์์ฑํ๊ธฐ
์๋ ๋งค๋ํ์คํธ์๋ ํค๋๋ฆฌ์ค ์๋น์ค, ์๋น์ค, PodDisruptionBudget, ์คํ ์ดํธํ์ ์ ํฌํจํ๋ค.
apiVersion: v1
kind: Service
metadata:
name: zk-hs
labels:
app: zk
spec:
ports:
- port: 2888
name: server
- port: 3888
name: leader-election
clusterIP: None
selector:
app: zk
---
apiVersion: v1
kind: Service
metadata:
name: zk-cs
labels:
app: zk
spec:
ports:
- port: 2181
name: client
selector:
app: zk
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: zk-pdb
spec:
selector:
matchLabels:
app: zk
maxUnavailable: 1
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: zk
spec:
selector:
matchLabels:
app: zk
serviceName: zk-hs
replicas: 3
updateStrategy:
type: RollingUpdate
podManagementPolicy: OrderedReady
template:
metadata:
labels:
app: zk
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: "app"
operator: In
values:
- zk
topologyKey: "kubernetes.io/hostname"
containers:
- name: kubernetes-zookeeper
imagePullPolicy: Always
image: "registry.k8s.io/kubernetes-zookeeper:1.0-3.4.10"
resources:
requests:
memory: "1Gi"
cpu: "0.5"
ports:
- containerPort: 2181
name: client
- containerPort: 2888
name: server
- containerPort: 3888
name: leader-election
command:
- sh
- -c
- "start-zookeeper \
--servers=3 \
--data_dir=/var/lib/zookeeper/data \
--data_log_dir=/var/lib/zookeeper/data/log \
--conf_dir=/opt/zookeeper/conf \
--client_port=2181 \
--election_port=3888 \
--server_port=2888 \
--tick_time=2000 \
--init_limit=10 \
--sync_limit=5 \
--heap=512M \
--max_client_cnxns=60 \
--snap_retain_count=3 \
--purge_interval=12 \
--max_session_timeout=40000 \
--min_session_timeout=4000 \
--log_level=INFO"
readinessProbe:
exec:
command:
- sh
- -c
- "zookeeper-ready 2181"
initialDelaySeconds: 10
timeoutSeconds: 5
livenessProbe:
exec:
command:
- sh
- -c
- "zookeeper-ready 2181"
initialDelaySeconds: 10
timeoutSeconds: 5
volumeMounts:
- name: datadir
mountPath: /var/lib/zookeeper
securityContext:
runAsUser: 1000
fsGroup: 1000
volumeClaimTemplates:
- metadata:
name: datadir
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 10Gi
ํฐ๋ฏธ๋์ ์ด๊ณ
kubectl apply
๋ช
๋ น์ด๋ก
๋งค๋ํ์คํธ๋ฅผ ์์ฑํ์.
kubectl apply -f https://k8s.io/examples/application/zookeeper/zookeeper.yaml
์ด๋ zk-hs
ํค๋๋ฆฌ์ค ์๋น์ค, zk-cs
์๋น์ค,
zk-pdb
PodDisruptionBudget๊ณผ zk
์คํ
์ดํธํ์
์ ์์ฑํ๋ค.
service/zk-hs created
service/zk-cs created
poddisruptionbudget.policy/zk-pdb created
statefulset.apps/zk created
kubectl get
์ ์ฌ์ฉํ์ฌ
์คํ
์ดํธํ์
์ปจํธ๋กค๋ฌ๊ฐ ์คํ
์ดํธํ์
ํ๋๋ฅผ ์์ฑํ๋์ง ํ์ธํ๋ค.
kubectl get pods -w -l app=zk
zk-2
ํ๋๊ฐ Running and Ready ์ํ๊ฐ ๋๋ฉด, CTRL-C
๋ฅผ ๋๋ฌ kubectl์ ์ข
๋ฃํ์.
NAME READY STATUS RESTARTS AGE
zk-0 0/1 Pending 0 0s
zk-0 0/1 Pending 0 0s
zk-0 0/1 ContainerCreating 0 0s
zk-0 0/1 Running 0 19s
zk-0 1/1 Running 0 40s
zk-1 0/1 Pending 0 0s
zk-1 0/1 Pending 0 0s
zk-1 0/1 ContainerCreating 0 0s
zk-1 0/1 Running 0 18s
zk-1 1/1 Running 0 40s
zk-2 0/1 Pending 0 0s
zk-2 0/1 Pending 0 0s
zk-2 0/1 ContainerCreating 0 0s
zk-2 0/1 Running 0 19s
zk-2 1/1 Running 0 40s
์คํ ์ดํธํ์ ์ปจํธ๋กค๋ฌ๋ 3๊ฐ์ ํ๋๋ฅผ ์์ฑํ๊ณ , ๊ฐ ํ๋๋ ZooKeeper ์๋ฒ๋ฅผ ํฌํจํ ์ปจํ ์ด๋๋ฅผ ๊ฐ์ง๋ค.
๋ฆฌ๋ ์ ์ถ ์ด์ง
์ต๋ช ๋คํธ์ํฌ์์ ๋ฆฌ๋ ์ ์ถ์ ์ํ ์ข ๋ฃ ์๊ณ ๋ฆฌ์ฆ์ด ์๊ธฐ์, Zab์ ๋ฆฌ๋ ์ ์ถ์ ์ํด ๋ช ์์ ์ธ ๋ฉค๋ฒ ๊ตฌ์ฑ์ ํด์ผ ํ๋ค. ์์๋ธ์ ๊ฐ ์๋ฒ๋ ๊ณ ์ ์๋ณ์๋ฅผ ๊ฐ์ ธ์ผ ํ๊ณ , ๋ชจ๋ ์๋ฒ๋ ์๋ณ์ ์ ์ญ ์งํฉ์ ์์์ผ ํ๋ฉฐ, ๊ฐ ์๋ณ์๋ ๋คํธ์ํฌ ์ฃผ์์ ์ฐ๊ด๋์ด์ผ ํ๋ค.
kubectl exec
๋ฅผ ์ด์ฉํ์ฌ zk
์คํ
์ดํธํ์
์ ํ๋์
ํธ์คํธ๋ค์์ ์์๋ด์.
for i in 0 1 2; do kubectl exec zk-$i -- hostname; done
์คํ
์ดํธํ์
์ปจํธ๋กค๋ฌ๋ ๊ฐ ์๋ฒ ์ธ๋ฑ์ค์ ๊ธฐ์ดํ์ฌ ๊ฐ ํ๋์ ๊ณ ์ ํ ํธ์คํธ๋ค์์ ๋ถ์ฌํ๋ค. ๊ฐ ํธ์คํธ๋ค์์ <์คํ
์ดํธํ์
์ด๋ฆ>-<์๋ฒ ์ธ๋ฑ์ค>
ํ์์ ์ทจํ๋ค. zk
์คํ
์ดํธํ์
์ replicas
ํ๋๋ 3
์ผ๋ก ์ค์ ๋์๊ธฐ ๋๋ฌธ์, ๊ทธ ์คํ
์ดํธํ์
์ปจํธ๋กค๋ฌ๋ 3๊ฐ ํ๋์ ํธ์คํธ๋ค์์ zk-0
, zk-1
,
zk-2
๋ก ์ ํ๋ค.
zk-0
zk-1
zk-2
ZooKeeper ์์๋ธ์ ์๋ฒ๋ค์ ๊ณ ์ ์๋ณ์๋ก์ ์์ฐ์๋ฅผ ์ด์ฉํ๊ณ ์๋ฒ ๋ฐ์ดํฐ ๋๋ ํฐ๋ฆฌ์ my
๋ผ๋ ํ์ผ๋ก ์๋ฒ ์๋ณ์๋ฅผ ์ ์ฅํ๋ค.
๊ฐ ์๋ฒ์์ ๋ค์ ๋ช
๋ น์ด๋ฅผ ์ด์ฉํ์ฌ myid
ํ์ผ์ ๋ด์ฉ์ ํ์ธํ์.
for i in 0 1 2; do echo "myid zk-$i";kubectl exec zk-$i -- cat /var/lib/zookeeper/data/myid; done
์๋ณ์๋ ์์ฐ์์ด๊ณ , ์๋ฒ ์ธ๋ฑ์ค๋ค๋ ์์๊ฐ ์๋๋ฏ๋ก, ์๋ฒ์ 1์ ๋ํ์ฌ ์๋ฒ์ ๋ง๋ค ์ ์๋ค.
myid zk-0
1
myid zk-1
2
myid zk-2
3
zk
์คํ
์ดํธํ์
์ ๊ฐ ํ๋ Fully Qualified Domain Name (FQDN)์ ์ป๊ธฐ ์ํด ๋ค์ ๋ช
๋ น์ด๋ฅผ ์ด์ฉํ์.
for i in 0 1 2; do kubectl exec zk-$i -- hostname -f; done
zk-hs
์๋น์ค๋ ๋ชจ๋ ํ๋๋ฅผ ์ํ ๋๋ฉ์ธ์ธ
zk-hs.default.svc.cluster.local
์ ๋ง๋ ๋ค.
zk-0.zk-hs.default.svc.cluster.local
zk-1.zk-hs.default.svc.cluster.local
zk-2.zk-hs.default.svc.cluster.local
์ฟ ๋ฒ๋คํฐ์ค DNS์ A ๋ ์ฝ๋๋ FQDN์ ํ๋์ IP ์ฃผ์๋ก ํ์ด๋ธ๋ค. ์ฟ ๋ฒ๋คํฐ์ค๊ฐ ํ๋๋ฅผ ๋ฆฌ์ค์ผ์คํ๋ฉด, ํ๋์ ์ IP ์ฃผ์๋ก A ๋ ์ฝ๋๋ฅผ ๊ฐฑ์ ํ์ง๋ง, A ๋ ์ฝ๋์ ์ด๋ฆ์ ๋ฐ๋์ง ์๋๋ค.
ZooKeeper๋ ๊ทธ๊ฒ์ ์ ํ๋ฆฌ์ผ์ด์
ํ๊ฒฝ์ค์ ์ zoo.cfg
ํ์ผ์ ์ ์ฅํ๋ค. kubectl exec
๋ฅผ ์ด์ฉํ์ฌ zk-0
ํ๋์ zoo.cfg
๋ด์ฉ์ ๋ณด์.
kubectl exec zk-0 -- cat /opt/zookeeper/conf/zoo.cfg
์๋ ํ์ผ์ server.1
, server.2
, server.3
์์ฑ์์
1
, 2
, 3
์ ZooKeeper ์๋ฒ์ myid
ํ์ผ์ ๊ตฌ๋ถ์์
์ฐ๊ด๋๋ค.
์ด๋ค์ zk
์คํ
์ดํธํ์
์ ํ๋์ FQDNS์ ์ค์ ํ๋ค.
clientPort=2181
dataDir=/var/lib/zookeeper/data
dataLogDir=/var/lib/zookeeper/log
tickTime=2000
initLimit=10
syncLimit=2000
maxClientCnxns=60
minSessionTimeout= 4000
maxSessionTimeout= 40000
autopurge.snapRetainCount=3
autopurge.purgeInterval=0
server.1=zk-0.zk-hs.default.svc.cluster.local:2888:3888
server.2=zk-1.zk-hs.default.svc.cluster.local:2888:3888
server.3=zk-2.zk-hs.default.svc.cluster.local:2888:3888
ํฉ์ ๋ฌ์ฑ
ํฉ์ ํ๋กํ ์ฝ์์ ๊ฐ ์ฐธ๊ฐ์์ ์๋ณ์๋ ์ ์ผํด์ผ ํ๋ค. Zab ํ๋กํ ์ฝ์์ ๋์ผํ ๊ณ ์ ์๋ณ์๋ฅผ ์์ฒญํ๋ ์ฐธ๊ฐ์๋ ์๋ค. ์ด๋ ์์คํ ํ๋ก์ธ์ค๊ฐ ์ด๋ค ํ๋ก์ธ์ค๊ฐ ์ด๋ค ๋ฐ์ดํฐ๋ฅผ ์ปค๋ฐํ๋์ง ๋์ํ๊ฒ ํ๋๋ฐ ํ์ํ๋ค. 2๊ฐ ํ๋๋ฅผ ๋์ผ ์๋ฒ์ผ๋ก ์์ํ์๋ค๋ฉด ๋ ๋์ ZooKeeper ์๋ฒ๋ ๋ ๋ค ์ค์ค๋ก๋ฅผ ๋์ผ ์๋ฒ๋ก ์๋ณํ๋ค.
ํฉ์ ํ๋กํ ์ฝ์์ ๊ฐ ์ฐธ์ฌ์์ ์๋ณ์๋ ๊ณ ์ ํด์ผ ํ๋ค. Zab ํ๋กํ ์ฝ์ ๋ ์ฐธ์ฌ์๊ฐ ๋์ผํ ๊ณ ์ ์๋ณ์๋ก ์์ฒญํด์๋ ์๋๋ค. ์ด๋ ์์คํ ํ๋ก์ธ์ค๊ฐ ์ด๋ค ํ๋ก์ธ์ค๊ฐ ์ด๋ค ๋ฐ์ดํฐ๋ฅผ ์ปค๋ฐํ๋์ง ๋์ํ๋๋ก ํ๊ธฐ ์ํด ํ์์ ์ด๋ค. ๋์ผ ์๋ฒ์ผ๋ก ๋ ๊ฐ์ ํ๋๊ฐ ์คํํ๋ค๋ฉด ๋ ZooKeeper ์๋ฒ๋ ๋ชจ๋ ๋์ผํ ์๋ฒ๋ก ์๋ณ๋๋ค.
kubectl get pods -w -l app=zk
NAME READY STATUS RESTARTS AGE
zk-0 0/1 Pending 0 0s
zk-0 0/1 Pending 0 0s
zk-0 0/1 ContainerCreating 0 0s
zk-0 0/1 Running 0 19s
zk-0 1/1 Running 0 40s
zk-1 0/1 Pending 0 0s
zk-1 0/1 Pending 0 0s
zk-1 0/1 ContainerCreating 0 0s
zk-1 0/1 Running 0 18s
zk-1 1/1 Running 0 40s
zk-2 0/1 Pending 0 0s
zk-2 0/1 Pending 0 0s
zk-2 0/1 ContainerCreating 0 0s
zk-2 0/1 Running 0 19s
zk-2 1/1 Running 0 40s
๊ฐ ํ๋์ A ๋ ์ฝ๋๋ ํ๋๊ฐ Ready ์ํ๊ฐ ๋๋ฉด ์
๋ ฅ๋๋ค. ๋ฐ๋ผ์
ZooKeeper ์๋ฒ์ FQDN์ ๋จ์ผ ์๋ํฌ์ธํธ๋ก ํ์ธ๋๊ณ
ํด๋น ์๋ํฌ์ธํธ๋ myid
ํ์ผ์ ๊ตฌ์ฑ๋ ์๋ณ์๋ฅผ ๊ฐ์ง
๊ณ ์ ํ ZooKeeper ์๋ฒ๊ฐ ๋๋ค.
zk-0.zk-hs.default.svc.cluster.local
zk-1.zk-hs.default.svc.cluster.local
zk-2.zk-hs.default.svc.cluster.local
์ด๊ฒ์ ZooKeeper์ zoo.cfg
ํ์ผ์ servers
์์ฑ์ด ์ ํํ ๊ตฌ์ฑ๋ ์์๋ธ๋ก ๋ํ๋๋ ๊ฒ์ ๋ณด์ฆํ๋ค.
server.1=zk-0.zk-hs.default.svc.cluster.local:2888:3888
server.2=zk-1.zk-hs.default.svc.cluster.local:2888:3888
server.3=zk-2.zk-hs.default.svc.cluster.local:2888:3888
์๋ฒ๊ฐ Zab ํ๋กํ ์ฝ๋ก ๊ฐ์ ์ปค๋ฐ ์๋ํ๋ฉด, ํฉ์๋ฅผ ์ด๋ฃจ์ด ๊ฐ์ ์ปค๋ฐํ๊ฑฐ๋(๋ฆฌ๋ ์ ์ถ์ ์ฑ๊ณตํ๊ณ ๋๋จธ์ง ๋ ๊ฐ ํ๋๋ Running๊ณผ Ready ์ํ๋ผ๋ฉด) ์คํจํ๋ค(์กฐ๊ฑด ์ค ํ๋๋ผ๋ ์ถฉ์กฑํ์ง ์์ผ๋ฉด). ๋ค๋ฅธ ์๋ฒ๋ฅผ ๋์ ํ์ฌ ์ฐ๊ธฐ๋ฅผ ์น์ธํ๋ ์ํ๋ ๋ฐ์ํ์ง ์๋๋ค.
์์๋ธ ๋ฌด๊ฒฐ์ฑ ํ ์คํธ
๊ฐ์ฅ ๊ธฐ๋ณธ์ ์ธ ํ ์คํธ๋ ํ ZooKeeper ์๋ฒ์ ๋ฐ์ดํฐ๋ฅผ ์ฐ๊ณ ๋ค๋ฅธ ZooKeeper ์๋ฒ์์ ๋ฐ์ดํฐ๋ฅผ ์ฝ๋ ๊ฒ์ด๋ค.
์๋ ๋ช
๋ น์ด๋ ์์๋ธ ๋ด์ zk-0
ํ๋์์ /hello
๊ฒฝ๋ก๋ก world
๋ฅผ ์ฐ๋ ์คํฌ๋ฆฝํธ์ธ zkCli.sh
๋ฅผ ์คํํ๋ค.
kubectl exec zk-0 -- zkCli.sh create /hello world
WATCHER::
WatchedEvent state:SyncConnected type:None path:null
Created /hello
zk-1
ํ๋์์ ๋ฐ์ดํฐ๋ฅผ ์ฝ๊ธฐ ์ํด ๋ค์ ๋ช
๋ น์ด๋ฅผ ์ด์ฉํ์.
kubectl exec zk-1 -- zkCli.sh get /hello
zk-0
์์ ์์ฑํ ๊ทธ ๋ฐ์ดํฐ๋ ์์๋ธ ๋ด์ ๋ชจ๋ ์๋ฒ์์
์ฌ์ฉํ ์ ์๋ค.
WATCHER::
WatchedEvent state:SyncConnected type:None path:null
world
cZxid = 0x100000002
ctime = Thu Dec 08 15:13:30 UTC 2016
mZxid = 0x100000002
mtime = Thu Dec 08 15:13:30 UTC 2016
pZxid = 0x100000002
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 5
numChildren = 0
๋ด๊ตฌ์ฑ์๋ ์ ์ฅ์ ์ ๊ณต
ZooKeeper ๊ธฐ๋ณธ ์น์ ์์ ์ธ๊ธํ๋ฏ์ด ZooKeeper๋ ๋ชจ๋ ํญ๋ชฉ์ ๋ด๊ตฌ์ฑ์๋ WAL์ ์ปค๋ฐํ๊ณ ๋ฉ๋ชจ๋ฆฌ ์ํ์ ์ค๋ ์ท์ ์ ์ฅ ๋ฏธ๋์์ ์ฃผ๊ธฐ์ ์ผ๋ก ์ ์ฅํ๋ค. ๋ด๊ตฌ์ฑ์ ์ ๊ณตํ๊ธฐ ์ํด WAL์ ์ด์ฉํ๋ ๊ฒ์ ๋ณต์ ๋ ์ํ ๋จธ์ ์ ์ด๋ฃจ๋ ํฉ์ ํ๋กํ ์ฝ์์ ์ด์ฉํ๋ ์ผ๋ฐ์ ์ธ ๊ธฐ๋ฒ์ด๋ค.
kubectl delete
๋ช
๋ น์ ์ด์ฉํ์ฌ
zk
์คํ
์ดํธํ์
์ ์ญ์ ํ์.
kubectl delete statefulset zk
statefulset.apps "zk" deleted
์คํ ์ดํธํ์ ์ ํ๋๊ฐ ์ข ๋ฃ๋๋ ๊ฒ์ ์ง์ผ๋ณด์.
kubectl get pods -w -l app=zk
zk-0
์ด ์์ ํ ์ข
๋ฃ๋๋ฉด CTRL-C
๋ฅผ ์ด์ฉํด kubectl์ ์ข
๋ฃํ์.
zk-2 1/1 Terminating 0 9m
zk-0 1/1 Terminating 0 11m
zk-1 1/1 Terminating 0 10m
zk-2 0/1 Terminating 0 9m
zk-2 0/1 Terminating 0 9m
zk-2 0/1 Terminating 0 9m
zk-1 0/1 Terminating 0 10m
zk-1 0/1 Terminating 0 10m
zk-1 0/1 Terminating 0 10m
zk-0 0/1 Terminating 0 11m
zk-0 0/1 Terminating 0 11m
zk-0 0/1 Terminating 0 11m
zookeeper.yaml
๋งค๋ํ์คํธ๋ฅผ ๋ค์ ์ ์ฉํ๋ค.
kubectl apply -f https://k8s.io/examples/application/zookeeper/zookeeper.yaml
zk
์คํ
์ดํธํ์
์ค๋ธ์ ํธ๋ฅผ ์์ฑํ์ง๋ง, ๋งค๋ํ์คํธ์ ๋ค๋ฅธ API ์ค๋ธ์ ํธ๋ ์ด๋ฏธ ์กด์ฌํ๋ฏ๋ก ์์ ๋์ง ์๋๋ค.
์คํ ์ดํธํ์ ์ปจํธ๋กค๋ฌ๊ฐ ์คํ ํธํ์ ์ ํ๋๋ฅผ ์ฌ์์ฑํ๋ ๊ฒ์ ํ์ธํ๋ค.
kubectl get pods -w -l app=zk
zk-2
ํ๋๊ฐ Running๊ณผ Ready๊ฐ ๋๋ฉด CTRL-C
๋ฅผ ์ด์ฉํ์ฌ kubectl์ ์ข
๋ฃํ๋ค.
NAME READY STATUS RESTARTS AGE
zk-0 0/1 Pending 0 0s
zk-0 0/1 Pending 0 0s
zk-0 0/1 ContainerCreating 0 0s
zk-0 0/1 Running 0 19s
zk-0 1/1 Running 0 40s
zk-1 0/1 Pending 0 0s
zk-1 0/1 Pending 0 0s
zk-1 0/1 ContainerCreating 0 0s
zk-1 0/1 Running 0 18s
zk-1 1/1 Running 0 40s
zk-2 0/1 Pending 0 0s
zk-2 0/1 Pending 0 0s
zk-2 0/1 ContainerCreating 0 0s
zk-2 0/1 Running 0 19s
zk-2 1/1 Running 0 40s
์๋ ๋ช
๋ น์ด๋ก ๋ฌด๊ฒฐ์ฑ ํ
์คํธ์์ ์
๋ ฅํ ๊ฐ์
zk-2
ํ๋์์ ์ป์ด์จ๋ค.
kubectl exec zk-2 zkCli.sh get /hello
zk
์คํ
์ดํธํ์
์ ๋ชจ๋ ํ๋๋ฅผ ์ข
๋ฃํ๊ณ ์ฌ์์ฑํ์์๋, ์์๋ธ์ ์ฌ์ ํ ์๋ ๊ฐ์ ๋๋ ค์ค๋ค.
WATCHER::
WatchedEvent state:SyncConnected type:None path:null
world
cZxid = 0x100000002
ctime = Thu Dec 08 15:13:30 UTC 2016
mZxid = 0x100000002
mtime = Thu Dec 08 15:13:30 UTC 2016
pZxid = 0x100000002
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 5
numChildren = 0
zk
์คํ
์ดํธํ์
์ spec
์ volumeClaimTemplates
ํ๋๋ ๊ฐ ํ๋์ ํ๋ก๋น์ ๋ ํผ์์คํดํธ๋ณผ๋ฅจ์ ์ง์ ํ๋ค.
volumeClaimTemplates:
- metadata:
name: datadir
annotations:
volume.alpha.kubernetes.io/storage-class: anything
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 20Gi
์คํ
์ดํธํ์
์ปจํธ๋กค๋ฌ๋ ์คํ
์ดํธํ์
์ ๊ฐ ํ๋์ ๋ํ
ํผ์์คํดํธ๋ณผ๋ฅจํด๋ ์
์ ์์ฑํ๋ค.
๋ค์ ๋ช
๋ น์ด๋ฅผ ์ด์ฉํ์ฌ ์คํ
์ดํธํ์
์ ํผ์์คํดํธ๋ณผ๋ฅจํด๋ ์
์ ์ดํด๋ณด์.
kubectl get pvc -l app=zk
์คํ
์ดํธํ์
์ ํ๋๋ฅผ ์ฌ์์ฑํ ๋์ ํ๋์ ํผ์์คํดํธ๋ณผ๋ฅจ๋ ๋ค์ ๋ง์ดํธํ๋ค.
NAME STATUS VOLUME CAPACITY ACCESSMODES AGE
datadir-zk-0 Bound pvc-bed742cd-bcb1-11e6-994f-42010a800002 20Gi RWO 1h
datadir-zk-1 Bound pvc-bedd27d2-bcb1-11e6-994f-42010a800002 20Gi RWO 1h
datadir-zk-2 Bound pvc-bee0817e-bcb1-11e6-994f-42010a800002 20Gi RWO 1h
์คํ
์ดํธํ์
์ ์ปจํ
์ด๋ template
์ volumeMounts
๋ถ๋ถ์ด ZooKeeper ์๋ฒ์ ๋ฐ์ดํฐ ๋๋ ํฐ๋ฆฌ์ ํผ์์คํดํธ๋ณผ๋ฅจ ๋ง์ดํธํ๋ ๋ด์ฉ์ด๋ค.
volumeMounts:
- name: datadir
mountPath: /var/lib/zookeeper
zk
์คํ
์ดํธํ์
์ด (์ฌ)์ค์ผ์ค๋ง๋ ๋ ํญ์ ๋์ผํ ํผ์์คํดํธ๋ณผ๋ฅจ
์
ZooKeeper์ ์๋ฒ ๋๋ ํฐ๋ฆฌ์ ๋ง์ดํธํ๋ค.
ํ๋๋ฅผ ์ฌ์ค์ผ์คํ ๋์๋ ZooKeeper์ WAL์ ํตํด ์ด๋ค์ง ๋ชจ๋ ์ฐ๊ธฐ์
๋ชจ๋ ๊ทธ ์ค๋
์ท๋ ๋ด๊ตฌ์ฑ์ ์ ์งํ๋ค.
์ผ๊ด๋ ๊ตฌ์ฑ ๋ณด์ฅํ๊ธฐ
๋ฆฌ๋ ์ ์ถ ์ด์ง๊ณผ ํฉ์ ๋ฌ์ฑ ์น์ ์์ ์๋ ธ๋ฏ์ด, ZooKeeper ์์๋ธ์ ์๋ฒ๋ ๋ฆฌ๋ ์ ์ถ๊ณผ ์ฟผ๋ผ์ ๊ตฌ์ฑํ๊ธฐ ์ํ ์ผ๊ด๋ ์ค์ ์ด ํ์ํ๋ค. ๋ํ Zab ํ๋กํ ์ฝ์ ์ผ๊ด๋ ์ค์ ๋ ๋คํธ์ํฌ์ ๊ฑธ์ณ ์ฌ๋ฐ๋ฅด๊ฒ ๋์ํ๊ธฐ ์ํด์ ํ์ํ๋ค. ์ด ์์์์๋ ๋งค๋ํ์คํธ์ ๊ตฌ์ฑ์ ์ง์ ํฌํจ์์ผ์ ์ผ๊ด๋ ๊ตฌ์ฑ์ ๋ฌ์ฑํ๋ค.
zk
์คํ
์ดํธํ์
์ ์ดํด๋ณด์.
kubectl get sts zk -o yaml
โฆ
command:
- sh
- -c
- "start-zookeeper \
--servers=3 \
--data_dir=/var/lib/zookeeper/data \
--data_log_dir=/var/lib/zookeeper/data/log \
--conf_dir=/opt/zookeeper/conf \
--client_port=2181 \
--election_port=3888 \
--server_port=2888 \
--tick_time=2000 \
--init_limit=10 \
--sync_limit=5 \
--heap=512M \
--max_client_cnxns=60 \
--snap_retain_count=3 \
--purge_interval=12 \
--max_session_timeout=40000 \
--min_session_timeout=4000 \
--log_level=INFO"
โฆ
ZooKeeper ์๋ฒ๋ฅผ ์์ํ๋๋ฐ ์ฌ์ฉํ ๋ช ๋ น์ด๋ ์ปค๋งจ๋๋ผ์ธ ํ๋ผ๋ฏธํฐ๋ก ํ๊ฒฝ ๊ตฌ์ฑ์ ์ ๋ฌํ๋ค. ํ๊ฒฝ ๋ณ์๋ฅผ ์ด์ฉํ์ฌ์๋ ์์๋ธ์ ํ๊ฒฝ ๊ตฌ์ฑ์ ์ ๋ฌํ ์ ์๋ค.
๋ก๊น ์ค์ ํ๊ธฐ
zkGenConfig.sh
์คํฌ๋ฆฝํธ๋ก ์์ฑ๋ ํ์ผ ์ค ํ๋๋ ZooKeeper์ ๋ก๊น
์ ์ ์ดํ๋ค.
ZooKeeper๋ Log4j๋ฅผ ์ด์ฉํ๋ฉฐ
๊ธฐ๋ณธ ๋ก๊น
๊ตฌ์ฑ์ผ๋ก๋ ์๊ฐ๊ณผ ํ์ผ ํฌ๊ธฐ ๊ธฐ์ค์ ๋กค๋ง ํ์ผ ์ดํ๋๋ฅผ ์ฌ์ฉํ๋ค.
zk
์คํ
์ดํธํ์
์ ํ ํ๋์์ ๋ก๊น
์ค์ ์ ์ดํด๋ณด๋ ์๋ ๋ช
๋ น์ด๋ฅผ ์ด์ฉํ์.
kubectl exec zk-0 cat /usr/etc/zookeeper/log4j.properties
์๋ ๋ก๊น ๊ตฌ์ฑ์ ZooKeeper๊ฐ ๋ชจ๋ ๋ก๊ทธ๋ฅผ ํ์ค ์ถ๋ ฅ ์คํธ๋ฆผ์ผ๋ก ์ฒ๋ฆฌํ๊ฒ ํ๋ค.
zookeeper.root.logger=CONSOLE
zookeeper.console.threshold=INFO
log4j.rootLogger=${zookeeper.root.logger}
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.Threshold=${zookeeper.console.threshold}
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} [myid:%X{myid}] - %-5p [%t:%C{1}@%L] - %m%n
์ด๋ ์ปจํ ์ด๋ ๋ด์์ ์์ ํ๊ฒ ๋ก๊น ํ๋ ๊ฐ์ฅ ๋จ์ํ ๋ฐฉ๋ฒ์ด๋ค. ํ์ค ์ถ๋ ฅ์ผ๋ก ์ ํ๋ฆฌ์ผ์ด์ ๋ก๊ทธ๋ฅผ ์์ฑํ๋ฉด, ์ฟ ๋ฒ๋คํฐ์ค๋ ๋ก๊ทธ ๋กํ ์ด์ ์ ์ฒ๋ฆฌํ๋ค. ๋ํ ์ฟ ๋ฒ๋คํฐ์ค๋ ์ ํ๋ฆฌ์ผ์ด์ ์ด ํ์ค ์ถ๋ ฅ๊ณผ ํ์ค ์ค๋ฅ์ ์ฐ์ธ ๋ก๊ทธ๋ก ์ธํ์ฌ ๋ก์ปฌ ์ ์ฅ ๋ฏธ๋์ด๊ฐ ๊ณ ๊ฐ๋์ง ์๋๋ก ๋ณด์ฅํ๋ ์ ์์ ์ธ ๋ณด์กด ์ ์ฑ ์ ๊ตฌํํ๋ค.
ํ๋์ ๋ง์ง๋ง 20์ค์ ๋ก๊ทธ๋ฅผ ๊ฐ์ ธ์ค๋ kubectl logs
๋ช
๋ น์ ์ด์ฉํ์.
kubectl logs zk-0 --tail 20
kubectl logs
๋ฅผ ์ด์ฉํ๊ฑฐ๋ ์ฟ ๋ฒ๋คํฐ์ค ๋์๋ณด๋์์ ํ์ค ์ถ๋ ฅ๊ณผ ํ์ค ์ค๋ฅ๋ก ์ฐ์ธ ์ ํ๋ฆฌ์ผ์ด์
๋ก๊ทธ๋ฅผ ๋ณผ ์ ์๋ค.
2016-12-06 19:34:16,236 [myid:1] - INFO [NIOServerCxn.Factory:0.0.0.0/0.0.0.0:2181:NIOServerCnxn@827] - Processing ruok command from /127.0.0.1:52740
2016-12-06 19:34:16,237 [myid:1] - INFO [Thread-1136:NIOServerCnxn@1008] - Closed socket connection for client /127.0.0.1:52740 (no session established for client)
2016-12-06 19:34:26,155 [myid:1] - INFO [NIOServerCxn.Factory:0.0.0.0/0.0.0.0:2181:NIOServerCnxnFactory@192] - Accepted socket connection from /127.0.0.1:52749
2016-12-06 19:34:26,155 [myid:1] - INFO [NIOServerCxn.Factory:0.0.0.0/0.0.0.0:2181:NIOServerCnxn@827] - Processing ruok command from /127.0.0.1:52749
2016-12-06 19:34:26,156 [myid:1] - INFO [Thread-1137:NIOServerCnxn@1008] - Closed socket connection for client /127.0.0.1:52749 (no session established for client)
2016-12-06 19:34:26,222 [myid:1] - INFO [NIOServerCxn.Factory:0.0.0.0/0.0.0.0:2181:NIOServerCnxnFactory@192] - Accepted socket connection from /127.0.0.1:52750
2016-12-06 19:34:26,222 [myid:1] - INFO [NIOServerCxn.Factory:0.0.0.0/0.0.0.0:2181:NIOServerCnxn@827] - Processing ruok command from /127.0.0.1:52750
2016-12-06 19:34:26,226 [myid:1] - INFO [Thread-1138:NIOServerCnxn@1008] - Closed socket connection for client /127.0.0.1:52750 (no session established for client)
2016-12-06 19:34:36,151 [myid:1] - INFO [NIOServerCxn.Factory:0.0.0.0/0.0.0.0:2181:NIOServerCnxnFactory@192] - Accepted socket connection from /127.0.0.1:52760
2016-12-06 19:34:36,152 [myid:1] - INFO [NIOServerCxn.Factory:0.0.0.0/0.0.0.0:2181:NIOServerCnxn@827] - Processing ruok command from /127.0.0.1:52760
2016-12-06 19:34:36,152 [myid:1] - INFO [Thread-1139:NIOServerCnxn@1008] - Closed socket connection for client /127.0.0.1:52760 (no session established for client)
2016-12-06 19:34:36,230 [myid:1] - INFO [NIOServerCxn.Factory:0.0.0.0/0.0.0.0:2181:NIOServerCnxnFactory@192] - Accepted socket connection from /127.0.0.1:52761
2016-12-06 19:34:36,231 [myid:1] - INFO [NIOServerCxn.Factory:0.0.0.0/0.0.0.0:2181:NIOServerCnxn@827] - Processing ruok command from /127.0.0.1:52761
2016-12-06 19:34:36,231 [myid:1] - INFO [Thread-1140:NIOServerCnxn@1008] - Closed socket connection for client /127.0.0.1:52761 (no session established for client)
2016-12-06 19:34:46,149 [myid:1] - INFO [NIOServerCxn.Factory:0.0.0.0/0.0.0.0:2181:NIOServerCnxnFactory@192] - Accepted socket connection from /127.0.0.1:52767
2016-12-06 19:34:46,149 [myid:1] - INFO [NIOServerCxn.Factory:0.0.0.0/0.0.0.0:2181:NIOServerCnxn@827] - Processing ruok command from /127.0.0.1:52767
2016-12-06 19:34:46,149 [myid:1] - INFO [Thread-1141:NIOServerCnxn@1008] - Closed socket connection for client /127.0.0.1:52767 (no session established for client)
2016-12-06 19:34:46,230 [myid:1] - INFO [NIOServerCxn.Factory:0.0.0.0/0.0.0.0:2181:NIOServerCnxnFactory@192] - Accepted socket connection from /127.0.0.1:52768
2016-12-06 19:34:46,230 [myid:1] - INFO [NIOServerCxn.Factory:0.0.0.0/0.0.0.0:2181:NIOServerCnxn@827] - Processing ruok command from /127.0.0.1:52768
2016-12-06 19:34:46,230 [myid:1] - INFO [Thread-1142:NIOServerCnxn@1008] - Closed socket connection for client /127.0.0.1:52768 (no session established for client)
์ฟ ๋ฒ๋คํฐ์ค๋ ๋ง์ ๋ก๊ทธ ์๋ฃจ์ ๊ณผ ํตํฉ๋๋ค. ํด๋ฌ์คํฐ์ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ฐ์ฅ ์ ํฉํ ๋ก๊ทธ ์๋ฃจ์ ์ ์ ํํ ์ ์๋ค. ํด๋ฌ์คํฐ ์์ค์ ๋ก๊ทธ ์ ์ฌ(ship)์ ํตํฉ์ ์ํด์๋ ๋ก๊ทธ ์ํ๊ณผ ์ ์ฌ๋ฅผ ์ํด ์ฌ์ด๋์นด ์ปจํ ์ด๋๋ฅผ ๋ฐฐํฌํ๋ ๊ฒ์ ๊ณ ๋ คํ๋ค.
๊ถํ ์๋ ์ฌ์ฉ์๋ฅผ ์ํด ๊ตฌ์ฑํ๊ธฐ
์ปจํ ์ด๋ ๋ด๋ถ์ ๊ถํ์๋ ์ ์ ๋ก ์ ํ๋ฆฌ์ผ์ด์ ์ ์คํํ ์ ์๋๋ก ํ๋ ์ต์์ ๋ฐฉ๋ฒ์ ๋ ผ์๊ฑฐ๋ฆฌ์ด๋ค. ์กฐ์ง์์ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ถํ ์๋ ์ฌ์ฉ์๊ฐ ์คํํ๋ค๋ฉด, ์ง์ ์ ์ ์คํํ ์ฌ์ฉ์๋ฅผ ์ ์ดํ๊ธฐ ์ํด ์ํ๋ฆฌํฐ์ปจํ ์คํธ๋ฅผ ์ด์ฉํ ์ ์๋ค.
zk
์คํ
์ดํธํ์
์ ํ๋ template
์ SecurityContext
๋ฅผ ํฌํจํ๋ค.
securityContext:
runAsUser: 1000
fsGroup: 1000
ํ๋ ์ปจํ ์ด๋์์ UID 1000์ ZooKeeper ์ฌ์ฉ์์ด๋ฉฐ, GID 1000์ ZooKeeper์ ๊ทธ๋ฃน์ ํด๋นํ๋ค.
zk-0
ํ๋์์ ํ๋ก์ธ์ค ์ ๋ณด๋ฅผ ์ป์ด์ค์.
kubectl exec zk-0 -- ps -elf
securityContext
์ค๋ธ์ ํธ์ runAsUser
ํ๋ ๊ฐ์ด 1000 ์ด๋ฏ๋ก
๋ฃจํธ ์ฌ์ฉ์๋ก ์คํํ๋ ๋์ ZooKeeper ํ๋ก์ธ์ค๋ ZooKeeper ์ฌ์ฉ์๋ก ์คํ๋๋ค.
F S UID PID PPID C PRI NI ADDR SZ WCHAN STIME TTY TIME CMD
4 S zookeep+ 1 0 0 80 0 - 1127 - 20:46 ? 00:00:00 sh -c zkGenConfig.sh && zkServer.sh start-foreground
0 S zookeep+ 27 1 0 80 0 - 1155556 - 20:46 ? 00:00:19 /usr/lib/jvm/java-8-openjdk-amd64/bin/java -Dzookeeper.log.dir=/var/log/zookeeper -Dzookeeper.root.logger=INFO,CONSOLE -cp /usr/bin/../build/classes:/usr/bin/../build/lib/*.jar:/usr/bin/../share/zookeeper/zookeeper-3.4.9.jar:/usr/bin/../share/zookeeper/slf4j-log4j12-1.6.1.jar:/usr/bin/../share/zookeeper/slf4j-api-1.6.1.jar:/usr/bin/../share/zookeeper/netty-3.10.5.Final.jar:/usr/bin/../share/zookeeper/log4j-1.2.16.jar:/usr/bin/../share/zookeeper/jline-0.9.94.jar:/usr/bin/../src/java/lib/*.jar:/usr/bin/../etc/zookeeper: -Xmx2G -Xms2G -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.local.only=false org.apache.zookeeper.server.quorum.QuorumPeerMain /usr/bin/../etc/zookeeper/zoo.cfg
๊ธฐ๋ณธ์ ์ผ๋ก ํ๋์ ํผ์์คํดํธ๋ณผ๋ฅจ์ ZooKeeper ์๋ฒ์ ๋ฐ์ดํฐ ๋๋ ํฐ๋ฆฌ์ ๋ง์ดํธ๋๊ณ , ๋ฃจํธ ์ฌ์ฉ์๋ง์ด ์ ๊ทผ ๊ฐ๋ฅํ๋ค. ์ด ๊ตฌ์ฑ์ ZooKeeper ํ๋ก์ธ์ค๊ฐ WAL์ ๊ธฐ๋กํ๊ณ ์ค๋ ์ท์ ์ ์ฅํ๋ ๊ฒ์ ๋ฐฉ์งํ๋ค.
zk-0
ํ๋์ ZooKeeper ๋ฐ์ดํฐ ๋๋ ํฐ๋ฆฌ์ ๊ถํ์ ์ป์ด์ค๋ ์๋ ๋ช
๋ น์ด๋ฅผ ์ด์ฉํ์.
kubectl exec -ti zk-0 -- ls -ld /var/lib/zookeeper/data
securityContext
์ค๋ธ์ ํธ์ fsGroup
ํ๋ ๊ฐ์ด 1000 ์ด๋ฏ๋ก, ํ๋์ ํผ์์คํดํธ ๋ณผ๋ฅจ์ ์์ ๊ถ์ ZooKeeper ๊ทธ๋ฃน์ผ๋ก ์ง์ ๋์ด ZooKeeper ํ๋ก์ธ์ค์์ ์ฝ๊ณ ์ธ ์ ์๋ค.
drwxr-sr-x 3 zookeeper zookeeper 4096 Dec 5 20:45 /var/lib/zookeeper/data
ZooKeeper ํ๋ก์ธ์ค ๊ด๋ฆฌํ๊ธฐ
ZooKeeper ๋ฌธ์์์๋ "ZooKeeper์ ์๋ฒ ํ๋ก์ธ์ค(JVM)์ ๊ด๋ฆฌํ ๊ฐ๋ ํ๋ก์ธ์ค๋ฅผ ํ์ํ ๊ฒ์ด๋ค."๋ผ๊ณ ๋งํ๋ค. ์์น๋ (๊ฐ๋ ํ๋ก์ธ์ค)๋ฅผ ํ์ฉํ์ฌ ์คํจํ ํ๋ก์ธ์ค๋ฅผ ์ฌ์์ํ๋ ๊ฒ์ ๋ถ์ฐ์์คํ ์์ ์ผ๋ฐ์ ์ธ ๋ฐฉ์์ด๋ค. ์ฟ ๋ฒ๋คํฐ์ค์์ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ฐฐํฌํ ๋์๋ ๊ฐ๋ ํ๋ก์ธ์ค๋ก ์ธ๋ถ ์ ํธ๋ฆฌํฐ๋ฅผ ์ฌ์ฉํ๊ธฐ๋ณด๋ค ์ฟ ๋ฒ๋คํฐ์ค๋ฅผ ์ ํ๋ฆฌ์ผ์ด์ ์ ์์น๋ ์ผ๋ก์ ์ฌ์ฉํด์ผ ํ๋ค.
์์๋ธ ๊ด๋ฆฌํ๊ธฐ
zk
์คํ
์ดํธํ์
์ RollingUpdate
์
๋ฐ์ดํธ ์ ๋ต์ ์ด์ฉํ๋๋ก ๊ตฌ์ฑ๋์๋ค.
kubectl patch
๋ก ์๋ฒ์ ํ ๋น๋ cpu
์๋ฅผ ๊ฐฑ์ ํ ์ ์๋ค.
kubectl patch sts zk --type='json' -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/resources/requests/cpu", "value":"0.3"}]'
statefulset.apps/zk patched
์
๋ฐ์ดํธ ์ํฉ์ ์ง์ผ๋ณด๊ธฐ ์ํด kubectl rollout status
์ด์ฉํ์.
kubectl rollout status sts/zk
waiting for statefulset rolling update to complete 0 pods at revision zk-5db4499664...
Waiting for 1 pods to be ready...
Waiting for 1 pods to be ready...
waiting for statefulset rolling update to complete 1 pods at revision zk-5db4499664...
Waiting for 1 pods to be ready...
Waiting for 1 pods to be ready...
waiting for statefulset rolling update to complete 2 pods at revision zk-5db4499664...
Waiting for 1 pods to be ready...
Waiting for 1 pods to be ready...
statefulset rolling update complete 3 pods at revision zk-5db4499664...
์ด๊ฒ์ ํ๋๋ฅผ ์ญ์์ผ๋ก ํ ๋ฒ์ ํ๋์ฉ ์ข ๋ฃํ๊ณ , ์๋ก์ด ๊ตฌ์ฑ์ผ๋ก ์ฌ์์ฑํ๋ค. ์ด๋ ๋กค๋ง์ ๋ฐ์ดํธ ๋์์ ์ฟผ๋ผ์ ์ ์งํ๋๋ก ๋ณด์ฅํ๋ค.
์ด๋ ฅ๊ณผ ์ด์ ๊ตฌ์ฑ์ ๋ณด๊ธฐ ์ํด kubectl rollout history
๋ช
๋ น์ ์ด์ฉํ์.
kubectl rollout history sts/zk
์ถ๋ ฅ์ ๋ค์๊ณผ ๋น์ทํ ๊ฒ์ด๋ค.
statefulsets "zk"
REVISION
1
2
์์ ์ฌํญ์ ๋กค๋ฐฑํ๊ธฐ ์ํด kubectl rollout undo
๋ช
๋ น์ ์ด์ฉํ์.
kubectl rollout undo sts/zk
์ถ๋ ฅ์ ๋ค์๊ณผ ๋น์ทํ ๊ฒ์ด๋ค.
statefulset.apps/zk rolled back
ํ๋ก์ธ์ค ์ฅ์ ๊ด๋ฆฌํ๊ธฐ
์ฌ์์ ์ ์ฑ
์
์ฟ ๋ฒ๋คํฐ์ค๊ฐ ํ๋ ๋ด์ ์ปจํ
์ด๋์ ์ง์
์ ์์ ํ๋ก์ธ์ค ์คํจ๋ฅผ ์ด๋ป๊ฒ ๋ค๋ฃจ๋์ง ์ ์ดํ๋ค.
์คํ
์ดํธํ์
์ ํ๋์์ ์ค์ง ์ ์ ํ ์ฌ์์ ์ ์ฑ
๋ Always์ด๋ฉฐ
์ด๊ฒ์ด ๊ธฐ๋ณธ ๊ฐ์ด๋ค. ์ํ๊ฐ ์ ์ง๋๋ ์ ํ๋ฆฌ์ผ์ด์
์ ์ํด
๊ธฐ๋ณธ ์ ์ฑ
์ ์ ๋๋ก ๋ณ๊ฒฝํ์ง ๋ง์.
zk-0
ํ๋์์ ์คํ ์ค์ธ ZooKeeper ์๋ฒ์์ ํ๋ก์ธ์ค ํธ๋ฆฌ๋ฅผ ์ดํด๋ณด๊ธฐ ์ํด ๋ค์ ๋ช
๋ น์ด๋ฅผ ์ด์ฉํ์.
kubectl exec zk-0 -- ps -ef
์ปจํ ์ด๋์ ์ํธ๋ฆฌ ํฌ์ธํธ๋ก PID 1 ์ธ ๋ช ๋ น์ด ์ฌ์ฉ๋์์ผ๋ฉฐ ZooKeeper ํ๋ก์ธ์ค๋ ์ํธ๋ฆฌ ํฌ์ธํธ์ ์์ ํ๋ก์ธ์ค๋ก PID 27 ์ด๋ค.
UID PID PPID C STIME TTY TIME CMD
zookeep+ 1 0 0 15:03 ? 00:00:00 sh -c zkGenConfig.sh && zkServer.sh start-foreground
zookeep+ 27 1 0 15:03 ? 00:00:03 /usr/lib/jvm/java-8-openjdk-amd64/bin/java -Dzookeeper.log.dir=/var/log/zookeeper -Dzookeeper.root.logger=INFO,CONSOLE -cp /usr/bin/../build/classes:/usr/bin/../build/lib/*.jar:/usr/bin/../share/zookeeper/zookeeper-3.4.9.jar:/usr/bin/../share/zookeeper/slf4j-log4j12-1.6.1.jar:/usr/bin/../share/zookeeper/slf4j-api-1.6.1.jar:/usr/bin/../share/zookeeper/netty-3.10.5.Final.jar:/usr/bin/../share/zookeeper/log4j-1.2.16.jar:/usr/bin/../share/zookeeper/jline-0.9.94.jar:/usr/bin/../src/java/lib/*.jar:/usr/bin/../etc/zookeeper: -Xmx2G -Xms2G -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.local.only=false org.apache.zookeeper.server.quorum.QuorumPeerMain /usr/bin/../etc/zookeeper/zoo.cfg
๋ค๋ฅธ ํฐ๋ฏธ๋์์ ๋ค์ ๋ช
๋ น์ด๋ก zk
์คํ
์ดํธํ์
์ ํ๋๋ฅผ ํ์ธํ๋ค.
kubectl get pod -w -l app=zk
๋ ๋ค๋ฅธ ํฐ๋ฏธ๋์์ ๋ค์ ๋ช
๋ น์ด๋ก zk-0
ํ๋์ ZooKeeper ํ๋ก์ธ์ค๋ฅผ ์ข
๋ฃ์ํจ๋ค.
kubectl exec zk-0 -- pkill java
ZooKeeper ํ๋ก์ธ์ค์ ์ข
๋ฃ๋ ๋ถ๋ชจ ํ๋ก์ธ์ค์ ์ข
๋ฃ๋ฅผ ์ผ์ผํจ๋ค. ์ปจํ
์ด๋ ์ฌ์์์ ์ฑ
์ด Always์ด๊ธฐ ๋๋ฌธ์ ๋ถ๋ชจ ํ๋ก์ธ์ค๋ฅผ ์ฌ์์ํ๋ค.
NAME READY STATUS RESTARTS AGE
zk-0 1/1 Running 0 21m
zk-1 1/1 Running 0 20m
zk-2 1/1 Running 0 19m
NAME READY STATUS RESTARTS AGE
zk-0 0/1 Error 0 29m
zk-0 0/1 Running 1 29m
zk-0 1/1 Running 1 29m
์ ํ๋ฆฌ์ผ์ด์
์ด ์คํฌ๋ฆฝํธ(zkServer.sh
๊ฐ์)๋ฅผ ์ ํ๋ฆฌ์ผ์ด์
์ ๋น์ง๋์ค ๋ก์ง์ ๊ตฌํํ ํ๋ก์ธ์ค๋ฅผ ์์ํ๊ธฐ ์ํด ์ด์ฉํ๋ค๋ฉด,
๊ทธ ์คํฌ๋ฆฝํธ๋ ์์ ํ๋ก์ธ์ค์ ํจ๊ป ๋ฐ๋์ ์ข
๋ฃ๋์ด์ผ ํ๋ค.
์ด๋ ์ฟ ๋ฒ๋คํฐ์ค๊ฐ ์ ํ๋ฆฌ์ผ์ด์
์ ๋น์ง๋์ค ๋ก์ง์ ๊ตฌํํ ํ๋ก์ธ์ค๊ฐ ์คํจํ ๋์
์ ํ๋ฆฌ์ผ์ด์
์ปจํ
์ด๋๋ฅผ ์ฌ์์ํ๋ ๊ฒ์ ๋ณด์ฆํ๋ค.
ํ์ฑ๋(Liveness) ํ ์คํธํ๊ธฐ
์คํจํ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฌ์์ํ๋๋ก ๊ตฌ์ฑํ๋ ๊ฒ์ ๋ถ์ฐ ์์คํ ์ ๊ฑด๊ฐํ๊ฒ ์ ์งํ๋๋ฐ ์ถฉ๋ถํ์ง ์๋ค. ์์คํ ์ ํ๋ก์ธ์ค๋ ์ด์์์ง๋ง ์๋ต์ด ์์ ์ ์๊ณ , ํน์ ๋ค๋ฅธ ๊ฑด๊ฐํ์ง ์์ ๊ฒฝ์ฐ์ ์๋๋ฆฌ์ค๊ฐ ์๋ค. ์ ํ๋ฆฌ์ผ์ด์ ํ๋ก์ธ์ค๊ฐ ๊ฑด๊ฐํ์ง ์๊ณ ์ฌ์์ํด์ผ๋ง ํ๋ค๋ ๊ฒ์ ์ฟ ๋ฒ๋คํฐ์ค์๊ฒ ์๋ฆฌ๋๋ก ํ์ฑ๋ ๊ฒ์ฌ๋ฅผ ์ด์ฉํด์ผ ํ๋ค.
zk
์คํ
์ดํธํ์
์ ํ๋ template
์ ํ์ฑ๋ ๊ฒ์ฌ๋ฅผ ๋ช
์ํ๋ค.
livenessProbe:
exec:
command:
- sh
- -c
- "zookeeper-ready 2181"
initialDelaySeconds: 15
timeoutSeconds: 5
๊ฒ์ฌ๋ ZooKeeper์ ruok
4 ๊ธ์ ๋จ์ด๋ฅผ ์ด์ฉํด์ ์๋ฒ์ ๊ฑด๊ฐ์ ํ
์คํธํ๋
๋ฐฐ์ฌ ์คํฌ๋ฆฝํธ๋ฅผ ํธ์ถํ๋ค.
OK=$(echo ruok | nc 127.0.0.1 $1)
if [ "$OK" == "imok" ]; then
exit 0
else
exit 1
fi
ํ ํฐ๋ฏธ๋์์ zk
์คํ
์ดํธํ์
์ ํ๋๋ฅผ ์ง์ผ๋ณด๊ธฐ ์ํด ๋ค์ ๋ช
๋ น์ด๋ฅผ ์ด์ฉํ์.
kubectl get pod -w -l app=zk
๋ค๋ฅธ ์ฐฝ์์ zk-0
ํ๋์ ํ์ผ์์คํ
์์ zookeeper-ready
์คํฌ๋ฆฝํธ๋ฅผ ์ญ์ ํ๊ธฐ ์ํด ๋ค์ ๋ช
๋ น์ด๋ฅผ ์ด์ฉํ์.
kubectl exec zk-0 -- rm /opt/zookeeper/bin/zookeeper-ready
ZooKeeper์ ํ์ฑ๋ ๊ฒ์ฌ์ ์คํจํ๋ฉด, ์ฟ ๋ฒ๋คํฐ์ค๋ ์๋์ผ๋ก ํ๋ก์ธ์ค๋ฅผ ์ฌ์์ํ์ฌ ์์๋ธ์ ๊ฑด๊ฐํ์ง ์์ ํ๋ก์ธ์ค๋ฅผ ์ฌ์์ํ๋ ๊ฒ์ ๋ณด์ฆํ๋ค.
kubectl get pod -w -l app=zk
NAME READY STATUS RESTARTS AGE
zk-0 1/1 Running 0 1h
zk-1 1/1 Running 0 1h
zk-2 1/1 Running 0 1h
NAME READY STATUS RESTARTS AGE
zk-0 0/1 Running 0 1h
zk-0 0/1 Running 1 1h
zk-0 1/1 Running 1 1h
์ค๋น๋ ํ ์คํธ
์ค๋น๋๋ ํ์ฑ๋์ ๋์ผํ์ง ์๋ค. ํ๋ก์ธ์ค๊ฐ ์ด์ ์๋ค๋ฉด, ์ค์ผ์ค๋ง๋๊ณ ๊ฑด๊ฐํ๋ค. ํ๋ก์ธ์ค๊ฐ ์ค๋น๋๋ฉด ์ ๋ ฅ์ ์ฒ๋ฆฌํ ์ ์๋ค. ํ์ฑ๋๋ ํ์์ ์ด๋ ์ค๋น๋์ ์กฐ๊ฑด์ผ๋ก๋ ์ถฉ๋ถํ์ง ์๋ค. ๋ช๋ช ๊ฒฝ์ฐ ํน๋ณํ ์ด๊ธฐํ์ ์ข ๋ฃ ์์ ํ๋ก์ธ์ค๋ ์ด์์์ง๋ง ์ค๋น๋์ง ์์ ์ ์๋ค.
์ค๋น๋ ๊ฒ์ฌ๋ฅผ ์ง์ ํ๋ฉด, ์ฟ ๋ฒ๋คํฐ์ค๋ ์ค๋น๋๊ฐ ํต๊ณผํ ๋๊น์ง ์ ํ๋ฆฌ์ผ์ด์ ํ๋ก์ธ์ค๊ฐ ๋คํธ์ํฌ ํธ๋ํฝ์ ์์ ํ์ง ์๊ฒ ํ๋ค.
ZooKeeper ์๋ฒ์์๋ ์ค๋น๋๊ฐ ํ์ฑ๋๋ฅผ ๋ดํฌํ๋ค. ๊ทธ๋ฌ๋ฏ๋ก zookeeper.yaml
๋งค๋ํ์คํธ์์
์ค๋น๋ ๊ฒ์ฌ๋ ํ์ฑ๋ ๊ฒ์ฌ์ ๋์ผํ๋ค.
readinessProbe:
exec:
command:
- sh
- -c
- "zookeeper-ready 2181"
initialDelaySeconds: 15
timeoutSeconds: 5
ํ์ฑ๋์ ์ค๋น๋ ๊ฒ์ฌ๊ฐ ๋์ผํจ์๋ ๋ ๋ค ์ง์ ํ๋ ๊ฒ์ ์ค์ํ๋ค. ์ด๋ ZooKeeper ์์๋ธ์ ๊ฑด๊ฐํ ์๋ฒ๋ง ์๋๋ผ ๋คํธ์ํฌ ํธ๋ํฝ์ ์์ ํ๋ ๊ฒ์ ๋ณด์ฅํ๋ค.
๋ ธ๋ ์คํจ ๋ฐฉ์ง
ZooKeeper๋ ๋ณ์กฐ๋ ๋ฐ์ดํฐ๋ฅผ ์ฑ๊ณต์ ์ผ๋ก ์ปค๋ฐํ๊ธฐ ์ํ ์๋ฒ์ ์ฟผ๋ผ์ด ํ์ํ๋ค. 3๊ฐ์ ์๋ฒ ์์๋ธ์์ ์ฑ๊ณต์ ์ผ๋ก ์ ์ฅํ๋ ค๋ฉด 2๊ฐ ์๋ฒ๋ ๋ฐ๋์ ๊ฑด๊ฐํด์ผ ํ๋ค. ์ฟผ๋ผ ๊ธฐ๋ฐ ์์คํ ์์, ๋ฉค๋ฒ๋ ๊ฐ์ฉ์ฑ์ ๋ณด์ฅํ๋ ์คํจ ์์ญ์ ๊ฑธ์ณ ๋ฐฐํฌ๋๋ค. ์ค๋จ์ ๋ฐฉ์งํ๊ธฐ ์ํด ๊ฐ๋ณ ์์คํ ์ ์์ค๋ก ์ธํด ๋ชจ๋ฒ ์ฌ๋ก์์๋ ๋์ผํ ์์คํ ์ ์ฌ๋ฌ ์ธ์คํด์ค์ ์์ฉ ํ๋ก๊ทธ๋จ์ ํจ๊ป ๋ฐฐ์นํ๋ ๊ฒ์ ๋ฐฐ์ ํ๋ค.
๊ธฐ๋ณธ์ ์ผ๋ก ์ฟ ๋ฒ๋คํฐ์ค๋ ๋์ผ ๋
ธ๋์์ ์คํ
์ดํธํ์
์ ํ๋๋ฅผ ์์น์ํฌ ์ ์๋ค.
์์ฑํ 3๊ฐ์ ์๋ฒ ์์๋ธ์์ 2๊ฐ์ ์๋ฒ๊ฐ ๊ฐ์ ๋
ธ๋์ ์๋ค๋ฉด, ๊ทธ ๋
ธ๋๋ ์คํจํ๊ณ
ZooKeeper ์๋น์ค ํด๋ผ์ด์ธํธ๋ ๊ทธ ํ๋๋ค์ ์ต์ ํ๋๊ฐ ์ฌ์ค์ผ์ค๋ง๋ ๋๊น์ง ์๋ ์ค๋จ์ ๊ฒฝํํ ๊ฒ์ด๋ค.
๋
ธ๋ ์คํจํ๋ ์ฌ๊ฑด ์ค์๋ ์ค์ ์์คํ
์ ํ๋ก์ธ์ค๊ฐ ์ฌ์ค์ผ์ค๋ ์ ์๊ฒ
ํญ์ ์ถ๊ฐ์ ์ธ ์ฉ๋์ ํ๋ก๋น์ ํด์ผ ํ๋ค. ๊ทธ๋ ๊ฒ ํ๋ฉด ์ฟ ๋ฒ๋คํฐ์ค ์ค์ผ์ค๋ฌ๊ฐ
ZooKeeper ์๋ฒ ํ๋๋ฅผ ๋ค์ ์ค์ผ์คํ๋ ๋์๊น์ง๋ง ์๋ ์ค๋จ๋ ๊ฒ์ด๋ค.
๊ทธ๋ฌ๋ ์๋น์ค์์ ๋
ธ๋ ์คํจ๋ก ์ธํ ๋ค์ดํ์์ ๋ฐฉ์งํ๋ ค ํ๋ค๋ฉด,
ํ๋์ํฐ์ดํผ๋ํฐ
๋ฅผ ์ค์ ํด์ผ ํ๋ค.
zk
์คํ
์ดํธํ์
์ ํ๋์ ๋
ธ๋๋ฅผ ์์๋ณด๊ธฐ ์ํด ๋ค์ ๋ช
๋ น์ด๋ฅผ ์ด์ฉํ์.
for i in 0 1 2; do kubectl get pod zk-$i --template {{.spec.nodeName}}; echo ""; done
zk
์คํ
์ดํธํ์
์ ๋ชจ๋ ํ๋๋ ๋ค๋ฅธ ๋
ธ๋์ ๋ฐฐํฌ๋๋ค.
kubernetes-node-cxpk
kubernetes-node-a5aq
kubernetes-node-2g2d
์ด๋ zk
์คํ
์ดํธํ์
์ ํ๋์ ํ๋์ํฐ์ดํผ๋ํฐ(PodAntiAffinity)
๋ฅผ ์ง์ ํ๊ธฐ ๋๋ฌธ์ด๋ค.
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: "app"
operator: In
values:
- zk
topologyKey: "kubernetes.io/hostname"
requiredDuringSchedulingIgnoredDuringExecution
ํ๋๋
์ฟ ๋ฒ๋คํฐ์ค ์ค์ผ์ค๋ฌ์ topologyKey
๋ก ์ ์๋ ๋๋ฉ์ธ์์ app
์ด zk
๋ผ๊ณ ๋ ์ด๋ธ๋ง๋
๋ ๊ฐ ํ๋๊ฐ ์์นํ์ง ์๋๋ก ํ๋ค.
topologyKey
kubernetes.io/hostname
์ ๋๋ฉ์ธ์ด ๊ฐ๋ณ ๋
ธ๋์์ ๋ํ๋ธ๋ค.
๋ค๋ฅธ ๊ท์น๊ณผ ๋ ์ด๋ธ, ์
๋ ํฐ๋ฅผ ์ฌ์ฉํ์ฌ
์์๋ธ์ ๋ฌผ๋ฆฌ์ ์ธ, ๋คํธ์ํฌ, ์ ์ ์ฅ์ ๋ถ์ผ์ ๊ฑธ์ณ ํ์ฐํ๋๋ก ์ด ๊ธฐ๋ฒ์ ํ์ฅํ ์ ์๋ค.
์์กด ์ ์ง
์ด ์น์ ์์๋ ๋ ธ๋๋ฅผ ํต์ (cordon)ํ๊ณ ๋น์ด๋ค(drain). ๊ณต์ ๋ ํด๋ฌ์คํฐ์์ ์ด ํํ ๋ฆฌ์ผ์ ์งํํ๋ค๋ฉด, ๋ค๋ฅธ ํ ๋ํธ์ ๋ถ์ ์ ์ธ ์ํฅ์ ๋น์น์ง ์์์ ๋ณด์ฆํด์ผ ํ๋ค.
์ด์ ์น์ ์ ๊ณํ๋์ง ์์ ๋ ธ๋ ์คํจ์์ ์ด์๋จ๋๋ก ์ด๋ป๊ฒ ํ๋๋ฅผ ํ์ฐํ ๊ฒ์ธ๊ฐ์ ๋ํด ์์๋ณด์๋ค. ๊ทธ๋ฌ๋ ๊ณํ๋ ์ ๊ฒ์ผ๋ก ์ธํด ๋ฐ์ํ๋ ์ผ์์ ์ธ ๋ ธ๋ ์คํจ์ ๋ํ ๊ณํ๋ ํ์ํ๋ค.
ํด๋ฌ์คํฐ์์ ๋ค์ ๋ช ๋ น์ผ๋ก ๋ ธ๋๋ฅผ ์ดํด๋ณด์.
kubectl get nodes
์ด ํํ ๋ฆฌ์ผ์์๋ ํด๋ฌ์คํฐ๊ฐ ์ต์ 4๊ฐ์ ๋
ธ๋๋ก ๊ตฌ์ฑ๋์๋ค๊ณ ๊ฐ์ ํ๋ค. ํด๋ฌ์คํฐ์ ๋
ธ๋๊ฐ 4๊ฐ๋ณด๋ค ๋ง๋ค๋ฉด, kubectl cordon
๋ช
๋ น์ ์ด์ฉํ์ฌ 4๊ฐ ๋
ธ๋๋ฅผ ์ ์ธํ๊ณ ๋ค๋ฅธ ๋ชจ๋ ๋
ธ๋๋ฅผ ํต์ (cordon)ํ๋ค. ์ด๋ ๊ฒ 4๊ฐ ๋
ธ๋๋ง ์ฌ์ฉํ๋๋ก ์ ํํ์ฌ, ๋ค์์ ์ ์ง๋ณด์ ์๋ฎฌ๋ ์ด์
์์์์ ์ฃผํคํผ ํ๋๋ฅผ ์ค์ผ์ค๋งํ ๋ ์ดํผ๋ํฐ์ PodDisruptionBudget ์ ์ฝ์ด ๋ฐ์ํ๋๋ก ํ ์ ์๋ค.
kubectl cordon <๋
ธ๋-์ด๋ฆ>
zk-pdb
PodDisruptionBudget
์ ์ดํด๋ณด๊ณ ์ ์ด ๋ช
๋ น์ด๋ฅผ ์ด์ฉํ์.
kubectl get pdb zk-pdb
max-unavailable
ํ๋๋ ์ฟ ๋ฒ๋คํฐ์ค๊ฐ zk
์คํ
์ดํธํ์
์์ ์ต๋ 1๊ฐ์ ํ๋๋
์ธ์ ๋ ์ง ๊ฐ์ฉํ์ง ์์ ์ ์์์ ๋ํ๋ธ๋ค.
NAME MIN-AVAILABLE MAX-UNAVAILABLE ALLOWED-DISRUPTIONS AGE
zk-pdb N/A 1 1
ํ ํฐ๋ฏธ๋์์ zk
์คํ
์ดํธํ์
์ ํ๋๋ฅผ ์ง์ผ๋ณด๋ ์ด ๋ช
๋ น์ด๋ฅผ ์ด์ฉํ์.
kubectl get pods -w -l app=zk
๋ค๋ฅธ ํฐ๋ฏธ๋์์ ํ์ฌ ์ค์ผ์ค๋๋ ํ๋์ ๋ ธ๋๋ฅผ ์ดํด๋ณด์.
for i in 0 1 2; do kubectl get pod zk-$i --template {{.spec.nodeName}}; echo ""; done
์ถ๋ ฅ์ ๋ค์๊ณผ ๋น์ทํ ๊ฒ์ด๋ค.
kubernetes-node-pb41
kubernetes-node-ixsl
kubernetes-node-i4c4
zk-0
ํ๋๊ฐ ์ค์ผ์ค๋๋ ๋
ธ๋๋ฅผ ํต์ ํ๊ธฐ ์ํด
kubectl drain
๋ฅผ ์ด์ฉํ์.
kubectl drain $(kubectl get pod zk-0 --template {{.spec.nodeName}}) --ignore-daemonsets --force --delete-emptydir-data
์ถ๋ ฅ์ ๋ค์๊ณผ ๋น์ทํ ๊ฒ์ด๋ค.
node "kubernetes-node-group-pb41" cordoned
WARNING: Deleting pods not managed by ReplicationController, ReplicaSet, Job, or DaemonSet: fluentd-cloud-logging-kubernetes-node-group-pb41, kube-proxy-kubernetes-node-group-pb41; Ignoring DaemonSet-managed pods: node-problem-detector-v0.1-o5elz
pod "zk-0" deleted
node "kubernetes-node-group-pb41" drained
ํด๋ฌ์คํฐ์ 4๊ฐ ๋
ธ๋๊ฐ ์๊ธฐ ๋๋ฌธ์ kubectl drain
์ด ์ฑ๊ณตํ์ฌ
zk-0
์ ๋ค๋ฅธ ๋
ธ๋๋ก ์ฌ์ค์ผ์ค๋ง ๋๋ค.
NAME READY STATUS RESTARTS AGE
zk-0 1/1 Running 2 1h
zk-1 1/1 Running 0 1h
zk-2 1/1 Running 0 1h
NAME READY STATUS RESTARTS AGE
zk-0 1/1 Terminating 2 2h
zk-0 0/1 Terminating 2 2h
zk-0 0/1 Terminating 2 2h
zk-0 0/1 Terminating 2 2h
zk-0 0/1 Pending 0 0s
zk-0 0/1 Pending 0 0s
zk-0 0/1 ContainerCreating 0 0s
zk-0 0/1 Running 0 51s
zk-0 1/1 Running 0 1m
๊ณ์ํด์ ์คํ
์ดํธํ์
์ ํ๋๋ฅผ ์ฒซ ํฐ๋ฏธ๋์์ ์ง์ผ๋ณด๊ณ
zk-1
์ด ์ค์ผ์ค๋ ๋
ธ๋๋ฅผ ๋น์๋ณด์.
kubectl drain $(kubectl get pod zk-1 --template {{.spec.nodeName}}) --ignore-daemonsets --force --delete-emptydir-data
์ถ๋ ฅ์ ๋ค์๊ณผ ๋น์ทํ ๊ฒ์ด๋ค.
"kubernetes-node-ixsl" cordoned
WARNING: Deleting pods not managed by ReplicationController, ReplicaSet, Job, or DaemonSet: fluentd-cloud-logging-kubernetes-node-ixsl, kube-proxy-kubernetes-node-ixsl; Ignoring DaemonSet-managed pods: node-problem-detector-v0.1-voc74
pod "zk-1" deleted
node "kubernetes-node-ixsl" drained
zk-1
ํ๋๋ ์ค์ผ์ค๋์ง ์๋๋ฐ ์ด๋ zk
StatefulSet
์ด ์ค์ง 2๊ฐ ๋
ธ๋๊ฐ ์ค์ผ์ค๋๋๋ก ํ๋๋ฅผ ์์น์ํค๋ ๊ฒ์ ๊ธํ๋
PodAntiAffinity
๊ท์น์ ํฌํจํ์๊ธฐ ๋๋ฌธ์ด๊ณ ๊ทธ ํ๋๋ Pending ์ํ๋ก ๋จ์ ๊ฒ์ด๋ค.
kubectl get pods -w -l app=zk
์ถ๋ ฅ์ ๋ค์๊ณผ ๋น์ทํ ๊ฒ์ด๋ค.
NAME READY STATUS RESTARTS AGE
zk-0 1/1 Running 2 1h
zk-1 1/1 Running 0 1h
zk-2 1/1 Running 0 1h
NAME READY STATUS RESTARTS AGE
zk-0 1/1 Terminating 2 2h
zk-0 0/1 Terminating 2 2h
zk-0 0/1 Terminating 2 2h
zk-0 0/1 Terminating 2 2h
zk-0 0/1 Pending 0 0s
zk-0 0/1 Pending 0 0s
zk-0 0/1 ContainerCreating 0 0s
zk-0 0/1 Running 0 51s
zk-0 1/1 Running 0 1m
zk-1 1/1 Terminating 0 2h
zk-1 0/1 Terminating 0 2h
zk-1 0/1 Terminating 0 2h
zk-1 0/1 Terminating 0 2h
zk-1 0/1 Pending 0 0s
zk-1 0/1 Pending 0 0s
๊ณ์ํด์ ์คํ
์ดํธํ์
์ ํ๋๋ฅผ ์ง์ผ๋ณด๊ณ
zk-2
๊ฐ ์ค์ผ์ค๋ ๋
ธ๋๋ฅผ ๋น์๋ณด์.
kubectl drain $(kubectl get pod zk-2 --template {{.spec.nodeName}}) --ignore-daemonsets --force --delete-emptydir-data
์ถ๋ ฅ์ ๋ค์๊ณผ ๋น์ทํ ๊ฒ์ด๋ค.
node "kubernetes-node-i4c4" cordoned
WARNING: Deleting pods not managed by ReplicationController, ReplicaSet, Job, or DaemonSet: fluentd-cloud-logging-kubernetes-node-i4c4, kube-proxy-kubernetes-node-i4c4; Ignoring DaemonSet-managed pods: node-problem-detector-v0.1-dyrog
WARNING: Ignoring DaemonSet-managed pods: node-problem-detector-v0.1-dyrog; Deleting pods not managed by ReplicationController, ReplicaSet, Job, or DaemonSet: fluentd-cloud-logging-kubernetes-node-i4c4, kube-proxy-kubernetes-node-i4c4
There are pending pods when an error occurred: Cannot evict pod as it would violate the pod's disruption budget.
pod/zk-2
kubectl ์ ์ข
๋ฃํ๊ธฐ ์ํด CTRL-C
๋ฅผ ์ด์ฉํ์.
zk-2
๋ฅผ ์ถ์ถํ๋ ๊ฒ์ zk-budget
์ ์๋ฐํ๊ธฐ ๋๋ฌธ์ ์
์งธ ๋
ธ๋๋ฅผ ๋น์ธ ์ ์๋ค. ๊ทธ๋ฌ๋ ๊ทธ ๋
ธ๋๋ ํต์ ์ํ๋ก ๋จ๋๋ค.
zk-0
์์ ์จ์ ์ฑ ํ
์คํธ ๋์ ์
๋ ฅํ ๊ฐ์ ๊ฐ์ ธ์ค๋ zkCli.sh
๋ฅผ ์ด์ฉํ์.
kubectl exec zk-0 zkCli.sh get /hello
PodDisruptionBudget
์ด ์กด์ค๋๊ธฐ ๋๋ฌธ์ ์๋น์ค๋ ์ฌ์ ํ ๊ฐ์ฉํ๋ค.
WatchedEvent state:SyncConnected type:None path:null
world
cZxid = 0x200000002
ctime = Wed Dec 07 00:08:59 UTC 2016
mZxid = 0x200000002
mtime = Wed Dec 07 00:08:59 UTC 2016
pZxid = 0x200000002
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 5
numChildren = 0
kubectl uncordon
์ด์ฉํ์ฌ ์ฒซ ๋
ธ๋์ ํต์ ๋ฅผ ํ์.
kubectl uncordon kubernetes-node-pb41
์ถ๋ ฅ์ ๋ค์๊ณผ ๋น์ทํ ๊ฒ์ด๋ค.
node "kubernetes-node-pb41" uncordoned
zk-1
์ ์ด ๋
ธ๋์์ ์ฌ์ค์ผ์ค๋๋ค. zk-1
์ด Running๊ณผ Ready๊ฐ ๋ ๋๊น์ง ๊ธฐ๋ค๋ฆฌ์.
kubectl get pods -w -l app=zk
์ถ๋ ฅ์ ๋ค์๊ณผ ๋น์ทํ ๊ฒ์ด๋ค.
NAME READY STATUS RESTARTS AGE
zk-0 1/1 Running 2 1h
zk-1 1/1 Running 0 1h
zk-2 1/1 Running 0 1h
NAME READY STATUS RESTARTS AGE
zk-0 1/1 Terminating 2 2h
zk-0 0/1 Terminating 2 2h
zk-0 0/1 Terminating 2 2h
zk-0 0/1 Terminating 2 2h
zk-0 0/1 Pending 0 0s
zk-0 0/1 Pending 0 0s
zk-0 0/1 ContainerCreating 0 0s
zk-0 0/1 Running 0 51s
zk-0 1/1 Running 0 1m
zk-1 1/1 Terminating 0 2h
zk-1 0/1 Terminating 0 2h
zk-1 0/1 Terminating 0 2h
zk-1 0/1 Terminating 0 2h
zk-1 0/1 Pending 0 0s
zk-1 0/1 Pending 0 0s
zk-1 0/1 Pending 0 12m
zk-1 0/1 ContainerCreating 0 12m
zk-1 0/1 Running 0 13m
zk-1 1/1 Running 0 13m
zk-2
๊ฐ ์ค์ผ์ค๋ ๋
ธ๋๋ฅผ ๋น์๋ณด์.
kubectl drain $(kubectl get pod zk-2 --template {{.spec.nodeName}}) --ignore-daemonsets --force --delete-emptydir-data
์ถ๋ ฅ์ ๋ค์๊ณผ ๋น์ทํ ๊ฒ์ด๋ค.
node "kubernetes-node-i4c4" already cordoned
WARNING: Deleting pods not managed by ReplicationController, ReplicaSet, Job, or DaemonSet: fluentd-cloud-logging-kubernetes-node-i4c4, kube-proxy-kubernetes-node-i4c4; Ignoring DaemonSet-managed pods: node-problem-detector-v0.1-dyrog
pod "heapster-v1.2.0-2604621511-wht1r" deleted
pod "zk-2" deleted
node "kubernetes-node-i4c4" drained
์ด๋ฒ์ kubectl drain
์ด ์ฑ๊ณตํ๋ค.
zk-2
๊ฐ ์ฌ์ค์ผ์ค๋๋๋ก ๋ ๋ฒ์งธ ๋
ธ๋์ ํต์ ๋ฅผ ํ์ด๋ณด์.
kubectl uncordon kubernetes-node-ixsl
์ถ๋ ฅ์ ๋ค์๊ณผ ๋น์ทํ ๊ฒ์ด๋ค.
node "kubernetes-node-ixsl" uncordoned
kubectl drain
์ PodDisruptionBudget
๊ณผ ๊ฒฐํฉํ๋ฉด ์ ์ง๋ณด์ ์ค์๋ ์๋น์ค๋ฅผ ๊ฐ์ฉํ๊ฒ ํ ์ ์๋ค.
drain์ผ๋ก ๋
ธ๋๋ฅผ ํต์ ํ๊ณ ์ ์ง๋ณด์๋ฅผ ์ํด ๋
ธ๋๋ฅผ ์คํ๋ผ์ธํ๊ธฐ ์ ์ ํ๋๋ฅผ ์ถ์ถํ๊ธฐ ์ํด ์ฌ์ฉํ๋ค๋ฉด
์๋น์ค๋ ํผ๋ ์์ฐ์ ํ๊ธฐํ ์๋น์ค๋ ๊ทธ ์์ฐ์ด ์กด์ค์ ์กด์ค๋ ๊ฒ์ด๋ค.
ํ๋๊ฐ ์ฆ๊ฐ์ ์ผ๋ก ์ฌ์ค์ผ์ค ํ ์ ์๋๋ก ํญ์ ์ค์ ์๋น์ค๋ฅผ ์ํ ์ถ๊ฐ ์ฉ๋์ ํ ๋นํด์ผ ํ๋ค.
์ ๋ฆฌํ๊ธฐ
kubectl uncordon
์ ํด๋ฌ์คํฐ ๋ด์ ๋ชจ๋ ๋ ธ๋๋ฅผ ํต์ ํด์ ํ๋ค.- ๋ฐ๋์ ์ด ํํ ๋ฆฌ์ผ์์ ์ฌ์ฉํ ํผ์์คํดํธ ๋ณผ๋ฅจ์ ์ํ ํผ์์คํดํธ ์คํ ๋ฆฌ์ง ๋ฏธ๋์ด๋ฅผ ์ญ์ ํ์. ๊ทํ์ ํ๊ฒฝ๊ณผ ์คํ ๋ฆฌ์ง ๊ตฌ์ฑ๊ณผ ํ๋ก๋น์ ๋ ๋ฐฉ๋ฒ์์ ํ์ํ ์ ์ฐจ๋ฅผ ๋ฐ๋ผ์ ๋ชจ๋ ์คํ ๋ฆฌ์ง๊ฐ ์ฌํ๋ณด๋๋๋ก ํ์.