EKS Storage & Node

(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# mount | grep nfs4
fs-036a45de37ff1463b.efs.ap-northeast-2.amazonaws.com:/ on /mnt/myefs type nfs4 (rw,relatime,vers=4.1,rsize=1048576,wsize=1048576,namlen=255,hard,noresvport,proto=tcp,timeo=600,retrans=2,sec=sys,clientaddr=192.168.1.100,local_lock=none,addr=192.168.1.114)
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# echo "efs file test" > /mnt/myefs/memo.txt
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# cat /mnt/myefs/memo.txt
efs file test
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# rm -f /mnt/myefs/memo.txt
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl get csinodes
NAME DRIVERS AGE
ip-192-168-1-213.ap-northeast-2.compute.internal 0 11m
ip-192-168-2-58.ap-northeast-2.compute.internal 0 11m
ip-192-168-3-171.ap-northeast-2.compute.internal 0 11m
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl get node --label-columns=node.kubernetes.io/instance-type,eks.amazonaws.com/capacityType,topology.kubernetes.io/zone
NAME STATUS ROLES AGE VERSION INSTANCE-TYPE CAPACITYTYPE ZONE
ip-192-168-1-213.ap-northeast-2.compute.internal Ready <none> 11m v1.24.11-eks-a59e1f0 t3.medium ON_DEMAND ap-northeast-2a
ip-192-168-2-58.ap-northeast-2.compute.internal Ready <none> 11m v1.24.11-eks-a59e1f0 t3.medium ON_DEMAND ap-northeast-2b
ip-192-168-3-171.ap-northeast-2.compute.internal Ready <none> 11m v1.24.11-eks-a59e1f0 t3.medium ON_DEMAND ap-northeast-2c
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# eksctl get iamidentitymapping --cluster myeks
ARN USERNAME GROUPS ACCOUNT
arn:aws:iam::070271542073:role/eksctl-myeks-nodegroup-ng1-NodeInstanceRole-B9CATVHE7DJH system:node:{{EC2PrivateDNSName}} system:bootstrappers,system:nodes
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# echo $N1, $N2, $N3
192.168.1.213, 192.168.2.58, 192.168.3.171
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#
AWS LB/ExternalDNS, kube-ops-view 설치
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl get pods --all-namespaces -o jsonpath="{.items[*].spec.containers[*].image}" | tr -s '[[:space:]]' '\n' | sort | uniq -c
3 602401143452.dkr.ecr.ap-northeast-2.amazonaws.com/amazon-k8s-cni:v1.12.6-eksbuild.2
2 602401143452.dkr.ecr.ap-northeast-2.amazonaws.com/eks/coredns:v1.9.3-eksbuild.3
3 602401143452.dkr.ecr.ap-northeast-2.amazonaws.com/eks/kube-proxy:v1.24.10-minimal-eksbuild.2
1 hjacobs/kube-ops-view:20.4.0
2 public.ecr.aws/eks/aws-load-balancer-controller:v2.5.1
1 registry.k8s.io/external-dns/external-dns:v0.13.4
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# eksctl get addon --cluster $CLUSTER_NAME
2023-05-14 01:19:49 [ℹ] Kubernetes version "1.24" in use by cluster "myeks"
2023-05-14 01:19:49 [ℹ] getting all addons
2023-05-14 01:19:50 [ℹ] to see issues for an addon run `eksctl get addon --name <addon-name> --cluster <cluster-name>`
NAME VERSION STATUS ISSUES IAMROLE UPDATE AVAILABLE CONFIGURATION VALUES
coredns v1.9.3-eksbuild.3 ACTIVE 0
kube-proxy v1.24.10-eksbuild.2 ACTIVE 0
vpc-cni v1.12.6-eksbuild.2 ACTIVE 0 arn:aws:iam::070271542073:role/eksctl-myeks-addon-vpc-cni-Role1-1CLY25OXB7ODI
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# eksctl get iamserviceaccount --cluster $CLUSTER_NAME
NAMESPACE NAME ROLE ARN
kube-system aws-load-balancer-controller arn:aws:iam::070271542073:role/eksctl-myeks-addon-iamserviceaccount-kube-sy-Role1-211MO6823FEL
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#

데이터베이스(파드)처럼 데이터 보존이 필요 == 상태가 있는(Stateful) 애플리케이션 : PV & PVC
→ 로컬 볼륨(hostPath) ⇒ 퍼시스턴트 볼륨(Persistent Volume, PV) - 어느 노드에서도 연결하여 사용 가능, 예시) NFS, AWS EBS, Ceph 등

파드가 생성될 때 자동으로 볼륨을 마운트하여 파드에 연결하는 기능을 동적 프로비저닝(Dynamic Provisioning)이라고 함

퍼시스턴트 볼륨의 사용이 끝났을 때 해당 볼륨은 어떻게 초기화할 것인지 별도로 설정할 수 있는데, 쿠버네티스는 이를 Reclaim Policy 라고 부릅니다.

다양한 볼륨 사용 : K8S 자체 제공(hostPath, local), 온프렘 솔루션(ceph 등), NFS, 클라우드 스토리지(AWS EBS 등)
동적 프로비저닝 & 볼륨 상태 , ReclaimPolicy


