公司网站公司哪家好万网网站建设的子分类能显示多少个
公司网站公司哪家好,万网网站建设的子分类能显示多少个,wordpress二开,网页设计要学些什么k8s之共享存储pvpvc 1 存储资源管理
在基于k8s容器云平台上#xff0c;对存储资源的使用需求通常包括以下几方面#xff1a; 1.应用配置文件、密钥的管理#xff1b;
2.应用的数据持久化存储#xff1b;
3.在不同的应用间共享数据存储#xff1b; k8s的Volume抽象概…k8s之共享存储pvpvc 1 存储资源管理
在基于k8s容器云平台上对存储资源的使用需求通常包括以下几方面 1.应用配置文件、密钥的管理
2.应用的数据持久化存储
3.在不同的应用间共享数据存储 k8s的Volume抽象概念就是针对这些问题提供的解决方案k8s的volume类型非常丰富从临时目录、宿主机目录、ConfigMap、Secret、共享存储PV和PVC。
k8s支持Volume类型包括以下几类
1.临时空目录随着Pod的销毁而销毁
emptyDir:
2.配置类将配置文件以Volume的形式挂载到容器内
ConfigMap将保存在ConfigMap资源对象中的配置文件信息挂载到容器内的某个目录下
Secret将保存在Secret资源对象中的密码密钥等信息挂载到容器内的某个文件中。
downwardAPI将downwardAPI的数据以环境变量或文件的形式注入容器中。
gitErpo将某Git代码库挂载到容器内的某个目录下
3.本地存储类
hostpath将宿主机的目录或文件挂载到容器内进行使用。
localKubernetes从v1.9版本引入将本地存储以PV的形式提供给容器使用并能够实现存储空间的管理。
4.共享存储
PVPersistent Volume将共享存储定义为一种“持久存储卷”可以被多个容器应用共享使用。
PVCPersistent Volume Claim用户对存储资源的一次“申请”PVC申请的对象是PV一旦申请成功应用就能够像使用本地目录一样使用共享存储了。
共享存储主要用于多个应用都能够使用存储资源例如NFS存储、光纤存储Glusterfs共享文件系统等在k8s系统中通过PV/StorageClass和PVC来完成定义并通过volumeMount挂载到容器的目录或文件进行使用。
ConfigMap、Secret、emptyDir、hostPath等属于临时性存储当pod被调度到某个节点上时它们随pod的创建而创建临时占用节点存储资源当pod离开节点时存储资源被交还给节点pod一旦离开这个节点存储就失效不具备持久化存储数据的能力。与此相反持久化存储拥有独立的生命周期具备持久化存储能力其后端一般是独立的存储系统如NFS、iSCSI、cephfs、glusterfs等。
pv与pvc
Kubernetes中的node代表计算资源而PersistentVolume(PV)则代表存储资源它是对各种诸如NFS、iSCSI、云存储等各种存储后端所提供存储块的统一抽象从而提供网络存储通过它屏蔽低层实现细节。与普通volume不同PV拥有完全独立的生命周期。
因为PV表示的是集群能力它是一种集群资源所以用户通常是开发人员不能直接使用PV就像不能直接使用内存一样需要先向系统申请而 PVC 就是请求存储资源的。
Kubernetes通过PersistentVolumeClaim(PVC)代理用户行为用户通过对PVC的操作实现对PV申请、使用、释放等操作PVC是用户层面的资源。
PV 和 PVC 可以将 pod 和数据卷解耦pod 不需要知道确切的文件系统或者支持它的持久化引擎。
Kubernetes的共享存储供应模式包括静态和动态两种模式
静态模式
静态PV由系统管理员负责创建、提供、维护系统管理员为用户屏蔽真正提供存储的后端及其实现细节普通用户作为消费者只需通过PVC申请、使用此类资源。
动态模式
集群管理员无须手工创建PV而是通过对Storage Class的设置对后端存储进行描述“storage class”可以理解成某种具体的后端存储标记为某种“类型Class”此时要求PVC对存储的类型进行声明系统将自动完成PV的创建与PVC的绑定。如果用户的PVC中“storage class”的值为则表示不能为此PVC动态创建PV。
PV与PVC的绑定
用户创建包含容量、访问模式等信息的PVC向系统请求存储资源。系统查找已存在PV或者监控新创建PV如果与PVC匹配则将两者绑定。如果PVC创建动态PV则系统将一直将两者绑定。PV与PVC的绑定是一一对应关系不能重复绑定。如果系统一直没有为PVC找到匹配PV则PVC无限期维持在unbound状态直到系统找到匹配PV。实际绑定的PV容量可能大于PVC中申请的容量。
2 持久卷pv的类型
PV 持久卷是用插件的形式来实现的。Kubernetes 目前支持以下插件
- GCEPersistentDisk
- AWSElasticBlockStore
- AzureFile
- AzureDisk
- FC (Fibre Channel)
- Flexvolume
- Flocker
- NFS
- iSCSI
- RBD (Ceph Block Device)
- CephFS
- Cinder (OpenStack block storage)
- Glusterfs
- VsphereVolume
- Quobyte Volumes
- HostPath (Single node testing only – local storage is not supported in any way and WILL NOT WORK in a multi-node cluster)
- Portworx Volumes
- ScaleIO Volumes
- StorageOS
5 实验mysql基于NFS共享存储实现持久化存储
5.1 安装NFS
机器准备
k8s-master 制作nfs服务端作为共享文件系统
[rootk8s-master ~]# yum install -y nfs-utils rpcbind
[rootk8s-master ~]# mkdir /mnt/data #制作共享目录
[rootk8s-master ~]# vim /etc/exports
/mnt/data *(rw,no_root_squash)
[rootk8s-master ~]# systemctl start rpcbind #启动服务
[rootk8s-master ~]# systemctl start nfs
# 使配置生效
[rootk8s-master ~]# exportfs -r
# 检查配置是否生效
[rootk8s-master ~]# exportfs
集群中的工作节点都需要安装客户端工具主要作用是节点能够驱动 nfs 文件系统
只安装不启动服务
# yum install -y nfs-utils
# mkdir /mnt/data
# showmount -e 192.168.58.149(master_ip)
# mount -t nfs 192.168.58.149:/mnt/data /mnt/data
master节点
制作pv.yaml一般这个动作由 kubernetes 管理员完成也就是我们运维人员
[rootk8s-master ~]# mkdir /k8s/mysql -p
[rootk8s-master ~]# cd /k8s/mysql/
[rootk8s-master mysql]# vim pv.yaml
apiVersion: v1
kind: PersistentVolume #类型定义为pv
metadata: name: my-pv #pv的名字labels: #定义标签type: nfs #类型为nfs
spec:nfs: # 存储类型需要与底层实际的存储一致这里采用 nfsserver: 192.168.122.24 # NFS 服务器的 IPpath: /mnt/data # NFS 上共享的目录capacity: #定义存储能力storage: 3Gi #指定存储空间accessModes: #定义访问模式- ReadWriteMany #读写权限允许被多个Node挂载persistentVolumeReclaimPolicy: Retain #定义数据回收策略,这里是保留
5.2 PV参数详解
1.存储能力Capacity
描述存储设备的能力目前仅支持对存储空间的设置storagexx。
2.访问模式Access Modes
对PV进行访问模式的设置用于描述用户应用对存储资源的访问权限。访问模式如下
ReadWriteOnce读写权限并且只能被单个pod挂载。
ReadOnlyMany只读权限允许被多个pod挂载。
ReadWriteMany读写权限允许被多个pod挂载。
某些PV可能支持多种访问模式但PV在挂载时只能使用一种访问模式多种访问模式不能同时生效。
3.persistentVolumeReclaimPolicy定义数据回收策略
目前支持如下三种回收策略
保留Retain保留数据需要手工处理。
回收空间Recycle警告 回收策略 Recycle 已被废弃。取而代之的建议方案是使用动态供应。如果下层的卷插件支持回收策略 Recycle 会在卷上执行一些基本的 擦除rm -rf /thevolume/*操作之后允许该卷用于新的 PVC 申领
删除Delete会将 PersistentVolume 对象从 Kubernetes 中移除同时也会从外部基础设施如 AWS EBS、GCE PD、Azure Disk 或 Cinder 卷中移除所关联的存储资产。 就是把云存储一起删了。
目前只有 NFS 和 HostPath 两种类型的存储设备支持 “Recycle” 策略 AWS EBS、 GCE PD、Azure Disk 和 Cinder volumes 支持 “Delete” 策略。
4.storageClassName存储类别Class
PV可以设定其存储的类型Class通过 storageClassName参数指定一个 StorageClass 资源对象的名称。
具有特定“类别”的 PV 只能与请求了该“类别”的 PVC 进行绑定。未设定 “类别” 的 PV 则只能与不请求任何 “类别” 的 PVC 进行绑定。
相当于一个标签。
5.3 创建pv
[rootk8s-master mysql]# kubectl apply -f pv.yaml
persistentvolume/my-pv created
[rootk8s-master mysql]# kubectl get pv PV 生命周期的各个阶段Phase
某个 PV 在生命周期中可以处于以下4个阶段之一
- Available可用状态还未与某个 PVC 绑定。
- Bound已与某个 PVC 绑定。
- Released释放绑定的 PVC 已经删除但没有被集群回收存储空间 。
- Failed自动资源回收失败。
pv创建成功目前属于可用状态还没有与pvc绑定那么现在创建pvc
创建pvc [rootk8s-master mysql]# vim mysql-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim #定义类型为PVC
metadata:name: mypvc #声明pvc的名称当做pod的卷使用时会用到
spec:accessModes: #定义访问pvc的模式与pv拥有一样的模式- ReadWriteMany #读写权限允许被多个pod挂载resources: #声明可以请求特定数量的资源目前仅支持 request.storage 的设置即存储空间大小。requests:storage: 3Gi #定义空间大小selector: #PV选择条件,标签选择器通过标签选择matchLabels:type: nfs #选择pv类型的nfs
注意当我们申请pvc的容量大于pv的容量是无法进行绑定的。
创建pvc
[rootk8s-master mysql]# kubectl apply -f mysql-pvc.yaml
persistentvolumeclaim/mypvc created
[rootk8s-master mysql]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
mypvc Bound my-pv 3Gi RWX pv-nfs 37s status状态 - Available (可用): 表示可用状态还未被任何PVC绑定
- Bound (已绑定)已经绑定到某个PVC
- Released (已释放)对应的PVC已经删除,但资源还没有被集群收回
- FailedPV自动回收失败 Kubernetes中会自动帮我们查看pv状态为Available并且根据声明pvc容量storage的大小进行筛选匹配同时还会根据AccessMode进行匹配。如果pvc匹配不到pv会一直处于pending状态。
5.4 mysql使用pvc持久卷
创建secret
[rootk8s-master mysql]# echo -n QianFeng123! | base64
UWlhbkZlbmdAMTIzIQ
[rootk8s-master mysql]# vim mysql-secret.yaml
apiVersion: v1
data:password: UWlhbkZlbmdAMTIzIQ
kind: Secret
metadata:annotations:name: my-pass
type: Opaque
[rootk8s-master mysql]# kubectl apply -f mysql-secret.yaml
secret/my-pass created
[rootk8s-master mysql]# kubectl get secret
NAME TYPE DATA AGE
default-token-24c52 kubernetes.io/service-account-token 3 6d22h
my-pass Opaque 1 69s
创建myslq-pod文件
[rootk8s-master mysql]# cat mysql-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:name: my-mysql
spec:replicas: 1selector:matchLabels:app: mysqltemplate:metadata:labels:app: mysqlspec:containers:- name: my-mysqlimage: daocloud.io/library/mysql:5.7
# imagePullPolicy: IfNotPresentports:- containerPort: 3306env:- name: MYSQL_ROOT_PASSWORDvalueFrom:secretKeyRef:name: my-passkey: passwordvolumeMounts:- name: mysql-datamountPath: /var/lib/mysqlvolumes:- name: mysql-datapersistentVolumeClaim: #绑定pvcclaimName: mypvc #指定对应的pvc名字
[rootk8s-master mysql]# kubectl apply -f mysql-deployment.yaml
[rootk8s-master mysql]# kubectl get pod
NAME READY STATUS RESTARTS AGE
my-mysql-5474b6885f-c5dmp 1/1 Running 0 8s
[rootk8s-master mysql]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
my-mysql-5474b6885f-c5dmp 1/1 Running 0 40s 10.244.2.5 k8s-node2 none none
测试
[rootk8s-master ~]# cd /mnt/data/
[rootk8s-master data]# ll
总用量 188484
-rw-r----- 1 polkitd ssh_keys 56 11月 8 21:49 auto.cnf
-rw------- 1 polkitd ssh_keys 1680 11月 8 21:49 ca-key.pem
-rw-r--r-- 1 polkitd ssh_keys 1112 11月 8 21:49 ca.pem
-rw-r--r-- 1 polkitd ssh_keys 1112 11月 8 21:49 client-cert.pem
-rw------- 1 polkitd ssh_keys 1680 11月 8 21:49 client-key.pem
-rw-r----- 1 polkitd ssh_keys 688 11月 8 21:57 ib_buffer_pool
-rw-r----- 1 polkitd ssh_keys 79691776 11月 8 21:59 ibdata1
-rw-r----- 1 polkitd ssh_keys 50331648 11月 8 21:59 ib_logfile0
-rw-r----- 1 polkitd ssh_keys 50331648 11月 8 21:49 ib_logfile1
-rw-r----- 1 polkitd ssh_keys 12582912 11月 8 22:00 ibtmp1
drwxr-x--- 2 polkitd ssh_keys 4096 11月 8 21:49 mysql
drwxr-x--- 2 polkitd ssh_keys 8192 11月 8 21:49 performance_schema
-rw------- 1 polkitd ssh_keys 1680 11月 8 21:49 private_key.pem
-rw-r--r-- 1 polkitd ssh_keys 452 11月 8 21:49 public_key.pem
-rw-r--r-- 1 polkitd ssh_keys 1112 11月 8 21:49 server-cert.pem
-rw------- 1 polkitd ssh_keys 1676 11月 8 21:49 server-key.pem
drwxr-x--- 2 polkitd ssh_keys 8192 11月 8 21:49 sys
6 动态绑定pv
StorageClass 相当于一个创建 PV 的模板用户通过 PVC 申请存储卷StorageClass 通过模板自动创建 PV然后和 PVC 进行绑定。
StorageClass创建动态存储卷流程 集群管理员预先创建存储类StorageClass 用户创建使用存储类的持久化存储声明(PVCPersistentVolumeClaim) 存储持久化声明通知系统它需要一个持久化存储(PV: PersistentVolume) 系统读取存储类的信息 系统基于存储类的信息在后台自动创建PVC需要的PV 用户创建一个使用PVC的Pod Pod中的应用通过PVC进行数据的持久化 而PVC使用PV进行数据的最终持久化处理。 NFS Provisioner 是一个自动配置卷程序它使用现有的和已配置的 NFS 服务器来支持通过持久卷声明动态配置 Kubernetes 持久卷。 注意k8s 1.21版本中创建pvc时nfs-provisioner会报错 E0903 08:00:24.858523 1 controller.go:1004] provision “default/test-claim” class “managed-nfs-storage”: unexpected error getting claim reference: selfLink was empty, can’t make reference 解决方法 修改 /etc/kubernetes/manifests/kube-apiserver.yaml文件 增加 - --feature-gatesRemoveSelfLinkfalse spec:containers:- command:- kube-apiserver- --feature-gatesRemoveSelfLinkfalse # 增加这行- --advertise-address172.24.0.5- --allow-privilegedtrue- --authorization-modeNode,RBAC- --client-ca-file/etc/kubernetes/pki/ca.crt
6.1 配置nfs-provisioner授权 创建ServiceAccount、ClusterRole、ClusterRoleBinding等为nfs-client-provisioner授权 # vim rbac.yaml
apiVersion: v1
kind: ServiceAccount
metadata:name: nfs-client-provisioner# replace with namespace where provisioner is deployednamespace: default
---
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: ServiceAccountname: nfs-client-provisioner# replace with namespace where provisioner is deployednamespace: default
roleRef:kind: ClusterRolename: nfs-client-provisioner-runnerapiGroup: 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 deployednamespace: default
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
subjects:- kind: ServiceAccountname: nfs-client-provisioner# replace with namespace where provisioner is deployednamespace: default
roleRef:kind: Rolename: leader-locking-nfs-client-provisionerapiGroup: rbac.authorization.k8s.io
6.2 部署nfs-client-provisioner
# vim nfs-provisioner.yaml
apiVersion: apps/v1
kind: Deployment
metadata:name: nfs-client-provisionerlabels:app: nfs-client-provisioner# replace with namespace where provisioner is deployednamespace: default #与RBAC文件中的namespace保持一致
spec:replicas: 1selector:matchLabels:app: nfs-client-provisionerstrategy:type: Recreateselector:matchLabels:app: nfs-client-provisionertemplate:metadata:labels:app: nfs-client-provisionerspec:serviceAccountName: nfs-client-provisionercontainers:- name: nfs-client-provisionerimage: quay.io/external_storage/nfs-client-provisioner:latestvolumeMounts:- name: nfs-client-rootmountPath: /persistentvolumesenv:- name: PROVISIONER_NAMEvalue: gxf-nfs-storage #provisioner名称,请确保该名称与 nfs-StorageClass.yaml文件中的provisioner名称保持一致- name: NFS_SERVERvalue: 10.24.X.X #NFS Server IP地址- name: NFS_PATH value: /home/nfs/1 #NFS挂载卷volumes:- name: nfs-client-rootnfs:server: 10.24.X.X #NFS Server IP地址path: /home/nfs/1 #NFS 挂载卷
# 部署
[rootkube-master ~]# kubectl apply -f rbac.yaml
[rootkube-master ~]# kubectl apply -f nfs-provisioner.yaml
[rootkube-master ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
nfs-client-provisioner-75bfdbdcd8-5mqbv 1/1 Running 0 4m24s 6.3 创建StorageClass
# vim nfs-StorageClass.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:name: managed-nfs-storage
provisioner: gxf-nfs-storage #这里的名称要和provisioner配置文件中的环境变量PROVISIONER_NAME保持一致
reclaimPolicy: Retain # 默认为delete
parameters:archiveOnDelete: true # false表示pv被删除时在nfs下面对应的文件夹也会被删除,true正相反
6.4 deployment 动态挂载 部署一个有2个副本的deployment挂载共享目录 # 创建pvc“storageClassName为上面创建的managed-nfs-storage”即指定动态创建PV的模板文件的名字。# test-pvclaim.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:name: test-claim
spec:accessModes:- ReadWriteManyresources:requests:storage: 100MistorageClassName: managed-nfs-storage[rootkube-master ~]# kubectl apply -f test-pvclaim.yaml
# deployment部署
# test-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:name: test-deploylabels:app: test-deploynamespace: default #与RBAC文件中的namespace保持一致
spec:replicas: 2selector:matchLabels:app: test-deploystrategy:type: Recreateselector:matchLabels:app: test-deploytemplate:metadata:labels:app: test-deployspec:containers:- name: test-podimage: busybox:1.24command:- /bin/shargs:- -c# - touch /mnt/SUCCESS3 exit 0 || exit 1 #创建一个SUCCESS文件后退出- touch /mnt/SUCCESS5; sleep 50000volumeMounts:- name: nfs-pvcmountPath: /mnt# subPath: test-pod-3 # 子路径 这路基代表存储卷下面的test-pod子目录 volumes:- name: nfs-pvcpersistentVolumeClaim:claimName: test-claim #与PVC名称保持一致
6.5 statefulset 动态挂载
# vim test-sts-1.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:name: test-stslabels:k8s-app: test-sts
spec:serviceName: test-sts-svcreplicas: 3selector:matchLabels:k8s-app: test-ststemplate:metadata:labels:k8s-app: test-stsspec:containers:- image: busybox:1.24name: test-podcommand:- /bin/shargs:- -c# - touch /mnt/SUCCESS3 exit 0 || exit 1 #创建一个SUCCESS文件后退出- touch /mnt/SUCCESS5; sleep 50000imagePullPolicy: IfNotPresentvolumeMounts:- name: nfs-pvcmountPath: /mntvolumeClaimTemplates:- metadata:name: nfs-pvcspec:accessModes: [ReadWriteMany]storageClassName: managed-nfs-storageresources:requests:storage: 20Mi
[rootkube-master ~]# kubectl apply -f test-sts-1.yaml
[rootkube-master ~]# kubectl get sts
NAME READY AGE
test-sts 3/3 4m46s StatefulSet有状态的应用 在Kubernetes系统中Pod的管理对象RC、Deployment、DaemonSet都是面向无状态的服务它们所管理的Pod的IP、名字启停顺序等都是随机的。但现实中有很多服务是有状态的特别是一些复杂的中间件集群。例如Mysql集群、MongoDB集群、Kafka集群、Zookeeper集群等这些都有一个共同的特点 1.每个节点都有固定的ID通过这个ID集群中的成员可以相互发现并且通信。 2.集群的规模是比较固定的集群规模不能随意改动。 3.集群里的每个节点都是有状态的通常会持久化数据到永久存储中。 4.如果磁盘损坏集群里的某个节点就无法正常运行集群功能受损。
StatefulSet本质上是Deployment的一种变体在v1.9版本中已成为GA版本它为了解决有状态服务的问题它所管理的Pod拥有固定的Pod名称启停顺序的如果使用RC/Deployment控制副本的方式实现有状态的集群那么pod的名字是没有办法控制的因为是随机产生同时也无法为每一个pod确定唯一不变的ID号为了解决这个问题在k8s中引用了新的资源对象即StatefulSet。在StatefulSet中Pod名字称为网络标识(hostname)还必须要用到共享存储。
1.StatefulSet里的每个Pod都有稳定、唯一的网络标识可以用来发现集群中的其他成员比如说StatefulSet的名字是N那么第一个pod的名字就是N-0第二个就是N-1以此类推
2.StatefulSet控制的pod副本的启停顺序是受控制的操作第n个pod前面的n-1的pod已经是运行且准备好的状态。
3.StatefulSet里的pod采用稳定的持久化存储卷通过PV/PVC来实现删除Pod时默认不会删除与StatefulSet相关的存储卷目的是为了保证数据的安全性
所以,StatefulSet的核心功能,就是通过某种方式,记录这些状态,然后在Pod被重新创建时,能够为新Pod恢复这些状态. 在Deployment中与之对应的服务是service而在StatefulSet中与之对应的headless serviceheadless service即无头服务与service的区别就是它没有Cluster IP解析它的名称时将返回该Headless Service对应的全部Pod的Endpoint列表。 除此之外StatefulSet在Headless Service的基础上又为StatefulSet控制的每个Pod副本创建了一个DNS域名这个域名的格式为$(podname).(headless server name) 1 StatefulSet实现Pod的存储状态
通过PVC机制来实现存储状态管理
在StatefulSet对象中除了定义PodTemplate还会定义一个volumeClaimTemplates凡是被这个StatefulSet管理的Pod都会声明一个对应的PVC,这个PVC的定义就来自于 volumeClaimTemplates这个模板字段这个PVC的名字,会被分配一个与这个Pod完全一致的编号。
把一个Pod比如N-0删除之后,这个Pod对应的PVC和PV并不会被删除,而这个Volume 里已经写入的数据,也依然会保存在远程存储服务里
StatefulSet在重新创建N-0这个pod的时候.它声明使用的PVC的名字还是叫作:N-0 这个PVC的定义,还是来自于PVC模板volumeClaimTemplates这是StatefulSet创建 Pod的标准流程
Kubernetes为它查找名叫N-0的PVC时,就会直接找到旧Pod遗留下来的同名的 PVC进而找到跟这个PVC绑定在一起的PV.这样新的Pod就可以挂载到旧Pod对应的那个Volume并且获取到保存在Volume里的数据.通过这种方式Kubernetes的StatefulSet就实现了对应用存储状态的管理
2 StatefulSet 的应用特点 StatefulSet的核心功能就是通过某种方式记录应用状态在Pod被重建的时候通过这种方式还可以恢复原来的状态。 StatefulSet由以下几个部分组成 Headless Service 用于定义网络标识DNS volumeClaimTemplates 用于创建PV StatefulSet 用于定义具体应用 稳定且有唯一的网络标识符 当节点挂掉既pod重新调度后其PodName和HostName不变基于Headless Service来实现 稳定且持久的存储 当节点挂掉既pod重新调度能访问到相同的持久化存储基于PVC实现 有序、平滑的扩展、部署 即Pod是有顺序的在部署或者扩展的时候要依据定义的顺序依次进行即从0到N-1在下一个Pod运行之前所有之前的Pod必须都是Running和Ready状态基于init containers来实现。 有序、平滑的收缩、删除 既Pod是有顺序的在收缩或者删除的时候要依据定义的顺序依次进行既从N-1到0既倒序。 拓扑状态。是应用多个实例之间的不完全对等的关系这些应用实例是必须按照定义的顺序启动的。例如主应用A先于从应用B启动如果把A和B删掉应用还要按照先启动主应用A再启动从应用B且创建的应用必须和原来的应用的网络标识一样既PodName和HostName。这样他们就可以按照原来的顺序创建了。 存储状态。应用实例分别绑定了不同的数据存储Pod A第一次读到的数据要和10分钟后读到的数据是同一份。哪怕这期间Pod A被重建。这种典型的例子就是数据库应用的多个存储实例。
3 实战1-通过StatefulSet创建nginx
由于statefulSet在创建的时候使用的是动态绑定pvc而动态绑定pvc是需要插件支持的一下实验通过手动创建pv在通过StatefulSet自动实现pvc申请持久卷。 1.创建基于NFS的pv持久卷
[rootk8s-master ~]# mkdir /mnt/data-1 #创建共享目录
[rootk8s-master ~]# mkdir /mnt/data-2
[rootk8s-master ~]# vim /etc/exports
/mnt/data-1 172.16.229.*/24 (rw,sync,insecure,no_subtree_check,no_root_squash)
/mnt/data-2 172.16.229.*/24 (rw,sync,insecure,no_subtree_check,no_root_squash)
[rootk8s-master ~]# systemctl restart nfs[rootk8s-master ~]# mkdir /k8s/nginx #创建工作目录
[rootk8s-master ~]# cd /k8s/nginx/
[rootk8s-master nginx]# vim nginx-pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata: name: pv-0labels:type: pv-0
spec:capacity:storage: 5GiaccessModes:- ReadWriteManypersistentVolumeReclaimPolicy: Recyclenfs:server: 172.16.229.143path: /mnt/data-1
---
apiVersion: v1
kind: PersistentVolume
metadata:name: pv-1labels:type: pv-1
spec:capacity:storage: 5GiaccessModes:- ReadWriteManypersistentVolumeReclaimPolicy: Recyclenfs:server: 172.16.229.143path: /mnt/data-22.创建pv
[rootk8s-master nginx]# kubectl apply -f nginx-pv.yaml
persistentvolume/nginx-pv created
[rootk8s-master nginx]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
my-pv 3Gi RWX Recycle Bound default/mypvc pv-nfs 6d16h
pv-0 5Gi RWX Recycle Available 43s
pv-1 5Gi RWX Recycle Available 43s3.创建 service的Headless Service无头服务
[rootk8s-master nginx]# vim nginx-service.yaml
apiVersion: v1
kind: Service
metadata:name: nginx #service的名字labels:app: nginx
spec:ports:- port: 80name: webclusterIP: None #采用什么类型的service这里采用的是Headless Serviceselector:app: nginx
[rootk8s-master nginx]# kubectl apply -f nginx-service.yaml
service/nginx created
[rootk8s-master nginx]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 none 443/TCP 12d
nginx ClusterIP None none 80/TCP 5s4.创建StatefulSet,通过StatefulSet创建pvc实现自动绑定已经创建好的pv
[rootk8s-master nginx]# cat nginx-web.yaml
apiVersion: apps/v1 #选择apiserver的版本
kind: StatefulSet #定义pod类型
metadata:name: nginx-web
spec:serviceName: nginx #定义属于哪个Headless Servicereplicas: 2 #定义pod的副本selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:containers:- name: nginximage: daocloud.io/library/nginxports:- containerPort: 80name: webvolumeMounts: #定义卷的挂载到pod的路径- name: nginx-datamountPath: /usr/share/nginx/htmlvolumeClaimTemplates: #pvc的申请模版会自动创建pvc并与pv绑定。从而实现各pod有专用存储我们使用的是静态创建pv- metadata:name: nginx-data #pvc的名字spec:accessModes: [ReadWriteMany]resources:requests:storage: 5Gi #指定每一个持久卷的大小
[rootk8s-master nginx]# kubectl apply -f nginx-web.yaml查看statefulset
[rootk8s-master nginx]# kubectl get statefulset nginx-web
NAME READY AGE
nginx-web 2/2 19m查看service
[rootk8s-master nginx]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx ClusterIP None none 80/TCP 18m 为什么需要volumeClaimTemplate 对于有状态的副本集都会用到持久存储对于分布式系统来讲它的最大特点是数据是不一样的所以各个节点不能使用同一存储卷每个节点有自已的专用存储但是如果在Deployment中的Pod template里定义的存储卷是所有副本集共用一个存储卷数据是相同的因为是基于模板来的 而statefulset中每个Pod都要自已的专有存储卷所以statefulset的存储卷就不能再用Pod模板来创建了于是statefulSet使用volumeClaimTemplate称为卷申请模板它会为每个Pod生成不同的pvc并绑定pv 从而实现各pod有专用存储。这就是为什么要用volumeClaimTemplate的原因。 3.1 顺序创建 Pod
对于一个拥有 N 个副本的 StatefulSetPod 被部署时是按照 {0 …… N-1} 的序号顺序创建的。在终端中使用 kubectl get 检查输出。这个输出最终将看起来像下面的样子
[rootk8s-master nginx]# kubectl get -l appnginx pods
NAME READY STATUS RESTARTS AGE
nginx-web-0 1/1 Running 0 18m
nginx-web-1 1/1 Running 0 6m34s
请注意在 nginx-web-0 Pod 处于 Running和Ready 状态后 nginx-web-1 Pod 才会被启动
如同 StatefulSets 概念中所提到的StatefulSet 中的 Pod 拥有一个具有黏性的、独一无二的身份标志。这个标志基于 StatefulSet 控制器分配给每个 Pod 的唯一顺序索引。Pod 的名称的形式为statefulset name-ordinal index。webStatefulSet 拥有两个副本所以它创建了两个 Podnginx-web-0和nginx-web-1。
3.2 使用稳定的网络身份标识
每个 Pod 都拥有一个基于其顺序索引的稳定的主机名。使用[kubectl exec](https://kubernetes.io/zh/docs/reference/generated/kubectl/kubectl-commands/#exec)在每个 Pod 中执行hostname
[rootk8s-master nginx]# for i in 0 1; do kubectl exec nginx-web-$i -- /bin/bash -c hostname; done
nginx-web-0
nginx-web-1
3.3 查看statefulset创建的pod的存储
获取 nginx-web-0 和 nginx-web-1 的 PersistentVolumeClaims。
[rootk8s-master nginx]# kubectl get pvc -l appnginx
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
nginx-data-nginx-web-0 Bound pv-0 5Gi RWX 53m
nginx-data-nginx-web-1 Bound pv-1 5Gi RWX 53m
StatefulSet 控制器创建了两个 PersistentVolumeClaims绑定到两个 PersistentVolumes。由于这里我们使用的是手动创建pv所有的 PersistentVolume 都是手动创建自动的绑定。
NGINX web 服务器默认会加载位于 /usr/share/nginx/html/index.html 的 index 文件。StatefulSets spec 中的 volumeMounts 字段保证了 /usr/share/nginx/html 文件夹由一个 PersistentVolume 支持。
将 Pod 的主机名写入它们的index.html文件并验证 NGINX web 服务器使用该主机名提供服务。
[rootk8s-master nginx]# kubectl exec -it nginx-web-0 /bin/bash
rootnginx-web-0:/# echo nginx-web-0 /usr/share/nginx/html/index.html
rootnginx-web-0:/# exit
exit
[rootk8s-master nginx]# kubectl exec -it nginx-web-1 /bin/bash
rootnginx-web-1:/# echo nginx-web-1 /usr/share/nginx/html/index.html
rootnginx-web-1:/# exit
exit[rootk8s-master nginx]# kubectl get pods -l appnginx -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-web-0 1/1 Running 0 84m 10.244.2.24 k8s-node2 none none
nginx-web-1 1/1 Running 0 84m 10.244.1.26 k8s-node1 none none[rootk8s-master nginx]# curl -s http://10.244.2.24
nginx-web-0
[rootk8s-master nginx]# curl -s http://10.244.1.26
nginx-web-1
3.4 说明 请注意如果你看见上面的 curl 命令返回了 403 Forbidden 的响应你需要像这样修复使用 volumeMounts挂载的目录的权限 # for i in 0 1; do kubectl exec web-$i -- chmod 755 /usr/share/nginx/html; done 将StatefulSet创建的 所有 Pod删除
[rootk8s-master nginx]# kubectl delete -f nginx-web.yaml
statefulset.apps nginx-web deleted
在使用StatefulSet重新创建的所有Pod
[rootk8s-master nginx]# kubectl apply -f nginx-web.yaml
statefulset.apps/nginx-web created
[rootk8s-master nginx]# kubectl get pods -l appnginx -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-web-0 1/1 Running 0 14s 10.244.2.25 k8s-node2 none none
nginx-web-1 1/1 Running 0 12s 10.244.1.27 k8s-node1 none none
我们发现pod的IP地址发生了变化接下来再次访问
[rootk8s-master nginx]# curl -s http://10.244.2.25
nginx-web-0
[rootk8s-master nginx]# curl -s http://10.244.1.27
nginx-web-1
虽然 nginx-web-0 和 nginx-web-1 被重新调度了但它们仍然继续监听各自的主机名因为和它们的 PersistentVolumeClaim 相关联的 PersistentVolume 被重新挂载到了各自的 volumeMount 上。不管 nginx-web-0 和 nginx-web-1 被调度到了哪个节点上它们的 PersistentVolumes 将会被挂载到合适的挂载点上。
3.5 扩容/缩容 StatefulSet
扩容/缩容 StatefulSet 指增加或减少它的副本数。这通过更新 replicas 字段完成.如果是手动创建的pv那么需要提前将pv创建好了。
4 实战2-通过StatefulSet来管理有状态的服务msyql
[rootk8s-master ~]# mkdir /mnt/data-3
[rootk8s-master ~]# vim /etc/exports
/mnt/data-3 172.16.229.*/24 (rw,sync,insecure,no_subtree_check,no_root_squash)
[rootk8s-master ~]# systemctl restart nfs
[rootk8s-master ~]# mkdir /k8s/application/mysql# 如果mysql-server.yaml在apply时出错请将mysql.pv.yaml delete即可
[rootk8s-master mysql]# cat mysql.pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata: name: mysql-pvlabels:type: mysql-pv
spec:capacity:storage: 5GiaccessModes:- ReadWriteManypersistentVolumeReclaimPolicy: Recyclenfs:server: 172.16.229.143path: /mnt/data-3[rootk8s-master mysql]# cat mysql-svc.yaml
apiVersion: v1
kind: Service
metadata:name: mysqllabels:app: mysql
spec:ports:- port: 3306name: mysqlclusterIP: Noneselector:app: mysql[rootk8s-master mysql]# cat mysql-server.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:name: mysql
spec:serviceName: mysqlreplicas: 1selector:matchLabels:app: mysqltemplate:metadata:labels:app: mysqlspec:containers:- name: mysqlimage: daocloud.io/library/mysql:5.7ports:- containerPort: 3306env:- name: MYSQL_ROOT_PASSWORDvalue: Qfedu123volumeMounts:- name: mysql-datamountPath: /var/lib/mysqlvolumeClaimTemplates:- metadata:name: mysql-dataspec:accessModes: [ReadWriteMany]storageClassName: managed-nfs-storageresources:requests:storage: 5Gi[rootk8s-master mysql]# kubectl apply -f mysql.pv.yaml
persistentvolume/mysql-pv created
[rootk8s-master mysql]# kubectl apply -f mysql-svc.yaml
service/mysql created
[rootk8s-master mysql]# kubectl apply -f mysql-server.yaml
statefulset.apps/mysql created[rootk8s-master mysql]# kubectl get pv | grep mysql
mysql-pv 5Gi RWX Recycle Bound default/mysql-data-mysql-0 7m28s[rootk8s-master mysql]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
mysql-data-mysql-0 Bound mysql-pv 5Gi RWX 7m16s[rootk8s-master mysql]# kubectl get pods -l appmysql -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
mysql-0 1/1 Running 0 6m22s 10.244.1.28 k8s-node1 none none[rootk8s-master mysql]# kubectl exec -it mysql-0 /bin/bash
rootmysql-0:/# mysql -uroot -pQfedu123
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
...
mysql show databases;
--------------------
| Database |
--------------------
| information_schema |
| mysql |
| performance_schema |
| sys |
--------------------
4 rows in set (0.01 sec)mysql create database test1;
Query OK, 1 row affected (0.00 sec)mysql exit
Bye
rootmysql-0:/# exit
exit
[rootk8s-master mysql]# cd /mnt/data-3/
[rootk8s-master data-3]# ll
总用量 188484
-rw-r----- 1 polkitd ssh_keys 56 11月 15 16:24 auto.cnf
-rw------- 1 polkitd ssh_keys 1676 11月 15 16:24 ca-key.pem
-rw-r--r-- 1 polkitd ssh_keys 1112 11月 15 16:24 ca.pem
-rw-r--r-- 1 polkitd ssh_keys 1112 11月 15 16:24 client-cert.pem
-rw------- 1 polkitd ssh_keys 1680 11月 15 16:24 client-key.pem
-rw-r----- 1 polkitd ssh_keys 1353 11月 15 16:25 ib_buffer_pool
-rw-r----- 1 polkitd ssh_keys 79691776 11月 15 16:25 ibdata1
-rw-r----- 1 polkitd ssh_keys 50331648 11月 15 16:25 ib_logfile0
-rw-r----- 1 polkitd ssh_keys 50331648 11月 15 16:24 ib_logfile1
-rw-r----- 1 polkitd ssh_keys 12582912 11月 15 16:25 ibtmp1
drwxr-x--- 2 polkitd ssh_keys 4096 11月 15 16:25 mysql
drwxr-x--- 2 polkitd ssh_keys 8192 11月 15 16:25 performance_schema
-rw------- 1 polkitd ssh_keys 1680 11月 15 16:24 private_key.pem
-rw-r--r-- 1 polkitd ssh_keys 452 11月 15 16:24 public_key.pem
-rw-r--r-- 1 polkitd ssh_keys 1112 11月 15 16:24 server-cert.pem
-rw------- 1 polkitd ssh_keys 1680 11月 15 16:24 server-key.pem
drwxr-x--- 2 polkitd ssh_keys 8192 11月 15 16:25 sys
drwxr-x--- 2 polkitd ssh_keys 20 11月 15 16:29 test1[rootk8s-master mysql]# kubectl delete -f mysql-server.yaml
statefulset.apps mysql deleted
[rootk8s-master mysql]# cd /mnt/data-3/
[rootk8s-master data-3]# ll
总用量 176196
-rw-r----- 1 polkitd ssh_keys 56 11月 15 16:24 auto.cnf
-rw------- 1 polkitd ssh_keys 1676 11月 15 16:24 ca-key.pem
-rw-r--r-- 1 polkitd ssh_keys 1112 11月 15 16:24 ca.pem
-rw-r--r-- 1 polkitd ssh_keys 1112 11月 15 16:24 client-cert.pem
-rw------- 1 polkitd ssh_keys 1680 11月 15 16:24 client-key.pem
-rw-r----- 1 polkitd ssh_keys 688 11月 15 16:32 ib_buffer_pool
-rw-r----- 1 polkitd ssh_keys 79691776 11月 15 16:32 ibdata1
-rw-r----- 1 polkitd ssh_keys 50331648 11月 15 16:32 ib_logfile0
-rw-r----- 1 polkitd ssh_keys 50331648 11月 15 16:24 ib_logfile1
drwxr-x--- 2 polkitd ssh_keys 4096 11月 15 16:25 mysql
drwxr-x--- 2 polkitd ssh_keys 8192 11月 15 16:25 performance_schema
-rw------- 1 polkitd ssh_keys 1680 11月 15 16:24 private_key.pem
-rw-r--r-- 1 polkitd ssh_keys 452 11月 15 16:24 public_key.pem
-rw-r--r-- 1 polkitd ssh_keys 1112 11月 15 16:24 server-cert.pem
-rw------- 1 polkitd ssh_keys 1680 11月 15 16:24 server-key.pem
drwxr-x--- 2 polkitd ssh_keys 8192 11月 15 16:25 sys
drwxr-x--- 2 polkitd ssh_keys 20 11月 15 16:29 test1[rootk8s-master data-3]# cd -
/k8s/application/mysql
[rootk8s-master mysql]# kubectl apply -f mysql-server.yaml
statefulset.apps/mysql created
[rootk8s-master mysql]# kubectl exec -it mysql-0 /bin/bash
rootmysql-0:/# mysql -uroot -pQfedu123
...
mysql show databases;
--------------------
| Database |
--------------------
| information_schema |
| mysql |
| performance_schema |
| sys |
| test1 |
--------------------
5 rows in set (0.01 sec)mysql
5 k8s中无状态服务和有状态服务部署的区别
无状态 1. pod命名pod名由资源名随机的字符串组成
2. 数据存储多个实例pod可以共享相同的持久化数据存储不是必要条件
3. 扩缩容可以随意扩缩容某个pod不会指定某个pod进行扩缩容
4. 启停顺序因为pod名的序号是随机串无启停顺序之分
5. 无状态k8s资源ReplicaSet、ReplicationController、Deployment、DaemonSet、Job等资源
6. 无状态服务tomcat、nginx等 有状态 这里假设有N个pod 1. pod命名pod名由statefulset资源名有序的数字组成0,1,2...N-1且pod有特定的网络标识
2. 数据存储有状态的服务对应实例需要有自己的独立持久卷存储
3. 扩缩容扩缩容不可随意缩容是从数字最大的开始递减扩容是在原有pod序号基础上递增1。
4. 启停顺序pod启停是有顺序的启动时先启动pod序号为0的然后依次递增至N-1停止时先停止pod序号为最大的N-1然后依次递减至0
5. 有状态k8s资源StatefulSet资源
6. 有状态服务Kafka、ZooKeeper、MySql、MongoDB以及一些需要保存日志的应用等服务
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/89920.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!