목차 |
---|
...
1. Resource Policies
2.1 Request / Limit (최소요구사항/최대 사용량)
쿠버네티스에서 파드를 어느 노드에 배포할지 스케쥴링 할 때, 스케쥴링이 될 노드에 해당 파드가 동작할 수 있는 충분한 자원이 확보가 되어야 합니다.
쿠버네티스에서 파드(컨테이너)에 필요한 리소스 양을 명시 할 수 있도록 설정을 지원합니다.
cpu/memory와 같은 컴퓨트 리소스 외에도 gpu/storage 리소스에 대한 쿼터도 지정 할 수 있습니다.
CPU는 m(밀리코어, 1코어=1000밀리코어) 단위로 지정하며, 해당 컨테이너에 어느정도의 CPU를 할당할 것인지를 지정합니다.
메모리는 Mi(Mib)를 사용합니다.
8/00-pod-resource.yaml
코드 블럭 |
---|
--- apiVersion: v1 kind: Pod metadata: name: frontend spec: containers: - name: app image: images.my-company.example/app:v4nginx:latest resources: requests: memory: "64Mi" cpu: "250m" limits: memory: "128Mi" cpu: "500m" - name: log-aggregator image: images.my-company.examplerancher/log-aggregator:v6v0.1.8 resources: requests: memory: "64Mi" cpu: "250m" limits: memory: "128Mi" cpu: "500m" |
...
코드 블럭 |
---|
root@k8s-master01:~# kubectl -n kube-system top pod | sort -n -k 2 NAME CPU(cores) MEMORY(bytes) nginx-proxy-k8s-worker01 1m 16Mi nginx-proxy-k8s-worker02 1m 17Mi dns-autoscaler-59b8867c86-hjkvs 2m 7Mi kube-controller-manager-k8s-master02 4m 19Mi kube-controller-manager-k8s-master03 4m 19Mi nodelocaldns-rdkbl 4m 15Mi coredns-588bb58b94-9qcvw 5m 16Mi kube-scheduler-k8s-master02 5m 20Mi nodelocaldns-sd99v 5m 10Mi coredns-588bb58b94-zcnvc 6m 14Mi kube-proxy-h584h 7m 22Mi kube-scheduler-k8s-master03 7m 19Mi nodelocaldns-9vlvr 7m 9Mi nodelocaldns-b8gpm 7m 9Mi metrics-server-6f77f96b88-v5jjs 8m 17Mi nodelocaldns-r4sjf 8m 16Mi kube-scheduler-k8s-master01 9m 21Mi kube-proxy-x8gcq 12m 22Mi calico-kube-controllers-75748cc9fd-gqdzw 13m 21Mi kube-proxy-w87v4 13m 15Mi kube-proxy-96tsm 20m 15Mi kube-proxy-tj8pv 24m 14Mi kube-controller-manager-k8s-master01 36m 52Mi calico-node-87g22 42m 85Mi calico-node-kk5vn 51m 84Mi calico-node-wckv7 51m 85Mi calico-node-8278d 64m 91Mi etcd-k8s-master02 70m 89Mi calico-node-4hzx4 71m 109Mi kube-apiserver-k8s-master02 77m 303Mi etcd-k8s-master03 81m 84Mi kube-apiserver-k8s-master01 94m 349Mi etcd-k8s-master01 99m 95Mi kube-apiserver-k8s-master03 111m 310Mi |
2.2 ResourceQuota
쿠버네티스 운영 시 특정 팀에서 많은 리소스를 요구할 경우 ResourceQuota를 이용하여 네임스페이스별로 사용할 수 있는 리소스의 양을 정하고, 컨테이너 마다 사용 할 수 있는 양을 지정할 수 있습니다.
...
쿼터 오브젝트를 생성하여 특정 우선 순위의 파드와 일치 시키며, "low(낮음)", "medium(중간)", "high(높음)"의 세 가지 우선 순위 클래스 중 하나를 가질 수도 있습니다.
...
8/01-resourcequota.yaml
코드 블럭 |
---|
--- apiVersion: v1 kind: ResourceQuota metadata: name: default spec: hard: cpu: "1000" memory: 200Gi pods: "10" # scopeSelector: # matchExpressions: # - operator : In # scopeName: PriorityClass # values: ["high"] |
8/02-resourcequota-test.yaml
코드 블럭 |
---|
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.19
ports:
- containerPort: 80
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m" |
코드 블럭 |
---|
root@k8s-master01:~# kubectl get pod NAME READY STATUS RESTARTS AGE nginx-deployment-5bccc488d-bqkvz 1/1 Running 0 18h nginx-deployment-5bccc488d-r4s5d 1/1 Running 0 18h nginx-deployment-5bccc488d-z29wp 1/1 Running 0 18h root@k8s-master01:~# kubectl get quota NAME AGE REQUEST LIMIT default 32s cpu: 750m/1k, memory: 192Mi/200Gi, pods: 3/10 |
2.3 LimitRange
...
ResourceQuota를 사용하면 네임스페이스의 리소스를 제한하고, LimitRange는 네임스페이스 내 파드(컨테이너)의 리소스를 제한합니다.
...
코드 블럭 |
---|
...
# k delete quota/default |
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
코드 블럭 |
---|
root@k8s-master01:~# cat LimitRange.yaml apiVersion: v1 kind: LimitRange metadata: name: cpu-min-max-demo-lr namespace: default spec: │INGW64 ~/project/2024 resourcequota "default" deleted |
2.3 LimitRange
ResourceQuota를 사용하면 네임스페이스의 리소스를 제한하고, LimitRange는 네임스페이스 내 파드(컨테이너)의 리소스를 제한합니다.
사용자가 컨테이너 리소스를 너무 크게 사용하면 특정 컨테이너가 많은 리소스를 점유하는 것을 방지할 수 있기 때문에 LimitRange를 사용합니다.
8/03-limitrange.yaml
코드 블럭 |
---|
apiVersion: v1 kind: LimitRange metadata: name: cpu-min-max-demo-lr namespace: default spec: limits: - max: cpu: "800m" min: cpu: "200m" type: Pod #Container |
...
8/04-limitrange-test.yaml
코드 블럭 |
---|
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.19
ports:
- containerPort: 80
resources:
requests:
memory: "64Mi"
cpu: "1000m"
limits:
memory: "128Mi"
cpu: "1500m" |
경고 |
---|
# kubectl get event --sort-by='lastTimestamp' |
2. Label & Selector
Label
Label은 Pod와 같은 객체에 연결된 키/값 쌍입니다.
리소스를 논리적인 그룹으로 나누거나, 식별의 편의를 위해 붙이는 이름표입니다.
Label은 생성 시 객체에 첨부할 수 있으며 나중에 언제든지 추가 및 수정할 수 있습니다.
Selector
특정 Label에 해당하는 객체를 식별하고 검색할 수 있습니다.
2.1 Node Label
...
코드 블럭 |
---|
# |
...
k |
...
2.2 Pod Selector
pod-label.yml
...
delete limitrange/cpu-min-max-demo-lr |
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
|
...
│INGW64 |
...
~/project/2024 limitrange "cpu-min-max-demo-lr" deleted |
...
# k delete |
...
3. 쿠버네티스 볼륨
PV(PersistentVolume): PV는 관리자가 프로비저닝했거나 스토리지 클래스를 사용해 동적으로 프로비저닝한 클러스터의 스토리지입니다. PV는 볼륨과 같은 볼륨 플러그인이지만 PV를 사용하는 개별 Pod와 독립적인 수명 주기를 가집니다.
PVC(PersistentVolumeClaim): PVC는 사용자가 볼륨을 사용하기 위해 PV에 하는 스토리지 요청입니다. Pod와 유사하게 Pod는 노드 리소스를 소비하고, PVC는 PV 리소스를 소비합니다.
3.1 PV의 Lifecycle
...
(1) Provisioning
PV를 생성하는 단계로 프로비저닝 방법에는 두 가지가 있습니다.
정적 프로비저닝
정적 프로비저닝은 클러스터 관리자가 미리 적정 용량의 PV를 만들어 두고 사용자의 요청이 있을 시 미리 만들어 둔 PV를 할당하는 방식입니다.
사용할 수 있는 스토리지 용량에 제한이 있을 때 유용합니다.
동적 프로비저닝
동적 프로비저닝은 사용자가 PVC를 거쳐서 PV를 요청했을 때 생성해 제공합니다.
클러스터에 사용자가 원하는 만큼의 스토리지 용량이 있다면, 원하는 용량만큼을 생성해서 사용할 수 있습니다.
(2) Binding
바인딩은 프로비저닝으로 생성된 PV를 PVC와 연결하는 단계입니다. PVC에서 원하는 스토리지 용량과 접근방법을 명시해서 용청하면 거기에 맞는 PV가 할당됩니다. PV와 PVC의 매핑은 1대1 관계입니다.
(3) Using
PVC는 Pod에 설정되고, Pod는 PVC를 볼륨으로 인식해서 사용합니다. 클러스터는 PVC를 확인하여 바인딩된 PV를 찾고 해당 볼륨을 Pod에서 사용할 수 있도록 해줍니다. 할당된 PVC는 파드를 유지하는 동안 계속 사용되며, 시스템에서 임의로 삭제할 수 없습니다.
(4) Reclaiming
사용이 끝난 PVC는 삭제되고, PV를 초기화(reclaim)하는 과정을 거칩니다. PV는 기존에 사용했던 PVC가 아니더라도 다른 PVC로 재활용이 가능합니다.
PV 초기화 정책
Retain: PV의 데이터를 그대로 보존합니다.
Recycle: 재사용하게 될 경우 기존의 PV 데이터들을 모두 삭제 후 재사용합니다.
Delete: 사용이 종료되면 해당 볼륨을 삭제합니다.
3.2 PV 생성
...
-f 04-limitrange-test.yaml │
deployment.apps "nginx-deployment" deleted |
...
2. Label & Selector
쿠버네티스 스케줄링에 포함된 내용입니다.
노드-파드도 Label&Selector를 이용하여 노드의 리소스 관리를 할 수 있고, 서비스-파드도 Label&Selector를 이용하여 엔드포인트를 지정합니다.
Label
Label은 Pod와 같은 객체에 연결된 키/값 쌍입니다.
리소스를 논리적인 그룹으로 나누거나, 식별의 편의를 위해 붙이는 이름표입니다.
Label은 생성 시 객체에 첨부할 수 있으며 나중에 언제든지 추가 및 수정할 수 있습니다.
Selector
특정 Label에 해당하는 객체를 식별하고 검색할 수 있습니다.
2.1 Node Label
코드 블럭 |
---|
# Node Label 확인
kubectl get nodes --show-labels
# Node Label 추가
kubectl label nodes w1-k8s svc=web |
2.2 Pod Selector
8/05-pod-selector.yaml
코드 블럭 |
---|
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
env: test
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
nodeSelector:
svc: web |
코드 블럭 |
---|
8# k get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
frontend 2/2 Running 2 (3h3m ago) 4h50m 172.16.132.5 w3-k8s <none> <none>
nfs-client-provisioner-5cf87f6995-rdkfr 1/1 Running 40 (14m ago) 14h 172.16.221.136 w1-k8s <none> <none>
nginx 1/1 Running 0 5m3s 172.16.221.140 w1-k8s <none> <none> |
...
3. 쿠버네티스 볼륨
지금까지 우리는 많은 실습을 통해 Pod를 배포하고 Service를 만들어 접속 할 수 있게 되었습니다.
이번 장 에서는 Pod에 사용하는 여러가지 Volume 종류에 대해 알아보고 실습 해 봅니다.
기본적으로 pod의 모든 내용은 휘발성이며 pod가 삭제되거나 재배치되면 데이터도 사라집니다.
이러한 데이터의 유지를 위하여 volume을 사용 합니다.
3.1 emptyDir
emptyDir 볼륨은 파드가 노드에 할당될 때 처음 생성되며, 해당 노드에서 파드가 실행되는 동안에만 존재합니다.
이름에서 알 수 있듯이 emptyDir 볼륨은 처음에는 비어있습니다.
파드 내 모든 컨테이너는 emptyDir 볼륨에서 동일한 파일을 읽고 쓸 수 있지만, 해당 볼륨은 각각의 컨테이너에서 동일하거나 다른 경로에 마운트 될 수 있습니다.
노드에서 파드가 제거되면 emptyDir 의 데이터가 영구적으로 삭제됩니다.
emptyDir은 주로 Pod내부에서 실행 중인 애플리케이션 간의 휘발성 파일을 공유할 때 유용하게 사용 됩니다.
공유가 필요 없는 볼륨이라면 굳이 emptyDir를 사용 할 필요는 없습니다 명시하지 않은 모든 볼륨의 데이터는 휘발성입니다 (이미지에 존재하지 않는 mountpath생성을 위한 용도로는 사용할 될 수 있습니다)
참고: 컨테이너가 크래시되는 것은 노드에서 파드를 제거하지 않습니다. emptyDir 볼륨의 데이터는 컨테이너 크래시로부터 안전합니다.
(1) emptyDir를 가지는 파드의 yaml 파일을 작성합니다.
nginx pod내 empytidir 을 /cache볼륨으로 마운트 하는 yaml입니다
8/06-volume-emptydir.yaml
코드 블럭 | ||
---|---|---|
| ||
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-vol-1
labels:
app: nginx-vol-1
spec:
replicas: 1
selector:
matchLabels:
app: nginx-vol-1
template:
metadata:
labels:
app: nginx-vol-1
spec:
containers:
- name: nginx-vol-1
image: nginx
ports:
- containerPort: 80
volumeMounts:
- name: cache-volume
mountPath: /cache
volumes:
- name: cache-volume
emptyDir: {} |
해당 yaml 파일을 적용하여 파드를 생성하여 마운트 상태를 확인합니다.
코드 블럭 | ||
---|---|---|
| ||
[root@m-k8s vagrant]# k apply -f 06-volume-emptydir.yaml
deployment.apps/nginx-vol-1 created
[root@m-k8s vagrant]# k get pods
NAME READY STATUS RESTARTS AGE
nginx-vol-1-77d6454655-xscpd 1/1 Running 0 38s
위와같이 Running 상태가 되면 pod내 볼륨이 정상적으로 mount되었는지 확인 합니다
[root@m-k8s vagrant]# k exec -it nginx-vol-1-77d6454655-xscpd -- df -h
Filesystem Size Used Avail Use% Mounted on
overlay 37G 5.4G 32G 15% /
tmpfs 64M 0 64M 0% /dev
tmpfs 1.5G 0 1.5G 0% /sys/fs/cgroup
/dev/mapper/centos_k8s-root 37G 5.4G 32G 15% /cache
shm 64M 0 64M 0% /dev/shm
tmpfs 2.9G 12K 2.9G 1% /run/secrets/kubernetes.io/serviceaccount
tmpfs 1.5G 0 1.5G 0% /proc/acpi
tmpfs 1.5G 0 1.5G 0% /proc/scsi
tmpfs 1.5G 0 1.5G 0% /sys/firmware
# 마운트 확인
/dev/mapper/centos_k8s-root 37G 5.4G 32G 15% /cache 가 정상적으로 마운트 되었습니다
/dev/mapper/centos_k8s-root은 worker node의 root disk입니다
[root@cp-k8s mapper]# ssh vagrant@w1-k8s
vagrant@w1-k8s's password:
[vagrant@w1-k8s ~]$ ls -al /dev/mapper/centos_k8s-root
lrwxrwxrwx. 1 root root 7 Sep 12 13:49 /dev/mapper/centos_k8s-root -> ../dm-0
# 파일을 쓰고 파드를 삭제하여 데이터가 존재하는지 확인 합니다
[root@m-k8s mapper]# k get pods
NAME READY STATUS RESTARTS AGE
nginx-vol-1-77d6454655-xscpd 1/1 Running 0 4m34s
[root@m-k8s mapper]# k exec -it nginx-vol-1-77d6454655-xscpd -- bash -c "echo 'test' > /cache/test.txt "
[root@m-k8s mapper]# k exec -it nginx-vol-1-77d6454655-xscpd -- ls -al /cache
total 4
drwxrwxrwx. 2 root root 22 Sep 13 00:33 .
drwxr-xr-x. 1 root root 52 Sep 13 00:28 ..
-rw-r--r--. 1 root root 5 Sep 13 00:33 test.txt
[root@m-k8s vagrant]# k get pod
NAME READY STATUS RESTARTS AGE
nginx-vol-1-77d6454655-xscpd 1/1 Running 0 8s
[root@m-k8s vagrant]# k delete pod/nginx-vol-1-77d6454655-xscpd
pod "nginx-vol-1-77d6454655-xscpd" deleted
# deploy로 pod가 재배포 되길 기다립니다
[root@m-k8s vagrant]# k get pod
NAME READY STATUS RESTARTS AGE
nginx-vol-1-77d6454655-fd9tg 1/1 Running 0 6s
# 새로운 pod가 배포 되었습니다
# 이후 해당 pod에 마운트된 /cache볼륨에 이전에 생성한 파일이 남아있는지 확인 합니다.
[root@m-k8s vagrant]# kubectl exec -it nginx-vol-1-77d6454655-fd9tg -- ls -al /cache
total 0
drwxrwxrwx. 2 root root 6 Sep 13 02:01 .
drwxr-xr-x. 1 root root 52 Sep 13 02:01 ..
이전에 만든 test.txt가 존재하지 않습니다(Pod가 제거되면 emptydir속성의 볼륨도 삭제)
# 다음 실습을 위해 환경을 정리 합니다.
[root@m-k8s vagrant]# k delete -f 06-volume-emptydir.yaml
deployment.apps "nginx-vol-1" deleted
|
(2) 멀티 컨테이너를 가지는 파드에서의 emptyDir 볼륨 파일공유를 확인합니다.
8/07-volume-emptydir-multicon.yaml
코드 블럭 | ||
---|---|---|
| ||
---
apiVersion: v1
kind: Pod
metadata:
name: nginx-vol-2
spec:
containers:
- image: nginx
name: nginx
volumeMounts:
- name: cache-volume
mountPath: /cache
readOnly: true #cache 디렉토리를 read only로 마운트 한다
- image: luksa/fortune
name: fortune
volumeMounts:
- name: cache-volume
mountPath: /cache
volumes:
- name: cache-volume |
생성 된 yaml을 적용하여 pod를 생성합니다.
코드 블럭 | ||
---|---|---|
| ||
kubectl apply -f 07-volume-emptydir-multicon.yaml
pod/nginx-vol-2 created
kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx-vol-2 2/2 Running 0 8s
# 확인하면 포드내 컨테이너가 2개로 보입니다
# 생성된 컨테이너를 확인합니다
# 컨테이너가 2개 이상인경우 get pod 명령어를 활용해서 컨테이너를 식별하고 제어하지 못합니다.
$ kubectl describe pod/nginx-vol-2
......
Containers:
nginx:
Container ID: containerd://a9eac4ae13b2a8f052fe9bf6eca53c93e95c0de7ce4352cf1e77a0c4d2e1c5bb
Image: nginx
Image ID: docker.io/library/nginx@sha256:6926dd802f40e5e7257fded83e0d8030039642e4e10c4a98a6478e9c6fe06153
Port: <none>
Host Port: <none>
State: Running
Started: Wed, 13 Sep 2023 11:05:21 +0900
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/cache from cache-volume (ro)
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-pjccg (ro)
fortune:
Container ID: containerd://6e343b738170e0b1d0b0fa18fe641c0cd0b1257ae3cab9d7fc75fff041f09084
Image: luksa/fortune
Image ID: docker.io/luksa/fortune@sha256:814dd72ecc4b431560ca6ede8649fc4862c401ba5b6d37520e6672e0657deea9
Port: <none>
Host Port: <none>
State: Running
Started: Wed, 13 Sep 2023 11:05:33 +0900
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/cache from cache-volume (rw)
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-pjccg (ro)
Volumes:
cache-volume:
Type: EmptyDir (a temporary directory that shares a pod's lifetime)
Medium:
SizeLimit: <unset>
# 두번째 yml을 보면 volume type을 EmptyDir로 선언하는것을 생략하였습니다 아무런 type이 없으면 기본값으로 EmptyDir를 사용 하게 됩니다
.....
# nginx와 fortune 2개의 컨테이너가 생성된것을 확인 할수 있습니다
# rw로 마운트된 fortune에서 파일을 생성하고 nginx컨테이너에서 파일을 볼수 있는지 실습 해봅시다
# pod내 컨테이너 선택은 -c옵션을 이용합니다
# fortune 컨테이너에서 만든 파일을 같은 pod내에 있는 nginx컨테이너테서 확인 할 수 있습니다.
[root@m-k8s vagrant]# kubectl exec nginx-vol-2 -c fortune -- bash -c ' echo "test" > /cache/test.txt '
[root@m-k8s vagrant]# kubectl exec nginx-vol-2 -c fortune -- ls -l /cache
total 4
-rw-r--r--. 1 root root 5 Sep 13 02:19 test.txt
[root@m-k8s vagrant]# kubectl exec nginx-vol-2 -c nginx -- ls -l /cache
total 4
-rw-r--r--. 1 root root 5 Sep 13 02:19 test.txt
# 아래와 같이 nginx는 ro권한밖에 없으므로, 실제 write는 불가능합니다.
[root@m-k8s vagrant]# kubectl exec nginx-vol-2 -c nginx -- bash -c 'echo "test" > /cache/test2.txt'
bash: line 1: /cache/test2.txt: Read-only file system
command terminated with exit code 1
# 실습환경을 정리합니다.
kubectl delete -f 07-volume-emptydir-multicon.yaml
pod "nginx-vol-2" deleted
*기본적으로 emptydir은 worker노드에 디스크(파일시스템)에 생성되지만 상황에따라 memory나 fc disk등에 생성 할 수도 있습니다. |
3.2 hostpath
hostPath 볼륨은 호스트 노드의 파일시스템에 있는 파일이나 디렉터리를 파드에 마운트 합니다.
emptydir과 달리 pod를 삭제하여도 워커노드의 파일은 삭제되지 않습니다.
각 워커노드의 파일이 다를 수 있으므로 사용에 주의하도록 합니다.
node seletor를 이용하여 필요한 볼륨이 있는 node만 스케줄되게 하거나 모든 node가 동일한 파일을 가지거나 등의 조치를 하지 않고 배포 시 문제가 발생 할 수 있습니다.
hostpath는 상황에 따라 다르나 매우 중요한 개념입니다.
(1) hostpath volume을 위한 경로에 파일을 생성합니다.
코드 블럭 |
---|
# worker1 노드에 hostpath를 설정하고 해당 폴더를 사용하도록 설정 합니다
[root@m-k8s vagrant]# ssh vagrant@w1-k8s
vagrant@w1-k8s's password:
Last failed login: Wed Sep 13 10:53:11 KST 2023 from 192.168.1.10 on ssh:notty
There were 3 failed login attempts since the last successful login.
[vagrant@w1-k8s ~]$ sudo -i
# 마운트 될 경로를 생성합니다.
mkdir /hostpath
# 노드에 마운트 될 경로에 파일/내용을 작성합니다.
cat <<EOF | tee /hostpath/index.html
hihihihi
EOF |
(2) 해당 hostpath를 사용하는 yaml을 작성합니다.
8/08-volume-hostpath.yaml
코드 블럭 | ||
---|---|---|
| ||
---
apiVersion: v1
kind: Pod
metadata:
name: nginx-vol-3
spec:
containers:
- name: nginx-vol-3
image: nginx
volumeMounts:
- name: host-path-volume
mountPath: /usr/share/nginx/html
nodeName: w1-k8s #노드네임을 이용하여 woker1번에서 구동되도록 만든다. 본인 서버의 워크 노드 이름으로 변경한다.
volumes:
- name: host-path-volume
hostPath:
path: /hostpath # Path를 잘못 입력하여 못찾는 경우 컨테이너가 기동되지 않는다.
type: Directory |
(3) 해당 pod를 배포하고 확인 합니다.
코드 블럭 | ||
---|---|---|
| ||
# yaml 파일을 적용합니다.
kubectl apply -f 08-volume-hostpath.yaml
# 생성된 파드에서 마운트 된 경로의 파일을 확인합니다.
kubectl exec -it nginx-vol-3 -- ls -l /usr/share/nginx/html
total 4
-rw-r--r-- 1 root root 9 Apr 28 01:17 index.html
# 파일 내용을 확인합니다.
kubectl exec -it nginx-vol-3 -- cat /usr/share/nginx/html/index.html
hihihihi
[root@m-k8s vagrant]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-vol-3 1/1 Running 0 107s 172.16.221.185 w1-k8s <none> <none>
[root@m-k8s vagrant]#
[root@m-k8s vagrant]# curl 172.16.221.185
hihihihi
# node에서 생성한 파일이 pod에 hostpath를 이용해 마운트 된것을 확인 할 수 있습니다.
# hostpath의 경우 권한이 다르면 사용할수 없으므로 컨테이너 내 사용자로 권한을 바꾸거나 root사용자로 구동되도록 하여야 합니다.
# 실습을 위해 실습환경을 정리합니다.
[root@m-k8s vagrant]# kubectl delete -f 08-volume-hostpath.yaml
pod "nginx-vol-3" deleted |
3.3 NFS
NFS를 volume으로 사용할 수 있습니다.
NFS를 이용하면 여러 pod에 동일한 volume을 마운트 할 수 있고, 여러 노드가 읽고 쓸 수 있으므로 파일 공유에 많은 이점이 있습니다.
(1) 실습을 위하여 w2-k8s번 노드에 nfs서버를 임시로 구성하여 진행 합니다
코드 블럭 |
---|
# nfs-utils 패키지를 설치 합니다
apt install -y nfs-server
# nfs 공유로 사용할 폴더를 생성하고 테스트에 사용할 index.html 파일을 생성합니다
mkdir /nfs
chmod 777 /nfs
echo "hihihi" > /nfs/index.html
# nfs공유 설정을 해줍니다.
cat <<EOF | tee /etc/exports
/nfs *(rw,no_root_squash)
EOF
# nfs서버 서비스를 실행하고 활성화 합니다.
systemctl enable nfs-server --now
Created symlink from /etc/systemd/system/multi-user.target.wants/nfs-server.service to /usr/lib/systemd/system/nfs-server.service.
# 확인
# 출력값이 없으면 [systemctl restart nfs-server] 실행합니다.
systemctl restart nfs-server
[root@w2-k8s ~]# exportfs
/nfs w2-k8s
# nfs설정이 정상인지 worker1번에서 마운트 하여 테스트 합니다
ssh w1-k8s
# 모든 마스터/워커노드에서 nfs 패키지를 설치합니다.
apt install nfs-common
mkdir /nfs
mount w2-k8s:/nfs /nfs
df -h
Filesystem Size Used Avail Use% Mounted on
.....
192.168.1.102:/nfs 38770304 4569856 34200448 12% /nfs
.....
[root@w1-k8s /]# ll /nfs
total 4
-rw-r--r--. 1 root root 6 Sep 13 12:47 index.html
#nfs서버가 정상 작동되는것을 확인 했으니 이제 실습을 진행 합니다.
#/nfs 폴더를 umount 해줍니다.
umount /nfs
이제 설정이 완료된 nfs볼륨을 이용하여 pod를 생성하여 줍니다 |
(2) 설정이 완료된 NFS 볼륨을 이용하여 마운트하는 파드 yaml 파일을 작성합니다.
8/09-volume-nfs.yaml
코드 블럭 |
---|
---
apiVersion: v1
kind: Pod
metadata:
name: nginx-vol-4
spec:
nodeName: w1-k8s
containers:
- name: nginx-vol-4
image: nginx
volumeMounts:
- name: nfs-volume
mountPath: /usr/share/nginx/html
volumes:
- name: nfs-volume
nfs:
path: /nfs
server: w2-k8s |
(3) 생성된 yaml을 적용하여 파드를 생성 합니다
코드 블럭 |
---|
kubectl apply -f 09-volume-nfs.yaml
pod/nginx-vol-4 created
[root@m-k8s vagrant]# k get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-vol-4 1/1 Running 0 53s 172.16.221.186 w1-k8s <none> <none>
[root@m-k8s vagrant]# curl 172.16.221.186
hiihi
kubectl exec -it nginx-vol-4 -- df -h
Filesystem Size Used Avail Use% Mounted on
...
w2-k8s:/nfs 37G 4.4G 33G 12% /usr/share/nginx/html
...
# pod가 구동중인 worker1의 마운트 상태 확인
[root@w1-k8s /]# df -h
Filesystem Size Used Avail Use% Mounted on
w2-k8s:/nfs 37G 4.4G 33G 12% /var/lib/kubelet/pods/23229ac8-acb5-4aa0-b
0f1-6d8f36236366/volumes/kubernetes.io~nfs/nfs-volume
#hostpath의 경우 해당파일이 존재하는 워커노드에서만 수행되도록 설정하였으나 nfs사용시에는 어느 노드에서 구동되어도 상관이 없습니다
# 다음 실습을 위해 실습환경을 정리 합니다.
kubectl delete -f 09-volume-nfs.yaml
pod "nginx-vol-4" deleted |
3.4 Persistent Volume(PV)
PV(PersistentVolume): PV는 관리자가 프로비저닝했거나 스토리지 클래스를 사용해 동적으로 프로비저닝한 클러스터의 스토리지입니다. PV는 볼륨과 같은 볼륨 플러그인이지만 PV를 사용하는 개별 Pod와 독립적인 수명 주기를 가집니다.
PVC(PersistentVolumeClaim): PVC는 사용자가 볼륨을 사용하기 위해 PV에 하는 스토리지 요청입니다. Pod와 유사하게 Pod는 노드 리소스를 소비하고, PVC는 PV 리소스를 소비합니다.
지금까지의 볼륨은 empty dir를 제외하고는 사용자(개발자)가 볼륨의 정보를 알아야 했습니다
볼륨의 정보를 몰라도 사용할 수 있게 볼륨을 PV로 생성 해 두면 개발자는 pvc를 생성하여 해당 볼륨을 사용할 수 있게 됩니다
persistent volume(이하 PV) 를 persistent volume claim(이하PVC) 로 요청하여 할당받아 사용하는 방식 입니다
대부분의 production환경은 PV를 사용합니다. NAS도 PV로 사용하지 앞서 실습한 형태의 구성으로 운영 환경에서 사용하지 않습니다.
(1) PV Lifecycle
Provisioning | PV를 생성하는 단계로 프로비저닝 방법에는 두 가지가 있습니다.
| |
Binding | 바인딩은 프로비저닝으로 생성된 PV를 PVC와 연결하는 단계입니다. PVC에서 원하는 스토리지 용량과 접근방법을 명시해서 용청하면 거기에 맞는 PV가 할당됩니다. PV와 PVC의 매핑은 1대1 관계입니다. | |
Using | PVC는 Pod에 설정되고, Pod는 PVC를 볼륨으로 인식해서 사용합니다. 클러스터는 PVC를 확인하여 바인딩된 PV를 찾고 해당 볼륨을 Pod에서 사용할 수 있도록 해줍니다. 할당된 PVC는 파드를 유지하는 동안 계속 사용되며, 시스템에서 임의로 삭제할 수 없습니다. | |
Reclaiming | 사용이 끝난 PVC는 삭제되고, PV를 초기화(reclaim)하는 과정을 거칩니다. PV는 기존에 사용했던 PVC가 아니더라도 다른 PVC로 재활용이 가능합니다. |
(2) PV는 Policy
Access Policy
RWO-ReadWriteOnce : 단일 노드만 읽기/쓰기를 위해 볼륨을 마운트 할 수 있다. (블록 디바이스는 이 모드만 지원)
ROX-ReadOnlyMany : 여러 노드가 읽기 위해 볼륨을 마운트 할 수 있다.(잘 사용안함)
RWX-ReadWriteMany: 여러 노드가 읽기 쓰기를 위해 볼륨을 마운트 할 수 있다.(지원하는 공유파일시스템에서 사용)
Pod의 수가 아니라 볼륨을 동시에 사용할 수 있는 worker 노드의 수에 해당 한다. 또한 nfs, ceph등 형태에 따라서 지원 하지 않는 AccessPolicy가 있을 수 있다. 예를 들면 nfs는 rwx를 지원하지만 rbd등 block device는 rwo만 지원 합니다.
Reclaim Policy
영구 볼륨이 삭제 요청할 때 아래 3가지 회수 정책이 있다. retain과 delete는 다시 사용 할 수 없으며, recycle은 재사용이 가능하나 이제 사용되지 않는다
delete | AWS EBS, GCE PD, 애저 디스크 또는 오픈스택 등 스토리지 자체에서 삭제 | 인스턴스 삭제 시 볼륨도 같이 삭제(테스트 시 보통 많이 사용함) |
recycle | 내용만 삭제(rm -rf /volume/*) | recycle은 사용 안되며, dynamic provisioning을 대체 하는 것을 권고 하고 있음 |
retain | 수동으로 회수가 필요한 볼륨 | 보통 retain을 기본값으로 사용함. |
정보 |
---|
|
실습은 dynamic 프로비저닝을 하는 방법을 진행할 것입니다. 넷앱이나 유명한 스토리지 회사는 CSI를 지원하고 있습니다. AWS는 그 기능이 몇 개 빠진 상황입니다.
(3) 마지막 실습한 nfs를 단순 pv로 만들어 사용하는 실습을 진행합니다.
8/10-volume-pv.yaml
코드 블럭 | ||
---|---|---|
| ||
---
apiVersion: v1
kind: PersistentVolume # PersistenVolume형태로 kind정의
metadata:
name: nginx-vol-pv-5
labels:
release: stable
capacity: 1Gi
spec:
capacity:
storage: 1Gi # 1G 사이즈로 생성
accessModes:
- ReadWriteOnce
- ReadOnlyMany
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain
nfs:
path: /nfs
server: w2-k8s |
yaml을 이용하여 pv를 생성합니다.
코드 블럭 |
---|
[root@m-k8s vagrant]# kubectl apply -f 10-volume-pv.yaml
persistentvolume/nginx-vol-pv-5 created
[root@m-k8s vagrant]# k get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
nginx-vol-pv-5 1Gi RWO,ROX,RWX Retain Available 6s |
PV가 설정한대로 생성되면, 해당 PV를 사용하는 PVC를 생성하는 yaml 파일을 작성합니다.
8/11-volume-pvc.yaml
코드 블럭 | ||
---|---|---|
| ||
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nginx-pvc-1
spec:
storageClassName: ""
accessModes:
- ReadWriteOnce # 서로 매칭되는 클래스를 사용하겠다는 의미
resources:
requests:
storage: 1Gi |
yaml 파일을 적용하여 PVC를 생성 합니다.
코드 블럭 |
---|
kubectl apply -f 11-volume-pvc.yaml
# 생성된 pvc를 확인합니다.
[root@m-k8s vagrant]# k get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
nginx-pvc-1 Bound nginx-vol-pv-5 1Gi RWO,ROX,RWX 7s
# 앞서 STATUS가 Available의 값과 CLAIM이 비어있던 것이 PVC에 바인딩 된 것을 아래와 같이 볼 수 있습니다.
[root@m-k8s vagrant]# k get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
nginx-vol-pv-5 1Gi RWO,ROX,RWX Retain Bound default/nginx-pvc-1 2m44s
# 해당 pvc가 요청하는 조건에 맞는 pv가 이미 생성되었으므로 Bound(할당) 되었습니다. Pod는 PV를 사용하는 것이 아니라 PVC를 사용하는 것입니다. |
해당 PVC를 사용하는 파드를 생성하는 yaml 파일을 작성합니다.
8/12-volume-pvc-pod.yaml
코드 블럭 | ||
---|---|---|
| ||
---
apiVersion: v1
kind: Pod
metadata:
name: nginx-vol-6
spec:
containers:
- name: nginx-container
image: nginx
volumeMounts:
- mountPath: /vol
name: nginx-volume
volumes:
- name: nginx-volume
persistentVolumeClaim:
claimName: nginx-pvc-1 |
yaml 파일을 적용하여 파드를 생성합니다.
코드 블럭 |
---|
# 파드를 생성합니다.
kubectl apply -f 12-volume-pvc-pod.yaml
pod/nginx-vol-6 created
# 컨테이너 안에서 마운트 상태를 확인합니다.
kubectl exec -it nginx-vol-6 -- df -h
Filesystem Size Used Avail Use% Mounted on
w2-k8s:/nfs 37G 4.4G 33G 12% /vol
# 정상적으로 마운트 된것을 확인 할수 있습니다
## 실습 환경을 정리 합니다
# 파드 삭제
kubectl delete pod nginx-vol-6
pod "nginx-vol-6" deleted
# PVC 삭제
kubectl delete pvc/nginx-pvc-1
persistentvolumeclaim "nginx-pvc-1" deleted
# PV 삭제
kubectl delete pv/nginx-vol-pv-5
persistentvolume "nginx-vol-pv-5" deleted |
3.5 동적 프로비저닝 + 프로덕션 환경 테스트
정보 |
---|
Dynamic 프로비저닝을 하려면 CSI를 제공하는 스토리지가 필요합니다. 보통 운영환경에서는 모두 이 방식을 사용합니다. 동적 프로비저닝의 의미는 PV를 PVC요청에 따라 동적으로 할당 한다는 것을 의미 합니다. |
3.4 항목에서 PV를 수동으로 생성하고 해당 PV를 사용할 PVC를 선언하고 해당 PVC를 pod에 할당하여 사용 했습니다.
동적 프로비저닝은 PVC가 생성되면 해당 PVC에 알맞도록 PV를 동적으로 생성하여 주는 기능입니다.
사용자가 스토리지나 볼륨에 대해 아무것도 몰라도 운영자가 볼륨을 만들지 않아도 사용자가 요청하면(PVC) 해당 요청에 맞는 PV가 생성되는 방식 입니다.
실제 프로덕션 환경에서 가장 많이 사용되고 있으며 일반적으로 동적 프로비저닝을 지원하는 스토리지 객체가 있어야 합니다
부가기능을위해 CSI(Container Storage Interface)를 지원하는 스토리지를 사용하는것이 좋습니다.
CSI를 지원하는 스토리지는 각 클라우드 공급자의 스토리지, Netapp등의 스토리지, ceph 등이 있습니다.
(1) 동적 프로비저닝으로 nfs를 가지고 실습합니다.
기존의 세팅값을 지웁니다.
NFS 프로비저너를 설치합니다.
코드 블럭 |
---|
[root@cp-k8s vagrant]# git clone https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner.git
[root@cp-k8s vagrant]# cd nfs-subdir-external-provisioner/deploy |
pvc만 지정하여 구성하면, 자동적으로 하드웨어에 용량이 할당되는 형태의 서비스가 시작됩니다.
deployment.yaml 파일 수정
코드 블럭 |
---|
...
env:
- name: PROVISIONER_NAME
value: k8s-sigs.io/nfs-subdir-external-provisioner
- name: NFS_SERVER
value: w2-k8s #수정
- name: NFS_PATH
value: /nfs #수정
volumes:
- name: nfs-client-root
nfs:
server: w2-k8s #수정
path: /nfs #수정 |
코드 블럭 |
---|
[root@m-k8s deploy]# k apply -f rbac.yaml
[root@m-k8s deploy]# k apply -f deployment.yaml
[root@m-k8s deploy]# k apply -f class.yaml |
pvc만 지정하여 구성하면, 자동적으로 하드웨어에 용량이 할당되는 형태의 서비스가 시작됩니다.
8/13-volume-dynamic-pvc.yaml
코드 블럭 |
---|
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mypvc-dynamic
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1G
storageClassName: 'nfs-client' |
코드 블럭 |
---|
[root@m-k8s deploy]# k apply -f 13-volume-dynamic-pvc.yaml |
코드 블럭 |
---|
[root@m-k8s deploy]# k get pv,pvc
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
persistentvolume/pvc-45758961-7542-4f32-a959-d5ee0bdc17e8 1G RWX Delete Bound default/mypvc-dynamic nfs-client 4s
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
persistentvolumeclaim/mypvc-dynamic Bound pvc-45758961-7542-4f32-a959-d5ee0bdc17e8 1G RWX nfs-client 4s
[root@m-k8s deploy]# k get sc
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
nfs-client k8s-sigs.io/nfs-subdir-external-provisioner Delete Immediate false 49m |
pvc조건에 부합하는 pv가 동적으로 프로비저닝 된것을 확인 할 수 있습니다.
코드 블럭 |
---|
[root@w2-k8s nfs]# ls
default-mypvc-dynamic-pvc-45758961-7542-4f32-a959-d5ee0bdc17e8 |
정상적으로 volume을 사용할 수 있는지 확인합니다.
8/14-volume-nfs-pvc.yaml
코드 블럭 |
---|
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nfs-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: nfs-client |
코드 블럭 |
---|
[root@m-k8s vagrant]# k get pv | grep nfs
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pvc-5ed060f5-d2a9-4966-b23b-cfcfdc06c7cf 1Gi RWO Delete Bound default/nfs-pvc nfs-client 98s
[root@m-k8s vagrant]# k get pvc | grep nfs
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
nfs-pvc Bound pvc-5ed060f5-d2a9-4966-b23b-cfcfdc06c7cf 1Gi RWO nfs-client 100s |
PV, PVC 생성된 것을 확인합니다.
코드 블럭 |
---|
[root@m-k8s vagrant]# k describe pv/pvc-45758961-7542-4f32-a959-d5ee0bdc17e8
Name: pvc-45758961-7542-4f32-a959-d5ee0bdc17e8
Labels: <none>
Annotations: pv.kubernetes.io/provisioned-by: k8s-sigs.io/nfs-subdir-external-provisioner
Finalizers: [kubernetes.io/pv-protection]
StorageClass: nfs-client
Status: Bound
Claim: default/mypvc-dynamic
Reclaim Policy: Delete
Access Modes: RWX
VolumeMode: Filesystem
Capacity: 1G
Node Affinity: <none>
Message:
Source:
Type: NFS (an NFS mount that lasts the lifetime of a pod)
Server: w2-k8s
Path: /nfs/default-mypvc-dynamic-pvc-45758961-7542-4f32-a959-d5ee0bdc17e8
ReadOnly: false
Events: <none>
[root@m-k8s vagrant]# k describe pvc/nfs-pvc
Name: nfs-pvc
Namespace: default
StorageClass: nfs-client
Status: Bound
Volume: pvc-5ed060f5-d2a9-4966-b23b-cfcfdc06c7cf
Labels: <none>
Annotations: pv.kubernetes.io/bind-completed: yes
pv.kubernetes.io/bound-by-controller: yes
volume.beta.kubernetes.io/storage-provisioner: k8s-sigs.io/nfs-subdir-external-provisioner
volume.kubernetes.io/storage-provisioner: k8s-sigs.io/nfs-subdir-external-provisioner
Finalizers: [kubernetes.io/pvc-protection]
Capacity: 1Gi
Access Modes: RWO
VolumeMode: Filesystem
Used By: <none>
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ExternalProvisioning 5m55s persistentvolume-controller waiting for a volume to be created, either by external provisioner "k8s-sigs.io/nfs-subdir-external-provisioner" or manually created by system administrator
Normal Provisioning 5m55s k8s-sigs.io/nfs-subdir-external-provisioner_nfs-client-provisioner-554d86f86-jlgt6_2df91802-b760-445b-b3f7-17fb3aa51f3f External provisioner is provisioning volume for claim "default/nfs-pvc"
Normal ProvisioningSucceeded 5m55s k8s-sigs.io/nfs-subdir-external-provisioner_nfs-client-provisioner-554d86f86-jlgt6_2df91802-b760-445b-b3f7-17fb3aa51f3f Successfully provisioned volume pvc-5ed060f5-d2a9-4966-b23b-cfcfdc06c7cf |
해당 pvc를 이용하여 pod를 구동해 정상적으로 volume이 attach 되는지 확인 합니다.
8/15-volume-nfs-pod.yaml
코드 블럭 |
---|
apiVersion: v1
kind: Pod
metadata:
name: nginx-nfs-pvc
spec:
containers:
- name: nginx-nfs-pvc
image: nginx
volumeMounts:
- mountPath: /vol
name: nginx-volume
volumes:
- name: nginx-volume
persistentVolumeClaim:
claimName: nfs-pvc |
코드 블럭 |
---|
[root@m-k8s vagrant]# k apply -f 15-volume-nfs-pod.yaml
pod/nginx-nfs-pvc created
[root@m-k8s vagrant]# k get pods
NAME READY STATUS RESTARTS AGE
gitea-66bc89d659-z577q 1/1 Running 0 6h15m
nfs-client-provisioner-554d86f86-jlgt6 1/1 Running 0 64m
nginx-nfs-pvc 0/1 ContainerCreating 0 3s
[root@m-k8s vagrant]# k get pods
NAME READY STATUS RESTARTS AGE
gitea-66bc89d659-z577q 1/1 Running 0 6h15m
nfs-client-provisioner-554d86f86-jlgt6 1/1 Running 0 64m
nginx-nfs-pvc 1/1 Running 0 8s |
코드 블럭 |
---|
[root@m-k8s vagrant]# k exec -it nginx-nfs-pvc -- bash root@nginx-nfs-pvc:/# df Filesystem 1K-blocks Used Available Use% Mounted on overlay 38770180 8663136 30107044 23% / tmpfs 65536 0 65536 0% /dev tmpfs 1023288 0 1023288 0% /sys/fs/cgroup w2-k8s:/nfs/default-nfs-pvc-pvc-5ed060f5-d2a9-4966-b23b-cfcfdc06c7cf 38770432 8663296 30107136 23% /vol /dev/mapper/centos_k8s-root 38770180 8663136 30107044 23% /etc/hosts shm 65536 Retain 0 Available65536 0% /dev/shm tmpfs 15s |
3.3 PVC 생성
코드 블럭 |
---|
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: test-pvc spec: accessModes: - ReadWriteMany resources: requests: storage: 1Gi kubectl apply1944180 -f test-pvc.yaml # PV, PVC12 조회 kubectl1944168 get pv,pvc NAME 1% /run/secrets/kubernetes.io/serviceaccount tmpfs CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE persistentvolume/test-pv 1Gi 1023288 RWX 0 1023288 Retain0% /proc/acpi tmpfs Bound default/test-pvc 2m22s NAME 1023288 STATUS 0 VOLUME 1023288 CAPACITY 0% /proc/scsi ACCESStmpfs MODES STORAGECLASS AGE persistentvolumeclaim/test-pvc Bound test-pv 1Gi RWX 18s => PV와 PVC가 연결되어 PV가 Bound 상태로 변경된 것을 확인할 수 있습니다. |
3.4 PVC를 사용할 Pod 생성
코드 블럭 |
---|
apiVersion: v1 kind: Pod metadata: 1023288 name: test-nginx20 spec: 1023288 containers: 0% /sys/firmware |
RECLAIM POLICY가 delete이므로 pvc를 삭제하여 pv와 실제 볼륨이 삭제되는지 확인 합니다.
코드 블럭 |
---|
[root@m- name: test-nginx2 image: nginx:1.19 ports:k8s vagrant]# k delete pvc/nfs-pvc persistentvolumeclaim "nfs-pvc" deleted [root@m-k8s vagrant]# k get pv NAME - containerPort: 80 volumeMounts: - mountPath: "/test/volume" name: test-pv volumes: - name:CAPACITY test-pv ACCESS MODES persistentVolumeClaim: RECLAIM POLICY STATUS claimName: test-pvcCLAIM # 옵션 - volumeMounts.mountPath: 볼륨 마운트할 컨테이너 안의 경로를 작성합니다. - volumes:.persistentVolumeClaim: 컨테이너에서 사용할 PV의 이름을 가져오고, PV와STORAGECLASS 연결되어 있으며 요청을REASON 보낼 PVC를 지정합니다. # 적용하기 kubectl apply -f test-nginx2.yaml # 확인해보기 # 외부에서 확인 # kubectl describe pod test-nginx2 | grep -A1 MountsAGE git-pv-volume Mounts: 2Gi /test/volume from test-pv (rw) #RWO 컨테이너 내부에서 확인 kubectl exec -it test-nginx2 -- bash root@test-nginx2:/# df -ThRetain | grep volume /dev/vda1 xfs Bound default/git-volume 50G 3.7G 47G 8% /test/volume => 지정한 경로에 볼륨이 마운트된 것을 확인할 수 있습니다. # 컨테이너 내부에서 test용 파일 생성 root@test-nginx2:/# touch /test/volume/test.txt # PV 생성 시 설정한 노드의 경로에서도 확인이 가능합니다. [root@worker-node ~]# ls -al /test/volume/ total 0 drwxr-xr-x 2 root root 22 Mar 10 06:22 . drwxr-xr-x 3 root root 20 Mar 10 06:18 .. -rw-r--r-- 1 root root 0 Mar 10 06:22 test.txt 6h18m pvc-45758961-7542-4f32-a959-d5ee0bdc17e8 1G RWX Delete Bound default/mypvc-dynamic nfs-client |