· Vojtech Svoboda · Kubernetes · 6 min čtení
PV na EKS clusteru s pouze Fargate nody
Jak vytvořit persistent volume v EKS clusteru s pouze Fargate nody a na co si dát pozor.

Na první pohled se může zdát, že nastavení persistent volume (PV) na Fargate-only EKS clusteru v AWS není problém. Ve skutečnosti je ale potřeba si dát pozor na několik důležitých detailů a omezení. V tomto článku si projdeme klíčové body a funkční řešení.
Úvodem
Tento článek chceme udržet stručný, ale nejprve je potřeba vysvětlit, co je to Fargate.
AWS Fargate je technologie, která umožňuje spouštět kontejnery (na ECS, EKS nebo dokonce Lambda funkce) bez nutnosti spravovat virtuální stroje pod nimi. Využívá konceptu microVM, kde každý workload (task v ECS nebo Pod v EKS) běží ve vlastním izolovaném VM. To je to, čemu AWS říká „serverless“.
Tyto microVM nejsou spravovány jako EC2 instance. Jako uživatelé k nim nemáme žádný přístup ani možnost správy, což je jednou z hlavních výhod serverless přístupu.
Existují ale i nevýhody. Například workloady se spouští pomaleji, protože je nejprve nutné vytvořit instanci pod nimi. Oproti spuštění Podů na již běžících EC2 nodech to může znamenat znatelné zpoždění (někdy až dvě minuty).
Dalším důležitým omezením je, že microVM nepodporují všechny funkce EC2. Konkrétně nepodporují připojení EBS disků. To se stává zásadním problémem ve chvíli, kdy chcete v Kubernetes clusteru používat Persistent Volumes – a právě tomu se tento článek věnuje.
Jak nastavit funkční PV
Jak tedy toto omezení obejít a zajistit, aby Fargate-only EKS cluster fungoval s persistentními volumes? Po prostudování AWS dokumentace jsme narazili na několik míst, která nejsou příliš dobře vysvětlena. Níže najdete krok za krokem postup, který tyto mezery vyplňuje.
Prerekvizity
Budete potřebovat:
- helm
- kubectl
- EKS cluster s Fargate profilem a administrátoský přístup
- AWS uživatele s dostatečnými oprávněními pro vytvoření a správu EFS a IAM
Pro účely tohoto článku předpokládáme, že AWS účet obsahuje:
- VPC s CIDR
10.0.0.0/16 - Tři privátní subnety (
10.0.0.0/24,10.0.1.0/24,10.0.2.0/24) - Tři veřejné subnety (
10.0.3.0/24,10.0.4.0/24,10.0.5.0/24) - Subnety rozložené do tří Availability Zones
- EKS cluster nasazený v privátních subneteche
V celém návodu používáme region us-east-1.
EFS
I když EBS na Fargate použít nelze, EFS je podporované a představuje doporučené řešení pro persistentní úložiště ve Fargate-only EKS clusterech. EFS má sice vyšší latenci než EBS, ale v tomto setupu jde o jedinou podporovanou možnost persistentního sdíleného úložiště (kromě objektových úložišť).
Nejprve vytvoříme EFS filesystem:
aws efs create-file-system \
--tags Key=Name,Value=my-efs \
--region us-east-1Následně vytvoříme security group pro mount targety:
aws ec2 create-security-group \
--group-name efs-sg \
--description efs \
--vpc-id vpc-XXXXPoté vytvoříme mount targety v každém privátním subnetu, ke kterým bude EKS cluster přistupovat:
aws efs create-mount-target \
--file-system-id fs-<ID of the EFS created earlier> \
--subnet-id subnet-private-1 \
--security-groups sg-<ID of the security group created earlier>
aws efs create-mount-target \
--file-system-id fs-<ID of the EFS created earlier> \
--subnet-id subnet-private-2 \
--security-groups sg-<ID of the security group created earlier>
aws efs create-mount-target \
--file-system-id fs-<ID of the EFS created earlier> \
--subnet-id subnet-private-3 \
--security-groups sg-<ID of the security group created earlier>Nakonec – a tento krok je velmi důležitý – je nutné přidat v security group ingress pravidla pro NFS (port 2049) z privátních subnetů. Tato pravidla musí být přiřazena security group mount targetů EFS:
aws ec2 authorize-security-group-ingress \
--group-id sg-<ID of the security group created earlier> \
--protocol tcp \
--port 2049 \
--cidr 10.0.0.0/24
aws ec2 authorize-security-group-ingress \
--group-id sg-<ID of the security group created earlier> \
--protocol tcp \
--port 2049 \
--cidr 10.0.1.0/24
aws ec2 authorize-security-group-ingress \
--group-id sg-<ID of the security group created earlier> \
--protocol tcp \
--port 2049 \
--cidr 10.0.2.0/24AWS IAM role pro service account
Dále musíme vytvořit IAM roli, která bude navázána na Kubernetes service account. Tato role umožní EFS CSI driver controlleru vytvářet a spravovat EFS access pointy.
Celý proces je popsán v AWS dokumentaci, ale pro úplnost jej uvádíme i zde.
Nejprve zjistíme OIDC issuer ID clusteru:
export cluster_name=my-cluster
aws eks describe-cluster \
--name $cluster_name \
--query "cluster.identity.oidc.issuer" \
--output textPoté vytvoříme IAM roli, která povolí AssumeRoleWithWebIdentity:
cat <<EOF > aws-efs-csi-driver-trust-policy.json
{
"Version":"2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::123456789012:oidc-provider/oidc.eks.us-east-1.amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringLike": {
"oidc.eks.us-east-1.amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE:sub": "system:serviceaccount:kube-system:efs-csi-*",
"oidc.eks.us-east-1.amazonaws.com/id/EXAMPLED539D4633E53DE1B71EXAMPLE:aud": "sts.amazonaws.com"
}
}
}
]
}
EOF
aws iam create-role \
--role-name AmazonEKS_EFS_CSI_DriverRole \
--assume-role-policy-document file://"aws-efs-csi-driver-trust-policy.json"Nakonec k roli připojíme potřebnou politiku (AmazonEFSCSIDriverPolicy):
aws iam attach-role-policy \
--policy-arn arn:aws:iam::aws:policy/service-role/AmazonEFSCSIDriverPolicy \
--role-name AmazonEKS_EFS_CSI_DriverRolePo dokončení konfigurace na straně AWS můžeme přejít k instalaci CSI controlleru. Service account se vytvoří automaticky během instalace pomocí Helm.
CSI controller
Pokud objekt CSIDriver v clusteru neexistuje, vytvoříme jej ručně:
apiVersion: storage.k8s.io/v1
kind: CSIDriver
metadata:
name: efs.csi.aws.com
spec:
attachRequired: falseI když lze EFS CSI driver nainstalovat jako EKS add-on, v případě Fargate-only clusterů jsme s tímto přístupem narazili na problémy. Proto v tomto návodu používáme self-managed instalaci pomocí Helm.
helm repo add aws-efs-csi-driver \
https://kubernetes-sigs.github.io/aws-efs-csi-driver/
helm repo update aws-efs-csi-driver
helm upgrade --install aws-efs-csi-driver \
--namespace kube-system \
--set controller.replicaCount=1 \
--set controller.serviceAccount.annotations.eks\\.amazonaws\\.com/role-arn=<ARN of the created IAM role> \
--set controller.containerSecurityContext.privileged=false \
--set node.enabled=false \
aws-efs-csi-driver/aws-efs-csi-driverZde je vysvětlení některých zvolených konfigurací:
replicaCountje nastaveno na 1, protože jde o ukázkovou instalaci a vysoká dostupnost není nutná.- Anotace
role-arnzajišťuje, že service account controlleru použije správnou IAM roli. node.enabled=falsevypíná node daemonset, který na Fargate není podporován.privileged=falseje nutné, protože privilegované kontejnery nejsou na Fargate povoleny, a nemá negativní dopad na funkčnost controlleru.
Storage class
Dále vytvoříme storage class, která používá EFS CSI driver a dříve vytvořený filesystem.
Používáme provisioning mód efs-ap, který umožňuje dynamické vytváření a mazání PersistentVolumeClaimů v Kubernetes. Každý PVC má vlastní EFS access point a změny se do EFS propisují velmi rychle.
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: efs-sc
provisioner: efs.csi.aws.com
parameters:
fileSystemId: fs-<ID of EFS>
provisioningMode: efs-ap
directoryPerms: '700'A to je vše! Nyní, když máme veškeré konfigurace připravené můžeme otestovat, že se nám PVC a PV vytvoří.
Testování setupu
Po dokončení všech kroků můžeme konfiguraci otestovat.
Nejprve vytvoříme PersistentVolumeClaim, který využívá námi vytvořenou StorageClass:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: poc-app-pvc
spec:
accessModes:
- ReadWriteMany
storageClassName: efs-sc
resources:
requests:
storage: 1GiPoté vytvoříme dva Pody, abychom otestovali sdílené úložiště. Použijeme příklady od AWS:
kubectl apply -f \
https://raw.githubusercontent.com/aws-samples/eks-efs-share-within-fargate/refs/heads/master/scripts/epic04/pod1.yaml
kubectl apply -f \
https://raw.githubusercontent.com/aws-samples/eks-efs-share-within-fargate/refs/heads/master/scripts/epic04/pod2.yamlJakmile jsou oba Pody spuštěné, můžete se připojit do libovolného z nich a zkontrolovat adresář /data. Měli byste vidět soubory vytvořené oběma Pody, což potvrzuje funkčnost sdíleného persistentního úložiště.
Závěr
Úspěšně jsme nakonfigurovali persistentní úložiště pomocí EFS pro Fargate-only EKS cluster. Přestože je řešení v principu jednoduché, existuje mnoho kroků, kde může drobná chyba vést k velmi matoucím problémům.
Chyba, u které bylo nejtěžší zjistit, kde se nachází příčina problému, byla následující:
kubelet MountVolume.MountDevice failed for volume "poc-app-pv" :
kubernetes.io/csi: attacher.MountDevice failed to create newCsiDriverClient:
driver name efs.csi.aws.com not found in the list of registered CSI driversTato chybová hláška jasně nepopisuje skutečnou příčinu problému. V našem případě byla příčina v nesprávně nastavených nebo chybějících ingress pravidlech security group u EFS mount targetů. Povolení NFS provozu (port 2049) ze všech relevantních privátních subnetů problém vyřešilo.