AWS-EKS-05--安装 Amazon EBS CSI 驱动程序

摘要

安装 Amazon EBS CSI 驱动程序

  • 如果您计划将工作负载部署到使用 Amazon EBS 卷的集群,并且您创建了 1.23 或更高版本的集群,则在部署工作负载之前,您必须将 Amazon EBS CSI 驱动程序 安装到您的集群。

  • 使用 eksctl 创建 Amazon EBS CSI 驱动程序 IAM 角色

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 使用以下命令创建 IAM 角色并附加所需的 AWS 托管策略。此命令将部署 AWS CloudFormation 堆栈,该堆栈将创建 IAM 角色,并会将 IAM policy 附加到该堆栈。如果您的集群位于 AWS GovCloud(美国东部)或 AWS GovCloud(美国西部)AWS 区域,则将 arn:aws: 替换为 arn:aws-us-gov:。
# 注意这里附加的策略是AWS托管策略
$ eksctl create iamserviceaccount \
--name ebs-csi-controller-sa \
--namespace kube-system \
--cluster eks-lexing \
--profile eks-us-west-2 \
--role-name AmazonEKS_EBS_CSI_DriverRole \
--role-only \
--attach-policy-arn arn:aws:iam::aws:policy/service-role/AmazonEBSCSIDriverPolicy \
--approve
2023-06-28 16:16:05 [ℹ] 1 iamserviceaccount (kube-system/ebs-csi-controller-sa) was included (based on the include/exclude rules)
2023-06-28 16:16:05 [!] serviceaccounts in Kubernetes will not be created or modified, since the option --role-only is used
2023-06-28 16:16:05 [ℹ] 1 task: { create IAM role for serviceaccount "kube-system/ebs-csi-controller-sa" }
2023-06-28 16:16:05 [ℹ] building iamserviceaccount stack "eksctl-eks-lexing-addon-iamserviceaccount-kube-system-ebs-csi-controller-sa"
2023-06-28 16:16:06 [ℹ] deploying stack "eksctl-eks-lexing-addon-iamserviceaccount-kube-system-ebs-csi-controller-sa"
2023-06-28 16:16:06 [ℹ] waiting for CloudFormation stack "eksctl-eks-lexing-addon-iamserviceaccount-kube-system-ebs-csi-controller-sa"
2023-06-28 16:16:37 [ℹ] waiting for CloudFormation stack "eksctl-eks-lexing-addon-iamserviceaccount-kube-system-ebs-csi-controller-sa"
  • 将Amazon EBS CSI 驱动程序添加到集群

1
2
3
4
5
# 运行以下命令。如果您的集群位于 AWS GovCloud(美国东部)或 AWS GovCloud(美国西部)AWS 区域,则将 arn:aws: 替换为 arn:aws-us-gov:。
$ eksctl create addon --name aws-ebs-csi-driver --cluster eks-lexing --profile eks-us-west-2 --service-account-role-arn arn:aws:iam::743263909655:role/AmazonEKS_EBS_CSI_DriverRole --force
2023-06-28 16:23:59 [ℹ] Kubernetes version "1.25" in use by cluster "eks-lexing"
2023-06-28 16:24:00 [ℹ] using provided ServiceAccountRoleARN "arn:aws:iam::743263909655:role/AmazonEKS_EBS_CSI_DriverRole"
2023-06-28 16:24:00 [ℹ] creating addon
  • 检查 Amazon EBS CSI 驱动程序的当前版本,注意这里如果有可用更新,UPDATE AVAILABLE会显示,默认安装是最新版本

1
2
3
4
5
$ eksctl get addon --name aws-ebs-csi-driver --cluster eks-lexing --profile eks-us-west-2
2023-06-28 16:24:08 [ℹ] Kubernetes version "1.25" in use by cluster "eks-lexing"
2023-06-28 16:24:09 [ℹ] 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.19.0-eksbuild.2 CREATING 0 arn:aws:iam::743263909655:role/AmazonEKS_EBS_CSI_DriverRole
  • 插件安装完成后可以查看已经安装的资源,Name中含有 ebs-csi

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
~ k get all -n kube-system -l app.kubernetes.io/component=csi-driver
NAME READY STATUS RESTARTS AGE
pod/ebs-csi-controller-5f945bbdfc-m2smb 6/6 Running 0 10m
pod/ebs-csi-controller-5f945bbdfc-nfl97 6/6 Running 0 10m
pod/ebs-csi-node-kmtv9 3/3 Running 0 10m
pod/ebs-csi-node-tdw7m 3/3 Running 0 10m

NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
daemonset.apps/ebs-csi-node 2 2 2 2 2 kubernetes.io/os=linux 42h
daemonset.apps/ebs-csi-node-windows 0 0 0 0 0 kubernetes.io/os=windows 42h

NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/ebs-csi-controller 2/2 2 2 42h

NAME DESIRED CURRENT READY AGE
replicaset.apps/ebs-csi-controller-57ff9dc5fc 0 0 0 42h
replicaset.apps/ebs-csi-controller-5f945bbdfc 2 2 2 10m
  • 此时可以通过aws控制台对eks的Amazon EBS CSI 驱动程序进行管理,后续升级可以直接在控制台进行

  • 查看Amazon EBS CSI 驱动程序的所有可用版本号

1
$ aws eks describe-addon-versions --addon-name aws-ebs-csi-driver --profile eks-us-west-2
  • 更新 Amazon EBS CSI 驱动程序 ,–force 表示强制更新

1
2
3
4
5
6
7
8
9
10
11
12
# 查看是否有更新,可以看到UPDATE下有个可用更新版本 v1.20.0-eksbuild.1
$ eksctl get addon --name aws-ebs-csi-driver --cluster eks-lexing --profile eks-us-west-2
2023-06-30 10:21:31 [ℹ] Kubernetes version "1.26" in use by cluster "eks-lexing"
2023-06-30 10:21:32 [ℹ] 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.19.0-eksbuild.2 ACTIVE 0 arn:aws:iam::743263909644:role/AmazonEKS_EBS_CSI_DriverRole v1.20.0-eksbuild.1

# 更新到v1.20.0-eksbuild.1
$ eksctl update addon --name aws-ebs-csi-driver --version v1.20.0-eksbuild.1 --cluster eks-lexing --profile eks-us-west-2 --force
2023-06-30 10:22:23 [ℹ] Kubernetes version "1.26" in use by cluster "eks-lexing"
2023-06-30 10:22:24 [ℹ] new version provided v1.20.0-eksbuild.1
2023-06-30 10:22:24 [ℹ] updating addon
  • 删除 Amazon EBS CSI 驱动程序

1
$ eksctl delete addon --cluster eks-lexing --profile eks-us-west-2 --name aws-ebs-csi-driver --preserve

默认eks为我们创建好了一个sc:gp2

1
2
3
4
5
6
7
8
9
10
11
12
13
# 默认的gp2配置yaml,其被设置为默认存储类
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: gp2
annotations:
storageclass.kubernetes.io/is-default-class: "true"
provisioner: kubernetes.io/aws-ebs
parameters:
type: gp2
fsType: ext4

# storageclass.kubernetes.io/is-default-class: "true" 这个注释表示其是默认存储类

关于默认存储类的说明

  • 在 AWS 的 Amazon EKS(Elastic Kubernetes Service)中,将一个 StorageClass(SC)设置为默认存储类具有以下作用:
    • 自动分配: 当没有显式指定 StorageClass 的情况下,如果某个 Persistent Volume Claim(PVC)没有指定所需的 StorageClass,则默认会选择设置为默认存储类的 StorageClass 进行 PVC 的动态分配。
    • 简化配置: 默认存储类可以简化 PVC 的配置,因为您不需要为每个 PVC 显式指定 StorageClass。只需创建 PVC,并且它将自动使用默认存储类进行分配。
    • 默认设置: 默认存储类是集群级别的默认设置,适用于没有显式指定 StorageClass 的 PVC。这样可以确保在没有特定要求的情况下,PVC 可以使用预定义的默认存储类。
    • 在 AWS EKS 中,只能有一个 StorageClass 被设置为默认存储类。这是因为默认存储类是集群范围的全局设置,它用于满足未显式指定 StorageClass 的 PVC 的需求。如果有多个 StorageClass 被设置为默认,会导致混乱和不确定性,因为 Kubernetes 将无法确定使用哪个默认存储类。
    • 如果需要为不同的 PVC 使用不同的默认存储类,可以通过为每个 PVC 显式指定所需的 StorageClass 来实现,而不是依赖默认存储类。
    • 总结来说,通过设置默认存储类,您可以简化 PVC 的配置并定义集群范围的默认设置。但是,在 AWS EKS 中,只能有一个默认存储类。

