使用EFS存储服务的EKS Kubernetes持久存储
在本教程中,我们将讨论如何为Kubernetes集群使用EFS Amazon服务配置EKS持久存储。最好使用的存储后端服务是EFS,这将是我们用于有状态应用程序使用的卷声明的默认持久性存储。 StorageClass为管理员提供了一种描述他们提供的存储类别的方法,以允许动态配置持久卷。
在Kubernetes中,PersistentVolume(PV)是集群中的一块存储,而PersistentVolumeClaim(PVC)是用户(通常是Pod)对存储的请求。我们需要一个有效的EKS群集,然后才能使用本教程为容器化工作负载设置持久性存储。
设置准备工作:
EKS群集:使用eksctlAWS CLI设置EKS群集
这是本教程中将使用的EKS群集的名称。
$eksctl get cluster NAME REGION prod-eks-cluster eu-west-1
将群集名称另存为变量,该变量将在其余步骤中使用。
EKS_CLUSTER="prod-eks-cluster"
使用EFS CSI驱动程序创建持久卷
Amazon Elastic File System容器存储接口(CSI)驱动程序为容器协调器实施CSI规范,以管理Amazon EFS文件系统的生命周期。
创建Amazon EFS文件系统
Amazon EFS CSI驱动程序支持Amazon EFS访问点,这些访问点是Amazon EFS文件系统中特定于应用程序的入口点,使在多个Pod之间共享文件系统更加容易。
我们可以从Amazon控制台或者终端执行这些操作。我在所有操作中均使用AWS CLI界面。
找到Amazon EKS集群的VPC ID:
EKS_CLUSTER="prod-eks-cluster" EKS_VPC_ID=$(aws eks describe-cluster --name $EKS_CLUSTER --query "cluster.resourcesVpcConfig.vpcId" --output text)
确认有效的VPC ID。
$echo $EKS_VPC_ID vpc-019a6458a973ace2b
找到群集VPC的CIDR范围:
EKS_VPC_CIDR=$(aws ec2 describe-vpcs --vpc-ids $EKS_VPC_ID --query "Vpcs[].CidrBlock" --output text)
确认VPC CIDR:
$echo $EKS_VPC_CIDR 192.168.0.0/16
创建一个安全组,该安全组允许Amazon EFS挂载点的入站NFS流量:
aws ec2 create-security-group --group-name efs-nfs-sg --description "Allow NFS traffic for EFS" --vpc-id $EKS_VPC_ID
记下安全组ID。我的是:
{ "GroupId": "sg-0fac73a0d7d943862" } # You can check with $aws ec2 describe-security-groups --query "SecurityGroups[*].{Name:GroupName,ID:GroupId}"
将规则添加到安全组:
SG_ID="sg-0fac73a0d7d943862" aws ec2 authorize-security-group-ingress --group-id $SG_ID --protocol tcp --port 2049 --cidr $EKS_VPC_CIDR
要查看对安全组的更改,请运行describe-security-groups命令:
$aws ec2 describe-security-groups --group-ids $SG_ID { "SecurityGroups": [ { "Description": "Allow NFS traffic for EFS", "GroupName": "efs-nfs-sg", "IpPermissions": [ { "FromPort": 2049, "IpProtocol": "tcp", "IpRanges": [ { "CidrIp": "192.168.0.0/16" } ], "Ipv6Ranges": [], "PrefixListIds": [], "ToPort": 2049, "UserIdGroupPairs": [] } ], "OwnerId": "253859766502", "GroupId": "sg-0fac73a0d7d943862", "IpPermissionsEgress": [ { "IpProtocol": "-1", "IpRanges": [ { "CidrIp": "0.0.0.0/0" } ], "Ipv6Ranges": [], "PrefixListIds": [], "UserIdGroupPairs": [] } ], "VpcId": "vpc-019a6458a973ace2b" } ] }
为Amazon EKS集群创建Amazon EFS文件系统:
# Not encrypted $aws efs create-file-system --region eu-west-1 # Encrypted EFS file system $aws efs create-file-system --encrypted --region eu-west-1
注意文件系统ID:
{ "OwnerId": "253759766542", "CreationToken": "c16c4603-c7ac-408f-ac4a-75a683ed2a29", "FileSystemId": "fs-22ac06e8", "FileSystemArn": "arn:aws:elasticfilesystem:eu-west-1:253759766542:file-system/fs-22ac06e8", "CreationTime": "2017-08-16T15:17:18+03:00", "LifeCycleState": "creating", "NumberOfMountTargets": 0, "SizeInBytes": { "Value": 0, "ValueInIA": 0, "ValueInStandard": 0 }, "PerformanceMode": "generalPurpose", "Encrypted": true, "KmsKeyId": "arn:aws:kms:eu-west-1:253759766542:key/6c9b725f-b86d-41c2-b804-1685ef43f620", "ThroughputMode": "bursting", "Tags": [] }
用户界面视图:
创建EFS挂载目标
在运行EC2实例的VPC中获取子网。在我的情况下,所有EKS实例都在专用子网中运行。
EKS_VPC_ID=$(aws eks describe-cluster --name $EKS_CLUSTER --query "cluster.resourcesVpcConfig.vpcId" --output text) aws ec2 describe-subnets --filter Name=vpc-id,Values=$EKS_VPC_ID --query 'Subnets[?MapPublicIpOnLaunch==`false`].SubnetId'
我的输出:
[ "subnet-0977bbaf236bd952f", "subnet-0df8523ca39f63938", "subnet-0a4a22d25f36c4124" ]
创建挂载目标。
# File system ID EFS_ID="fs-22ac06e8" # Create mount targets for the subnets - Three subnets in my case for subnet in subnet-0977bbaf236bd952f subnet-0df8523ca39f63938 subnet-0a4a22d25f36c4124; do aws efs create-mount-target \ --file-system-id $EFS_ID \ --security-group $SG_ID \ --subnet-id $subnet \ --region eu-west-1 done
使用EFS CSI驱动程序
在创建EFS文件系统和Mount Target之后,我们可以通过创建静态持久卷并通过测试容器声明它来测试EFS CSI驱动程序。
部署EFS CSI预配器。
$kubectl apply -k "github.com/kubernetes-sigs/aws-efs-csi-driver/deploy/kubernetes/overlays/dev/?ref=master" daemonset.apps/efs-csi-node created csidriver.storage.k8s.io/efs.csi.aws.com created
列出可用的CSI驱动程序:
$kubectl get csidrivers.storage.k8s.io NAME CREATED AT efs.csi.aws.com 2017-08-16T19:10:35Z
首先获取EFS文件系统ID:
$aws efs describe-file-systems --query "FileSystems[*].FileSystemId" [ "fs-22ac06e8" ]
创建存储类:
kubectl apply -f - <<EOF kind: StorageClass apiVersion: storage.k8s.io/v1 metadata: name: efs-sc provisioner: efs.csi.aws.com EOF
列出可用的存储类别:
$kubectl get sc NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE efs-sc efs.csi.aws.com Delete Immediate false 28s gp2 (default) kubernetes.io/aws-ebs Delete WaitForFirstConsumer false 4d21h
创建并修改以下列表文件以设置正确的文件系统ID:
$vim efs-pv.yml apiVersion: v1 kind: PersistentVolume metadata: name: efs-pv spec: capacity: storage: 1Gi volumeMode: Filesystem accessModes: - ReadWriteOnce persistentVolumeReclaimPolicy: Retain storageClassName: efs-sc csi: driver: efs.csi.aws.com volumeHandle: fs-22ac06e8 # Your EFS file system ID
应用文件创建资源:
$kubectl apply -f efs-pv.yml persistentvolume/efs-pv created $kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE efs-pv 1Gi RWO Retain Available efs-sc 19s
创建索赔资源:
kubectl apply -f - <<EOF apiVersion: v1 kind: PersistentVolumeClaim metadata: name: efs-claim spec: accessModes: - ReadWriteOnce storageClassName: efs-sc resources: requests: storage: 1Gi EOF
列出声明以确认它已创建且状态为"绑定":
$kubectl get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE efs-claim Bound efs-pv 1Gi RWO efs-sc 7s
创建使用体积声明的测试容器。
kubectl apply -f - <<EOF apiVersion: v1 kind: Pod metadata: name: efs-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: efs-claim EOF
验证Pod是否正在运行:
$kubectl get pod NAME READY STATUS RESTARTS AGE efs-app 1/1 Running 0 34s
内部容器检查安装点。
$kubectl exec -ti efs-app -- bash [theitroad@localhost /]# df -hT Filesystem Type Size Used Avail Use% Mounted on overlay overlay 80G 3.4G 77G 5% / tmpfs tmpfs 64M 0 64M 0% /dev tmpfs tmpfs 1.9G 0 1.9G 0% /sys/fs/cgroup 127.0.0.1:/ nfs4 8.0E 0 8.0E 0% /data /dev/nvme0n1p1 xfs 80G 3.4G 77G 5% /etc/hosts shm tmpfs 64M 0 64M 0% /dev/shm tmpfs tmpfs 1.9G 12K 1.9G 1% /run/secrets/kubernetes.io/serviceaccount tmpfs tmpfs 1.9G 0 1.9G 0% /proc/acpi tmpfs tmpfs 1.9G 0 1.9G 0% /sys/firmware
将一些测试文件写入安装了EFS文件系统的/data。
[theitroad@localhost /]# touch /data/testfile1 [theitroad@localhost /]# touch /data/testfile2 [theitroad@localhost /]# [theitroad@localhost /]# ls /data/ out.txt testfile1 testfile2 [theitroad@localhost /]# exit exit
清理测试数据。
kubectl delete pod efs-app kubectl delete pvc efs-claim kubectl delete pv efs-pv