[k8s] pv 생성시의 avz 배치 설정에 관하여
AWS CSI 인터페이스에 대한 이해
쿠버네티스에서는 스토리지 연계를 위해 CSI 인터페이스를 제공. 쿠버네티스 CSI 인터페이스에 맞춰 개발된 AWS CSI를 CSI드라이버라고 한다. EKS에서 EBS,EFS등 AWS스토리지를 다룰 수 있게되는 것. 간단하게 헬름으로 설치할 수 있다.
AWS CSI 드라이버는 크게 2가지 구성요소가 있다.
- AWS API를 호출하면서 aws 스토리지를 실제로 생성하는 csi-controller
- kubelet 과 상호작용하면서 aws 스토리지를 pod에 마운트하는 csi-node
EBS 사용시 주의할점은 아래 3가지 설정.
1. accessMode: 몇개의 파드에서 연결할지 등 설정. 기본적으로 readwriteonce로 설정
2. volumeBindingMode: pv동적프로비저닝, pv바인딩의 타이밍 관련 설정
3. reclaimPolicy: pv 재사용시 삭제 혹은 보존등 관련 설정
볼륨 바인딩 모드에 대한 이해
- volumeBindingMode 파라미터로 설정된다
- Immediate 모드: pvc가 생성되면 pv동적 프로비저닝 & 볼륨바인딩 즉시 발생한다. 문제가 있을 수 있는데, 파드가 실제로 노드에 배치되어 해당 노드에 pv가 마운트될때 고려되어야 할 사항이 고려되지 않은 상태로 pv가 생성되서, 파드가 실제로 안뜰 수 있다는 것이다. 즉 node selector, node affinitym, taint, toleration 등등 조건에서 막힐 수 있다.
- WaitForFirstConsumer 모드: pvc를 사용하는 파드가 생성될 때까지 pv 동적 프로비저닝 & pv 바인딩 지연시킨다. pv는 파드의 스케줄링 제약조건에 의해 지정된 토폴로지에 따라서 선택되거나 프로비전된다. 이때 고려되는 것들은 node selector, node affinity, taint, toleration 등이다.
volume affinity conflict 에러 발생
실제로 문제가 발생했던 부분은 WaitForFirstConsumer 바인딩 모드를 사용했음에도, 파드가 노드에 배치되지 못하는 상황이 발생했었다. 이유는 aws에서 node 의 avz와 pv의 avz가 달라서 생기는 문제였다. 해당문제 해결을 위해 노드의 avz를 특정하고, 이와 같은 avz로 pv의 avz를 특정하여 둘을 통일시키는 환경을 만들었다(모든 노드의 avz를 통일한 것은 아니고, 필요한 부분만)
https://stackoverflow.com/questions/51946393/kubernetes-pod-warning-1-nodes-had-volume-node-affinity-conflict
위 url의 마지막 답변과 aws ebs csi driver의 git 설명을 참고하여 해결하였다.
https://github.com/kubernetes-sigs/aws-ebs-csi-driver/blob/master/docs/parameters.md
Volume Availability Zone and Topologies
The EBS CSI Driver supports the WaitForFirstConsumer volume binding mode in Kubernetes. When using WaitForFirstConsumer binding mode the volume will automatically be created in the appropriate Availability Zone and with the appropriate topology. The WaitForFirstConsumer binding mode is recommended whenever possible for dynamic provisioning.
When using static provisioning, or if WaitForFirstConsumer is not suitable for a specific usecase, the Availability Zone can be specified via the standard CSI topology mechanisms. The EBS CSI Driver supports specifying the Availability Zone via either the key topology.kubernetes.io/zone or the key topology.ebs.csi.aws.com/zone.
분명 설명을 보면 WaitForFirstConsumer 볼륨바인딩모드를 사용시에 볼륨이 자동적으로 노드의 avz에 맞게 생성될것이라고 적혀 있었으나.. 에러가 발생한 것을 보면 제대로 동작하지 않은것으로 보인다. 따라서 아래와 같이 storage class 에서 allowedTopologies 를 이용해 "ebs가 생성될 avz들을 지정" 하여 해결했다.
allowedTopologies:
- matchLabelExpressions:
- key: topology.ebs.csi.aws.com/zone
values:
- ${var.volume_avz1}
- ${var.volume_avz2}
참고
How do I create and troubleshoot topology aware volume provisioning that uses an EBS CSI driver in Amazon EKS?
https://repost.aws/knowledge-center/eks-topology-aware-volumes
k8s storage class
https://kubernetes.io/ko/docs/concepts/storage/storage-classes/
EKS가 AWS스토리지를 다루는 원리
https://malwareanalysis.tistory.com/598