千家信息网

Kubernetes针对有状态服务数据持久化之Statefu

发表于:2024-11-21 作者:千家信息网编辑
千家信息网最后更新 2024年11月21日,一、Kubernetes无状态服务VS有状态服务1)Kubernetes无状态服务Kubernetes无状态服务特征:1)是指该服务运行的实例不会在本地存储需要持久化的数据,并且多个实例对于同一请求响
千家信息网最后更新 2024年11月21日Kubernetes针对有状态服务数据持久化之Statefu

一、Kubernetes无状态服务VS有状态服务

1)Kubernetes无状态服务

Kubernetes无状态服务特征:
1)是指该服务运行的实例不会在本地存储需要持久化的数据,并且多个实例对于同一请求响应的结果是完全一致的;
2)多个实例可以共享相同的持久化数据。例如:nginx实例、tomcat实例等;
3)相关的Kubernetes资源有:ReplicaSet、ReplicationController、Deployment等,由于是无状态服务,所以这些控制器创建的Pod名称都是随机性的。并且在缩容时并不会明确缩容某一个Pod,而是随机的,因为所有实例得到的返回值都是一样的,所以缩容任何一个Pod都可以;

2)Kubernetes有状态服务

Kubernetes有状态服务特征:
1)有状态服务可以说是需要数据存储功能的服务、或者指多线程类型的服务、队列等。(比如:mysql数据库、kafka、zookeeper等);
2)每个实例都需要自己独立的持久化存储,并且在Kubernetes中通过声明模板的方式来进行定义。持久卷声明模板在创建pod之前创建,绑定到pod中,模板可以定义多个;
3)相关的Kubernetes资源有:StatefulSet。由于是有状态的服务,所以每个Pod都有特定的名称和网络标识。比如Pod名称是由StatefulSet名+有序的数字组成(0、1、2……);
4)在进行缩容操作时,可以明确知道会缩容那一个Pod,从数字最大的开始。并且StatefulSet在已有实例不健康的情况下是不允许做缩容操作的;

3)无状态服务和有状态服务的区别

主要表现在以下方面:
1)实例数量:无状态服务可以有一个或多个实例,因此支持两种服务容量调节模式;有状态服务职能有一个实例,不允许创建多个实例,因此也不支持服务容量的调节;
2)存储卷:无状态服务可以有存储卷,也可以没有,即使有也无法备份存储卷中的数据;有状态服务必须要有存储卷,并且在创建服务时,必须指定该存储卷分配的磁盘空间大小;
3)数据存储: 无状态服务运行过程中的所有数据(除日志和监控数据)都存在容器实例里的文件系统中,如果实例停止或者删除,则这些数据都将丢失,无法找回;而对于有状态服务,凡是已经挂载了存储卷的目录下的文件内容都可以随时进行备份,备份的数据可以下载,也可以用于恢复新的服务。但对于没有挂载卷的目录下的数据,仍然是无法备份和保存的,如果实例停止或者删除,这些非挂载卷里的文件内容同样会丢失。

4)StatefulSet概述

StatefulSet是Kubernetes提供的管理有状态应用的负载管理控制器API。在Pods管理的基础上,保证Pods的顺序和一致性。与Deployment一样,StatefulSet也是使用容器的Spec来创建Pod,与之不同StatefulSet创建的Pods在生命周期中会保持持久的标记(例如Pod Name)。

5)StatefulSet特点

1)稳定的持久化存储,即Pod重新调度后还是能访问到相同的持久化数据,基于PVC来实现;
2)稳定的网络标志,即Pod重新调度后其PodName和HostName不变,基于Headless Service(即没有Cluster IP的Service)来实现;
3)有序部署,有序扩展,即Pod是有顺序的,在部署或者扩展的时候要依据定义的顺序依次依次进行(即从0到N-1,在下一个Pod运行之前所有之前的Pod必须都是Running和Ready状态),基于init containers来实现;
4)有序收缩,有序删除(即从N-1到0);

二、使用StatefulSet实现自动创建PVC

1)搭建NFS共享存储

为了方便,就直接在master节点上部署NFS存储了!

[root@master ~]# yum -y install nfs-utils rpcbind[root@master ~]# vim /etc/exports/nfsdata *(rw,sync,no_root_squash)[root@master ~]# mkdir /nfsdata[root@master ~]# systemctl start nfs-server[root@master ~]# systemctl start rpcbind[root@master ~]# showmount -eExport list for master:/nfsdata *

2)创建rbac授权

