为什么需要持久化存储
------抄自Kerbernetes权威指南第四版509页
在原生的Kubernetes中我们使用的持久化存储,我们常用的持久化存储一般有
local
iscsi
nfs
glusterfs-heketi
cephfs
这几种是在原生Kubernetes中经常会被企业选用的方式,而我们接下来需要说的是EKS中我们会选择的持久化存储的类型
ebs(SAN)
efs(NAS)
fsx(对于windows特有的存储这里不用它)
概念
ebs存储
优点:
性能优化: Pod到存储之间有用独立的网络带宽,吞吐量高
低延迟性能:通过使用SSD EBS卷,它可以提供可靠的I/O性能,满足各种存储需求(小文件4k随机读写)
高可用性和安全性:EBS卷支持快照与加密
在线扩容:可以随时动态扩容(无法缩容)
缺点:
每个硬盘只能给一个pod进行挂载
硬盘所在的az要跟pod所在的az相同,否则无法挂载
efs存储
优点:
弹性:efs是一个理论上无限大的存储
全面的托管服务:不需要维护的一个高可用性的nas存储
灵活跨az:efs是一个可以多个pod 一起使用,并且可以跨AZ的nas存储
缺点:
性能不高:iops性能不够高,即使用了MaxIO,我测试了一下大概500iops左右
部署
EBS
将 Amazon EBS CSI 驱动程序部署到 Amazon EKS 集群
官网上会有一个步骤让我们部署一个IAM把这个IAM附加给EKS的worker节点上,在我上篇文章中在创建nodegroup的时候已经添加了这个权限
iam:
withAddonPolicies:
ebs: true
我们可以查看这个IAM的权限
kubectl -n kube-system describe configmap aws-auth
Name: aws-auth
Namespace: kube-system
Labels: <none>
Annotations: <none>
Data
====
mapRoles:
----
- groups:
- system:bootstrappers
- system:nodes
rolearn: arn:aws:iam::xxxx:role/eksctl-nuclearport-tokyo-eks-prod-NodeInstanceRole-xxxx
username: system:node:{{EC2PrivateDNSName}}
- groups:
- system:bootstrappers
- system:nodes
rolearn: arn:aws:iam::xxxx:role/eksctl-nuclearport-tokyo-eks-prod-NodeInstanceRole-xxxx
username: system:node:{{EC2PrivateDNSName}}
mapUsers:
----
[]
Events: <none>
复制rolearn 去iam中查看,已经有了ebs的权限

