K8s----Volumes(三)NFS动态分配PV
K8s----Volumes之NFS动态分配PV1 NFS Client Provisioner的介绍2 NFS动态分配PV的部署2.1 配置授权2.2 部署NFS Client Provisioner2.3 创建 NFS SotageClass2.4 创建PVC和测试pod2.5设定默认的StorageClass2.6 维持Pod的拓扑状态2.7 StatefulSet控制器2.8 Statef
K8s----Volumes之NFS动态分配PV
1 NFS Client Provisioner的介绍
NFS作为在Kubernetes当前版本的中,可以创建类型为nfs的持久化存储卷,用于为PersistentVolumClaim提供存储卷
NFS Client Provisioner是一个automatic provisioner,使用NFS作为存储,自动创建PV和对应的PVC,本身不提供NFS存储,需要外部先有一套NFS存储服务
- PV以
${namespace}-${pvcName}-${pvName}
的命名格式提供(在NFS服务器上) - PV回收的时候以
archieved-${namespace}-${pvcName}-${pvName}
的命名格式(在NFS服务器上)
2 NFS动态分配PV的部署
配置授权 部署NFS Client Provisioner
(1)创建命名空间:kubectl create namespace nfs-client-provisioner
- 查看命名空间:
kubectl get ns
(2)应用文件:kubectl apply -f nfs-client-provisioner.yaml
2.1 配置授权
## 配置授权
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: nfs-client-provisioner
# replace with namespace where provisioner is deployed
namespace: nfs-client-provisioner
---
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
# replace with namespace where provisioner is deployed
namespace: nfs-client-provisioner
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
# replace with namespace where provisioner is deployed
namespace: nfs-client-provisioner
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
# replace with namespace where provisioner is deployed
namespace: nfs-client-provisioner
subjects:
- kind: ServiceAccount
name: nfs-client-provisioner
# replace with namespace where provisioner is deployed
namespace: nfs-client-provisioner
roleRef:
kind: Role
name: leader-locking-nfs-client-provisioner
apiGroup: rbac.authorization.k8s.io
---
---
2.2 部署NFS Client Provisioner
apiVersion: apps/v1
kind: Deployment
metadata:
name: nfs-client-provisioner
labels:
app: nfs-client-provisioner
# replace with namespace where provisioner is deployed
namespace: 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: nfs-subdir-external-provisioner:v4.0.0
volumeMounts:
- name: nfs-client-root
mountPath: /persistentvolumes
env:
- name: PROVISIONER_NAME
value: k8s-sigs.io/nfs-subdir-external-provisioner
- name: NFS_SERVER
value: 172.25.12.1
- name: NFS_PATH
value: /nfsdata
volumes:
- name: nfs-client-root
nfs:
server: 172.25.12.1
path: /nfsdata
2.3 创建 NFS SotageClass
官网:https://kubernetes.io/zh/docs/concepts/storage/storage-classes/
StorageClass提供了一种描述存储类(class)的方法,不同的class可能会映射到不同的服务质量等级和备份策略或其他策略等。
- 每个 StorageClass 都包含 provisioner、parameters 和 reclaimPolicy 字段,这些字段会在StorageClass需要动态分配 PersistentVolume 时会使用到。
StorageClass的属性
- Provisioner(存储分配器):用来决定使用哪个卷插件分配
PV,该字段必须指定。可以指定内部分配器,也可以指定外部分配器,外部分配器的代码地址为:
kubernetes-incubator/external-storage,其中包括NFS和Ceph等 - Reclaim Policy(回收策略):通过reclaimPolicy字段指定创建的Persistent
Volume的回收策略,回收策略包括:Delete 或者 Retain,没有指定默认为Delete
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: managed-nfs-storage
provisioner: k8s-sigs.io/nfs-subdir-external-provisioner
parameters:
archiveOnDelete: "true"
将上述三个清单文件整合到一个文件并应用:
- 应用文件:
kubectl apply -f nfs-client-provisioner.yaml
- 查看SotageClass:
kubectl get sc
2.4 创建PVC和测试pod
(1)应用资源清单文件:kubectl apply -f pvc.yaml
## 创建PVC
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: test-claim
spec:
storageClassName: managed-nfs-storage
accessModes:
- ReadWriteMany
resources:
requests:
storage: 2Gi
## 创建测试pod
---
kind: Pod
apiVersion: v1
metadata:
name: test-pod
spec:
containers:
- name: test-pod
image: myapp:v1
volumeMounts:
- name: nfs-pvc
mountPath: "/usr/share/nginx/html"
volumes:
- name: nfs-pvc
persistentVolumeClaim:
claimName: test-claim
- 查看NFS服务端的挂载目录下的挂载卷:
[root@server1 nfsdata]# ll
total 4
drwxrwxrwx 2 root root 6 Feb 25 16:54 default-test-claim-2-pvc-a15b9c41-94e9-4ed3-8ad2-b408d929752c
drwxrwxrwx 2 root root 6 Feb 25 16:53 default-test-claim-pvc-d855a068-ab3c-4744-b9f5-0ca828c3a8af
2.5 设定默认的StorageClass
- 默认的 StorageClass 被用于动态的为没有特定 storage class 需求的 PersistentVolumeClaims配置存储:(只能有一个默认StorageClass) 如果没有默认StorageClass,PVC也没有指定storageClassName 的值,那么它只能够跟 storageClassName 也是的 PV 进行绑定。
(1)应用的资源清单文件没有指定StorageClass:kubectl apply -f pvc.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: test-claim
spec:
# storageClassName: managed-nfs-storage
accessModes:
- ReadWriteMany
resources:
requests:
storage: 2Gi
- 查看pvc的信息:
kubectl get pvc
,test-claim
一直在Pending状态
(2)解决方案:
- 设定默认的StorageClass
kubectl patch storageclass managed-nfs-storage -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
- 查看StorageClass的信息:
kubectl get sc
,此时设定默认的StorageClass设定成功
(3)测试
- 删除相应的资源:
kubectl delete -f pvc.yaml
- 应用资源清单文件:
kubectl apply -f pvc.yaml
- 查看pvc:
kubectl get pvc
2.6 维持Pod的拓扑状态
StatefulSet通过Headless Service维持Pod的拓扑状态
(1)创建Headless service
- 应用文件:
kubectl apply -f service.yml
## 创建Headless service
---
apiVersion: v1
kind: Service
metadata:
name: nginx-svc
labels:
app: nginx
spec:
ports:
- port: 80
name: web
clusterIP: None
selector:
app: nginx
- 查看svc的信息,
kubectl get svc
kubectl describe svc nginx-svc ##Endpoints没有相应的ip信息
2.7 StatefulSet控制器
StatefulSet将应用状态抽象成了两种情况:
- 拓扑状态:应用实例必须按照某种顺序启动。新创建的Pod必须和原来Pod的网络标识一样
- 存储状态:应用的多个实例分别绑定了不同存储数据
(1)应用文件:kubectl apply -f service.yml
## 创建Headless service
---
apiVersion: v1
kind: Service
metadata:
name: nginx-svc
labels:
app: nginx
spec:
ports:
- port: 80
name: web
clusterIP: None
selector:
app: nginx
## StatefulSet控制器
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
serviceName: "nginx-svc"
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: myapp:v1
ports:
- containerPort: 80
name: web
- StatefulSet给所有的Pod进行了编号,编号规则是:
$(statefulset名称)-$(序号)
,从0开始。pod的创建也是严格按照编号顺序进行的。比如在web-0进入到running状态,并且Conditions为Ready之前,web-1一直会处于pending状态
[root@server2 mnt]# kubectl get pod
NAME READY STATUS RESTARTS AGE
web-0 0/1 Pending 0 2s
[root@server2 mnt]# kubectl get pod
NAME READY STATUS RESTARTS AGE
web-0 1/1 Running 0 5s
web-1 0/1 Pending 0 1s
[root@server2 mnt]# kubectl get pod
NAME READY STATUS RESTARTS AGE
web-0 1/1 Running 0 13s
web-1 1/1 Running 0 9s
- 查看pod的信息:
kubectl get pod -o wide
- 查看nginx-svc 服务的详细信息:
kubectl describe svc nginx-svc
(2)测试
- 访问pod的服务会访问Pod的网络标识
[root@server2 mnt]# kubectl attach demo -it
Defaulting container name to demo.
Use 'kubectl describe pod/demo -n default' to see all of the containers in this pod.
If you don't see a command prompt, try pressing enter.
/ # nslookup nginx-svc
Server: 10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
Name: nginx-svc
Address 1: 10.244.22.0 web-1.nginx-svc.default.svc.cluster.local
Address 2: 10.244.141.210 web-0.nginx-svc.default.svc.cluster.local
/ # curl nginx-svc
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
/ # curl nginx-svc/hostname.html
web-0
/ # curl nginx-svc/hostname.html
web-0
/ # curl nginx-svc/hostname.html
web-1
/ # curl nginx-svc/hostname.html
web-1
/ # curl web-1.nginx-svc.default.svc.cluster.local
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
/ # curl web-1.nginx-svc.default.svc.cluster.local/hostname.html
web-1
/ # curl web-0.nginx-svc.default.svc.cluster.local/hostname.html
web-0
- Pod对应的DNS记录:
dig -t A nginx-svc.default.svc.cluster.local. @10.96.0.10
Pod被删除后重建,重建Pod的网络标识也不会改变,Pod的拓扑状态按照Pod的“名字+编号”的方式固定下来,并且为每个Pod提供了一个固定且唯一的访问入口,即Pod对应的DNS记录。
- 删除所有的pod:
kubectl delete pod --all --force
,会自动生成指定数量的pod - 查看pod的信息:
kubectl get pod -o wide
,此时各个pod的ip重新动态分配
- Pod对应的DNS记录:
dig -t A nginx-svc.default.svc.cluster.local. @10.96.0.10
- 重建后Pod的网络标识未改变
2.8 StatefulSet对存储状态的管理
PV和PVC的设计,使得StatefulSet对存储状态的管理成为了可能:
(1)应用文件:kubectl apply -f service.yml
## 创建Headless service
---
apiVersion: v1
kind: Service
metadata:
name: nginx-svc
labels:
app: nginx
spec:
ports:
- port: 80
name: web
clusterIP: None
selector:
app: nginx
## StatefulSet控制器
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
serviceName: "nginx-svc"
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: myapp:v1
ports:
- containerPort: 80
name: web
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: www
spec:
storageClassName: managed-nfs-storage
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
- Pod的创建也是严格按照编号顺序进行的。比如在web-0进入到running状态,并且Conditions为Ready之前,web-1一直会处于pending状态
[root@server2 mnt]# kubectl get pod
NAME READY STATUS RESTARTS AGE
web-0 1/1 Running 0 3s
web-1 0/1 Pending 0 1s
[root@server2 mnt]# kubectl get pod
NAME READY STATUS RESTARTS AGE
web-0 1/1 Running 0 5s
web-1 0/1 ContainerCreating 0 3s
[root@server2 mnt]# kubectl get pod
NAME READY STATUS RESTARTS AGE
web-0 1/1 Running 0 8s
web-1 1/1 Running 0 6s
- 查看指定pod的详细信息:
kubectl describe pod web-0
,nginx的默认发布目录挂载成功
- StatefulSet还会为每一个Pod分配并创建一个同样编号的PVC。这样,kubernetes就可以通过Persistent Volume机制为这个PVC绑定对应的PV,从而保证每一个Pod都拥有一个独立的Volume
[root@server2 mnt]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pvc-15e7aef5-8664-4767-a039-f9369ab7d1af 1Gi RWO Delete Bound default/www-web-1 managed-nfs-storage 11m
pvc-1e322dce-de7f-43e3-8a06-8e82a1c452f5 1Gi RWO Delete Bound default/www-web-0 managed-nfs-storage 11m
[root@server2 mnt]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
www-web-0 Bound pvc-1e322dce-de7f-43e3-8a06-8e82a1c452f5 1Gi RWO managed-nfs-storage 11m
www-web-1 Bound pvc-15e7aef5-8664-4767-a039-f9369ab7d1af 1Gi RWO managed-nfs-storage 11m
- 查看nginx-svc服务的信息 :
kubectl describe svc nginx-svc
- 查看pod的详细信息:
kubectl get pod -o wide
- 查看NFS服务端的挂载目录,并向挂载目录中写入nginx默认的发布页面的信息
(2)测试:访问pod的服务时,显示的是默认的发布信息
[root@server2 mnt]# kubectl attach demo -it
Defaulting container name to demo.
Use 'kubectl describe pod/demo -n default' to see all of the containers in this pod.
If you don't see a command prompt, try pressing enter.
/ # nslookup nginx-svc
Server: 10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
Name: nginx-svc
Address 1: 10.244.141.209 web-1.nginx-svc.default.svc.cluster.local
Address 2: 10.244.22.5 web-0.nginx-svc.default.svc.cluster.local
/ # curl web-0.nginx-svc.default.svc.cluster.local
www.web-0.org
/ # curl web-1.nginx-svc.default.svc.cluster.local
www.web-1.org
/ # curl nginx-svc
www.web-0.org
/ # curl nginx-svc
www.web-1.org
/ # curl nginx-svc
www.web-1.org
/ # curl nginx-svc
www.web-0.org
- Pod对应的DNS记录:
dig -t A nginx-svc.default.svc.cluster.local. @10.96.0.10
2.9 kubectl 弹缩
(1)想要弹缩的StatefulSet,需先验证是否能弹缩该应用
[root@server2 mnt]# kubectl get statefulsets web
NAME READY AGE
web 2/2 21m
(2)改变StatefulSet副本数量并重新应用
- pod的收缩:
kubectl apply -f statefulset.yml
- Pod的收缩也是严格按照编号倒序进行的,比如在web-0进入到Terminating状态,并且被彻底删除之前,web-0一直会处于running状态
root@server2 mnt]# kubectl get pod
NAME READY STATUS RESTARTS AGE
web-0 1/1 Running 0 95m
web-1 0/1 Terminating 0 95m
[root@server2 mnt]# kubectl get pod
NAME READY STATUS RESTARTS AGE
web-0 0/1 Terminating 0 95m
[root@server2 mnt]# kubectl get pod
No resources found in default namespace.
[root@server2 mnt]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pvc-15e7aef5-8664-4767-a039-f9369ab7d1af 1Gi RWO Delete Bound default/www-web-1 managed-nfs-storage 11m
pvc-1e322dce-de7f-43e3-8a06-8e82a1c452f5 1Gi RWO Delete Bound default/www-web-0 managed-nfs-storage 11m
[root@server2 mnt]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
www-web-0 Bound pvc-1e322dce-de7f-43e3-8a06-8e82a1c452f5 1Gi RWO managed-nfs-storage 11m
www-web-1 Bound pvc-15e7aef5-8664-4767-a039-f9369ab7d1af 1Gi RWO managed-nfs-storage 11m
- pod的拉伸:
kubectl apply -f service.yml
- Pod对应的DNS记录:
dig -t A nginx-svc.default.svc.cluster.local. @10.96.0.10
- 虽然pod的ip地址被重新分配,但是挂载目录中的内容被没有改变
更多推荐
所有评论(0)