Kubernetes无状态服务特征:
1)是指该服务运行的实例不会在本地存储须要持久化的数据,而且多个实例对于同一请求响应的结果是彻底一致的;
2)多个实例能够共享相同的持久化数据。例如:nginx实例、tomcat实例等;
3)相关的Kubernetes资源有:ReplicaSet、ReplicationController、Deployment等,因为是无状态服务,因此这些控制器建立的Pod名称都是随机性的。而且在缩容时并不会明确缩容某一个Pod,而是随机的,由于全部实例获得的返回值都是同样的,因此缩容任何一个Pod均可以;html
Kubernetes有状态服务特征:
1)有状态服务能够说是须要数据存储功能的服务、或者指多线程类型的服务、队列等。(好比:mysql数据库、kafka、zookeeper等);
2)每一个实例都须要本身独立的持久化存储,而且在Kubernetes中经过声明模板的方式来进行定义。持久卷声明模板在建立pod以前建立,绑定到pod中,模板能够定义多个;
3)相关的Kubernetes资源有:StatefulSet。因为是有状态的服务,因此每一个Pod都有特定的名称和网络标识。好比Pod名称是由StatefulSet名+有序的数字组成(0、一、2……);
4)在进行缩容操做时,能够明确知道会缩容那一个Pod,从数字最大的开始。而且StatefulSet在已有实例不健康的状况下是不容许作缩容操做的;node
主要表如今如下方面:
1)实例数量:无状态服务能够有一个或多个实例,所以支持两种服务容量调节模式;有状态服务职能有一个实例,不容许建立多个实例,所以也不支持服务容量的调节;
2)存储卷:无状态服务能够有存储卷,也能够没有,即便有也没法备份存储卷中的数据;有状态服务必需要有存储卷,而且在建立服务时,必须指定该存储卷分配的磁盘空间大小;
3)数据存储: 无状态服务运行过程当中的全部数据(除日志和监控数据)都存在容器实例里的文件系统中,若是实例中止或者删除,则这些数据都将丢失,没法找回;而对于有状态服务,凡是已经挂载了存储卷的目录下的文件内容均可以随时进行备份,备份的数据能够下载,也能够用于恢复新的服务。但对于没有挂载卷的目录下的数据,仍然是没法备份和保存的,若是实例中止或者删除,这些非挂载卷里的文件内容一样会丢失。mysql
StatefulSet是Kubernetes提供的管理有状态应用的负载管理控制器API。在Pods管理的基础上,保证Pods的顺序和一致性。与Deployment同样,StatefulSet也是使用容器的Spec来建立Pod,与之不一样StatefulSet建立的Pods在生命周期中会保持持久的标记(例如Pod Name)。nginx
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);web
为了方便,就直接在master节点上部署NFS存储了!sql
[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 -e Export list for master: /nfsdata *
[root@master ~]# vim rbac-rolebind.yaml apiVersion: v1 #建立一个用于认证的服务帐号 kind: ServiceAccount metadata: name: nfs-provisioner --- apiVersion: rbac.authorization.k8s.io/v1 #建立群集规则 kind: ClusterRole metadata: name: nfs-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: ["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/v1 metadata: name: run-nfs-provisioner subjects: - 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
[root@master ~]# vim nfs-deployment.yaml apiVersion: extensions/v1beta1 kind: Deployment metadata: name: nfs-client-provisioner spec: 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 AGE nfs-client-provisioner-66df958f9c-mbvhv 1/1 Running 0 2m34s
[root@master ~]# vim sc.yaml apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: stateful-nfs namespace: xiaojiang-test provisioner: lzj #这个要和nfs-client-provisioner的env环境变量中的PROVISIONER_NAME的value值对应。 reclaimPolicy: Retain #指定回收策略为Retain(手动释放) [root@master ~]# kubectl apply -f sc.yaml [root@master ~]# kubectl get StorageClass NAME PROVISIONER AGE stateful-nfs lzj 17s
[root@master ~]# vim statefulset.yaml apiVersion: v1 kind: Service metadata: name: headless-svc #从名称就能够是无头服务 labels: app: headless-svc spec: ports: - port: 80 name: myweb selector: app: headless-pod clusterIP: None #不分配群集的IP地址,因此不具有负载均衡的能力 --- apiVersion: apps/v1 kind: StatefulSet #定义pod中运行的应用 metadata: name: statefulset-test spec: 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 pod NAME READY STATUS RESTARTS AGE nfs-client-provisioner-66df958f9c-mbvhv 1/1 Running 0 10m statefulset-test-0 1/1 Running 0 29s statefulset-test-1 1/1 Running 0 18s statefulset-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-255b10978cbe default-test-statefulset-test-1-pvc-1b499d49-a787-4f2b-b238-404b05f75fd7 default-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-0 statefulset-test-0 1/1 Running 0 4m53s 10.244.2.4 node02 <none> <none> [root@master ~]# curl 10.244.2.4 hello world [root@master ~]# curl -I 10.244.2.4 HTTP/1.1 200 OK Date: Wed, 12 Feb 2020 09:52:04 GMT Server: Apache/2.4.41 (Unix) Last-Modified: Wed, 12 Feb 2020 09:45:37 GMT ETag: "c-59e5dd5ac0a63" Accept-Ranges: bytes Content-Length: 12 Content-Type: text/html #能够看出如今提供web页面的服务是Apache
[root@master ~]# vim statefulset.yaml apiVersion: v1 kind: Service metadata: name: headless-svc labels: app: headless-svc spec: ports: - port: 80 name: myweb selector: app: headless-pod clusterIP: None --- apiVersion: apps/v1 kind: StatefulSet metadata: name: statefulset-test spec: 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 wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nfs-client-provisioner-66df958f9c-mbvhv 1/1 Running 0 35m 10.244.2.2 node02 <none> <none> statefulset-test-0 1/1 Running 0 21m 10.244.2.4 node02 <none> <none> statefulset-test-1 1/1 Running 0 20m 10.244.1.4 node01 <none> <none> statefulset-test-2 1/1 Running 0 3m52s 10.244.1.9 node01 <none> <none> statefulset-test-3 1/1 Running 0 4m54s 10.244.2.5 node02 <none> <none> statefulset-test-4 1/1 Running 0 4m43s 10.244.1.6 node01 <none> <none> statefulset-test-5 1/1 Running 0 4m31s 10.244.2.6 node02 <none> <none> statefulset-test-6 1/1 Running 0 4m25s 10.244.1.7 node01 <none> <none> statefulset-test-7 1/1 Running 0 4m19s 10.244.2.7 node02 <none> <none> statefulset-test-8 1/1 Running 0 4m12s 10.244.1.8 node01 <none> <none> statefulset-test-9 1/1 Running 0 4m3s 10.244.2.8 node02 <none> <none> [root@master ~]# ls /nfsdata/ | wc -l 10 [root@master ~]# curl -I 10.244.2.4 HTTP/1.1 200 OK Date: Wed, 12 Feb 2020 10:05:34 GMT Server: Apache/2.4.41 (Unix) Last-Modified: Wed, 12 Feb 2020 09:45:37 GMT ETag: "c-59e5dd5ac0a63" Accept-Ranges: bytes Content-Length: 12 Content-Type: text/html [root@master ~]# curl -I 10.244.2.8 HTTP/1.1 403 Forbidden Server: nginx/1.17.8 Date: Wed, 12 Feb 2020 10:05:41 GMT Content-Type: text/html Content-Length: 153 Connection: keep-alive
由此能够看出在执行扩容操做时,并不会更改pod,这就是StatefulSet的特色!数据库
————————————本文到此结束,感谢阅读————————————apache