AWS EC2 Type에 따라 볼륨 최대 제한 : 25개 ~ 39개
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl describe node | grep Allocatable: -A1
Allocatable:
attachable-volumes-aws-ebs: 25
--
Allocatable:
attachable-volumes-aws-ebs: 25
--
Allocatable:
attachable-volumes-aws-ebs: 25
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# curl -s -O https://raw.githubusercontent.com/gasida/PKOS/main/3/date-busybox-pod.yaml
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# cat date-busybox-pod.yaml | yh
apiVersion: v1
kind: Pod
metadata:
name: busybox
spec:
terminationGracePeriodSeconds: 3
containers:
- name: busybox
image: busybox
command:
- "/bin/sh"
- "-c"
- "while true; do date >> /home/pod-out.txt; cd /home; sync; sync; sleep 10; done"
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl apply -f date-busybox-pod.yaml
pod/busybox created
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#
파일 확인
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
busybox 1/1 Running 0 38s
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl exec busybox -- tail -f /home/pod-out.txt
Sat May 13 16:43:26 UTC 2023
Sat May 13 16:43:36 UTC 2023
Sat May 13 16:43:46 UTC 2023
Sat May 13 16:43:56 UTC 2023
파드 삭제 후 다시 생성 후 파일 정보 확인 > 이전 기록이 보존되어 있는지?
이로 인해서 영구저장소가 필요하다!!
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl delete pod busybox
pod "busybox" deleted
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl apply -f date-busybox-pod.yaml
pod/busybox created
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl exec busybox -- tail -f /home/pod-out.txt
Sat May 13 16:46:16 UTC 2023
Sat May 13 16:46:26 UTC 2023
Sat May 13 16:46:36 UTC 2023
호스트 Path 를 사용하는 PV/PVC : local-path-provisioner 스트리지 클래스 배포
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# curl -s -O https://raw.githubusercontent.com/rancher/local-path-provisioner/master/deploy/local-path-storage.yaml
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl apply -f local-path-storage.yaml
namespace/local-path-storage created
serviceaccount/local-path-provisioner-service-account created
clusterrole.rbac.authorization.k8s.io/local-path-provisioner-role created
clusterrolebinding.rbac.authorization.k8s.io/local-path-provisioner-bind created
deployment.apps/local-path-provisioner created
storageclass.storage.k8s.io/local-path created
configmap/local-path-config created
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl get-all -n local-path-storage
NAME NAMESPACE AGE
configmap/kube-root-ca.crt local-path-storage 13s
configmap/local-path-config local-path-storage 13s
pod/local-path-provisioner-759f6bd7c9-m4st6 local-path-storage 13s
serviceaccount/default local-path-storage 13s
serviceaccount/local-path-provisioner-service-account local-path-storage 13s
deployment.apps/local-path-provisioner local-path-storage 13s
replicaset.apps/local-path-provisioner-759f6bd7c9 local-path-storage 13s
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl get pod -n local-path-storage -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
local-path-provisioner-759f6bd7c9-m4st6 1/1 Running 0 20s 192.168.1.108 ip-192-168-1-213.ap-northeast-2.compute.internal <none> <none>
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# 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:
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>
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl get sc
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
gp2 (default) kubernetes.io/aws-ebs Delete WaitForFirstConsumer false 66m
local-path rancher.io/local-path Delete WaitForFirstConsumer false 34s
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl get sc local-path
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
local-path rancher.io/local-path Delete WaitForFirstConsumer false 42s
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#
@ PV/PVC 를 사용하는 파드 생성
PVC 생성
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# curl -s -O https://raw.githubusercontent.com/gasida/PKOS/main/3/localpath1.yaml
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# cat localpath1.yaml | yh
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: localpath-claim
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: "local-path"
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl apply -f localpath1.yaml
persistentvolumeclaim/localpath-claim created
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#
PVC 확인
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
localpath-claim Pending local-path 67s
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl describe pvc
Name: localpath-claim
Namespace: default
StorageClass: local-path
Status: Pending
Volume:
Labels: <none>
Annotations: <none>
Finalizers: [kubernetes.io/pvc-protection]
Capacity:
Access Modes:
VolumeMode: Filesystem
Used By: <none>
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal WaitForFirstConsumer 12s (x6 over 76s) persistentvolume-controller waiting for first consumer to be created before binding
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#
파드 생성
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# curl -s -O https://raw.githubusercontent.com/gasida/PKOS/main/3/localpath2.yaml
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# cat localpath2.yaml | yh
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
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl apply -f localpath2.yaml
pod/app created
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#
파드 확인
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl get pod,pv,pvc
NAME READY STATUS RESTARTS AGE
pod/app 1/1 Running 0 39s
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
persistentvolume/pvc-110950ea-3e70-41c4-a5b6-bf2e95acb560 1Gi RWO Delete Bound default/localpath-claim local-path 36s
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
persistentvolumeclaim/localpath-claim Bound pvc-110950ea-3e70-41c4-a5b6-bf2e95acb560 1Gi RWO local-path 3m59s
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl describe pv
Name: pvc-110950ea-3e70-41c4-a5b6-bf2e95acb560
Labels: <none>
Annotations: pv.kubernetes.io/provisioned-by: rancher.io/local-path
Finalizers: [kubernetes.io/pv-protection]
StorageClass: local-path
Status: Bound
Claim: default/localpath-claim
Reclaim Policy: Delete
Access Modes: RWO
VolumeMode: Filesystem
Capacity: 1Gi
Node Affinity:
Required Terms:
Term 0: kubernetes.io/hostname in [ip-192-168-3-171.ap-northeast-2.compute.internal]
Message:
Source:
Type: HostPath (bare host directory volume)
Path: /opt/local-path-provisioner/pvc-110950ea-3e70-41c4-a5b6-bf2e95acb560_default_localpath-claim
HostPathType: DirectoryOrCreate
Events: <none>
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl exec -it app -- tail -f /data/out.txt
Sat May 13 16:53:50 UTC 2023
Sat May 13 16:53:56 UTC 2023
Sat May 13 16:54:01 UTC 2023
Sat May 13 16:54:06 UTC 2023
Sat May 13 16:54:11 UTC 2023
Sat May 13 16:54:16 UTC 2023
Sat May 13 16:54:21 UTC 2023
Sat May 13 16:54:26 UTC 2023
Sat May 13 16:54:31 UTC 2023
Sat May 13 16:54:36 UTC 2023
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# ssh ec2-user@$N1 tree /opt/local-path-provisioner
/opt/local-path-provisioner [error opening dir]
0 directories, 0 files
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# ssh ec2-user@$N2 tree /opt/local-path-provisioner
/opt/local-path-provisioner [error opening dir]
0 directories, 0 files
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# ssh ec2-user@$N3 tree /opt/local-path-provisioner
/opt/local-path-provisioner
└── pvc-110950ea-3e70-41c4-a5b6-bf2e95acb560_default_localpath-claim
└── out.txt
1 directory, 1 file
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#
워커노드 자체에서 out.txt 파일 확인
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# ssh ec2-user@$N3 tail -f /opt/local-path-provisioner/pvc-110950ea-3e70-41c4-a5b6-bf2e95acb560_default_localpath-claim/out.txt
Sat May 13 16:59:31 UTC 2023
Sat May 13 16:59:36 UTC 2023
Sat May 13 16:59:41 UTC 2023
Sat May 13 16:59:46 UTC 2023
Sat May 13 16:59:51 UTC 2023
Sat May 13 16:59:56 UTC 2023
Sat May 13 17:00:01 UTC 2023
Sat May 13 17:00:06 UTC 2023
Sat May 13 17:00:11 UTC 2023
Sat May 13 17:00:16 UTC 2023
파드 삭제 후 파드 재생성해서 데이터 유지 되는지 확인
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl delete pod app
pod "app" deleted
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl get pod,pv,pvc
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
persistentvolume/pvc-110950ea-3e70-41c4-a5b6-bf2e95acb560 1Gi RWO Delete Bound default/localpath-claim local-path 8m19s
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
persistentvolumeclaim/localpath-claim Bound pvc-110950ea-3e70-41c4-a5b6-bf2e95acb560 1Gi RWO local-path 11m
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# ssh ec2-user@$N3 tree /opt/local-path-provisioner
/opt/local-path-provisioner
└── pvc-110950ea-3e70-41c4-a5b6-bf2e95acb560_default_localpath-claim
└── out.txt
1 directory, 1 file
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#
파드 다시 실행 & 확인
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl apply -f localpath2.yaml
pod/app created
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl apply -f localpath2.yaml
pod/app configured
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl exec -it app -- tail -f /data/out.txt
Sat May 13 17:01:26 UTC 2023
Sat May 13 17:01:31 UTC 2023
Sat May 13 17:01:36 UTC 2023
Sat May 13 17:01:41 UTC 2023
Sat May 13 17:01:46 UTC 2023
**Sat May 13 17:01:51 UTC 2023
Sat May 13 17:03:32 UTC 2023**
Sat May 13 17:03:37 UTC 2023
Sat May 13 17:03:42 UTC 2023
Sat May 13 17:03:47 UTC 2023
kubectl exec -it app -- tail -f /data/out.txtSat May 13 17:03:52 UTC 2023
Sat May 13 17:03:57 UTC 2023
Sat May 13 17:04:02 UTC 2023
Sat May 13 17:04:07 UTC 2023
^Ccommand terminated with exit code 130
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl exec -it app -- tail -f /data/out.txt
Sat May 13 17:04:02 UTC 2023
Sat May 13 17:04:07 UTC 2023
Sat May 13 17:04:12 UTC 2023
Sat May 13 17:04:17 UTC 2023
Sat May 13 17:04:22 UTC 2023
Sat May 13 17:04:27 UTC 2023
Sat May 13 17:04:32 UTC 2023
Sat May 13 17:04:37 UTC 2023
Sat May 13 17:04:42 UTC 2023
Sat May 13 17:04:47 UTC 2023
Sat May 13 17:04:52 UTC 2023
Sat May 13 17:04:57 UTC 2023
파드와 PVC삭제
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl delete pod app
pod "app" deleted
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl get pv,pvc
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
persistentvolume/pvc-110950ea-3e70-41c4-a5b6-bf2e95acb560 1Gi RWO Delete Bound default/localpath-claim local-path 12m
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
persistentvolumeclaim/localpath-claim Bound pvc-110950ea-3e70-41c4-a5b6-bf2e95acb560 1Gi RWO local-path 16m
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl delete pvc localpath-claim
persistentvolumeclaim "localpath-claim" deleted
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl get pv
No resources found
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# ssh ec2-user@$N3 tree /opt/local-path-provisioner
/opt/local-path-provisioner
0 directories, 0 files
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#
Volume (ebs-csi-controller) : EBS CSI driver 동작 : 볼륨 생성 및 파드에 볼륨 연결 - 링크
CSI-controller, csi-node