[root@master ~]# vim rbac-rolebind.yamlapiVersion: v1                            #创建一个用于认证的服务账号kind: ServiceAccountmetadata:  name: nfs-provisioner---apiVersion: rbac.authorization.k8s.io/v1        #创建群集规则kind: ClusterRolemetadata:  name: nfs-provisioner-runnerrules:   -  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: ["watch", "create", "update", "patch"]   -  apiGroups: [""]      resources: ["services", "endpoints"]      verbs: ["get","create","list", "watch","update"]   -  apiGroups: ["extensions"]      resources: ["podsecuritypolicies"]      resourceNames: ["nfs-provisioner"]      verbs: ["use"]---kind: ClusterRoleBinding                #将服务认证用户与群集规则进行绑定apiVersion: rbac.authorization.k8s.io/v1metadata:  name: run-nfs-provisionersubjects:  - kind: ServiceAccount    name: nfs-provisioner    namespace: default                    #必写字段,否则会提示错误roleRef:  kind: ClusterRole  name: nfs-provisioner-runner  apiGroup: rbac.authorization.k8s.io[root@master ~]# kubectl apply -f rbac-rolebind.yaml    

3)创建nfs-deployment.资源

[root@master ~]# vim nfs-deployment.yamlapiVersion: extensions/v1beta1kind: Deploymentmetadata:  name: nfs-client-provisionerspec:  replicas: 1                              #指定副本数量为1  strategy:    type: Recreate                      #指定策略类型为重置  template:    metadata:      labels:        app: nfs-client-provisioner    spec:      serviceAccount: nfs-provisioner            #指定rbac yanl文件中创建的认证用户账号      containers:        - name: nfs-client-provisioner          image: registry.cn-hangzhou.aliyuncs.com/open-ali/nfs-client-provisioner     #使用的镜像           volumeMounts:            - name: nfs-client-root              mountPath:  /persistentvolumes             #指定容器内挂载的目录          env:            - name: PROVISIONER_NAME           #容器内的变量用于指定提供存储的名称              value: lzj            - name: NFS_SERVER                      #容器内的变量用于指定nfs服务的IP地址              value: 192.168.1.1            - name: NFS_PATH                       #容器内的变量指定nfs服务器对应的目录              value: /nfsdata      volumes:                                                #指定挂载到容器内的nfs的路径及IP        - name: nfs-client-root          nfs:            server: 192.168.1.1            path: /nfsdata[root@master ~]# kubectl apply -f nfs-deployment.yaml[root@master ~]# kubectl get pod NAME                                      READY   STATUS    RESTARTS   AGEnfs-client-provisioner-66df958f9c-mbvhv   1/1     Running   0          2m34s

4)创建SC(Storage Class)

[root@master ~]# vim sc.yamlapiVersion: storage.k8s.io/v1kind: StorageClassmetadata:  name: stateful-nfs  namespace: xiaojiang-testprovisioner: lzj                  #这个要和nfs-client-provisioner的env环境变量中的PROVISIONER_NAME的value值对应。reclaimPolicy: Retain               #指定回收策略为Retain(手动释放)[root@master ~]# kubectl apply -f sc.yaml [root@master ~]# kubectl get StorageClassNAME           PROVISIONER   AGEstateful-nfs   lzj           17s

5)创建Pod

[root@master ~]# vim statefulset.yaml apiVersion: v1kind: Servicemetadata:  name: headless-svc                    #从名称就可以是无头服务  labels:    app: headless-svcspec:  ports:  - port: 80    name: myweb  selector:    app: headless-pod  clusterIP: None                        #不分配群集的IP地址,所以不具备负载均衡的能力---apiVersion: apps/v1kind: StatefulSet                          #定义pod中运行的应用metadata:  name: statefulset-testspec:  serviceName: headless-svc  replicas: 3  selector:    matchLabels:      app: headless-pod  template:    metadata:      labels:        app: headless-pod    spec:      containers:      - image: httpd        name: myhttpd        ports:        - containerPort: 80          name: httpd        volumeMounts:        - mountPath: /usr/local/apache2/htdocs          name: test  volumeClaimTemplates:                       #定义创建PVC使用的模板  - metadata:      name: test      annotations:  #这是指定storageclass        volume.beta.kubernetes.io/storage-class: stateful-nfs    spec:      accessModes:        - ReadWriteOnce      resources:        requests:          storage: 100Mi[root@master ~]# kubectl apply -f statefulset.yaml [root@master ~]# kubectl get podNAME                                      READY   STATUS    RESTARTS   AGEnfs-client-provisioner-66df958f9c-mbvhv   1/1     Running   0          10mstatefulset-test-0                        1/1     Running   0          29sstatefulset-test-1                        1/1     Running   0          18sstatefulset-test-2                        1/1     Running   0          11s[root@master ~]# kubectl get pv[root@master ~]# kubectl get pvc              #PV与PVC已经生成[root@master ~]# ls /nfsdata/default-test-statefulset-test-0-pvc-54d0b06c-698e-4f1a-8327-255b10978cbedefault-test-statefulset-test-1-pvc-1b499d49-a787-4f2b-b238-404b05f75fd7default-test-statefulset-test-2-pvc-7766f8da-6f3b-4c1f-9eb8-dfadda1e656f[root@master ~]# echo "hello world" > /nfsdata/default-test-statefulset-test-0-pvc-54d0b06c-698e-4f1a-8327-255b10978cbe/index.html[root@master ~]# kubectl get pod -o wide | grep test-0statefulset-test-0                        1/1     Running   0          4m53s   10.244.2.4   node02              [root@master ~]# curl 10.244.2.4hello world[root@master ~]# curl -I 10.244.2.4HTTP/1.1 200 OKDate: Wed, 12 Feb 2020 09:52:04 GMTServer: Apache/2.4.41 (Unix)Last-Modified: Wed, 12 Feb 2020 09:45:37 GMTETag: "c-59e5dd5ac0a63"Accept-Ranges: bytesContent-Length: 12Content-Type: text/html#可以看出现在提供web页面的服务是Apache

