Google Kubernetes Engine (GKE) 클러스터의 스토리지 문제는 성능 병목 현상 및 볼륨 마운트 실패부터 특정 머신 유형에서 특정 디스크 유형을 사용할 때 발생하는 오류에 이르기까지 다양한 방식으로 나타날 수 있습니다. 이러한 문제는 애플리케이션 스테이트풀(Stateful), 데이터 지속성, 전반적인 워크로드 상태에 영향을 줄 수 있습니다.
이 문서를 사용하여 클러스터의 스토리지 기능에 영향을 미치는 일반적인 문제를 해결합니다. 볼륨 프로비저닝 및 연결, 데이터 액세스 및 성능, 스토리지 용량 관리와 관련된 문제 해결에 대한 안내를 확인하세요.
이 정보는 클러스터 인프라 및 스토리지를 관리하는 플랫폼 관리자 및 운영자와 워크로드가 영구 스토리지에 의존하는 애플리케이션 개발자 모두에게 중요합니다. Google Cloud 콘텐츠에서 참조하는 일반적인 역할과 예시 태스크에 대한 자세한 내용은 일반 GKE 사용자 역할 및 태스크를 참조하세요.
오류 400: 최적화된 VM에 RePD를 연결할 수 없음
리전 영구 디스크는 메모리 최적화 머신 또는 컴퓨팅 최적화 머신과 함께 사용할 수 없도록 제한됩니다.
리전 영구 디스크를 사용하는 것이 필수 요구사항이 아닌 경우 리전이 아닌 영구 디스크 스토리지 클래스를 사용하는 것이 좋습니다. 리전 영구 디스크를 사용하는 것이 필수 요구사항인 경우 리전 영구 디스크가 필요한 포드가 최적화된 머신이 아닌 노드 풀에 예약되도록 taint 및 톨러레이션(toleration)과 같은 예약 전략을 수립하는 것이 좋습니다.
디스크 성능 문제 해결
GKE 노드의 부팅 디스크는 운영체제뿐만 아니라 다음 용도로도 사용되므로 부팅 디스크의 성능이 중요합니다.
- Docker 이미지
- 볼륨으로 마운트되지 않는(즉, 오버레이 파일 시스템) 컨테이너 파일 시스템. 여기에는 일반적으로
/tmp같은 디렉터리가 포함됩니다. - 디스크 지원
emptyDir볼륨(노드가 로컬 SSD를 사용하는 경우는 제외)
디스크 성능은 노드의 동일한 디스크 유형의 모든 디스크에 공유됩니다. 예를 들어 100GB pd-standard 부팅 디스크와 활동이 많은 100GB pd-standard PersistentVolume이 있는 경우 부팅 디스크의 성능은 200GB 디스크와 동일합니다. 또한 PersistentVolume에서 활동이 많으면 부팅 디스크의 성능에도 영향을 미칩니다.
노드에 다음과 유사한 메시지가 표시되면 디스크 성능이 저하된 것일 수 있습니다.
INFO: task dockerd:2314 blocked for more than 300 seconds.
fs: disk usage and inodes count on following dirs took 13.572074343s
PLEG is not healthy: pleg was last seen active 6m46.842473987s ago; threshold is 3m0s
이러한 문제를 해결하려면 다음을 검토하세요.
- 스토리지 디스크 유형 비교를 참조하고 요구사항에 맞는 영구 디스크 유형을 선택하세요.
- 이 문제는 크기가 200GB 미만인 표준 영구 디스크를 사용하는 노드에서 자주 발생합니다. 특히 프로덕션에 사용되는 클러스터의 경우 디스크 크기를 늘리거나 SSD로 전환하는 것이 좋습니다.
- 노드 풀의 임시 스토리지에 로컬 SSD를 사용 설정하는 것이 좋습니다.
이는
emptyDir볼륨을 자주 사용하는 컨테이너가 있는 경우에 특히 효과적입니다.
fsGroup 설정으로 인해 볼륨 마운트가 응답하지 않음
PersistentVolume 마운트가 실패하는 원인이 되는 한 가지 문제는 fsGroup 설정으로 구성된 포드입니다. 일반적으로 마운트가 자동으로 재시도 되므로 마운트 실패는 자동으로 해결됩니다. 하지만 PersistentVolume에 파일이 많으면 kubelet이 파일 시스템의 각 파일에 대한 소유권을 변경하려고 시도하므로 볼륨 마운트 지연 시간이 늘어날 수 있습니다.
Unable to attach or mount volumes for pod; skipping pod ... timed out waiting for the condition
fsGroup 설정으로 인해 실패한 마운트 오류가 발생했는지 확인하려면 포드의 로그를 확인하면 됩니다.
문제가 fsGroup 설정과 관련된 경우 다음 로그 항목이 표시됩니다.
Setting volume ownership for /var/lib/kubelet/pods/POD_UUID and fsGroup set. If the volume has a lot of files then setting volume ownership could be slow, see https://github.com/kubernetes/kubernetes/issues/69699
몇 분 내에 PersistentVolume이 마운트되지 않으면 다음 단계를 시도하여 이 문제를 해결하세요.
- 볼륨의 파일 수를 줄입니다.
[fsGroup]설정 사용을 중지합니다.- 애플리케이션
fsGroupChangePolicy를OnRootMismatch로 변경합니다.
느린 디스크 작업으로 인해 포드 생성 실패
자세한 내용은 containerd 문제 #4604를 참조하세요.
영향을 받는 GKE 노드 버전: 1.18, 1.19, 1.20.0~1.20.15-gke.2100, 1.21.0~1.21.9-gke.2000, 1.21.10~1.21.10-gke.100, 1.22.0~1.22.6-gke.2000, 1.22.7~1.22.7-gke.100, 1.23.0~1.23.3-gke.700, 1.23.4~1.23.4-gke.100
k8s_node container-runtime 로그에 다음 오류 예시가 표시될 수 있습니다.
Error: failed to reserve container name "container-name-abcd-ef12345678-91011_default_12131415-1234-5678-1234-12345789012_0": name "container-name-abcd-ef12345678-91011_default_12131415-1234-5678-1234-12345789012_0" is reserved for "1234567812345678123456781234567812345678123456781234567812345678"
위험 완화
- 포드가 실패하면 PodSpec에서
restartPolicy:Always또는restartPolicy:OnFailure을 사용하는 것이 좋습니다. - 부팅 디스크 IOPS를 늘립니다(예: 디스크 유형 업그레이드 또는 디스크 크기 증가).
수정
이 문제는 containerd 1.6.0 이상에서 수정되었습니다. 이 수정사항이 포함된 GKE 버전은 1.20.15-gke.2100+, 1.21.9-gke.2000+, 1.21.10-gke.100+, 1.22.6-gke.2000+, 1.22.7-gke.100+, 1.23.3-gke.1700+, 1.23.4-gke.100+입니다.
볼륨 확장 변경사항이 컨테이너 파일 시스템에 반영되지 않음
볼륨 확장을 수행할 때는 항상 PersistentVolumeClaim을 업데이트해야 합니다. PersistentVolume을 직접 변경하면 볼륨 확장이 진행되지 않을 수 있습니다. 이로 인해 다음과 같은 시나리오 중 하나가 발생할 수 있습니다.
PersistentVolume 객체가 직접 수정되면 PersistentVolume 및 PersistentVolumeClaim 값이 모두 새 값으로 업데이트되지만 파일 시스템 크기는 컨테이너에 반영되지 않고 여전히 이전 볼륨 크기를 사용합니다.
PersistentVolume 객체를 직접 수정한 후
status.capacity필드를 새 크기로 업데이트하는 PersistentVolumeClaim으로 업데이트하면 PersistentVolumeClaim 또는 컨테이너 파일 시스템이 아닌 PersistentVolume이 변경될 수 있습니다.
이 문제를 해결하려면 다음 단계를 완료하시기 바랍니다.
- 수정된 PersistentVolume 객체는 그대로 유지합니다.
- PersistentVolumeClaim 객체를 수정하고
spec.resources.requests.storage를 PersistentVolume에서 사용한 값보다 높은 값으로 설정합니다. - PersistentVolume의 크기가 새 값으로 조절되었는지 확인합니다.
이러한 변경 후에는 kubelet에서 PersistentVolume, PersistentVolumeClaim, 컨테이너 파일 시스템 크기를 자동으로 조절되어야 합니다.
변경사항이 포드에 반영되는지 확인합니다.
kubectl exec POD_NAME -- /bin/bash -c "df -h"
POD_NAME을 PersistentVolumeClaim에 연결된 포드로 바꿉니다.
선택한 머신 유형에 로컬 SSD가 있어야 함
로컬 SSD를 사용하는 클러스터나 노드 풀을 만들 때 다음 오류가 발생할 수 있습니다.
The selected machine type (c3-standard-22-lssd) has a fixed number of local SSD(s): 4. The EphemeralStorageLocalSsdConfig's count field should be left unset or set to 4, but was set to 1.
지정된 오류에 따라 오류 메시지에 EphemeralStorageLocalSsdConfig 대신 LocalNvmeSsdBlockConfig가 표시될 수 있습니다.
이 오류는 지정된 로컬 SSD 디스크 수가 머신 유형에 포함된 로컬 SSD 디스크 수와 일치하지 않을 때 발생합니다.
이 문제를 해결하려면 원하는 머신 유형과 일치하는 로컬 SSD 디스크 수를 지정합니다.
3세대 머신 시리즈의 경우 로컬 SSD count 플래그를 생략해야 합니다. 그러면 자동으로 올바른 값이 구성됩니다.
하이퍼디스크 스토리지 풀: 클러스터 또는 노드 풀 생성 실패
Hyperdisk Storage Pool에서 Hyperdisk Balanced 디스크를 노드의 부팅 디스크 또는 연결된 디스크로 프로비저닝하려고 하면 ZONE_RESOURCE_POOL_EXHAUSTED 오류 또는 유사한 Compute Engine 리소스 오류가 발생할 수 있습니다.
이는 리소스가 부족한 영역에서 GKE 클러스터나 노드 풀을 만들려고 할 때 발생합니다. 예를 들면 다음과 같습니다.
- 해당 영역에서 사용할 수 있는 하이퍼디스크 균형 디스크가 충분하지 않을 수 있습니다.
- 지정한 머신 유형(예:
c3-standard-4)의 노드를 만들 만큼 영역의 용량이 충분하지 않을 수 있습니다.
이 문제를 해결하려면 다음 안내를 따르세요.
- 선택한 머신 유형에 충분한 용량이 있고 하이퍼디스크 균형 스토리지 풀을 사용할 수 있는 동일한 리전 내의 새 영역을 선택합니다.
- 기존 스토리지 풀을 삭제하고 새 영역에서 다시 만듭니다. 스토리지 풀은 영역별 리소스이기 때문입니다.
- 새 영역에서 클러스터 또는 노드 풀을 만듭니다.
높은 노드 스토리지 압력 감지됨
StoragePressureDetected 이유와 함께 StoragePressureRootFileSystem와 관련된 노드 이벤트 또는 조건이 관찰되면 노드의 루트 파일 시스템 또는 중요한 스토리지 마운트 지점의 디스크 사용량이 많아 용량에 근접하고 있음을 나타냅니다.
kubectl describe node NODE_NAME 명령어를 사용하여 노드를 설명할 때 다음과 유사한 이벤트가 표시될 수 있습니다.
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
...
Warning StoragePressureDetected 46m device-capacity-monitor Node condition StoragePressureRootFileSystem is now: True, reason: StoragePressureDetected, message: "Disk /dev/nvme0n1 usage 89% exceeds threshold 85%"
원인:
StoragePressureDetected 이유는 노드의 루트 파일 시스템 (종종 mnt/stateful_partition 또는 관련 마운트)의 디스크 사용량이 사전 정의된 기준 (예: 85%)을 초과했음을 나타냅니다. 이는 다음과 같은 이유로 발생할 수 있습니다.
- 로컬 SSD에서 지원되지 않는 emptyDir 볼륨에 과도한 데이터를 쓰는 워크로드
- 노드로 가져오는 컨테이너 이미지가 큽니다.
- 노드에 누적되는 로그 파일
- 디스크 공간을 사용하는 다른 프로세스
디스크 사용량이 계속 높으면 노드가 불안정해지거나, 포드가 제거되거나, 애플리케이션이 실패할 수 있습니다.
디버깅 및 해결:
디스크 사용량 파악: SSH를 사용하여 영향을 받는 노드에 연결하고 df -h와 같은 명령어를 사용하여 다양한 마운트 지점의 디스크 사용량을 확인합니다. 이때 /mnt/stateful_partition 및 임시 스토리지 마운트에 특히 주의를 기울입니다.
워크로드 스토리지 패턴 분석: 노드에서 실행 중인 포드의 스토리지 요청 및 사용 패턴을 검토합니다. 특정 워크로드가 임시 스토리지를 과도하게 사용하고 있는지 확인합니다.
노드 스토리지 용량 늘리기: 기본 해결 방법은 노드에 워크로드에 적합한 스토리지 용량이 있는지 확인하는 것입니다. 다음 사항을 고려하세요.
- 더 큰 부팅 디스크 사용: 노드 풀을 만들 때 워크로드에 루트 파일 시스템의 임시 스토리지가 더 많이 필요한 경우 더 큰 부팅 디스크 크기를 선택합니다.
- 임시 스토리지에 더 큰 로컬 SSD 활용: 고성능, 지연 시간이 짧은 임시 스토리지가 필요한 워크로드의 경우 로컬 SSD를 사용하도록 노드 풀을 구성합니다. 이렇게 하면 emptyDir 볼륨에 더 큰 별도의 용량이 제공됩니다.
- 워크로드 요청 또는 한도 조정: 포드 사양에 적절한 임시 스토리지 요청 및 한도가 포함되어 있는지 확인하여 스케줄러가 충분한 공간이 있는 노드에 포드를 배치하고 제어되지 않는 디스크 사용을 방지할 수 있도록 합니다.
- 사용하지 않는 리소스 정리: 높은 디스크 사용량의 원인이 되는 불필요한 파일, 이전 컨테이너 이미지 또는 로그를 노드에서 삭제합니다.
노드의 스토리지 용량과 사용량을 해결하면 StoragePressureDetected와 관련된 문제를 완화하고 노드 작업에 도움이 될 수 있습니다.
Cloud Storage FUSE 메모리 부족 (OOM) 이벤트 문제 해결
포드에서 Cloud Storage FUSE CSI 드라이버와 관련된 높은 메모리 사용률 또는 메모리 부족 (OOM) 이벤트가 발생하는 경우 Cloud Profiler를 사용하여 CPU 및 메모리 스냅샷을 수집하고 분석할 수 있습니다. Cloud Storage FUSE CSI 드라이버 사이드카 컨테이너 구성에서 이러한 옵션을 설정합니다.
포드에서 OOM 종료가 발생하면 다음 워크플로를 사용하여 이벤트를 올바른 Cloud Profiler 스냅샷과 연결할 수 있습니다.
- Cloud Logging 확인: Cloud Logging으로 이동하여 Kubernetes OOM 이벤트를 찾습니다.
포드 이름으로 필터링: 다음 쿼리를 실행하여 특정 포드의 이벤트 로그를 찾습니다. 이때
POD_NAME을 워크로드 포드의 이름으로 바꿉니다.jsonPayload.involvedObject.name="POD_NAME" jsonPayload.involvedObject.kind="Pod" OOMKilled포드 UID 추출: 관련 OOM 이벤트 로그를 펼치고
jsonPayload.involvedObject.uid에 있는 타임스탬프와 정확한 포드 UID를 기록합니다.Cloud Profiler에서 분석: Cloud Profiler로 이동하고
POD_NAME_POD_UID형식을 사용하여 서비스 버전을 필터링하고 OOM 타임스탬프와 일치하도록 기간을 조정합니다. 이렇게 하면 특정 컨테이너 인스턴스가 종료되기 직전의 정확한 메모리 프로필을 확인할 수 있습니다.
컴퓨팅 용량 부족으로 인해 스테이트풀(Stateful) 워크로드가 Pending 상태에서 멈춤
ZONE_RESOURCE_POOL_EXHAUSTED 또는 GCE_STOCKOUT와 같은 오류 메시지와 함께 Pending 상태에서 중단된 스테이트풀(Stateful) 워크로드가 있는 경우 특정 영역의 컴퓨팅 용량이 제한될 수 있습니다.
용량이 부족한 영역에서 컴퓨팅 노드가 오프라인 상태가 되면 해당 노드를 교체하지 못할 수 있습니다. 기존 영역 PersistentVolume(예: 표준 pd-ssd 또는 pd-balanced 디스크)을 사용하는 스테이트풀(Stateful) 포드는 해당 볼륨이 생성된 영역으로 제한됩니다. 볼륨을 마운트하려면 포드가 해당 특정 영역에 예약되어야 하므로 해당 영역의 컴퓨팅 용량을 사용할 수 있을 때까지 포드는 Pending 상태로 유지됩니다.
향후 스테이트풀(Stateful) 워크로드에서 이 문제를 완화하려면 다음을 고려하세요.
pd-ssd와pd-balanced간의 동일 영역 대체 방지:pd-ssd및pd-balanced볼륨은 영역에서 동일한 용량 한도와 가용성 풀을 공유하므로 동일한 영역에서 StorageClass를pd-ssd에서pd-balanced로 변경해도 용량 부족 문제가 해결되지 않습니다. 대체 수단으로 시도하지 마세요.- Hyperdisk 호환 형태 사용: 일부 머신 시리즈는 Hyperdisk를 지원합니다. 하이퍼디스크 호환 형태를 사용하는 것이 좋습니다. 영역에 용량이 부족할 때 도움이 되는 다양한 가용성 제약조건이 있을 수 있기 때문입니다. 워크로드를 마이그레이션하기 전에 디스크 할당량이 충분한지 확인하세요.
- 동적 토폴로지 바인딩 사용 설정(
WaitForFirstConsumer): 새 스테이트풀(Stateful) 워크로드를 만들 때volumeBindingMode: WaitForFirstConsumer필드 값 쌍으로 StorageClass 정의를 구성합니다. 이 설정은 컴퓨팅 용량이 충분한 영역의 정상 노드에 포드가 예약될 때까지 볼륨 생성을 지연시켜 조기 볼륨 생성으로 인해 포드가 오프라인 또는 소진된 영역에 잠기는 것을 방지합니다. - VM 대체에 대한 자동 디스크 유형 선택 구성: GKE 버전 1.35.3-gke.1290000 이상에서는 VM 세대 간에 대체되는 워크로드 (예: N4에서 N2로 또는 C4에서 C2로)에 대해 커스텀 ComputeClass를 구성할 수 있습니다. 자동 디스크 유형 선택을 사용하면
parameters.type: dynamic및use-allowed-disk-topology: "true"필드 값 쌍으로StorageClass정의를 구성할 수 있습니다. 이 구성을 사용하면 GKE가 최신 머신 세대에서hyperdisk-balanced디스크를 자동으로 프로비저닝하고 이전 세대에서pd-balanced디스크로 대체할 수 있습니다.
다음 단계
문서에서 문제 해결 방법을 찾을 수 없으면 지원 받기를 참조하여 다음 주제에 대한 조언을 포함한 추가 도움을 요청하세요.
- Cloud Customer Care에 문의하여 지원 케이스를 엽니다.
- StackOverflow에서 질문하고
google-kubernetes-engine태그를 사용하여 유사한 문제를 검색해 커뮤니티의 지원을 받습니다.#kubernetes-engineSlack 채널에 가입하여 더 많은 커뮤니티 지원을 받을 수도 있습니다. - 공개 Issue Tracker를 사용하여 문제나 기능 요청을 엽니다.