使用说明

  • 创建StorageClass

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# 创建基于gp3的sc
# create-sc-gp3.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: gp3
provisioner: ebs.csi.aws.com
volumeBindingMode: WaitForFirstConsumer
parameters:
type: gp3
allowVolumeExpansion: true
reclaimPolicy: Delete

# 部署
$ k apply -f create-sc-gp3.yaml
# 查看sc
$ k get sc
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
gp2 (default) kubernetes.io/aws-ebs Delete WaitForFirstConsumer false 175m
gp3 ebs.csi.aws.com Delete WaitForFirstConsumer true 6s

# 虽然创建sc时没有为其指定默认存储类,我们可以通过如下命令将指定的sc设置为默认存储类
$ k annotate storageclass gp3 storageclass.kubernetes.io/is-default-class=true
# 此时原gp2的默认存储类不会被去掉
$ k get sc
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
gp2 (default) kubernetes.io/aws-ebs Delete WaitForFirstConsumer false 20h
gp3 (default) ebs.csi.aws.com Delete WaitForFirstConsumer true 17h

# 取消指定的sc为默认存储类
$ k annotate storageclass --overwrite=true gp3 storageclass.kubernetes.io/is-default-class=false

配置说明

  • provisioner
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# provisioner 定义了用于动态分配 PV 的存储插件或存储后端。它指定了负责创建和管理 PV 的控制器。
# provisioner 的值通常是存储提供商或存储插件的名称,例如
# kubernetes.io/aws-ebs(用于 Amazon EBS)、
# kubernetes.io/gce-pd(用于 Google Compute Engine PD)等。
# 不同的存储插件或存储后端可能具有不同的特性和配置选项。
# 这里的ebs.csi.aws.com就是我们安装的Amazon EBS CSI 附加组件。

# 在 AWS 的 Amazon EKS(Elastic Kubernetes Service)中,创建 StorageClass(SC)时,支持以下一些常见的 provisioner(供应商)选项:
# kubernetes.io/aws-ebs: 这是用于 Amazon EBS(Elastic Block Store)的默认 provisioner。它允许在 EKS 集群上动态分配和管理基于 Amazon EBS 的持久卷(PV)。
# kubernetes.io/aws-s3: 这是用于 Amazon S3(Simple Storage Service)的 provisioner。它允许在 EKS 集群中创建和管理基于 Amazon S3 的持久卷。
# kubernetes.io/azure-disk: 这是用于 Azure Disk 的 provisioner。它允许在 EKS 集群上动态分配和管理基于 Azure Disk 的持久卷。
# kubernetes.io/azure-file: 这是用于 Azure File 的 provisioner。它允许在 EKS 集群中创建和管理基于 Azure File 的持久卷。
# 这些是一些常见的 provisioner,但实际上,您还可以使用其他存储插件或自定义 provisioner,以满足您特定的存储需求。不同的存储插件和供应商可能会支持不同的 provisioner,具体取决于您所使用的存储插件和存储后端。
# 在创建 StorageClass 时,您需要指定适当的 provisioner 标识符,以便 Kubernetes 和 EKS 能够根据指定的 provisioner 来分配和管理持久卷。
  • allowVolumeExpansion
1
2
3
4
# allowVolumeExpansion 是一个布尔值参数,用于指定是否允许 PVC 的大小在运行时进行扩展。
# 如果将其设置为 true,则表示 PVC 可以动态扩展其大小以满足需求。
# 如果将其设置为 false,则 PVC 的大小将在创建时被固定,并且不能在后续进行扩展。
# 这取决于存储后端是否支持 PVC 大小的动态调整。
  • volumeBindingMode

