8. 쿠버네티스 리소스 관리 및 볼륨
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: nginx:latest
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
- name: log-aggregator
image: rancher/log-aggregator:v0.1.8
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
metrics-server를 이용한 노드 별 리소스 모니터링
root@k8s-master01:~# kubectl top nodes | sort -n -k 2
NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
k8s-worker02 114m 1% 4030Mi 25%
k8s-worker01 176m 2% 3196Mi 20%
k8s-master03 279m 3% 4727Mi 29%
k8s-master02 347m 4% 4144Mi 26%
k8s-master01 414m 5% 4557Mi 28%
metrics-server를 이용한 파드 별 리소스 모니터링
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를 이용하여 네임스페이스별로 사용할 수 있는 리소스의 양을 정하고, 컨테이너 마다 사용 할 수 있는 양을 지정할 수 있습니다.
Resource Name | Description |
---|---|
| Across all pods in a non-terminal state, the sum of CPU limits cannot exceed this value. |
| Across all pods in a non-terminal state, the sum of memory limits cannot exceed this value. |
| Across all pods in a non-terminal state, the sum of CPU requests cannot exceed this value. |
| Across all pods in a non-terminal state, the sum of memory requests cannot exceed this value. |
| Across all pods in a non-terminal state, the number of huge page requests of the specified size cannot exceed this value. |
| Same as |
| Same as |
쿼터 오브젝트를 생성하여 특정 우선 순위의 파드와 일치 시키며, "low(낮음)", "medium(중간)", "high(높음)"의 세 가지 우선 순위 클래스 중 하나를 가질 수도 있습니다.
8/01-resourcequota.yaml
8/02-resourcequota-test.yaml
2.3 LimitRange
ResourceQuota를 사용하면 네임스페이스의 리소스를 제한하고, LimitRange는 네임스페이스 내 파드(컨테이너)의 리소스를 제한합니다.
사용자가 컨테이너 리소스를 너무 크게 사용하면 특정 컨테이너가 많은 리소스를 점유하는 것을 방지할 수 있기 때문에 LimitRange를 사용합니다.
8/03-limitrange.yaml
8/04-limitrange-test.yaml
# kubectl get event --sort-by='lastTimestamp'
LAST SEEN TYPE REASON OBJECT MESSAGE
78s Warning FailedCreate replicaset/nginx-deployment-8579d7f98c Error creating: pods "nginx-deployment-8579d7f98c-mxw8q" is forbidden: maximum cpu usage per Pod is 800m, but limit is 1500m
2. Label & Selector
쿠버네티스 스케줄링에 포함된 내용입니다.
노드-파드도 Label&Selector를 이용하여 노드의 리소스 관리를 할 수 있고, 서비스-파드도 Label&Selector를 이용하여 엔드포인트를 지정합니다.
Label
Label은 Pod와 같은 객체에 연결된 키/값 쌍입니다.
리소스를 논리적인 그룹으로 나누거나, 식별의 편의를 위해 붙이는 이름표입니다.
Label은 생성 시 객체에 첨부할 수 있으며 나중에 언제든지 추가 및 수정할 수 있습니다.
Selector
특정 Label에 해당하는 객체를 식별하고 검색할 수 있습니다.
2.1 Node Label
2.2 Pod Selector
8/05-pod-selector.yaml
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
해당 yaml 파일을 적용하여 파드를 생성하여 마운트 상태를 확인합니다.
(2) 멀티 컨테이너를 가지는 파드에서의 emptyDir 볼륨 파일공유를 확인합니다.
8/07-volume-emptydir-multicon.yaml
생성 된 yaml을 적용하여 pod를 생성합니다.
3.2 hostpath
hostPath 볼륨은 호스트 노드의 파일시스템에 있는 파일이나 디렉터리를 파드에 마운트 합니다.
emptydir과 달리 pod를 삭제하여도 워커노드의 파일은 삭제되지 않습니다.
각 워커노드의 파일이 다를 수 있으므로 사용에 주의하도록 합니다.
node seletor를 이용하여 필요한 볼륨이 있는 node만 스케줄되게 하거나 모든 node가 동일한 파일을 가지거나 등의 조치를 하지 않고 배포 시 문제가 발생 할 수 있습니다.
hostpath는 상황에 따라 다르나 매우 중요한 개념입니다.
(1) hostpath volume을 위한 경로에 파일을 생성합니다.
(2) 해당 hostpath를 사용하는 yaml을 작성합니다.
8/08-volume-hostpath.yaml
(3) 해당 pod를 배포하고 확인 합니다.
3.3 NFS
NFS를 volume으로 사용할 수 있습니다.
NFS를 이용하면 여러 pod에 동일한 volume을 마운트 할 수 있고, 여러 노드가 읽고 쓸 수 있으므로 파일 공유에 많은 이점이 있습니다.
(1) 실습을 위하여 w2-k8s번 노드에 nfs서버를 임시로 구성하여 진행 합니다
(2) 설정이 완료된 NFS 볼륨을 이용하여 마운트하는 파드 yaml 파일을 작성합니다.
8/09-volume-nfs.yaml
(3) 생성된 yaml을 적용하여 파드를 생성 합니다
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을 기본값으로 사용함. |
Retain
반환 정책은 리소스를 수동으로 반환할 수 있게 한다. 퍼시스턴트 볼륨 클레임이 삭제되면 퍼시스턴트볼륨은 여전히 존재하며 볼륨은 "릴리스 된" 것으로 간주된다. 그러나 이전 요청자의 데이터가 여전히 볼륨에 남아 있기 때문에 다른 요청에 대해서는 아직 사용할 수 없다. 관리자는 다음 단계에 따라 볼륨을 수동으로 반환할 수 있다.
퍼시스턴트볼륨을 삭제한다. PV가 삭제된 후에도 외부 인프라(예: AWS EBS, GCE PD, Azure Disk 또는 Cinder 볼륨)의 관련 스토리지 자산이 존재한다.
관련 스토리지 자산의 데이터를 수동으로 삭제한다.
연결된 스토리지 자산을 수동으로 삭제하거나 동일한 스토리지 자산을 재사용하려는 경우 스토리지 자산 정의로 새 퍼시스턴트볼륨을 생성한다
실습은 dynamic 프로비저닝을 하는 방법을 진행할 것입니다. 넷앱이나 유명한 스토리지 회사는 CSI를 지원하고 있습니다. AWS는 그 기능이 몇 개 빠진 상황입니다.
(3) 마지막 실습한 nfs를 단순 pv로 만들어 사용하는 실습을 진행합니다.
8/10-volume-pv.yaml
yaml을 이용하여 pv를 생성합니다.
PV가 설정한대로 생성되면, 해당 PV를 사용하는 PVC를 생성하는 yaml 파일을 작성합니다.
8/11-volume-pvc.yaml
yaml 파일을 적용하여 PVC를 생성 합니다.
해당 PVC를 사용하는 파드를 생성하는 yaml 파일을 작성합니다.
8/12-volume-pvc-pod.yaml
yaml 파일을 적용하여 파드를 생성합니다.
3.5 동적 프로비저닝 + 프로덕션 환경 테스트
3.4 항목에서 PV를 수동으로 생성하고 해당 PV를 사용할 PVC를 선언하고 해당 PVC를 pod에 할당하여 사용 했습니다.
동적 프로비저닝은 PVC가 생성되면 해당 PVC에 알맞도록 PV를 동적으로 생성하여 주는 기능입니다.
사용자가 스토리지나 볼륨에 대해 아무것도 몰라도 운영자가 볼륨을 만들지 않아도 사용자가 요청하면(PVC) 해당 요청에 맞는 PV가 생성되는 방식 입니다.
실제 프로덕션 환경에서 가장 많이 사용되고 있으며 일반적으로 동적 프로비저닝을 지원하는 스토리지 객체가 있어야 합니다
부가기능을위해 CSI(Container Storage Interface)를 지원하는 스토리지를 사용하는것이 좋습니다.
CSI를 지원하는 스토리지는 각 클라우드 공급자의 스토리지, Netapp등의 스토리지, ceph 등이 있습니다.
(1) 동적 프로비저닝으로 nfs를 가지고 실습합니다.
기존의 세팅값을 지웁니다.
NFS 프로비저너를 설치합니다.
pvc만 지정하여 구성하면, 자동적으로 하드웨어에 용량이 할당되는 형태의 서비스가 시작됩니다.
deployment.yaml 파일 수정
pvc만 지정하여 구성하면, 자동적으로 하드웨어에 용량이 할당되는 형태의 서비스가 시작됩니다.
8/13-volume-dynamic-pvc.yaml
pvc조건에 부합하는 pv가 동적으로 프로비저닝 된것을 확인 할 수 있습니다.
정상적으로 volume을 사용할 수 있는지 확인합니다.
8/14-volume-nfs-pvc.yaml
PV, PVC 생성된 것을 확인합니다.
해당 pvc를 이용하여 pod를 구동해 정상적으로 volume이 attach 되는지 확인 합니다.
8/15-volume-nfs-pod.yaml
RECLAIM POLICY가 delete이므로 pvc를 삭제하여 pv와 실제 볼륨이 삭제되는지 확인 합니다.