


























基于 centos7.9,docker-ce-20.10.18,kubelet-1.22.3-0
为什么需要数据卷
数据卷概述
常用的数据卷:
emptyDir 卷:是一个临时存储卷,与 Pod 生命周期绑定一起,如果 Pod 删除了卷也会被删除。
应用场景:Pod 中容器之间数据共享
emptyDir 的实际存储路径在 pod 所在节点的 /var/lib/kubelet/pods/<pod-id>/volumes/kubernetes.io~empty-dir 目录下
查看 pod 的 uid
kubectl get pod <pod-name> -o jsonpath='{.metadata.uid}'
示例如下
apiVersion: v1
kind: Pod
metadata:
name: demo-emptydir
spec:
terminationGracePeriodSeconds: 5
containers:
- name: write
image: busybox
imagePullPolicy: IfNotPresent
command: ["/bin/sh", "-c", "for i in $(seq 100); do echo $i >> /data/hello; sleep 1; done"]
volumeMounts:
- name: data
mountPath: /data
- name: read
image: busybox
imagePullPolicy: IfNotPresent
command: ["/bin/sh", "-c", "tail -f /data/hello"]
volumeMounts:
- name: data
mountPath: /data
volumes:
- name: data
emptyDir: {}
查看日志
[root@k8s-node1 ~]# kubectl logs -f demo-emptydir -c read
1
2
3
...
hostPath 卷:挂载 Node 文件系统(Pod 所在节点)上文件或者目录到 Pod 中的容器。
应用场景:Pod 中容器需要访问宿主机文件
示例 yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-hostpath
spec:
terminationGracePeriodSeconds: 5
containers:
- name: busybox
image: busybox
imagePullPolicy: IfNotPresent
command: ["/bin/sh", "-c", "sleep 36000"]
volumeMounts:
- name: data
mountPath: /data
volumes:
- name: data
hostPath:
path: /tmp
type: Directory
NFS 卷提供对 NFS 挂载支持,可以自动将 NFS 共享路径挂载到 Pod 中
配置 nfs 服务端,
yum install nfs-utils # nfs-utils包每个节点都需安装
mkdir -p /nfs
echo "/nfs 1.1.1.0/24(rw,async,no_root_squash)" >> /etc/exports
# 格式:NFS共享的目录 客户端地址1(参数1,参数2,...) 客户端地址2(参数1,参数2,...))
systemctl enable --now nfs
systemctl enable --now rpcbind
客户端测试
[root@k8s-node2 ~]# mount -t nfs k8s-node1:/nfs /mnt/
[root@k8s-node2 ~]# df -hT | grep k8s-node1
k8s-node1:/nfs nfs4 44G 4.0G 41G 9% /mnt
示例 yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: demo-nfs
labels:
app: demo-nfs
spec:
replicas: 3
selector:
matchLabels:
app: demo-nfs
template:
metadata:
labels:
app: demo-nfs
spec:
terminationGracePeriodSeconds: 5
containers:
- name: demo-nfs
image: nginx:1.22.1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html/
volumes:
- name: www
nfs:
server: k8s-node1
path: /nfs/
---
apiVersion: v1
kind: Service
metadata:
name: demo-nfs
labels:
app: demo-nfs
spec:
selector:
app: demo-nfs
ports:
- protocol: TCP
port: 80
targetPort: 80
nodePort: 30003
type: NodePort
验证
[root@k8s-node1 ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
demo-nfs NodePort 10.97.209.119 <none> 80:30003/TCP 5m41s
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 5d2h
[root@k8s-node1 ~]# echo "hello, nfs" > /nfs/index.html
[root@k8s-node1 ~]# curl 10.97.209.119
hello, nfs
pvc 如何匹配到 pv
存储空间字段能否限制实际可用容量
AccessModes(访问模式):
AccessModes 是用来对 PV 进行访问模式的设置,用于描述用户应用对存储资源的访问权限,访问权限包括下面几种方式:
RECLAIM POLICY(回收策略):
目前 PV 支持的策略有三种:
STATUS(状态):
一个 PV 的生命周期中,可能会处于 4 中不同的阶段:
pv 示例
apiVersion: v1
kind: PersistentVolume
metadata:
name: demo-pv
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteMany
nfs:
server: k8s-node1
path: /nfs
pvc 示例
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: demo-pvc
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 5Gi
deployment & service 示例
apiVersion: apps/v1
kind: Deployment
metadata:
name: demo-pvc
labels:
app: demo-pvc
spec:
replicas: 3
selector:
matchLabels:
app: demo-pvc
template:
metadata:
labels:
app: demo-pvc
spec:
terminationGracePeriodSeconds: 5
containers:
- name: demo-pvc
image: nginx:1.22.1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
volumeMounts:
- name: www-pvc
mountPath: /usr/share/nginx/html/
volumes:
- name: www-pvc
persistentVolumeClaim:
claimName: demo-pvc
---
apiVersion: v1
kind: Service
metadata:
name: demo-pvc
labels:
app: demo-pvc
spec:
selector:
app: demo-pvc
ports:
- protocol: TCP
port: 80
targetPort: 80
验证
[root@k8s-node1 ~]# echo "pvc for NFS is successful" > /nfs/index.html
[root@k8s-node1 ~]# kubectl get svc -l app=demo-pvc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
demo-pvc ClusterIP 10.97.28.93 <none> 80/TCP 102s
[root@k8s-node1 ~]# curl 10.97.28.93
pvc for NFS is successful
之前的 PV 使用方式称为静态供给,需要 K8s 运维工程师提前创建一堆 PV,供开发者使用
因此,K8s 开始支持 PV 动态供给,使用 StorageClass 对象实现。
基于 NFS 实现自动创建 pv 插件
自动创建的 pv 挂载路径为 <nfs-path>/<namespace>-<pvc-name>-<pv-name>
<volumeClaimTemplates-name>-<pod-name>pvc-<pvc-uid>k8s-1.20 版本后默认禁止使用 selfLink,需要打开一下
修改 k8s 的 apiserver 参数,改完 apiserver 会自动重启
[root@k8s-node1 ~]# vi /etc/kubernetes/manifests/kube-apiserver.yaml
apiVersion: v1
···
- --tls-private-key-file=/etc/kubernetes/pki/apiserver.key
- --feature-gates=RemoveSelfLink=false # 添加这个配置
此组件是对 nfs-client-provisioner 的扩展,nfs-client-provisioner 已经不提供更新,且 nfs-client-provisioner 的 Github 仓库已经迁移到 NFS-Subdir-External-Provisioner 的仓库
rbac
创建 nfs-rbac.yml
apiVersion: v1
kind: ServiceAccount
metadata:
name: nfs-client-provisioner
namespace: kube-system
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: nfs-client-provisioner-runner
rules:
- apiGroups: [""]
resources: ["persistentvolumes"]
verbs: ["get", "list", "watch", "create", "delete"]
- apiGroups: [""]
resources: ["persistentvolumeclaims"]
verbs: ["get", "list", "watch", "update"]
- apiGroups: ["storage.k8s.io"]
resources: ["storageclasses"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["events"]
verbs: ["create", "update", "patch"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: run-nfs-client-provisioner
subjects:
- kind: ServiceAccount
name: nfs-client-provisioner
namespace: kube-system
roleRef:
kind: ClusterRole
name: nfs-client-provisioner-runner
apiGroup: rbac.authorization.k8s.io
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: leader-locking-nfs-client-provisioner
namespace: kube-system
rules:
- apiGroups: [""]
resources: ["endpoints"]
verbs: ["get", "list", "watch", "create", "update", "patch"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: leader-locking-nfs-client-provisioner
namespace: kube-system
subjects:
- kind: ServiceAccount
name: nfs-client-provisioner
namespace: kube-system
roleRef:
kind: Role
name: leader-locking-nfs-client-provisioner
apiGroup: rbac.authorization.k8s.io
nfs-subdir-external-provisioner
创建 nfs-provisioner-deploy.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nfs-client-provisioner
namespace: kube-system
labels:
app: nfs-client-provisioner
spec:
replicas: 1
strategy:
type: Recreate # 设置升级策略为删除再创建(默认为滚动更新)
selector:
matchLabels:
app: nfs-client-provisioner
template:
metadata:
labels:
app: nfs-client-provisioner
spec:
serviceAccountName: nfs-client-provisioner
containers:
- name: nfs-client-provisioner
#image: gcr.io/k8s-staging-sig-storage/nfs-subdir-external-provisioner:v4.0.0
image: registry.cn-hangzhou.aliyuncs.com/lvbibir/nfs-subdir-external-provisioner:v4.0.2
volumeMounts:
- name: nfs-client-root
mountPath: /persistentvolumes
env:
- name: PROVISIONER_NAME # Provisioner的名称,以后设置的storageclass要和这个保持一致
value: nfs-client
- name: NFS_SERVER # NFS服务器地址,需和valumes参数中配置的保持一致
value: 1.1.1.1
- name: NFS_PATH # NFS服务器数据存储目录,需和valumes参数中配置的保持一致
value: /nfs/kubernetes
volumes:
- name: nfs-client-root
nfs:
server: 1.1.1.1 # NFS服务器地址
path: /nfs/kubernetes # NFS服务器数据存储目录
storageClass
创建 nfs-sc.yml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: nfs
annotations:
storageclass.kubernetes.io/is-default-class: "true" ## 是否设置为默认的storageclass
provisioner: nfs-client ## 动态卷分配者名称,必须和deployment的PROVISIONER_NAME变量中设置的Name一致
parameters:
archiveOnDelete: "false" ## 设置为"false"时删除PVC不会保留数据,"true"则保留数据
mountOptions:
- hard ## 指定为硬挂载方式
- nfsvers=4 ## 指定NFS版本,这个需要根据NFS Server版本号设置
创建上述资源
[root@k8s-node1 nfs]# mkdir /nfs/kubernetes/
[root@k8s-node1 nfs]# kubectl apply -f .
deployment.apps/nfs-client-provisioner created
serviceaccount/nfs-client-provisioner created
clusterrole.rbac.authorization.k8s.io/nfs-client-provisioner-runner created
clusterrolebinding.rbac.authorization.k8s.io/run-nfs-client-provisioner created
role.rbac.authorization.k8s.io/leader-locking-nfs-client-provisioner created
rolebinding.rbac.authorization.k8s.io/leader-locking-nfs-client-provisioner created
storageclass.storage.k8s.io/nfs created
apiVersion: apps/v1
kind: Deployment
metadata:
name: demo-auto-pv
labels:
app: demo-auto-pv
spec:
replicas: 3
selector:
matchLabels:
app: demo-auto-pv
template:
metadata:
labels:
app: demo-auto-pv
spec:
terminationGracePeriodSeconds: 5
containers:
- name: demo-auto-pv
image: nginx:1.22.1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html/
volumes:
- name: www
persistentVolumeClaim:
claimName: pvc-auto
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-auto
spec:
storageClassName: "nfs"
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 2Gi
测试验证
[root@k8s-node1 ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
pod/demo-auto-pv-7c974689b4-4cwr6 1/1 Running 0 47s
pod/demo-auto-pv-7c974689b4-bb9v8 1/1 Running 0 47s
pod/demo-auto-pv-7c974689b4-p525n 1/1 Running 0 47s
pod/nfs-client-provisioner-66d6cb77fd-47hsf 1/1 Running 0 4m15s
[root@k8s-node1 ~]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
persistentvolumeclaim/pvc-auto Bound pvc-22b65e10-ab97-47eb-aaa1-6c354a749a55 2Gi RWO managed-nfs-storage 47s
[root@k8s-node1 ~]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
persistentvolume/pvc-22b65e10-ab97-47eb-aaa1-6c354a749a55 2Gi RWO Delete Bound default/pvc-auto managed-nfs-storage 47s
[root@k8s-node1 ~]# ls -l /nfs/
total 4
drwxrwxrwx. 2 root root 6 Apr 11 17:37 default-pvc-auto-pvc-22b65e10-ab97-47eb-aaa1-6c354a749a55
以上
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。