ISRA 설정 : AWS관리형 정책 AmazonEBSCSIDriverPolicy 사용
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# eksctl create iamserviceaccount \
> --name ebs-csi-controller-sa \
> --namespace kube-system \
> --cluster ${CLUSTER_NAME} \
> --attach-policy-arn arn:aws:iam::aws:policy/service-role/AmazonEBSCSIDriverPolicy \
> --approve \
> --role-only \
> --role-name AmazonEKS_EBS_CSI_DriverRole
2023-05-14 02:18:38 [ℹ] 1 existing iamserviceaccount(s) (kube-system/aws-load-balancer-controller) will be excluded
2023-05-14 02:18:38 [ℹ] 1 iamserviceaccount (kube-system/ebs-csi-controller-sa) was included (based on the include/exclude rules)
2023-05-14 02:18:38 [!] serviceaccounts in Kubernetes will not be created or modified, since the option --role-only is used
2023-05-14 02:18:38 [ℹ] 1 task: { create IAM role for serviceaccount "kube-system/ebs-csi-controller-sa" }
2023-05-14 02:18:38 [ℹ] building iamserviceaccount stack "eksctl-myeks-addon-iamserviceaccount-kube-system-ebs-csi-controller-sa"
2023-05-14 02:18:38 [ℹ] deploying stack "eksctl-myeks-addon-iamserviceaccount-kube-system-ebs-csi-controller-sa"
2023-05-14 02:18:38 [ℹ] waiting for CloudFormation stack "eksctl-myeks-addon-iamserviceaccount-kube-system-ebs-csi-controller-sa"
2023-05-14 02:19:08 [ℹ] waiting for CloudFormation stack "eksctl-myeks-addon-iamserviceaccount-kube-system-ebs-csi-controller-sa"
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# eksctl get iamserviceaccount --cluster myeks
NAMESPACE NAME ROLE ARN
kube-system aws-load-balancer-controller arn:aws:iam::070271542073:role/eksctl-myeks-addon-iamserviceaccount-kube-sy-Role1-211MO6823FEL
kube-system ebs-csi-controller-sa arn:aws:iam::070271542073:role/AmazonEKS_EBS_CSI_DriverRole
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#
Amazon EBS CSI driver addon 추가
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# eksctl create addon --name aws-ebs-csi-driver --cluster ${CLUSTER_NAME} --service-account-role-arn arn:aws:iam::${ACCOUNT_ID}:role/AmazonEKS_EBS_CSI_DriverRole --force
2023-05-14 02:20:48 [ℹ] Kubernetes version "1.24" in use by cluster "myeks"
2023-05-14 02:20:48 [ℹ] using provided ServiceAccountRoleARN "arn:aws:iam::070271542073:role/AmazonEKS_EBS_CSI_DriverRole"
2023-05-14 02:20:48 [ℹ] creating addon
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#
Amazon EBS CSI driver addon 추가
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# eksctl get addon --cluster ${CLUSTER_NAME}
2023-05-14 02:21:34 [ℹ] Kubernetes version "1.24" in use by cluster "myeks"
2023-05-14 02:21:34 [ℹ] getting all addons
2023-05-14 02:21:35 [ℹ] to see issues for an addon run `eksctl get addon --name <addon-name> --cluster <cluster-name>`
NAME VERSION STATUS ISSUES IAMROLE UPDATE AVAILABLE CONFIGURATION VALUES
aws-ebs-csi-driver v1.18.0-eksbuild.1 ACTIVE 0 arn:aws:iam::070271542073:role/AmazonEKS_EBS_CSI_DriverRole
coredns v1.9.3-eksbuild.3 ACTIVE 0
kube-proxy v1.24.10-eksbuild.2 ACTIVE 0
vpc-cni v1.12.6-eksbuild.2 ACTIVE 0 arn:aws:iam::070271542073:role/eksctl-myeks-addon-vpc-cni-Role1-1CLY25OXB7ODI
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#
csinodes 확인
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl get csinodes
NAME DRIVERS AGE
ip-192-168-1-213.ap-northeast-2.compute.internal 1 91m
ip-192-168-2-58.ap-northeast-2.compute.internal 1 91m
ip-192-168-3-171.ap-northeast-2.compute.internal 1 91m
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#
gp3 스토리지 클래스 생성
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl get sc
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
gp2 (default) kubernetes.io/aws-ebs Delete WaitForFirstConsumer false 101m
gp3 ebs.csi.aws.com Delete WaitForFirstConsumer true 9s
local-path rancher.io/local-path Delete WaitForFirstConsumer false 36m
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl describe sc gp3 | grep Parameters
Parameters: allowAutoIOPSPerGBIncrease=true,encrypted=true,type=gp3
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#
parameters:
type: gp3
allowAutoIOPSPerGBIncrease: 'true'
encrypted: 'true'
PVC/PV 파드 테스트
워커노드의 EBS 볼륨 확인 : tag(키/값) 필터링 - 링크
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# aws ec2 describe-volumes --filters Name=tag:Name,Values=$CLUSTER_NAME-ng1-Node --output table
--------------------------------------------------------------
| DescribeVolumes |
+------------------------------------------------------------+
|| Volumes ||
|+---------------------+------------------------------------+|
|| AvailabilityZone | ap-northeast-2a ||
|| CreateTime | 2023-05-13T15:51:26.652000+00:00 ||
|| Encrypted | False ||
|| Iops | 3000 ||
|| MultiAttachEnabled | False ||
|| Size | 30 ||
|| SnapshotId | snap-01ef0ca3352a5c1a2 ||
|| State | in-use ||
|| Throughput | 125 ||
|| VolumeId | vol-04960a285d1c60629 ||
|| VolumeType | gp3 ||
|+---------------------+------------------------------------+|
||| Attachments |||
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# aws ec2 describe-volumes --filters Name=tag:Name,Values=$CLUSTER_NAME-ng1-Node --query "Volumes[].{VolumeId: VolumeId, VolumeType: VolumeType, InstanceId: Attachments[0].InstanceId, State: Attachments[0].State}" | jq
[
{
"VolumeId": "vol-04960a285d1c60629",
"VolumeType": "gp3",
"InstanceId": "i-0869aa2fb32d3d0ff",
"State": "attached"
},
{
"VolumeId": "vol-0e60d29b4a484c653",
"VolumeType": "gp3",
"InstanceId": "i-0f5832ddd92531730",
"State": "attached"
},
{
"VolumeId": "vol-0e2f28bdb37afb471",
"VolumeType": "gp3",
"InstanceId": "i-0d0ae5fe5f1a45cfe",
"State": "attached"
}
]
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#
PVC & POD 생성
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# cat <<EOT > awsebs-pvc.yaml
> apiVersion: v1
> kind: PersistentVolumeClaim
> metadata:
> name: ebs-claim
> spec:
> accessModes:
> - ReadWriteOnce
> resources:
> requests:
> storage: 4Gi
> storageClassName: gp3
> EOT
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl apply -f awsebs-pvc.yaml
persistentvolumeclaim/ebs-claim created
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl get pvc,pv
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
persistentvolumeclaim/ebs-claim Pending gp3 20s
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# cat <<EOT > awsebs-pod.yaml
> 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: ebs-claim
> EOT
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl apply -f awsebs-pod.yaml
pod/app created
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#
PVC & POD 확인
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl get pvc,pv,pod
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
persistentvolumeclaim/ebs-claim Bound pvc-4eef7975-76de-49f5-99fe-3a9f4ae355c8 4Gi RWO gp3 103s
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
persistentvolume/pvc-4eef7975-76de-49f5-99fe-3a9f4ae355c8 4Gi RWO Delete Bound default/ebs-claim gp3 27s
NAME READY STATUS RESTARTS AGE
pod/app 1/1 Running 0 31s
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl get VolumeAttachment
NAME ATTACHER PV NODE ATTACHED AGE
csi-90aaf1e10bd47efb0fd4064b143aee8a687768f467dcfba1d74ca81b189ec932 ebs.csi.aws.com pvc-4eef7975-76de-49f5-99fe-3a9f4ae355c8 ip-192-168-3-171.ap-northeast-2.compute.internal true 60s


