25๋ ๋ AWS EKS Hands-on Study ์คํฐ๋ ์ ๋ฆฌ ๋ด์ฉ์ ๋๋ค.
๋ณผ๋ฅจ
์ฟ ๋ฒ๋คํฐ์ค์์ ๋ณผ๋ฅจ์ ์ปจํ
์ด๋๊ฐ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅ๋๋ ๊ณต๊ฐ์ด๋ฉฐ ํ๋์ ์๋ช
์ฃผ๊ธฐ ๋์ ์ ์ง๋๋ค.
ํ๋ ๋ด ์ฌ๋ฌ ์ปจํ
์ด๋๊ฐ ๋์ผ ๋ณผ๋ฅจ์ ๊ณต์ ํ ์ ์๊ณ , ํ๋๊ฐ ์ญ์ ๋๋ฉด ๋ณผ๋ฅจ๋ ํจ๊ป ์ญ์ ๋๋ค.
emptyDir
# ๋ ๋์ค ํ
์คํธ ํ๋ ์์ฑ
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: redis
spec:
terminationGracePeriodSeconds: 0
containers:
- name: redis
image: redis
EOF
pod/redis created
kubectl get po -A
NAMESPACE NAME READY STATUS RESTARTS AGE
default redis 0/1 ContainerCreating 0 5s
# ํ
์คํธ ๋ฐ์ดํฐ ์์ฑ
kubectl exec -it redis -- sh -c "echo hello > /data/hello.txt"
kubectl exec -it redis -- cat /data/hello.txt
hello
# ํ๋ ํฌ
kubectl exec -it redis -- kill 1
kubectl get po
NAME READY STATUS RESTARTS AGE
redis 1/1 Running 1 (10s ago) 10s
# ์ฌ๋ผ์ง ๋ฐ์ดํฐ ํ์ธ
kubectl exec -it redis -- cat /data/hello.txt
cat: /data/hello.txt: No such file or directory
kubectl exec -it redis -- ls -l /data
command terminated with exit code 1
total 0
์์์ ๋ ๋์ค ํ๋๋ฅผ ์์ฑ ํ ์ฌ๋ ธ๋ค kill ํ๊ฒ ๋๋ฉด ํ๋๊ฐ ์ฌ์์๋๋ค.
์๋ํ๋ฉด ํ๋๊ฐ ์ข
๋ฃ ์์ฒญ์ด ๋ค์ด์ค๋ฉด terminationGracePeriodSeconds: 0์ด๊ธฐ ๋๋ฌธ์ ์ฆ์ ์ข
๋ฃ๋๊ณ , restartPolicy๊ฐ ๊ธฐ๋ณธ๊ฐ์ Always๋ก ์ค์ ๋์ด ์์ผ๋ฏ๋ก ํ๋ก์ธ์ค๊ฐ ์ข
๋ฃ๋์๋ง์ ๋ค์ ํ๋๊ฐ ์ฌ์์๋๋ฉด์ ๊ธฐ์กด ์ปจํ
์ด๋๊ฐ ์ญ์ ๋๊ณ ์๋ก์ด ์ปจํ
์ด๋๊ฐ ์์ฑ๋๋ฉด์ ํ์ผ์์คํ
์ด ์ด๊ธฐํ๋๋ค. ๊ทธ๋์ ์ด์ ์ปจํ
์ด๋ ์์์ ๋ง๋ค์๋ hello.txt ํ์ผ์ด ๋ ์๊ฐ ๊ฒ์ ํ์ธํ ์ ์๋ค.
hostPath
hostPath๋ ํธ์คํธ ๋
ธ๋์ ํน์ ๋ก์ปฌ ๋๋ ํฐ๋ฆฌ๋ฅผ ๋ง์ดํธํ์ฌ ํ๋ ๋ด๋ถ์์ ์ง์ ์ฌ์ฉํ ์ ์๋ ๋ฐฉ์์ด๋ค.
๋ฐ๋ผ์ ์ปจํ
์ด๋๊ฐ ์ข
๋ฃ๋์ด๋ ํ๋๊ฐ ์ญ์ ๋์ง ์๋ ์ด์ ๋ฐ์ดํฐ๊ฐ ์ ์ง๋๋ฉฐ ๋ก์ปฌ ๋์คํฌ๋ฅผ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ๊ฐ์ ๋
ธ๋์ ํ๋๊ฐ ๋์ด์ง ๊ฒฝ์ฐ, ๊ทธ ํ๋๊ฐ์ ๋์ผํ ๋ฐ์ดํฐ ์ ๊ทผ์ด ๊ฐ๋ฅํ๋ค.
ํ์ง๋ง ํ๋๊ฐ ํน์ ๋
ธ๋์ ๋์ฐ๋๋ก ์ค์ผ์ค๋ง ํด์ผํ๋ค.
1๋ฒ ์์ปค ๋
ธ๋ ๋ก์ปฌ ๋์คํฌ ๊ฒฝ๋ก๋ก ํ
์คํธํด๋ณธ๋ค.
apiVersion: v1
kind: Pod
metadata:
name: hostpath-test
spec:
nodeSelector:
kubernetes.io/hostname: 1๋ฒ ์์ปค๋
ธ๋
containers:
- name: busybox
image: busybox
command: ["sleep", "3600"]
volumeMounts:
- mountPath: "/mnt/data"
name: my-volume
volumes:
- name: my-volume
hostPath:
path: "/data"
type: DirectoryOrCreate
ํ๋๋ฅผ ์์ปค ๋
ธ๋ 1๋ฒ์ ๊ณ ์ ํ๊ธฐ ์ํด ๋
ธ๋์
๋ ํฐ๋ฅผ ์ฌ์ฉํ๋ค.
1๋ฒ ๋
ธ๋์ /data ๋๋ ํฐ๋ฆฌ๋ฅผ ์ปจํ
์ด๋ ๋ด๋ถ /mnt/data์ ๋ง์ดํธํ๋๋ก ์ ์ํ๋ค.
k get po
NAME READY STATUS RESTARTS AGE
hostpath-test 1/1 Running 0 8s
kubectl exec -it hostpath-test -- sh
/ # echo "hostPath test" > /mnt/data/test.txt
/ # cat /mnt/data/test.txt
hostPath test
ํ๋์์ ๋ฐ์ดํฐ๋ฅผ ์ฐ๊ณ 1๋ฒ ์์ปค ๋
ธ๋์์ ํ์ธํ๋ฉด
[ec2-user@1๋ฒ ์์ปค๋
ธ๋ ~]$ ls -l /data/
total 4
-rw-r--r--. 1 root root 14 Feb 17 17:07 test.txt
# ํ๋ ์ญ์
kubectl delete pod hostpath-test
pod "hostpath-test" deleted
[ec2-user@1๋ฒ ์์ปค๋
ธ๋ ~]$ ls -l /data/
total 4
-rw-r--r--. 1 root root 14 Feb 17 17:07 test.txt
์ปจํ
์ด๋์์ ์ด ๋ฐ์ดํฐ๊ฐ ์์ปค ๋
ธ๋์์๋ ํ์ธ๋๋ ๊ฒ์ ๋ณผ ์ ์๋ค. ์ด๋ ๊ฒ ์ธ ๊ฒฝ์ฐ ํ๋๋ฅผ ์ง์๋ ํธ์คํธ์์ ๋ฐ์ดํฐ๊ฐ ์ ์ง๋๋ค.
hostPath์ ๊ฒฝ์ฐ์๋ ์ด๋ ๊ฒ pv๋ฅผ ์ง์ ๋ง๋ค์ด์ผ ๋๋ ๊ตฌ์กฐ์ด๋ฏ๋ก ๋์ ์ผ๋ก ํ ๋น์ด ์๋๋ค.
Local path provisioner
๊ทธ๋ ๋ค๋ฉด ํธ์คํธ ๋ ธ๋์ ๋ก์ปฌ ๋์คํฌ๋ฅผ ๋์ ์ผ๋ก ํ ๋นํ์ฌ ๋ณผ๋ฅจ์ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ๋ํ ๋ด์ฉ์ด local path provisioner์ด๋ค.
kubectl apply -f https://raw.githubusercontent.com/rancher/local-path-provisioner/v0.0.31/deploy/local-path-storage.yaml
kubectl get pod -n local-path-storage -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
local-path-provisioner-84967477f-7bg7g 1/1 Running 0 2m37s 192.168.1.201 ip-[์์ปค๋
ธ๋].ap-northeast-2.compute.internal <none> <none>
kubectl describe cm -n local-path-storage local-path-config
Name: local-path-config
Namespace: local-path-storage
Labels: <none>
Annotations: <none>
Data
====
config.json:
----
{
"nodePathMap":[
{
"node":"DEFAULT_PATH_FOR_NON_LISTED_NODES",
"paths":["/opt/local-path-provisioner"]
}
]
}
helperPod.yaml:
----
apiVersion: v1
kind: Pod
metadata:
name: helper-pod
spec:
priorityClassName: system-node-critical
tolerations:
- key: node.kubernetes.io/disk-pressure
operator: Exists
effect: NoSchedule
containers:
- name: helper-pod
image: busybox
imagePullPolicy: IfNotPresent
setup:
----
#!/bin/sh
set -eu
mkdir -m 0777 -p "$VOL_DIR"
teardown:
----
#!/bin/sh
set -eu
rm -rf "$VOL_DIR"
BinaryData
====
Events: <none>
kubectl get sc
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
gp2 kubernetes.io/aws-ebs Delete WaitForFirstConsumer false 29h
local-path rancher.io/local-path Delete WaitForFirstConsumer false 3m47s
kubectl get sc local-path
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
local-path rancher.io/local-path Delete WaitForFirstConsumer false 3m55s
๊ทธ๋ฌ๋ฉด ์ด์ ์ฌ๊ธฐ์ pvc, ํ๋๋ฅผ ์์ฑํด๋ณด๋ฉด...
# pvc
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: localpath-claim
spec:
accessModes:
- ReadWriteOnce
storageClassName: local-path
resources:
requests:
storage: 1Gi
EOF
kubectl get pv
Normal WaitForFirstConsumer 13s (x3 over 42s) persistentvolume-controller waiting for first consumer to be created before binding
pvc๊ฐ ์์ฑ๋์ง๋ง ์์ง pv์ ๋ฐ์ธ๋ฉ๋์ง ์์ ์ํ์ธ๋ฐ ์ด๋ ํ๋๊ฐ ์์ฑ๋ ๋๊น์ง ๋๊ธฐํ๋ ์ํ์ด๋ค.
ํ๋๊ฐ ์คํ๋ ๋
ธ๋์์๋ง pv๋ฅผ ํ ๋นํ๊ธฐ ์ํด ๊ธฐ๋ค๋ฆฌ๋ ๊ฒ์ด๋ผ ๋ณผ ์ ์๋ค.
# ํ๋
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: app
spec:
terminationGracePeriodSeconds: 3
containers:
- name: app
image: centos
command: ["/bin/sh"]
args: ["-c", "while true; do echo \$(date -u) >> /data/out.txt; sleep 5; done"]
volumeMounts:
- name: persistent-storage
mountPath: /data
volumes:
- name: persistent-storage
persistentVolumeClaim:
claimName: localpath-claim
EOF
ํ๋๋ฅผ ์์ฑํด์ฃผ๊ณ ๋๋ฉด
kubectl get pod,pv,pvc
NAME READY STATUS RESTARTS AGE
pod/app 1/1 Running 0 5m44s
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE
persistentvolume/pvc-55aa6c67-5fc5-4994-a2ea-c005a89f0482 1Gi RWO Delete Bound default/localpath-claim local-path <unset> 5m41s
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE
persistentvolumeclaim/localpath-claim Bound pvc-55aa6c67-5fc5-4994-a2ea-c005a89f0482 1Gi RWO local-path <unset>
kubectl describe pv
...
Node Affinity:
Required Terms:
Term 0: kubernetes.io/hostname in [ip-1๋ฒ ์์ปค๋
ธ๋.ap-northeast-2.compute.internal]
Message:
Source:
Type: HostPath (bare host directory volume)
Path: /opt/local-path-provisioner/pvc-55aa6c67-5fc5-4994-a2ea-c005a89f0482_default_localpath-claim
HostPathType: DirectoryOrCreate
...
pv์ pvc๊ฐ ํ ๋น(Bound)๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
pvc๊ฐ ๋ฐ์ธ๋ฉ๋ ๋ local path provisioner๊ฐ ์๋์ผ๋ก pv๋ฅผ ์์ฑํ๋๋ฐ ์ด pv๋ ์์ปค ๋
ธ๋์์๋ง ์ฌ์ฉ ๊ฐ๋ฅํ๊ณ ์ค์ ์์ปค ๋
ธ๋์ ๋ง์ดํธ๋ ๊ฒฝ๋ก์ด๋ค.
kubectl exec -it app -- tail -f /data/out.txt
Mon Feb 17 17:33:43 UTC 2025
Mon Feb 17 17:33:48 UTC 2025
Mon Feb 17 17:33:53 UTC 2025
Mon Feb 17 17:33:58 UTC 2025
Mon Feb 17 17:34:03 UTC 2025
Mon Feb 17 17:34:08 UTC 2025
Mon Feb 17 17:34:13 UTC 2025
Mon Feb 17 17:34:18 UTC 2025
Mon Feb 17 17:34:23 UTC 2025
Mon Feb 17 17:34:28 UTC 2025
Mon Feb 17 17:34:33 UTC 2025
Mon Feb 17 17:34:38 UTC 2025
[ec2-user@์์ปค๋
ธ๋ ~]$ sudo ls /opt/local-path-provisioner/
pvc-55aa6c67-5fc5-4994-a2ea-c005a89f0482_default_localpath-claim
์ปจํ
์ด๋์์ ๋ก๊ทธ ์ฐ๊ณ ์์ปค๋
ธ๋์์ ๋ค์ด๊ฐ๋ณด๋ฉด ์ค์ ๋ก ๋ฐ์ดํฐ๊ฐ ์ ์ฅ๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
kubectl delete pod app
pod "app" deleted
kubectl get pod,pv,pvc
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE
persistentvolume/pvc-55aa6c67-5fc5-4994-a2ea-c005a89f0482 1Gi RWO Delete Bound default/localpath-claim local-path <unset> 10m
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE
persistentvolumeclaim/localpath-claim Bound pvc-55aa6c67-5fc5-4994-a2ea-c005a89f0482 1Gi RWO local-path <unset> 10m
# ํ๋ ์ฌ์์ฑ ํ~
kubectl exec -it app -- head /data/out.txt
kubectl exec -it app -- tail -f /data/out.txt
Mon Feb 17 17:27:07 UTC 2025
Mon Feb 17 17:27:12 UTC 2025
Mon Feb 17 17:27:17 UTC 2025
Mon Feb 17 17:27:22 UTC 2025
Mon Feb 17 17:27:27 UTC 2025
Mon Feb 17 17:27:32 UTC 2025
Mon Feb 17 17:27:37 UTC 2025
Mon Feb 17 17:27:42 UTC 2025
Mon Feb 17 17:27:47 UTC 2025
Mon Feb 17 17:27:52 UTC 2025
Mon Feb 17 17:36:18 UTC 2025
Mon Feb 17 17:36:23 UTC 2025
Mon Feb 17 17:36:28 UTC 2025
Mon Feb 17 17:36:33 UTC 2025
Mon Feb 17 17:36:38 UTC 2025
Mon Feb 17 17:36:43 UTC 2025
Mon Feb 17 17:36:48 UTC 2025
Mon Feb 17 17:36:53 UTC 2025
Mon Feb 17 17:38:52 UTC 2025
Mon Feb 17 17:38:57 UTC 2025
ํ๋๋ฅผ ์ญ์ ํ๋๋ผ๋ pvc๋ ๊ทธ๋๋ก ์ ์ง๋๋ฏ๋ก pv๋ ๊ทธ๋๋ก ์๋ ์ํ์์ ํ์ธํ ์ ์๋ค.
pvc๊ฐ ์ญ์ ๋์ด ์์ง ์์ผ๋ฏ๋ก ํ๋๋ฅผ ๋ค์ ๋์์ ๋ณด๋ฉด ๋ฐ์ดํฐ๊ฐ ๊ทธ๋๋ก ์๊ณ ๊ณ์ ์ถ๊ฐํด๋๊ฐ๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
๋ฐ๋ผ์ local path provisioner๊ฐ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅ ๊ณผ์ ์ ์ ๋ฆฌํ๋ฉด, pvc๊ฐ ๋ฐ์ธ๋ฉ๋ ๋ local path provisioner๊ฐ ์๋์ผ๋ก pv๋ฅผ ์์ฑํ๋ค. ๊ทธ๋ฆฌ๊ณ pv๋ ํน์ ์์ปค ๋
ธ๋์์๋ง ์ฌ์ฉ ๊ฐ๋ฅํ๋ฉฐ ์ค์ ๋
ธ๋์ ๋ง์ดํธ๋ ๋๋ ํฐ๋ฆฌ ๊ฒฝ๋ก๋ฅผ ์ฌ์ฉํ๋ค.