6)对pod进行更新并扩容

[root@master ~]# vim statefulset.yaml apiVersion: v1kind: Servicemetadata:  name: headless-svc  labels:    app: headless-svcspec:  ports:  - port: 80    name: myweb  selector:    app: headless-pod  clusterIP: None---apiVersion: apps/v1kind: StatefulSetmetadata:  name: statefulset-testspec:  updateStrategy:    rollingUpdate:      partition: 2                           #指定并行升级的个数  serviceName: headless-svc  replicas: 10  selector:    matchLabels:      app: headless-pod  template:    metadata:      labels:        app: headless-pod    spec:      containers:      - image: nginx                       #更换扩容时使用的镜像        name: myhttpd        ports:        - containerPort: 80          name: httpd        volumeMounts:        - mountPath: /usr/share/nginx/html/                 #更换容器中的主目录          name: test  volumeClaimTemplates:  - metadata:      name: test      annotations:  #这是指定storageclass        volume.beta.kubernetes.io/storage-class: stateful-nfs    spec:      accessModes:        - ReadWriteOnce      resources:        requests:          storage: 100Mi[root@master ~]# kubectl apply -f statefulset.yaml [root@master ~]# kubectl get pod -o wideNAME                                      READY   STATUS    RESTARTS   AGE     IP           NODE     NOMINATED NODE   READINESS GATESnfs-client-provisioner-66df958f9c-mbvhv   1/1     Running   0          35m     10.244.2.2   node02              statefulset-test-0                        1/1     Running   0          21m     10.244.2.4   node02              statefulset-test-1                        1/1     Running   0          20m     10.244.1.4   node01              statefulset-test-2                        1/1     Running   0          3m52s   10.244.1.9   node01              statefulset-test-3                        1/1     Running   0          4m54s   10.244.2.5   node02              statefulset-test-4                        1/1     Running   0          4m43s   10.244.1.6   node01              statefulset-test-5                        1/1     Running   0          4m31s   10.244.2.6   node02              statefulset-test-6                        1/1     Running   0          4m25s   10.244.1.7   node01              statefulset-test-7                        1/1     Running   0          4m19s   10.244.2.7   node02              statefulset-test-8                        1/1     Running   0          4m12s   10.244.1.8   node01              statefulset-test-9                        1/1     Running   0          4m3s    10.244.2.8   node02              [root@master ~]# ls /nfsdata/ | wc -l10[root@master ~]# curl -I 10.244.2.4HTTP/1.1 200 OKDate: Wed, 12 Feb 2020 10:05:34 GMTServer: Apache/2.4.41 (Unix)Last-Modified: Wed, 12 Feb 2020 09:45:37 GMTETag: "c-59e5dd5ac0a63"Accept-Ranges: bytesContent-Length: 12Content-Type: text/html[root@master ~]# curl -I 10.244.2.8HTTP/1.1 403 ForbiddenServer: nginx/1.17.8Date: Wed, 12 Feb 2020 10:05:41 GMTContent-Type: text/htmlContent-Length: 153Connection: keep-alive

由此可以看出在执行扩容操作时,并不会更改pod,这就是StatefulSet的特点!

------------本文到此结束,感谢阅读------------

服务 状态 实例 存储 数据 容器 有序 名称 多个 目录 变量 备份 文件 模板 运行 资源 顺序 管理 认证 相同 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 网络安全技能比赛 高速两侧的服务器互通吗 河南一览网络技术有限公司待遇 服务器能关机吗 saas组织架构数据库表设计 数据库的两种扩展方式指的是什么 央企网络安全工作 网络安全态势链接 ios网易版我的世界服务器 实验室管理系统视图数据库 银河证券的软件开发在哪里 上海冰人互联网科技公司 计算机网络技术网络层试题 歌尔西安软件开发 服务器返回码550 客户管理系统数据库逻辑结构设计 软件开发外包公司该不该去 浙江有哪些网络安全学校 无线软件开发流程 江西安卓智能产品软件开发 贵州谷雨互联网络科技有限公司 北京公安大学网络安全就业情况 如何租服务器跑代码 中文生物医学期刊数据库 2020年服务器cpu二手 利用arcgis软件开发 黑暗与光明手游如何进服务器 信阳软件开发网上价格 高校加强网络安全监管力度 我的世界服务器高级附魔软件
0