(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl get pv -o yaml | yh
required:
nodeSelectorTerms:
- matchExpressions:
- key: topology.ebs.csi.aws.com/zone
operator: In
values:
- ap-northeast-2c
persistentVolumeReclaimPolicy: Delete
storageClassName: gp3
volumeMode: Filesystem
status:
phase: Bound
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl get node --label-columns=topology.ebs.csi.aws.com/zone,topology.kubernetes.io/zone
NAME STATUS ROLES AGE VERSION ZONE ZONE
ip-192-168-1-213.ap-northeast-2.compute.internal Ready <none> 107m v1.24.11-eks-a59e1f0 ap-northeast-2a ap-northeast-2a
ip-192-168-2-58.ap-northeast-2.compute.internal Ready <none> 107m v1.24.11-eks-a59e1f0 ap-northeast-2b ap-northeast-2b
ip-192-168-3-171.ap-northeast-2.compute.internal Ready <none> 107m v1.24.11-eks-a59e1f0 ap-northeast-2c ap-northeast-2c
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl df-pv
PV NAME PVC NAME NAMESPACE NODE NAME POD NAME VOLUME MOUNT NAME SIZE USED AVAILABLE %USED IUSED IFREE %IUSED
pvc-4eef7975-76de-49f5-99fe-3a9f4ae355c8 ebs-claim default ip-192-168-3-171.ap-northeast-2.compute.internal app persistent-storage 3Gi 28Ki 3Gi 0.00 12 262132 0.00
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#
파드 내에서 볼륨 정보 확인
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl exec -it app -- sh -c 'df -hT --type=overlay'
Filesystem Type Size Used Avail Use% Mounted on
overlay overlay 30G 3.8G 27G 13% /
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl exec -it app -- sh -c 'df -hT --type=ext4'
Filesystem Type Size Used Avail Use% Mounted on
/dev/nvme1n1 ext4 3.8G 28K 3.8G 1% /data
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#
볼륨 증가
현재 pv 의 이름을 기준하여 4G > 10G 로 증가 : .spec.resources.requests.storage의 4Gi 를 10Gi로 변경
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl exec -it app -- sh -c 'df -hT --type=ext4'
Filesystem Type Size Used Avail Use% Mounted on
/dev/nvme1n1 ext4 9.8G 28K 9.7G 1% /data
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl df-pv
PV NAME PVC NAME NAMESPACE NODE NAME POD NAME VOLUME MOUNT NAME SIZE USED AVAILABLE %USED IUSED IFREE %IUSED
pvc-4eef7975-76de-49f5-99fe-3a9f4ae355c8 ebs-claim default ip-192-168-3-171.ap-northeast-2.compute.internal app persistent-storage 3Gi 28Ki 3Gi 0.00 12 262132 0.00
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# aws ec2 describe-volumes --volume-ids $(kubectl get pv -o jsonpath="{.items[0].spec.csi.volumeHandle}") | jq
{
"Volumes": [
{
"Attachments": [
{
"AttachTime": "2023-05-13T17:33:29+00:00",
"Device": "/dev/xvdaa",
"InstanceId": "i-0d0ae5fe5f1a45cfe",
"State": "attached",
"VolumeId": "vol-0008be154a8d576fd",
"DeleteOnTermination": false
}
],
"AvailabilityZone": "ap-northeast-2c",
"CreateTime": "2023-05-13T17:33:24.976000+00:00",
"Encrypted": true,
"KmsKeyId": "arn:aws:kms:ap-northeast-2:070271542073:key/d3943824-4a45-40a9-a318-642327604394",
"Size": 10,
"SnapshotId": "",
"State": "in-use",
"VolumeId": "vol-0008be154a8d576fd",
"Iops": 3000,
"Tags": [
{
"Key": "kubernetes.io/created-for/pv/name",
"Value": "pvc-4eef7975-76de-49f5-99fe-3a9f4ae355c8"
},
{
"Key": "ebs.csi.aws.com/cluster",
"Value": "true"
},
{
"Key": "kubernetes.io/created-for/pvc/namespace",
"Value": "default"
},
{
"Key": "KubernetesCluster",
"Value": "myeks"
},
{
"Key": "kubernetes.io/cluster/myeks",
"Value": "owned"
},
{
"Key": "kubernetes.io/created-for/pvc/name",
"Value": "ebs-claim"
},
{
"Key": "Name",
"Value": "myeks-dynamic-pvc-4eef7975-76de-49f5-99fe-3a9f4ae355c8"
},
{
"Key": "CSIVolumeName",
"Value": "pvc-4eef7975-76de-49f5-99fe-3a9f4ae355c8"
}
],
"VolumeType": "gp3",
"MultiAttachEnabled": false,
"Throughput": 125
}
]
}
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl df-pv
PV NAME PVC NAME NAMESPACE NODE NAME POD NAME VOLUME MOUNT NAME SIZE USED AVAILABLE %USED IUSED IFREE %IUSED
pvc-4eef7975-76de-49f5-99fe-3a9f4ae355c8 ebs-claim default ip-192-168-3-171.ap-northeast-2.compute.internal app persistent-storage 9Gi 32Ki 9Gi 0.00 12 655348 0.00
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#

PVC 삭제시 PV 도 삭제됨
Volumesnapshots 컨트롤러 설치
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# curl -s -O https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/master/client/config/crd/snapshot.storage.k8s.io_volumesnapshots.yaml
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# curl -s -O https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/master/client/config/crd/snapshot.storage.k8s.io_volumesnapshotclasses.yaml
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# curl -s -O https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/master/client/config/crd/snapshot.storage.k8s.io_volumesnapshotcontents.yaml
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl apply -f snapshot.storage.k8s.io_volumesnapshots.yaml,snapshot.storage.k8s.io_volumesnapshotclasses.yaml,snapshot.storage.k8s.io_volumesnapshotcontents.yaml
customresourcedefinition.apiextensions.k8s.io/volumesnapshots.snapshot.storage.k8s.io created
customresourcedefinition.apiextensions.k8s.io/volumesnapshotclasses.snapshot.storage.k8s.io created
customresourcedefinition.apiextensions.k8s.io/volumesnapshotcontents.snapshot.storage.k8s.io created
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl get crd | grep snapshot
volumesnapshotclasses.snapshot.storage.k8s.io 2023-05-13T17:55:30Z
volumesnapshotcontents.snapshot.storage.k8s.io 2023-05-13T17:55:30Z
volumesnapshots.snapshot.storage.k8s.io 2023-05-13T17:55:30Z
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl api-resources | grep snapshot
volumesnapshotclasses vsclass,vsclasses snapshot.storage.k8s.io/v1 false VolumeSnapshotClass
volumesnapshotcontents vsc,vscs snapshot.storage.k8s.io/v1 false VolumeSnapshotContent
volumesnapshots vs snapshot.storage.k8s.io/v1 true VolumeSnapshot
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# curl -s -O https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/master/deploy/kubernetes/snapshot-controller/rbac-snapshot-controller.yaml
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# curl -s -O https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/master/deploy/kubernetes/snapshot-controller/setup-snapshot-controller.yaml
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# [root@myeks-bastion-EC2
-bash: [root@myeks-bastion-EC2: command not found
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl apply -f rbac-snapshot-controller.yaml,setup-snapshot-controller.yaml
serviceaccount/snapshot-controller created
clusterrole.rbac.authorization.k8s.io/snapshot-controller-runner created
clusterrolebinding.rbac.authorization.k8s.io/snapshot-controller-role created
role.rbac.authorization.k8s.io/snapshot-controller-leaderelection created
rolebinding.rbac.authorization.k8s.io/snapshot-controller-leaderelection created
deployment.apps/snapshot-controller created
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl get deploy -n kube-system snapshot-controller
NAME READY UP-TO-DATE AVAILABLE AGE
snapshot-controller 2/2 2 0 9s
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl get pod -n kube-system -l app=snapshot-controller
NAME READY STATUS RESTARTS AGE
snapshot-controller-76494bf6c9-6n9hk 1/1 Running 0 18s
snapshot-controller-76494bf6c9-vqqss 1/1 Running 0 18s
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# curl -s -O https://raw.githubusercontent.com/kubernetes-sigs/aws-ebs-csi-driver/master/examples/kubernetes/snapshot/manifests/classes/snapshotclass.yaml
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl apply -f snapshotclass.yaml
volumesnapshotclass.snapshot.storage.k8s.io/csi-aws-vsc created
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl get vsclass
NAME DRIVER DELETIONPOLICY AGE
csi-aws-vsc ebs.csi.aws.com Delete 8s
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#
테스트 PVC/파드 생성
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl apply -f awsebs-pvc.yaml
persistentvolumeclaim/ebs-claim created
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl apply -f awsebs-pod.yaml
pod/app created
VolumeSnapshot 생성
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# curl -s -O https://raw.githubusercontent.com/gasida/PKOS/main/3/ebs-volume-snapshot.yaml
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# cat ebs-volume-snapshot.yaml | yh
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
name: ebs-volume-snapshot
spec:
volumeSnapshotClassName: csi-aws-vsc
source:
persistentVolumeClaimName: ebs-claim
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl apply -f ebs-volume-snapshot.yaml
volumesnapshot.snapshot.storage.k8s.io/ebs-volume-snapshot created
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl apply -f ebs-volume-snapshot.yaml
volumesnapshot.snapshot.storage.k8s.io/ebs-volume-snapshot created
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl get volumesnapshot
NAME READYTOUSE SOURCEPVC SOURCESNAPSHOTCONTENT RESTORESIZE SNAPSHOTCLASS SNAPSHOTCONTENT CREATIONTIME AGE
ebs-volume-snapshot true ebs-claim 4Gi csi-aws-vsc snapcontent-1a03fed0-447a-4b91-8a84-f3918373e27d 97s 97s
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl get volumesnapshot ebs-volume-snapshot -o jsonpath={.status.boundVolumeSnapshotContentName} ; echo
snapcontent-1a03fed0-447a-4b91-8a84-f3918373e27d
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl describe volumesnapshot.snapshot.storage.k8s.io ebs-volume-snapshot
Name: ebs-volume-snapshot
Namespace: default
Labels: <none>
Annotations: <none>
API Version: snapshot.storage.k8s.io/v1
Kind: VolumeSnapshot
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl get volumesnapshotcontents
NAME READYTOUSE RESTORESIZE DELETIONPOLICY DRIVER VOLUMESNAPSHOTCLASS VOLUMESNAPSHOT VOLUMESNAPSHOTNAMESPACE AGE
snapcontent-1a03fed0-447a-4b91-8a84-f3918373e27d true 4294967296 Delete ebs.csi.aws.com csi-aws-vsc ebs-volume-snapshot default 2m26s
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#
# VolumeSnapshot ID 확인
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl get volumesnapshotcontents -o jsonpath='{.items[*].status.snapshotHandle}' ; echo
snap-0cb45902cd5ce798d
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#
# VolumeSnapshot ID 확인
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# aws ec2 describe-snapshots --owner-ids self | jq
{
"Snapshots": [
{
"Description": "Created by AWS EBS CSI driver for volume vol-045304eb6f27d9766",
"Encrypted": true,
"KmsKeyId": "arn:aws:kms:ap-northeast-2:070271542073:key/d3943824-4a45-40a9-a318-642327604394",
"OwnerId": "070271542073",
"Progress": "100%",
"SnapshotId": "snap-0cb45902cd5ce798d",
"StartTime": "2023-05-13T18:00:29.632000+00:00",
"State": "completed",
"VolumeId": "vol-045304eb6f27d9766",
"VolumeSize": 4,
"Tags": [
{
"Key": "ebs.csi.aws.com/cluster",
"Value": "true"
},
{
"Key": "CSIVolumeSnapshotName",
"Value": "snapshot-1a03fed0-447a-4b91-8a84-f3918373e27d"
},
{
"Key": "kubernetes.io/cluster/myeks",
"Value": "owned"
},
{
"Key": "Name",
"Value": "myeks-dynamic-snapshot-1a03fed0-447a-4b91-8a84-f3918373e27d"
}
],
"StorageTier": "standard"
}
]
}
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# aws ec2 describe-snapshots --owner-ids self | jq
{
"Snapshots": [
{
"Description": "Created by AWS EBS CSI driver for volume vol-045304eb6f27d9766",
"Encrypted": true,
"KmsKeyId": "arn:aws:kms:ap-northeast-2:070271542073:key/d3943824-4a45-40a9-a318-642327604394",
"OwnerId": "070271542073",
"Progress": "100%",
"SnapshotId": "snap-0cb45902cd5ce798d",
"StartTime": "2023-05-13T18:00:29.632000+00:00",
"State": "completed",
"VolumeId": "vol-045304eb6f27d9766",
"VolumeSize": 4,
"Tags": [
{
"Key": "ebs.csi.aws.com/cluster",
"Value": "true"
},
{
"Key": "CSIVolumeSnapshotName",
"Value": "snapshot-1a03fed0-447a-4b91-8a84-f3918373e27d"
},
{
"Key": "kubernetes.io/cluster/myeks",
"Value": "owned"
},
{
"Key": "Name",
"Value": "myeks-dynamic-snapshot-1a03fed0-447a-4b91-8a84-f3918373e27d"
}
],
"StorageTier": "standard"
}
]
}
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#
aws ec2 describe-snapshots --owner-ids self | jq
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl delete pod app && kubectl delete pvc ebs-claim
pod "app" deleted
persistentvolumeclaim "ebs-claim" deleted
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#

스냅샷으로 복원
아래와 같이 없음!!
primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl get pvc,pv
No resources found
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# cat <<EOT > ebs-snapshot-restored-claim.yaml
> apiVersion: v1
> kind: PersistentVolumeClaim
> metadata:
> name: ebs-snapshot-restored-claim
> spec:
> storageClassName: gp3
> accessModes:
> - ReadWriteOnce
> resources:
> requests:
> storage: 4Gi
> dataSource:
> name: ebs-volume-snapshot
> kind: VolumeSnapshot
> apiGroup: snapshot.storage.k8s.io
> EOT
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# cat ebs-snapshot-restored-claim.yaml | yh
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: ebs-snapshot-restored-claim
spec:
storageClassName: gp3
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 4Gi
dataSource:
name: ebs-volume-snapshot
kind: VolumeSnapshot
apiGroup: snapshot.storage.k8s.io
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#
**
dataSource:
name: ebs-volume-snapshot
kind: VolumeSnapshot
apiGroup: snapshot.storage.k8s.io**
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl apply -f ebs-snapshot-restored-claim.yaml
persistentvolumeclaim/ebs-snapshot-restored-claim created
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#
확인!!
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl get pvc,pv
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
persistentvolumeclaim/ebs-snapshot-restored-claim Pending gp3 66s
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#
# 파드 생성
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# curl -s -O https://raw.githubusercontent.com/gasida/PKOS/main/3/ebs-snapshot-restored-pod.yaml
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# cat ebs-snapshot-restored-pod.yaml | yh
apiVersion: v1
kind: Pod
metadata:
name: app
spec:
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: ebs-snapshot-restored-claim
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl apply -f ebs-snapshot-restored-pod.yaml
pod/app created
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl exec app -- cat /data/out.txt
Sat May 13 18:12:39 UTC 2023
Sat May 13 18:12:44 UTC 2023
Sat May 13 18:12:49 UTC 2023
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#
# 삭제
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl delete pod app && kubectl delete pvc ebs-snapshot-restored-claim && kubectl delete volumesnapshots ebs-volume-snapshot
pod "app" deleted
persistentvolumeclaim "ebs-snapshot-restored-claim" deleted
volumesnapshot.snapshot.storage.k8s.io "ebs-volume-snapshot" deleted
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#


# EFS 정보 확인
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# aws efs describe-file-systems --query "FileSystems[*].FileSystemId" --output text
fs-036a45de37ff1463b
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#
# IAM 정책 생성
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# curl -s -O https://raw.githubusercontent.com/kubernetes-sigs/aws-efs-csi-driver/master/docs/iam-policy-example.json
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# aws iam create-policy --policy-name AmazonEKS_EFS_CSI_Driver_Policy --policy-document file://iam-policy-example.json
# ISRA 설정 : 고객관리형 정책 AmazonEKS_EFS_CSI_Driver_Policy 사용
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# eksctl create iamserviceaccount \
> --name efs-csi-controller-sa \
> --namespace kube-system \
> --cluster ${CLUSTER_NAME} \
> --attach-policy-arn arn:aws:iam::${ACCOUNT_ID}:policy/AmazonEKS_EFS_CSI_Driver_Policy \
> --approve
2023-05-14 03:18:35 [ℹ] 2 existing iamserviceaccount(s) (kube-system/aws-load-balancer-controller,kube-system/ebs-csi-controller-sa) will be excluded
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# kubectl get sa -n kube-system efs-csi-controller-sa -o yaml | head -5
apiVersion: v1
kind: ServiceAccount
metadata:
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::070271542073:role/eksctl-myeks-addon-iamserviceaccount-kube-sy-----
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# eksctl get iamserviceaccount --cluster myeks
NAMESPACE NAME ROLE ARN
kube-system aws-load-balancer-controller arn:aws:iam::070271542073:role/eksctl-myeks-addon-iamserviceaccount-kube-sy-Role1-211MO6823FEL
kube-system ebs-csi-controller-sa arn:aws:iam::070271542073:role/AmazonEKS_EBS_CSI_DriverRole
kube-system efs-csi-controller-sa arn:aws:iam::070271542073:role/eksctl-myeks-addon-iamserviceaccount-kube-sy-Role1-BSIE936WMAQ9
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]#
# EFS Controller 설치
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# helm upgrade -i aws-efs-csi-driver aws-efs-csi-driver/aws-efs-csi-driver \
> --namespace kube-system \
> --set image.repository=602401143452.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com/eks/aws-efs-csi-driver \
> --set controller.serviceAccount.create=false \
> --set controller.serviceAccount.name=efs-csi-controller-sa
Release "aws-efs-csi-driver" does not exist. Installing it now.
# 확인
kubectl get pod -n kube-system -l "app.kubernetes.io/name=aws-efs-csi-driver,app.kubernetes.io/instance=aws-efs-csi-driver"
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# cd /root/efs-csi/examples/kubernetes/multiple_pods/specs && tree
.
├── claim.yaml
├── pod1.yaml
├── pod2.yaml
├── pv.yaml
└── storageclass.yaml
0 directories, 5 files
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 specs]# cat pv.yaml | yh
apiVersion: v1
kind: PersistentVolume
metadata:
name: efs-pv
spec:
capacity:
storage: 5Gi
volumeMode: Filesystem
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain
storageClassName: efs-sc
csi:
driver: efs.csi.aws.com
volumeHandle: fs-036a45de37ff1463b
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 specs]#
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 specs]#
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 specs]# kubectl apply -f pv.yaml
persistentvolume/efs-pv created
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 specs]# kubectl get pv; kubectl describe pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
efs-pv 5Gi RWX Retain Available efs-sc 8s
Name: efs-pv
Labels: <none>
Annotations: <none>
Finalizers: [kubernetes.io/pv-protection]
StorageClass: efs-sc
Status: Available
Claim:
Reclaim Policy: Retain
Access Modes: RWX
VolumeMode: Filesystem
Capacity: 5Gi
Node Affinity: <none>
Message:
Source:
Type: CSI (a Container Storage Interface (CSI) volume source)
Driver: efs.csi.aws.com
FSType:
VolumeHandle: fs-036a45de37ff1463b
ReadOnly: false
VolumeAttributes: <none>
Events: <none>
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 specs]#
# 파드 정보 확인 : PV에 5Gi 와 파드 내에서 확인한 NFS4 볼륨 크리 8.0E의 차이는 무엇? 파드에 6Gi 이상 저장 가능한가?
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 specs]#
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 specs]# kubectl get pods
NAME READY STATUS RESTARTS AGE
app1 1/1 Running 0 113s
app2 1/1 Running 0 113s
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 specs]#
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 specs]#
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 specs]# kubectl exec -ti app1 -- sh -c "df -hT -t nfs4"
Filesystem Type Size Used Available Use% Mounted on
127.0.0.1:/ nfs4 8.0E 0 8.0E 0% /data
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 specs]# kubectl exec -ti app2 -- sh -c "df -hT -t nfs4"
Filesystem Type Size Used Available Use% Mounted on
127.0.0.1:/ nfs4 8.0E 0 8.0E 0% /data
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 specs]#
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 specs]# tail -f /mnt/myefs/out1.txt

