我研究了Kubernetes的PVC、Deployment和StatefulSet之间的关系
首先
「Persistent Volume」是为了在Kubernetes中管理和使用存储而设计的Pod。我们将通过验证来进一步理解在使用Deployment和StatefulSet时如何将Persistent Volume与Pod关联起来。我们将在一个由一个Master和两个Node组成的Kubernetes集群上使用NFS进行Persistent Volume的验证。
准备NFS服务器
请适当准备NFS服务器
请参考以下网址
准备NFS客户端
为了执行 NFS 挂载,Node 上需要进行 NFS 客户端的预先准备。为了安全起见,请在 Master 和所有 Node 上提前安装。
请参考以下网址。
请查看以下链接。
请点击以下链接。
持久卷和部署的关联验证
创建持久化卷
KubernetesMaster上で、Persistent Volume を定義するYAMLファイルを作成します
cat <<'EOF' > /root/kube_yaml/persistent_volume/persistent_volume.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv0001
spec:
capacity:
storage: 1Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Recycle
storageClassName: slow
mountOptions:
- hard
nfs:
server: 192.168.120.230
path: /mnt/nfsserv
EOF
以下是各个参数的显著特点。
Kubernetes 1.9 より、 “Block” がサポートされたため、volumeMode を指定出来るようになったspec.accessModesアクセスモードPVへアクセスするモードを定義する。選択可能なアクセスモードは、PVのVolumePluginに依存している。
ReadWriteOnce : 1つのNodeがPVをmountすることが出来る。読み書き可能。
ReadOnlyMany : 複数のNodeがPVをmountすることが出来る。読み取り専用。
ReadWriteMany : 複数のNodeがPVをmountすることが出来る。読み書き可能spec.storageClassNameストレージクラス名Kubernetesクラスタ管理者が定義しているストレージのクラスから、1種類を選択します。
ストレージの性質をクラスタ管理者が定義するものが、ストレージクラスです。
例えば、fast class は高価な早いストレージと定義し、slow class は安価な遅めなストレージと定義する運用が考えられますspec.persistentVolumeReclaimPolicy削除時の動作PVを削除したときの動作を指定します。
Retain : 削除しない。手動で削除を行う
Recycle : 削除して再利用する “rm -rf /voluma_path/*” のイメージ
Delete : Volumeを削除
PV を作成します
kubectl create -f /root/kube_yaml/persistent_volume/persistent_volume.yaml
確認します
[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]# kubectl get pv -o wide
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv0001 1Gi RWO Recycle Available slow 22s
目前阶段,NFS上尚未创建任何文件。
[root@sugi-nfs nfsserv]# pwd
/mnt/nfsserv
[root@sugi-nfs nfsserv]#
[root@sugi-nfs nfsserv]# ls -la
total 0
drwxr-xr-x 2 root root 6 Jun 1 11:59 .
drwxr-xr-x. 3 root root 21 Jun 1 11:50 ..
创建持久化存储声明
PVC(Persistent Volume Claims)とは、PVを要求するためのKubernetesリソースです。
PVには、ストレージ提供側の固有の情報(IPアドレスや、NFSエクスポートポイントなど)が含まれています。
Kubernetesクラスタの利用者がPVを作成しようとすると、ストレージ提供側の固有の情報を知る必要があります。
ストレージ固有の情報を抽象化するために、PVCが存在しています。
PVをKubernetesクラスタの管理者が作成し、PVCを利用者が作成することが想定されています。
为了创建PVC,创建以下YAML文件。
cat <<'EOF' > /root/kube_yaml/persistent_volume/persistent_volume_claims.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: test-claim
annotations:
volume.kubernetes.io/storage-class: "nfs"
spec:
accessModes:
- ReadWriteOnce
volumeMode: Filesystem
storageClassName: slow
resources:
requests:
storage: 1Gi
EOF
创建PVC
kubectl create -f /root/kube_yaml/persistent_volume/persistent_volume_claims.yaml
我会确认。 (Wǒ huì .)
[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]# kubectl get pvc -o wide
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
test-claim Bound pv0001 1Gi RWO slow 17s
当查看PVC的详细信息时,我们可以发现PV0001被使用了。
[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]# kubectl describe pvc test-claim
Name: test-claim
Namespace: default
StorageClass: slow
Status: Bound
Volume: pv0001
Labels: <none>
Annotations: pv.kubernetes.io/bind-completed=yes
pv.kubernetes.io/bound-by-controller=yes
volume.kubernetes.io/storage-class=nfs
Finalizers: [kubernetes.io/pvc-protection]
Capacity: 1Gi
Access Modes: RWO
Events: <none>
PVを確認すると、Available だった STATUS が、 Bound と変化しており、PVCに紐づけられています
[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]# kubectl get pv -o wide
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv0001 1Gi RWO Recycle Bound default/test-claim slow 2h
创建部署
为了部署,创建以下的YAML文件。
在Deployment中,通过spec.template.spec.volumes.persistentVolumeClaim.claimName指定要使用的PVC。
为了将其分配给实际容器,通过spec.template.spec.containers.volumeMounts指定。
将PVC挂载到容器内的/persistent-volume的设置。
cat <<'EOF' > /root/kube_yaml/persistent_volume/persistent_deployment.yaml
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
name: persistent-deployment
spec:
selector:
matchLabels:
app: persistest_test
replicas: 1
template:
metadata:
labels:
app: persistest_test
spec:
containers:
- name: master
image: nginx
resources:
requests:
cpu: 100m
memory: 100Mi
ports:
- containerPort: 80
volumeMounts:
- mountPath: /persistent-volume
name: pvc-volume
volumes:
- name: pvc-volume
persistentVolumeClaim:
claimName: test-claim
restartPolicy: Always
EOF
创建部署
kubectl create -f /root/kube_yaml/persistent_volume/persistent_deployment.yaml
创建了部署,并且创建了Pod。
[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE
persistent-deployment-b9db64785-7fq4z 1/1 Running 0 47s 10.244.1.29 sugi-kubernetes110-node01.localdomain
当在node01上查看df时,可以看到已经挂载了NFS服务器。
[root@sugi-kubernetes110-node01 ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/cl-root 14G 3.5G 10G 26% /
devtmpfs 1.9G 0 1.9G 0% /dev
tmpfs 1.9G 0 1.9G 0% /dev/shm
tmpfs 1.9G 129M 1.8G 7% /run
tmpfs 1.9G 0 1.9G 0% /sys/fs/cgroup
/dev/sda1 1014M 289M 726M 29% /boot
tmpfs 1.9G 12K 1.9G 1% /var/lib/kubelet/pods/436d9ed6-4ae3-11e8-bbe9-0050569817ee/volumes/kubernetes.io~secret/kube-proxy-token-c9qtq
tmpfs 1.9G 12K 1.9G 1% /var/lib/kubelet/pods/436dce14-4ae3-11e8-bbe9-0050569817ee/volumes/kubernetes.io~secret/flannel-token-6pnqp
tmpfs 380M 0 380M 0% /run/user/0
tmpfs 1.9G 12K 1.9G 1% /var/lib/kubelet/pods/2f404ff6-6562-11e8-8767-0050569817ee/volumes/kubernetes.io~secret/default-token-q65hj
192.168.120.230:/mnt/nfsserv 14G 1.5G 12G 11% /var/lib/kubelet/pods/2f404ff6-6562-11e8-8767-0050569817ee/volumes/kubernetes.io~nfs/pv0001
另外,在node01上查看docker列表
[root@sugi-kubernetes110-node01 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b7dea7029d25 docker.io/nginx@sha256:0fb320e2a1b1620b4905facb3447e3d84ad36da0b2c8aa8fe3a5a81d1187b884 "nginx -g 'daemon ..." 4 minutes ago Up 4 minutes k8s_master_persistent-deployment-b9db64785-7fq4z_default_2f404ff6-6562-11e8-8767-0050569817ee_0
13deb2cc4164 k8s.gcr.io/pause-amd64:3.1 "/pause" 4 minutes ago Up 4 minutes k8s_POD_persistent-deployment-b9db64785-7fq4z_default_2f404ff6-6562-11e8-8767-0050569817ee_0
b9d65d4ddb1c 2b736d06ca4c "/opt/bin/flanneld..." 4 weeks ago Up 4 weeks k8s_kube-flannel_kube-flannel-ds-d92qj_kube-system_436dce14-4ae3-11e8-bbe9-0050569817ee_1
5592ed89cbe0 77019aa0531a "/usr/local/bin/ku..." 4 weeks ago Up 4 weeks k8s_kube-proxy_kube-proxy-khhwf_kube-system_436d9ed6-4ae3-11e8-bbe9-0050569817ee_1
496d9d63cddd k8s.gcr.io/pause-amd64:3.1 "/pause" 4 weeks ago Up 4 weeks k8s_POD_kube-flannel-ds-d92qj_kube-system_436dce14-4ae3-11e8-bbe9-0050569817ee_1
fab2fd0c0a3b k8s.gcr.io/pause-amd64:3.1 "/pause" 4 weeks ago Up 4 weeks k8s_POD_kube-proxy-khhwf_kube-system_436d9ed6-4ae3-11e8-bbe9-0050569817ee_1
显示该容器的详细信息后,可以看出它正在使用已挂载到NFS的卷。
# docker inspect b7dea7029d25
... snip ....
"Mounts": [
{
"Type": "bind",
"Source": "/var/lib/kubelet/pods/2f404ff6-6562-11e8-8767-0050569817ee/etc-hosts",
"Destination": "/etc/hosts",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
},
{
"Type": "bind",
"Source": "/var/lib/kubelet/pods/2f404ff6-6562-11e8-8767-0050569817ee/containers/master/1abcb732",
"Destination": "/dev/termination-log",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
},
{
"Type": "bind",
"Source": "/var/lib/kubelet/pods/2f404ff6-6562-11e8-8767-0050569817ee/volumes/kubernetes.io~nfs/pv0001",
"Destination": "/persistent-volume", ← ココを見る
"Mode": "rslave",
"RW": true,
"Propagation": "rslave"
},
nginx pod にログインします
[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]# kubectl exec -it persistent-deployment-b9db64785-7fq4z bash
root@persistent-deployment-b9db64785-7fq4z:/#
您可以确认在 Pod 内正常安装了。
从Pod内可以看到NFS服务器的IP地址。这取决于存储类型,但可能还需要考虑到确保Pod使用者可以知道存储端的IP地址而不会有问题。
root@persistent-deployment-b9db64785-7fq4z:/# df -h
Filesystem Size Used Avail Use% Mounted on
overlay 14G 3.5G 10G 26% /
tmpfs 1.9G 0 1.9G 0% /dev
tmpfs 1.9G 0 1.9G 0% /sys/fs/cgroup
192.168.120.230:/mnt/nfsserv 14G 1.5G 12G 11% /persistent-volume
/dev/mapper/cl-root 14G 3.5G 10G 26% /etc/hosts
shm 64M 0 64M 0% /dev/shm
tmpfs 1.9G 12K 1.9G 1% /run/secrets/kubernetes.io/serviceaccount
tmpfs 1.9G 0 1.9G 0% /proc/scsi
tmpfs 1.9G 0 1.9G 0% /sys/firmware
在pod内创建文件。
root@persistent-deployment-b9db64785-7fq4z:/persistent-volume# touch test_from_pod
root@persistent-deployment-b9db64785-7fq4z:/persistent-volume# pwd
/persistent-volume
root@persistent-deployment-b9db64785-7fq4z:/persistent-volume#
root@persistent-deployment-b9db64785-7fq4z:/persistent-volume# ls -la
total 0
drwxr-xr-x 2 root root 27 Jun 1 06:26 .
drwxr-xr-x 1 root root 53 Jun 1 06:08 ..
-rw-r--r-- 1 root root 0 Jun 1 06:26 test_from_pod
我能在NFS服务器上确认到上述创建的文件。
可以看出NFS服务器的ExportPoint和PV是一对一对应的。(使用NFS的DynamicProvisioner,ExportPoint会自动创建吗?)
[root@sugi-nfs nfsserv]# ls -la
total 0
drwxr-xr-x 2 root root 27 Jun 1 15:26 .
drwxr-xr-x. 3 root root 21 Jun 1 11:50 ..
-rw-r--r-- 1 root root 0 Jun 1 15:26 test_from_pod
[root@sugi-nfs nfsserv]#
[root@sugi-nfs nfsserv]# pwd
/mnt/nfsserv
如果将此部署的副本从1增加到2,会出现什么情况呢?
cat <<'EOF' > /root/kube_yaml/persistent_volume/persistent_deployment.yaml
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
name: persistent-deployment
spec:
selector:
matchLabels:
app: persistest_test
replicas: 2
template:
metadata:
labels:
app: persistest_test
spec:
containers:
- name: master
image: nginx
resources:
requests:
cpu: 100m
memory: 100Mi
ports:
- containerPort: 80
volumeMounts:
- mountPath: /persistent-volume
name: pvc-volume
volumes:
- name: pvc-volume
persistentVolumeClaim:
claimName: test-claim
restartPolicy: Always
EOF
申请进行更新 (” “)
[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]# kubectl apply -f /root/kube_yaml/persistent_volume/persistent_deployment.yaml
Warning: kubectl apply should be used on resource created by either kubectl create --save-config or kubectl apply
deployment.apps "persistent-deployment" configured
确认
[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]# kubectl get replicaset
NAME DESIRED CURRENT READY AGE
persistent-deployment-b9db64785 2 2 2 44m
确认pod
[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE
persistent-deployment-b9db64785-7fq4z 1/1 Running 0 44m 10.244.1.29 sugi-kubernetes110-node01.localdomain
persistent-deployment-b9db64785-rtbk7 1/1 Running 0 2m 10.244.2.28 sugi-kubernetes110-node02.localdomain
真是奇怪,PV被创建为ReadWriteOnce,但却连接到了多个节点。
你可以在node01和node02的容器上分别创建文件。
我不确定这是个bug还是什么原因导致的。
即使是第二个Pod,也可以正常写入。
root@persistent-deployment-b9db64785-rtbk7:/persistent-volume# touch test_from_pod02
root@persistent-deployment-b9db64785-rtbk7:/persistent-volume# ls -la
total 0
drwxr-xr-x 2 root root 50 Jun 1 06:59 .
drwxr-xr-x 1 root root 53 Jun 1 06:50 ..
-rw-r--r-- 1 root root 0 Jun 1 06:26 test_from_pod
-rw-r--r-- 1 root root 0 Jun 1 06:59 test_from_pod02
root@persistent-deployment-b9db64785-rtbk7:/persistent-volume#
root@persistent-deployment-b9db64785-rtbk7:/persistent-volume# pwd
/persistent-volume
确认Pod自动修复功能与PV之间的关系。
删除第一个Pod,并通过ReplicaSet触发自动修复功能。
[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]# kubectl delete pod persistent-deployment-b9db64785-7fq4z
pod "persistent-deployment-b9db64785-7fq4z" deleted
将会创建一个新的Pod。
[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE
persistent-deployment-b9db64785-rtbk7 1/1 Running 0 53m 10.244.2.28 sugi-kubernetes110-node02.localdomain
persistent-deployment-b9db64785-vfcd5 1/1 Running 0 27s 10.244.1.30 sugi-kubernetes110-node01.localdomain
当您确认到已经进行了自动修复的Pod时,可以看到这里仍然在使用PV。
您可以查看之前创建的文件,然后再删除它。
[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]# kubectl exec -it persistent-deployment-b9db64785-vfcd5 bash
root@persistent-deployment-b9db64785-vfcd5:/# ls -la /persistent-volume/
total 0
drwxr-xr-x 2 root root 50 Jun 1 06:59 .
drwxr-xr-x 1 root root 53 Jun 1 07:43 ..
-rw-r--r-- 1 root root 0 Jun 1 06:26 test_from_pod
-rw-r--r-- 1 root root 0 Jun 1 06:59 test_from_pod02
Deployment和PVC之间的关系总结
通过Deployment创建的Pod都会引用相同的PV。
这次我们创建了NFS作为PV,所以允许了ReadWriteAny,并且可以从多个Pod进行挂载。
然而,使用AWSElasticBlockStore或AWSElasticBlockStore时,由于不支持ReadWriteMany,所以预计在将PV与Deployment绑定时,无法将副本数量设为2或更多个。

当 Pod 遇到故障并执行了自动修复操作时,它仍然能够继续挂载相同的 PV。

对Persistent Volume(持续卷)和StatefulSet(有状态集)的关联进行验证。
在NFS服务器上导出用于PV的存储空间。
创建两个Pod作为StatefulSet。作为准备,我们需要设置两个NFS Export以创建两个PV。
[root@sugi-nfs mnt]# mkdir /mnt/pv002
[root@sugi-nfs mnt]# mkdir /mnt/pv003
[root@sugi-nfs mnt]# vi /etc/exports
/mnt/pv002 *(rw,async,no_root_squash)
/mnt/pv003 *(rw,async,no_root_squash)
重新加载导出点
[root@sugi-nfs mnt]# exportfs -ra
[root@sugi-nfs mnt]# exportfs -v
/mnt/pv002 <world>(rw,async,wdelay,hide,no_subtree_check,sec=sys,secure,no_root_squash,no_all_squash)
/mnt/pv003 <world>(rw,async,wdelay,hide,no_subtree_check,sec=sys,secure,no_root_squash,no_all_squash)
创建持久卷
cat <<'EOF' > /root/kube_yaml/persistent_volume/persistent_volume_002.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv002
spec:
capacity:
storage: 1Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Recycle
# storageClassName: slow
mountOptions:
- hard
nfs:
server: 192.168.120.230
path: /mnt/pv002
EOF
cat <<'EOF' > /root/kube_yaml/persistent_volume/persistent_volume_003.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv003
spec:
capacity:
storage: 1Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Recycle
# storageClassName: slow
mountOptions:
- hard
nfs:
server: 192.168.120.230
path: /mnt/pv003
EOF
PVを作成します
[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]# kubectl create -f /root/kube_yaml/persistent_volume/persistent_volume_002.yaml
persistentvolume "pv002" created
[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]# kubectl create -f /root/kube_yaml/persistent_volume/persistent_volume_003.yaml
persistentvolume "pv003" created
确认一下
[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv0001 1Gi RWO Recycle Bound default/test-claim slow 4h
pv002 1Gi RWO Recycle Available 8s
pv003 1Gi RWO Recycle Available 6s
创建 StatefulSet
定义 StatefulSet 的 YAML
cat <<'EOF' > /root/kube_yaml/persistent_volume/persistent_volume_statefulset.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: persistent-stateset
spec:
serviceName: nginx-service
replicas: 2
selector:
matchLabels:
app: persistent-stateful
template:
metadata:
labels:
app: persistent-stateful
spec:
containers:
- name: nginx-container
image: nginx
ports:
- containerPort: 80
volumeMounts:
- name: pvc-volume
mountPath: /persistent-volume
volumeClaimTemplates:
- metadata:
name: pvc-volume
spec:
accessModes:
- ReadWriteOnce
volumeMode: Filesystem
resources:
requests:
storage: 1Gi
EOF
创建StatefulSet。
kubectl create -f /root/kube_yaml/persistent_volume/persistent_volume_statefulset.yaml
[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]# kubectl get statefulset -o wide
NAME DESIRED CURRENT AGE CONTAINERS IMAGES
persistent-stateset 2 2 29s nginx-container nginx
PVC是自动生成的。
[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]# kubectl get pvc -o wide
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
pvc-volume-persistent-stateset-0 Bound pv002 1Gi RWO 1m
pvc-volume-persistent-stateset-1 Bound pv003 1Gi RWO 51s
test-claim Bound pv0001 1Gi RWO slow 2h
PVの一覧でも、PVCに bound されていることを確認できます
Deployment とは違い、Pod ごとに PV が接続されています
[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]# kubectl get pv -o wide
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv0001 1Gi RWO Recycle Bound default/test-claim slow 4h
pv002 1Gi RWO Recycle Bound default/pvc-volume-persistent-stateset-0 18m
pv003 1Gi RWO Recycle Bound default/pvc-volume-persistent-stateset-1 18m
StatefulSet の Pod も作成されています
[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE
persistent-stateset-0 1/1 Running 0 2m 10.244.1.32 sugi-kubernetes110-node01.localdomain
persistent-stateset-1 1/1 Running 0 2m 10.244.2.31 sugi-kubernetes110-node02.localdomain
通过查看分配给Pod的PVC,可以确定PVC已经与之关联。
# kubectl describe pod persistent-stateset-0
snip
Volumes:
pvc-volume:
Type: PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace)
ClaimName: pvc-volume-persistent-stateset-0
ReadOnly: false
default-token-q65hj:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-q65hj
Optional: false
# kubectl describe pod persistent-stateset-1
snip
Volumes:
pvc-volume:
Type: PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace)
ClaimName: pvc-volume-persistent-stateset-1
ReadOnly: false
default-token-q65hj:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-q65hj
Optional: false
それぞれのPodにログインし、test file を作成します
[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]# kubectl exec -it persistent-stateset-0 bash
root@persistent-stateset-0:/# df -h
Filesystem Size Used Avail Use% Mounted on
overlay 14G 3.5G 10G 26% /
tmpfs 1.9G 0 1.9G 0% /dev
tmpfs 1.9G 0 1.9G 0% /sys/fs/cgroup
192.168.120.230:/mnt/pv002 14G 1.5G 12G 11% /persistent-volume
/dev/mapper/cl-root 14G 3.5G 10G 26% /etc/hosts
shm 64M 0 64M 0% /dev/shm
tmpfs 1.9G 12K 1.9G 1% /run/secrets/kubernetes.io/serviceaccount
tmpfs 1.9G 0 1.9G 0% /proc/scsi
tmpfs 1.9G 0 1.9G 0% /sys/firmware
root@persistent-stateset-0:/# touch /persistent-volume/testfile-frompod-0
root@persistent-stateset-0:/# ls -la /persistent-volume/
total 0
drwxr-xr-x 2 root root 32 Jun 1 08:57 .
drwxr-xr-x 1 root root 65 Jun 1 08:48 ..
-rw-r--r-- 1 root root 0 Jun 1 08:57 testfile-frompod-0
[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]# kubectl exec -it persistent-stateset-1 bash
root@persistent-stateset-1:/# df -h
Filesystem Size Used Avail Use% Mounted on
overlay 14G 4.1G 9.4G 31% /
tmpfs 1.9G 0 1.9G 0% /dev
tmpfs 1.9G 0 1.9G 0% /sys/fs/cgroup
192.168.120.230:/mnt/pv003 14G 1.5G 12G 11% /persistent-volume
/dev/mapper/cl-root 14G 4.1G 9.4G 31% /etc/hosts
shm 64M 0 64M 0% /dev/shm
tmpfs 1.9G 12K 1.9G 1% /run/secrets/kubernetes.io/serviceaccount
tmpfs 1.9G 0 1.9G 0% /proc/scsi
tmpfs 1.9G 0 1.9G 0% /sys/firmware
root@persistent-stateset-1:/# touch /persistent-volume/testfile-frompod-1
root@persistent-stateset-1:/# ls -la /persistent-volume/
total 0
drwxr-xr-x 2 root root 32 Jun 1 08:57 .
drwxr-xr-x 1 root root 53 Jun 1 08:48 ..
-rw-r--r-- 1 root root 0 Jun 1 08:57 testfile-frompod-1
当您检查NFS服务器时,可以确认每个Export Point都创建了一个名为“test file”的文件。
[root@sugi-nfs mnt]# ls -la /mnt/pv002/
total 0
drwxr-xr-x 2 root root 32 Jun 1 17:57 .
drwxr-xr-x. 5 root root 47 Jun 1 17:10 ..
-rw-r--r-- 1 root root 0 Jun 1 17:57 testfile-frompod-0
[root@sugi-nfs mnt]#
[root@sugi-nfs mnt]# ls -la /mnt/pv003/
total 0
drwxr-xr-x 2 root root 32 Jun 1 17:57 .
drwxr-xr-x. 5 root root 47 Jun 1 17:10 ..
-rw-r--r-- 1 root root 0 Jun 1 17:57 testfile-frompod-1
Pod をオートヒーリングしたときのPVとの関係を確認
Podの1個目を削除して、StatefulSet によりオートヒーリングを発生させます。
您可以在删除后立即确认哪个Pod进行了自动治愈。
[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]# kubectl delete pod persistent-stateset-0
pod "persistent-stateset-0" deleted
[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]#
[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]# kubectl get pod
NAME READY STATUS RESTARTS AGE
persistent-stateset-0 0/1 Terminating 0 14m
persistent-stateset-1 1/1 Running 0 14m
[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]#
[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]# kubectl get pod
NAME READY STATUS RESTARTS AGE
persistent-stateset-0 0/1 Terminating 0 14m
persistent-stateset-1 1/1 Running 0 14m
[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]#
[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]# kubectl get pod
NAME READY STATUS RESTARTS AGE
persistent-stateset-0 0/1 Terminating 0 14m
persistent-stateset-1 1/1 Running 0 14m
[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]#
[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]# kubectl get pod
NAME READY STATUS RESTARTS AGE
persistent-stateset-0 0/1 Pending 0 0s
persistent-stateset-1 1/1 Running 0 14m
[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]#
[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]# kubectl get pod
NAME READY STATUS RESTARTS AGE
persistent-stateset-0 0/1 ContainerCreating 0 2s
persistent-stateset-1 1/1 Running 0 14m
[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]#
[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]# kubectl get pod
NAME READY STATUS RESTARTS AGE
persistent-stateset-0 0/1 ContainerCreating 0 3s
persistent-stateset-1 1/1 Running 0 14m
オートヒーリングされたPodを確認すると、こちらでも引き続き PV を使用していることがわかります。
削除前に作っていたファイルが確認できます
[root@sugi-kubernetes110-master01 ~(default kubernetes-admin)]# kubectl exec -it persistent-stateset-0 bash
root@persistent-stateset-0:/# ls -la /persistent-volume/
total 0
drwxr-xr-x 2 root root 32 Jun 1 08:57 .
drwxr-xr-x 1 root root 53 Jun 1 09:02 ..
-rw-r--r-- 1 root root 0 Jun 1 08:57 testfile-frompod-0
StatefulSet と PVC の関係まとめ
StatefulSet で作成された Pod は、それぞれ単一の PV をマウントしています
Deployment では、全てのPodで1個のPV をマウントしている違いがあります

当Pod发生故障并执行自动恢复时,仍然可以继续挂载相同的持久化卷以确保数据的持久性。