1
2
3
4
5
6
7
# 在创建 StorageClass 时,可以指定 volumeBindingMode 来定义持久卷(Persistent Volume,PV)与 Persistent Volume Claim(PVC)之间的绑定行为。volumeBindingMode 可以具有以下几种选项:
# Immediate: 当使用 Immediate 绑定模式时,Kubernetes 立即绑定 PVC 和 PV。这意味着在创建 PVC 时,Kubernetes 将立即选择并绑定一个可用的 PV。这种模式适用于那些支持动态供应的存储后端。
# WaitForFirstConsumer: 使用 WaitForFirstConsumer 绑定模式时,PV 不会立即绑定到 PVC。PV 只有在第一个 Pod 试图使用 PVC 时才会绑定。这种模式适用于那些需要在 Pod 实际使用 PVC 之前进行一些准备工作的存储后端。例如,如果需要在创建 PV 后手动配置外部存储系统。
# Delayed: Delayed 绑定模式类似于 WaitForFirstConsumer,但不支持多个 Pod 使用同一个 PVC。只有当 Pod 被调度到节点并使用 PVC 时,PV 才会绑定。这种模式适用于那些只支持单个 Pod 使用 PVC 的存储后端。与 WaitForFirstConsumer 模式相比,Delayed 模式对 PV 和 PVC 之间的绑定更加延迟。
# Unknown: 如果未指定 volumeBindingMode,则默认为 Unknown。这意味着 Kubernetes 控制器或存储系统将决定如何绑定 PV 和 PVC。这种情况下,存储系统或云提供商的默认行为将适用。

Amazon EBS CSI 只支持 Immediate 和 WaitForFirstConsumer,默认是Immediate。
  • reclaimPolicy

1
2
3
4
5
6
7
# 在 Kubernetes 中,reclaimPolicy 是指定持久卷(Persistent Volume,PV)的回收策略。reclaimPolicy 可以具有以下几种选项:
# Retain: 使用 Retain 回收策略时,PV 的数据将被保留,而不会被自动删除。当 PV 和其对应的 Persistent Volume Claim(PVC)之间的关系解除时,PV 不会被回收或删除。管理员需要手动处理 PV 的回收或重新使用。
# Delete: Delete 回收策略表示在 PV 和 PVC 之间的关系解除时,PV 将被自动删除和回收。PV 中存储的数据将被清除,且无法恢复。这是最常见的回收策略,适用于临时数据或不需要长期保留的情况。
# Recycle: Recycle 回收策略是 Kubernetes 早期版本中使用的一种策略,但在 Kubernetes v1.7 版本之后已被弃用。该策略在解除 PV 和 PVC 之间的关系后,会尝试清除 PV 中的数据,使其可以被其他 PVC 重新使用。但这个清除过程仅限于删除 PV 上的文件,而不会对 PV 进行格式化或重建。
# External: External 回收策略表示在 PV 和 PVC 之间的关系解除时,PV 的回收和删除操作由外部的存储管理系统或管理员处理。Kubernetes 不会主动回收或删除 PV,而是委托给外部系统进行处理。

Amazon EBS CSI 只支持 Retain 和 Delete,默认是Delete。
  • 创建PVC

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
create-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: ebs-gp3-claim
spec:
accessModes:
- ReadWriteOnce
storageClassName: gp3
resources:
requests:
storage: 4Gi

$ k apply -f create-pvc.yaml

# pvc指定的sc中的volumeBindingMode是WaitForFirstConsumer,只有被使用到时才会去真正申请资源,所以此时看到的状态一直都会是Pending
$ k get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
ebs-gp3-claim Pending gp3 2m51s

配置说明

  • accessModes
1
2
3
4
5
6
7
8
# 在 Kubernetes 中,PVC 是用于声明性地请求持久化存储资源的对象。它定义了 Pod 对持久卷(Persistent Volume,PV)的访问要求。PVC 可以指定不同的 accessModes,以确定 Pod 如何访问与之绑定的 PV。以下是 PVC 可能的 accessModes:
# ReadWriteOnce (RWO): 此模式表示 PVC 可以被一个单个 Pod 以读写的方式挂载。这意味着 PVC 只能被一个 Pod 使用,而且可以同时读取和写入数据。这是许多常见应用程序的默认模式,例如关系型数据库。
# ReadOnlyMany (ROX): 此模式表示 PVC 可以被多个 Pod 以只读的方式挂载。这意味着多个 Pod 可以同时读取数据,但不能写入。通常用于需要共享只读数据的场景,例如日志收集或静态内容的共享。
# ReadWriteMany (RWX): 此模式表示 PVC 可以被多个 Pod 以读写的方式挂载。这意味着多个 Pod 可以同时读取和写入数据。然而,不是所有的存储插件都支持此模式,因此需要确保所使用的存储后端能够满足该要求。这是最具挑战性的模式,因为需要提供多个 Pod 之间的数据同步和一致性。