所以我们不需要做这个IAM权限了,接下来直接测试EBS存储
EBS存储有几种模式
Dynamic Volume Provisioning:创建一个动态的卷等待pod来加载它
Static Provisioning:手动创建一个EBS,把他附加给pod
Block Volume:创建一个块存储挂给pod
Volume Snapshot:可以为EBS创建快照
部署EBS-CSI驱动程序
kubectl apply -k "github.com/kubernetes-sigs/aws-ebs-csi-driver/deploy/kubernetes/overlays/stable/?ref=master"
创建Dynamic Volume Provisioning(动态扩容)
注:EKS1.16 目前不支持因为aws-ebs-csi-driver 还不支持1.16版本
storageclass.yaml
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: ebs-sc
provisioner: ebs.csi.aws.com
volumeBindingMode: WaitForFirstConsumer
parameters: ## 配置一些可选参数
csi.storage.k8s.io/fstype: xfs ## ebs文件系统
type: io1 ## ebs类型
iopsPerGB: "50" ## ebs 初始容量
encrypted: "true" ## 是否加密
allowVolumeExpansion: true ## 开启这个参数可以动态扩容
allowedTopologies: ## 选择ebs创建的分区
- matchLabelExpressions:
- key: topology.ebs.csi.aws.com/zone
values:
- us-east-1a
claim.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: ebs-claim
spec:
accessModes:
- ReadWriteOnce
storageClassName: ebs-sc
resources:
requests:
storage: 4Gi
pod.yaml
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-claim
tolerations:
- key: "uessystem"
operator: "Equal"
value: "true"
effect: "NoSchedule"
创建他们
kubectl apply -f storageclass.yaml
kubectl apply -f claim.yaml
kubectl apply -f pod.yaml
验证一下
kubectl describe pv
kubectl exec -it app cat /data/out.txt
清理资源
kubectl apply -f storageclass.yaml
kubectl apply -f claim.yaml
kubectl apply -f pod.yaml
创建Static Provisioning
如果你有一个EBS硬盘需要挂在给pod,那么就使用这种方法
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: ebs-sc
provisioner: ebs.csi.aws.com
volumeBindingMode: WaitForFirstConsumer
reclaimPolicy: Retain
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: test-pv
spec:
capacity:
storage: 50Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
storageClassName: ebs-sc
csi:
driver: ebs.csi.aws.com
volumeHandle: {{ vol-id }}
fsType: xfs
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: topology.ebs.csi.aws.com/zone
operator: In
values:
- us-east-1c
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: ebs-claim
spec:
accessModes:
- ReadWriteOnce
storageClassName: ebs-sc
resources:
requests:
storage: 50Gi
---
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-claim
创建Block Volume
storageclass.yaml
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: ebs-sc
provisioner: ebs.csi.aws.com
volumeBindingMode: WaitForFirstConsumer
raw-claim.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: block-claim
spec:
accessModes:
- ReadWriteOnce
volumeMode: Block
storageClassName: ebs-sc
resources:
requests:
storage: 10Gi
pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: app
spec:
containers:
- name: app
image: busybox
command: ["/bin/sh", "-c"]
args: ["tail -f /dev/null"]
volumeDevices:
- name: data
devicePath: /dev/xvda
volumes:
- name: data
persistentVolumeClaim:
claimName: block-claim
tolerations:
- key: "uessystem"
operator: "Equal"
value: "true"
effect: "NoSchedule"
创建他们
kubectl apply -f storageclass.yaml
kubectl apply -f raw-claim.yaml
kubectl apply -f pod.yaml
验证一下
kubectl get pods
kubectl exec -ti app -- ls -al /dev/xvda
brw-rw---- 1 root disk 202, 23296 Mar 12 04:23 /dev/xvda
# 写入测试
dd if=/dev/zero of=/dev/xvda bs=1024k count=100
100+0 records in
100+0 records out
104857600 bytes (105 MB, 100 MiB) copied, 0.0492386 s, 2.1 GB/s
清理资源
kubectl apply -f storageclass.yaml
kubectl apply -f raw-claim.yaml
kubectl apply -f pod.yaml
创建Volume Snapshot
创建Storage Class
storageclass.yaml
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: ebs-sc
provisioner: ebs.csi.aws.com
volumeBindingMode: WaitForFirstConsumer
snapshotclass.yaml
apiVersion: snapshot.storage.k8s.io/v1beta1
kind: VolumeSnapshotClass
metadata:
name: csi-aws-vsc
driver: ebs.csi.aws.com
deletionPolicy: Delete
创建
kubectl apply -f storageclass.yaml
kubectl apply -f snapshotclass.yaml
创建APP
pod.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: ebs-claim
spec:
accessModes:
- ReadWriteOnce
storageClassName: ebs-sc
resources:
requests:
storage: 4Gi
---
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-claim
创建
kubectl apply -f pod.yaml
验证该卷已创建并volumeHandle包含EBS volumeID
kubectl describe pv
验证pod成功地将数据写入卷,并注意第一个条目的时间戳记
kubectl exec -it app cat /data/out.txt
创建VolumeSnapshot引用PersistentVolumeClaim名称
snapshot.yaml
apiVersion: snapshot.storage.k8s.io/v1beta1
kind: VolumeSnapshot
metadata:
name: ebs-volume-snapshot
spec:
volumeSnapshotClassName: csi-aws-vsc
source:
persistentVolumeClaimName: ebs-claim
创建
kubectl apply -f snapshot.yaml
等待VolumeSnapshot的 Ready To Use: true
kubectl describe volumesnapshot.snapshot.storage.k8s.io ebs-volume-snapshot
删除现有的应用程序
kubectl delete -f pod.yaml
还原从快照卷与PersistentVolumeClaim引用VolumeSnapshot它dataSource
pod.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: ebs-snapshot-restored-claim
spec:
accessModes:
- ReadWriteOnce
storageClassName: ebs-sc
resources:
requests:
storage: 4Gi
dataSource:
name: ebs-volume-snapshot
kind: VolumeSnapshot
apiGroup: snapshot.storage.k8s.io
---
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
创建
kubectl apply -f pod.yaml
通过将第一个条目的时间戳与步骤4中的时间戳进行比较,验证新的容器是否具有已还原的数据
kubectl exec -it app cat /data/out.txt
清理资源
kubectl delete -f test
EFS
部署 Amazon EFS CSI 驱动程序
kubectl apply -k "github.com/kubernetes-sigs/aws-efs-csi-driver/deploy/kubernetes/overlays/stable/?ref=master"
创建一个EFS文件系统
----码不动了贴个官网
为您的 Amazon EKS 集群创建 Amazon EFS 文件系统,并记录efsid
通过 https://console.aws.amazon.com/efs/ 打开 Amazon Elastic File System 控制台。
选择 Create file system。
在Configure file system access (配置文件系统访问权限) 页面上,选择您的 Amazon EKS 集群使用的 VPC。
对于 Security groups (安全组),将您在上一步中创建的安全组添加到各个挂载目标并选择 Next step (下一步)。
为您的文件系统配置任意可选设置,然后选择 Next step (下一步) 和 Create File System (创建文件系统) 以完成操作。
找到您 Amazon EKS 集群的 VPC ID
aws eks describe-cluster --name cluster_name --query "cluster.resourcesVpcConfig.vpcId" --output text
输出
vpc-exampledb76d3e813
查找您集群 VPC 的 CIDR 范围。您可以在 Amazon VPC 控制台中查找此信息,或者使用以下 AWS CLI 命令。
aws ec2 describe-vpcs --vpc-ids vpc-exampledb76d3e813 --query "Vpcs[].CidrBlock" --output text
输出
192.168.0.0/16
创建一个安全组,该安全组允许您 Amazon EFS 装载点的入站 NFS 流量。
打开 Amazon VPC 控制台 https://console.aws.amazon.com/vpc/。
在左侧导航窗格中,选择安全组,然后选择创建安全组。
为您的安全组输入名称和描述,然后选择您的 Amazon EKS 集群使用的 VPC。
选择创建,然后选择关闭以完成操作。
添加规则到您安全组以允许从 VPC CIDR 范围的入站 NFS 流量。
选择您在上一步中创建的安全组。
选择入站规则选项卡,然后选择 编辑规则。
选择添加规则,填写以下字段,然后选择保存规则。
Type (类型):NFS
Source (源):自定义粘贴 VPC CIDR 范围。
描述:添加描述,如“允许来自 VPC 的入站 NFS 流量”。
部署一个示例应用程序并验证 CSI 驱动程序是否正常运行
将 Amazon EFS Container Storage Interface (CSI) 驱动程序 GitHub 存储库克隆到您的本地系统。
git clone https://github.com/kubernetes-sigs/aws-efs-csi-driver.git
导航到 multiple_pods 示例目录。
cd aws-efs-csi-driver/examples/kubernetes/multiple_pods/
检索 Amazon EFS 文件系统 ID。您可以在 Amazon EFS 控制台中查找此信息,或者使用以下 AWS CLI 命令。
aws efs describe-file-systems --query "FileSystems[*].FileSystemId" --output text
输出:
fs-582a03f3
编辑 specs/pv.yaml 文件并将 volumeHandle 值替换为您的 Amazon EFS 文件系统 ID。
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-582a03f3
注意
由于 Amazon EFS 是弹性文件系统,它不会强制实施任何文件系统容量限制。在创建系统时,不使用持久性卷和持久性卷声明中的实际存储容量值。但是,由于存储容量是 Kubernetes 中的必需字段,您必须指定有效值,例如,在此示例中为 5Gi。此值不会限制 Amazon EFS 文件系统的大小。
从 specs 目录部署 efs-sc 存储类、efs-claim 持久性卷声明、efs-pv 持久性卷以及 app1 和 app2 示例应用程序。
kubectl apply -f specs/
查看默认命名空间中的 Pod 并等待 app1 和 app2 Pod 进入就绪状态。
kubectl get pods --watch
列出默认命名空间中的持久性卷。查找 default/efs-claim 声明中的持久性卷。
kubectl get pv
输出:
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
efs-pv 5Gi RWX Retain Bound default/efs-claim efs-sc 2m50s
描述持久性卷。
kubectl describe pv efs-pv
输出:
Name: efs-pv
Labels: <none>
Annotations: kubectl.kubernetes.io/last-applied-configuration:
{"apiVersion":"v1","kind":"PersistentVolume","metadata":{"annotations":{},"name":"efs-pv"},"spec":{"accessModes":["ReadWriteMany"],"capaci...
pv.kubernetes.io/bound-by-controller: yes
Finalizers: [kubernetes.io/pv-protection]
StorageClass: efs-sc
Status: Bound
Claim: default/efs-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
VolumeHandle: fs-582a03f3
ReadOnly: false
VolumeAttributes: <none>
Events: <none>
Amazon EFS 文件系统 ID 将作为 VolumeHandle 列出。
验证 app1 Pod 成功将数据写入卷。
kubectl exec -ti app1 -- tail /data/out1.txt
输出:
Wed Sep 18 20:30:48 UTC 2019
Wed Sep 18 20:30:53 UTC 2019
Wed Sep 18 20:30:58 UTC 2019
Wed Sep 18 20:31:03 UTC 2019
Wed Sep 18 20:31:08 UTC 2019
Wed Sep 18 20:31:13 UTC 2019
验证 app2 Pod 显示与卷中相同的数据。
kubectl exec -ti app2 -- tail /data/out1.txt
输出:
Wed Sep 18 20:30:48 UTC 2019
Wed Sep 18 20:30:53 UTC 2019
Wed Sep 18 20:30:58 UTC 2019
Wed Sep 18 20:31:03 UTC 2019
Wed Sep 18 20:31:08 UTC 2019
Wed Sep 18 20:31:13 UTC 2019
完成试验时,请删除此示例应用程序来清除资源。
kubectl delete -f specs/
下一篇写什么呢,还没想好不过后续会发一系列的文档,大家也可以在公众号里留言告诉我想看什么