삭제
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 specs]#
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 specs]# kubectl delete pod app1 app2
pod "app1" deleted
pod "app2" deleted
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 specs]#
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 specs]# kubectl delete pvc efs-claim && kubectl delete pv efs-pv && kubectl delete sc efs-sc
persistentvolumeclaim "efs-claim" deleted
persistentvolume "efs-pv" deleted
storageclass.storage.k8s.io "efs-sc" deleted
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 specs]#

# 인스턴스 스토어 볼륨이 있는 c5 모든 타입의 스토리지 크기
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 specs]# aws ec2 describe-instance-types \
> --filters "Name=instance-type,Values=c5*" "Name=instance-storage-supported,Values=true" \
> --query "InstanceTypes[].[InstanceType, InstanceStorageInfo.TotalSizeInGB]" \
> --output table
--------------------------
| DescribeInstanceTypes |
+---------------+--------+
| c5d.12xlarge | 1800 |
| c5d.large | 50 |
| c5d.24xlarge | 3600 |
| c5d.2xlarge | 200 |
| c5d.4xlarge | 400 |
| c5d.18xlarge | 1800 |
| c5d.metal | 3600 |
| c5d.xlarge | 100 |
| c5d.9xlarge | 900 |
+---------------+--------+
#신규 노드 그룹 생성
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 specs]# eksctl create nodegroup -c $CLUSTER_NAME -r $AWS_DEFAULT_REGION --subnet-ids "$PubSubnet1","$PubSubnet2","$PubSubnet3" --ssh-access \
> -n ng2 -t c5d.large -N 1 -m 1 -M 1 --node-volume-size=30 --node-labels disk=nvme --max-pods-per-node 100 --dry-run > myng2.yaml
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 specs]#
#워커 노드 SSH 접속 & max-pod 확인
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 specs]# ssh ec2-user@$N4 hostname
The authenticity of host '192.168.3.85 (192.168.3.85)' can't be established.
ECDSA key fingerprint is SHA256:uH1vY+SY7qVRgbFvo6G5TnGLkxbesHR+geeavdLqCrw.
ECDSA key fingerprint is MD5:ab:11:7d:c0:e2:79:0e:bf:ed:96:01:0c:48:bd:34:35.
Are you sure you want to continue connecting (yes/no)? ㅛ yes
Warning: Permanently added '192.168.3.85' (ECDSA) to the list of known hosts.
ip-192-168-3-85.ap-northeast-2.compute.internal
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 specs]#
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 specs]#
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 specs]# kubectl get node -owide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
ip-192-168-1-213.ap-northeast-2.compute.internal Ready <none> 3h5m v1.24.11-eks-a59e1f0 192.168.1.213 13.125.228.99 Amazon Linux 2 5.10.178-162.673.amzn2.x86_64 containerd://1.6.19
ip-192-168-2-58.ap-northeast-2.compute.internal Ready <none> 3h5m v1.24.11-eks-a59e1f0 192.168.2.58 3.35.227.76 Amazon Linux 2 5.10.178-162.673.amzn2.x86_64 containerd://1.6.19
ip-192-168-3-171.ap-northeast-2.compute.internal Ready <none> 3h5m v1.24.11-eks-a59e1f0 192.168.3.171 13.125.217.250 Amazon Linux 2 5.10.178-162.673.amzn2.x86_64 containerd://1.6.19
ip-192-168-3-85.ap-northeast-2.compute.internal Ready <none> 6m29s v1.24.11-eks-a59e1f0 192.168.3.85 52.79.133.153 Amazon Linux 2 5.10.178-162.673.amzn2.x86_64 containerd://1.6.19
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 specs]#
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 specs]# ssh ec2-user@$N4 sudo nvme list
Node SN Model Namespace Usage Format FW Rev
---------------- -------------------- ---------------------------------------- --------- -------------------------- ---------------- --------
/dev/nvme0n1 vol05ec5edb534aefb18 Amazon Elastic Block Store 1 32.21 GB / 32.21 GB 512 B + 0 B 1.0
/dev/nvme1n1 AWS250C59ADA5F344C57 Amazon EC2 NVMe Instance Storage 1 50.00 GB / 50.00 GB 512 B + 0 B 0
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 specs]# ssh ec2-user@$N4 sudo lsblk -e 7 -d
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
nvme0n1 259:0 0 30G 0 disk
nvme1n1 259:1 0 46.6G 0 disk /data
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 specs]# ssh ec2-user@$N4 sudo df -hT -t xfs
Filesystem Type Size Used Avail Use% Mounted on
/dev/nvme0n1p1 xfs 30G 3.3G 27G 11% /
/dev/nvme1n1 xfs 47G 365M 47G 1% /data
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 specs]# ssh ec2-user@$N4 sudo tree /data
/data
0 directories, 0 files
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 specs]# ssh ec2-user@$N4 sudo cat /etc/fstab
#
UUID=0ccd3c9e-3e0f-4e59-ae3c-9498ef40c541 / xfs defaults,noatime 1 1
/dev/nvme1n1 /data xfs defaults,noatime 0 2
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 specs]#
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 specs]# kubectl describe node -l disk=nvme | grep Allocatable: -A7
Allocatable:
attachable-volumes-aws-ebs: 25
cpu: 1930m
ephemeral-storage: 27905944324
hugepages-1Gi: 0
hugepages-2Mi: 0
memory: 3097560Ki
pods: 100
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 specs]# ssh ec2-user@$N4 sudo ps -ef | grep kubelet
root 2972 1 0 18:51 ? 00:00:02 /usr/bin/kubelet --config /etc/kubernetes/kubelet/kubelet-config.json --kubeconfig /var/lib/kubelet/kubeconfig --container-runtime-endpoint unix:///run/containerd/containerd.sock --image-credential-provider-config /etc/eks/image-credential-provider/config.json --image-credential-provider-bin-dir /etc/eks/image-credential-provider --node-ip=192.168.3.85 --pod-infra-container-image=602401143452.dkr.ecr.ap-northeast-2.amazonaws.com/eks/pause:3.5 --v=2 --cloud-provider=aws --container-runtime=remote --node-labels=eks.amazonaws.com/sourceLaunchTemplateVersion=1,alpha.eksctl.io/cluster-name=myeks,alpha.eksctl.io/nodegroup-name=ng2,disk=nvme,eks.amazonaws.com/nodegroup-image=ami-02ddbc7e7f404a16a,eks.amazonaws.com/capacityType=ON_DEMAND,eks.amazonaws.com/nodegroup=ng2,eks.amazonaws.com/sourceLaunchTemplateId=lt-0f24123c65b88fe4e --max-pods=29 --max-pods=100
root 3692 3132 0 18:51 ? 00:00:00 /csi-node-driver-registrar --csi-address=/csi/csi.sock --kubelet-registration-path=/var/lib/kubelet/plugins/efs.csi.aws.com/csi.sock --v=2
root 3865 3748 0 18:51 ? 00:00:00 /csi-node-driver-registrar --csi-address=/csi/csi.sock --kubelet-registration-path=/var/lib/kubelet/plugins/ebs.csi.aws.com/csi.sock --v=2
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 specs]#
모니터링
(primedo_eks@myeks:default) [root@myeks-bastion-EC2 ~]# ssh ec2-user@$N4 iostat -xmdz 1 -p nvme1n1
Linux 5.10.178-162.673.amzn2.x86_64 (ip-192-168-3-85.ap-northeast-2.compute.internal) 05/13/2023 _x86_64_ (2 CPU)
Device: rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
nvme1n1 0.00 0.00 0.31 0.30 0.01 0.03 123.87 0.00 0.20 0.06 0.35 0.26 0.02
Device: rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
Device: rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
Device: rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await r_await w_await svctm %util