需要注意的是,Amazon EBS CSI 目前只支持 ReadWriteOnce 访问模式,即每个卷只能被单个 Pod 以读写方式挂载。ReadOnlyMany 和 ReadWriteMany 访问模式在 Amazon EBS CSI 中尚未支持。

如果您需要多个 Pod 可以同时以只读方式访问卷,您可以考虑使用 Amazon EFS(Elastic File System),它提供了 ReadWriteMany 访问模式,以满足多个 Pod 的同时只读访问需求。
  • 申请ebs资源

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# 可以创建一个pod绑定这个pvc就可以看到资源被申请了
# create-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-gp3-claim

$ k apply -f create-pod.yaml

# 查看pv和pvc
$ k get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pvc-02700260-b5e0-40bf-8c72-c1afad9e103e 4Gi RWO Delete Bound test/ebs-gp3-claim gp3 4m34s
$ k get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
ebs-gp3-claim Bound pvc-02700260-b5e0-40bf-8c72-c1afad9e103e 4Gi RWO gp3 9m27s

# VolumeHandle: vol-0362860fb03d9d618 就是实际的EBS卷ID
$ k describe pv pvc-02700260-b5e0-40bf-8c72-c1afad9e103e
Name: pvc-02700260-b5e0-40bf-8c72-c1afad9e103e
Labels: <none>
Annotations: pv.kubernetes.io/provisioned-by: ebs.csi.aws.com
volume.kubernetes.io/provisioner-deletion-secret-name:
volume.kubernetes.io/provisioner-deletion-secret-namespace:
Finalizers: [kubernetes.io/pv-protection external-attacher/ebs-csi-aws-com]
StorageClass: gp3
Status: Bound
Claim: test/ebs-gp3-claim
Reclaim Policy: Delete
Access Modes: RWO
VolumeMode: Filesystem
Capacity: 4Gi
Node Affinity:
Required Terms:
Term 0: topology.ebs.csi.aws.com/zone in [us-west-2b]
Message:
Source:
Type: CSI (a Container Storage Interface (CSI) volume source)
Driver: ebs.csi.aws.com
FSType: ext4
VolumeHandle: vol-0362860fb03d9d618
ReadOnly: false
VolumeAttributes: storage.kubernetes.io/csiProvisionerIdentity=1687940646992-1017-ebs.csi.aws.com
Events: <none>

# Used By 中展示的就是当前正在使用pvc的pod
$ k describe pvc ebs-gp3-claim
Name: ebs-gp3-claim
Namespace: test
StorageClass: gp3
Status: Bound
Volume: pvc-02700260-b5e0-40bf-8c72-c1afad9e103e
Labels: <none>
Annotations: pv.kubernetes.io/bind-completed: yes
pv.kubernetes.io/bound-by-controller: yes
volume.beta.kubernetes.io/storage-provisioner: ebs.csi.aws.com
volume.kubernetes.io/selected-node: ip-192-168-48-14.us-west-2.compute.internal
volume.kubernetes.io/storage-provisioner: ebs.csi.aws.com
Finalizers: [kubernetes.io/pvc-protection]
Capacity: 4Gi
Access Modes: RWO
VolumeMode: Filesystem
Used By: app-56df75755d-2phz4
app-56df75755d-cvjvc
app-56df75755d-xx9gh
Events: <none>

# 此时如果删除pod,则其对应的pvc并不会被删除,之前申请到的ebs也不会被清除
$ k delete -f create-pod.yaml
$ k get pod
No resources found in test namespace.

$ k get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pvc-02700260-b5e0-40bf-8c72-c1afad9e103e 4Gi RWO Delete Bound test/ebs-gp3-claim gp3 9m47s
$ k get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
ebs-gp3-claim Bound pvc-02700260-b5e0-40bf-8c72-c1afad9e103e 4Gi RWO gp3 14m

# 此时如果重新创建pod并关联该pvc,则磁盘依旧有效,并且是不会被清空的
$ k apply -f create-pod.yaml
# 查看pod的输出,可以看到中间有个超过5秒的间隔,这就是pod被删除然后又重建的间隔时间,说明磁盘没有被清空重建
$ k exec -it app -- tail -f /data/out.txt
Thu Jun 29 01:51:31 UTC 2023
Thu Jun 29 01:51:36 UTC 2023
Thu Jun 29 01:51:41 UTC 2023
Thu Jun 29 01:53:25 UTC 2023
Thu Jun 29 01:53:30 UTC 2023
Thu Jun 29 01:53:35 UTC 2023

# 如果要彻底删除磁盘,需要删除pvc,sc中的reclaimPolicy是Delete才会被删除
$ k delete -f create-pvc.yaml
persistentvolumeclaim "ebs-gp3-claim" deleted
$ k get pvc
No resources found in test namespace.
$ k get pv
No resources found

一个deployment并挂载ebs的示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# deployment-volume.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: ebs-gp3-claim
spec:
accessModes:
- ReadWriteOnce
storageClassName: gp3
resources:
requests:
storage: 4Gi

---
apiVersion: apps/v1
kind: Deployment
metadata:
name: app
spec:
replicas: 3
selector:
matchLabels:
app: app
template:
metadata:
labels:
app: 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-gp3-claim

# 部署
~ k deploy -f deployment-volume.yaml
# 查看deploy
~ k get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
app 3/3 3 3 85s

~ k get pod
NAME READY STATUS RESTARTS AGE
app-699cf8fdd-fk8vs 0/1 Running 0 90s
app-699cf8fdd-gpk7m 0/1 Running 0 90s
app-699cf8fdd-h5mbr 0/1 Running 0 90s

# 可以看到3个pod在同时写入一个文件
~ k exec -it app-699cf8fdd-fk8vs -- head /data/out.txt
Fri Jul 7 09:55:21 UTC 2023
Fri Jul 7 09:55:21 UTC 2023
Fri Jul 7 09:55:21 UTC 2023
Fri Jul 7 09:55:26 UTC 2023
Fri Jul 7 09:55:26 UTC 2023
Fri Jul 7 09:55:26 UTC 2023
Fri Jul 7 09:55:31 UTC 2023
Fri Jul 7 09:55:31 UTC 2023

# 重启deploy
~ k rollout restart deployment app
deployment.apps/app restarted

# 可以看到重新启动了3个pod,并且终止了原先启动的3个pod
~ k get pod
NAME READY STATUS RESTARTS AGE
app-667968b659-62dpl 1/1 Running 0 6s
app-667968b659-7x6wj 1/1 Running 0 4s
app-667968b659-n2rvz 1/1 Running 0 2s
app-699cf8fdd-fk8vs 1/1 Terminating 0 287s
app-699cf8fdd-gpk7m 1/1 Terminating 0 287s
app-699cf8fdd-h5mbr 1/1 Terminating 0 287s

# 可以看到重启deploy后,文件内容依旧存在
~ k exec -it app-667968b659-62dpl -- head /data/out.txt
Fri Jul 7 09:55:21 UTC 2023
Fri Jul 7 09:55:21 UTC 2023
Fri Jul 7 09:55:21 UTC 2023
Fri Jul 7 09:55:26 UTC 2023
Fri Jul 7 09:55:26 UTC 2023
Fri Jul 7 09:55:26 UTC 2023
Fri Jul 7 09:55:31 UTC 2023
Fri Jul 7 09:55:31 UTC 2023

讨论

  • 这里注意一下,k8s-1.23版本创建时会成功,但是重启不成功,只会重新启动成功一个pod,另外两个pod会失败,提示pvc已经被一个pod关联了,但是1.25版就可以创建和重启时都可以成功,不确定是否和Amazon EBS CSI 版本有关系。

后记

  • 这里要注意一个问题,如果pv被pvc绑定,此时是无法删除pv的,同理pvc被其它资源关联,也是不能被删除的,需要先删除对应的资源才可以。

  • EBS不能跨可用区,如果pod部署在不同的可用区,则不能使用ebs作为存储,此时可以使用EFS。