StatefulSet

StatefulSet

StatefulSet:Pod控制器。

? RC,RS,Deployment,DS。---------->无状态的服务。

? template(模板):根据模板创建出来的Pod,他们的状态都是一模一样的(除了名称,IP,域名之外)

? 可以理解为:任何一个Pod,都可以被删除,然后用新生成的Pod进行替换。

有状态的服务:需要记录前一次或者多次通信中的相关事件,以作为一下通信的分类标准。比如:mysql等数据库服务。(Pod的名称,不能随意变化。数据持久化的目录也是不一样,每一个Pod都有自己独有的数据持久化存储目录。)

? mysql:主从关系。

如果把之前无状态的服务比喻为牛,羊等牲畜。把有状态比喻为:宠物。

每一个Pod对应一个PVC,每一个PVC对应一个PV。

? storageclass:自动创建PV。

? 需要解决:自动创建PVC------------>volumeClaimTemplates

[[email protected] ~]# vim statefulset.yaml

apiVersion: v1
kind: Service
metadata:
  name: headless-svc
  labels:
    app: headless-svc
spec:
  ports:
  - port: 80
  selector:
    app: headless-pod
  clusterIP: None
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: statefulset-test
spec:
  serviceName: headless-svc
  replicas: 3
  selector:
    matchLabels:
      app: headless-pod
  template:
    metadata:
      labels:
        app: headless-pod
    spec:
      containers:
      - name: myhttpd
        image: httpd
        ports:
        - containerPort: 80

[[email protected] ~]# kubectl apply -f statefulset.yaml
service/headless-svc created
statefulset.apps/statefulset-test created

Deployment:Deeployment+RS+随机字符串(Pod的名称。)没有顺序的。可以被随意替代的。

1.headless-svc:无头服务。因为没有IP地址,所以它不具备负载均衡的功能了。因为statefulset要求Pod的名称是由顺序的,每一个Pod都不能被随意取代,也就是即使Pod重建之后,名称依然不变。为后端的每一个Pod,去命名。

2.statefulset:定义具体的应用

3.volumeClaimTemplates:自动能够创建PVC,为后端提供专有的存储。

一、创建StorageClass资源对象。

? 1.基于NFS服务,创建NFS服务。

[[email protected] ~]# showmount -e
Export list for master:
/nfsdata *

? 2.创建rbac权限。

[[email protected] ~]# mkdir yaml
[[email protected] ~]# cp rbac-rolebind.yaml yaml/
[[email protected] ~]# cd yaml/
[[email protected] yaml]# 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
roleRef:
  kind: ClusterRole
  name: nfs-provisioner-runner
  apiGroup: rbac.authorization.k8s.io

报错:
[[email protected] yaml]# kubectl apply -f rbac-rolebind.yaml
serviceaccount/nfs-provisioner created
clusterrole.rbac.authorization.k8s.io/nfs-provisioner-runner unchanged
The ClusterRoleBinding "run-nfs-provisioner" is invalid: subjects[0].namespace: Required value

排错:
38行添加:
    namespace: default

成功:
[[email protected] yaml]# kubectl apply -f rbac-rolebind.yaml
serviceaccount/nfs-provisioner unchanged
clusterrole.rbac.authorization.k8s.io/nfs-provisioner-runner unchanged
clusterrolebinding.rbac.authorization.k8s.io/run-nfs-provisioner configured

3.创建Deployment资源对象,用Pod代替真正的

[[email protected] ~]# cp nfs-deployment.yaml yaml/
[[email protected] ~]# cd yaml/
[[email protected] yaml]# vim nfs-deployment.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: nfs-client-provisioner
spec:
  replicas: 1
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: nfs-client-provisioner
    spec:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: nfs-client-provisioner
spec:
  replicas: 1
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: nfs-client-provisioner
    spec:
      serviceAccount: nfs-provisioner
      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: bdqn
            - name: NFS_SERVER
              value: 192.168.1.10
            - name: NFS_PATH
              value: /nfsdata
      volumes:
        - name: nfs-client-root
          nfs:
            server: 192.168.1.10
            path: /nfsdata

[[email protected] yaml]# kubectl apply -f nfs-deployment.yaml
deployment.extensions/nfs-client-provisioner created

4.创建storageclass

[[email protected] ~]# cp test-storageclass.yaml yaml/
[[email protected] ~]# cd yaml/
[[email protected] yaml]# vim test-storageclass.yaml 

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: sc-nfs
provisioner: bdqn
reclaimPolicy: Retain

删除之前创建的sc:
[[email protected] yaml]# kubectl delete sc sc-nfs
storageclass.storage.k8s.io "sc-nfs" deleted
查看有没有删除:
[[email protected] yaml]# kubectl get sc
No resources found.
再次运行文件:
[[email protected] yaml]# kubectl apply -f test-storageclass.yaml
storageclass.storage.k8s.io/sc-nfs created

二、解决自动创建PVC

先删除之前创建的statefulset

[[email protected] yaml]# kubectl delete -f statefulset.yaml
service "headless-svc" deleted
statefulset.apps "statefulset-test" deleted

再修改statefulset.yaml里的文件:

[[email protected] yaml]# 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:
  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: /mnt
          name: test
  volumeClaimTemplates:
  - metadata:
      name: test
      annotations:   //这是指定storageclass
        volume.beta.kubernetes.io/storage-class: sc-nfs
    spec:
      accessModes:
        - ReadWriteOnce
      resources:
        requests:
          storage: 100Mi

生成一下:
[[email protected] yaml]# kubectl apply -f statefulset.yaml
service/headless-svc created
statefulset.apps/statefulset-test created

验证是否能被使用:
[[email protected] yaml]# kubectl exec -it statefulset-test-0 /bin/sh
# cd /mnt
# touch testfile
# exit

[[email protected] yaml]# ls /nfsdata/default-test-statefulset-test-0-pvc-2fd45b61-6c69-4901-80da-66184e220b6f/
testfile

拓展:
以自己的名称创建一个名称空间,以下所有资源都运行在此空间中。用statefuset资源运行一个httpd web服务,要求3个Pod,但是每个Pod的主界面内容不一样,并且都要做专有的数据持久化,尝试删除其中一个Pod,查看新生成的Pod,总结对比与之前Deployment资源控制器控制的Pod有什么不同之处?
(一)创建StorageClass资源对象。
注意:nfs服务要开启
1、创建namespace的yaml文件
[[email protected] yaml]# vim namespace.yaml
kind: Namespace
apiVersion: v1
metadata:
name: xgp-lll #namespave的名称
执行一下
[[email protected] yaml]# kubectl apply -f namespace.yaml
查看一下
[[email protected] yaml]# kubectl get namespaces

  1. 创建rbac权限。
    [[email protected] yaml]# vim rbac-rolebind.yaml
    apiVersion: v1
    kind: ServiceAccount
    metadata:
    name: nfs-provisioner
    namespace: xgp-lll

    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
    name: nfs-provisioner-runner
    namespace: xgp-lll
    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: xgp-lll
      roleRef:
      kind: ClusterRole
      name: nfs-provisioner-runner
      apiGroup: rbac.authorization.k8s.io
      执行一下
      [[email protected] yaml]# kubectl apply -f rbac-rolebind.yaml
      3、创建Deployment资源对象,用Pod代替 真正的NFS服务。
      [[email protected] yaml]# vim nfs-deployment.yaml

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nfs-client-provisioner
namespace: xgp-lll
spec:
replicas: 1
strategy:
type: Recreate
template:
metadata:
labels:
app: nfs-client-provisioner
spec:
serviceAccount: nfs-provisioner
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: xgp
    • name: NFS_SERVER
      value: 192.168.1.21
    • name: NFS_PATH
      value: /nfsdata
      volumes:
  • name: nfs-client-root
    nfs:
    server: 192.168.1.21
    path: /nfsdata
    执行一下
    [[email protected] yaml]# kubectl apply -f nfs-deployment.yaml
    查看一下
    [[email protected] yaml]# kubectl get pod -n xgp-lll

4、创建storageclass的yaml文件
[[email protected] yaml]# vim test-storageclass.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: stateful-nfs
namespace: xgp-lll
provisioner: xgp #通过provisioner字段关联到上述Deploy
reclaimPolicy: Retain
执行一下
[[email protected] yaml]# kubectl apply -f test-storageclass.yaml
查看一下
[[email protected] yaml]# kubectl get sc -n xgp-lll

(二)解决自动创建pvc
1、创建statefulset的yaml文件
apiVersion: v1
kind: Service
metadata:
name: headless-svc
namespace: xgp-lll
labels:
app: headless-svc
spec:
ports:

  • port: 80
    name: myweb
    selector:
    app: headless-pod
    apiVersion: apps/v1
    kind: StatefulSet
    metadata:
    name: statefulset-test
    namespace: xgp-lll
    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,为后端的Pod提供专有的>存储。**
  • metadata:
    name: test
    annotations: #这是指定storageclass
    volume.beta.kubernetes.io/storage-class: stateful-nfs
    spec:
    accessModes:
    • ReadWriteOnce
      resources:
      requests:
      storage: 100Mi
      执行一下
      [[email protected] yaml]# kubectl apply -f statefulset.yaml
      查看一下
      [[email protected] yaml]# kubectl get pod -n xgp-lll

2、 验证一下数据存储
容器中创建文件
第一个
[[email protected] yaml]# kubectl exec -it -n xgp-lll statefulset-test-0 /bin/bash
[email protected]:/usr/local/apache2# echo 123 > /usr/local/apache2/htdocs/index.html

第二个
[[email protected] yaml]# kubectl exec -it -n xgp-lll statefulset-test-1 /bin/bash
[email protected]:/usr/local/apache2# echo 456 > /usr/local/apache2/htdocs/index.html

第三个
[[email protected] yaml]# kubectl exec -it -n xgp-lll statefulset-test-2 /bin/bash
[email protected]:/usr/local/apache2# echo 789 > /usr/local/apache2/htdocs/index.html
宿主机查看一下
第一个
[[email protected] yaml]# cat /nfsdata/xgp-lll-test-statefulset-test-0-pvc-ccaa02df-4721-4453-a6ec-4f2c928221d7/index.html
123

第二个
[[email protected] yaml]# cat /nfsdata/xgp-lll-test-statefulset-test-1-pvc-88e60a58-97ea-4986-91d5-a3a6e907deac/index.html
456

第三个
[[email protected] yaml]# cat /nfsdata/xgp-lll-test-statefulset-test-2-pvc-4eb2bbe2-63d2-431a-ba3e-b7b8d7e068d3/index.html
789
访问一下

kubernetes(k8s)StatefulSet 和 Deployment 区别及选择方式
访问方式:

Compare Deployment & StatefulSet

综上所述:
如果是不需额外数据依赖或者状态维护的部署,或者replicas是1,优先考虑使用Deployment;
如果单纯的要做数据持久化,防止pod宕掉重启数据丢失,那么使用pv/pvc就可以了;
如果要打通app之间的通信,而又不需要对外暴露,使用headlessService即可;
如果需要使用service的负载均衡,不要使用StatefulSet,尽量使用clusterIP类型,用serviceName做转发;
如果是有多replicas,且需要挂载多个pv且每个pv的数据是不同的,因为pod和pv之间是 一 一对应的,如果某个pod挂掉再重启,还需要连接之前的pv,不能连到别的pv上,考虑使用StatefulSet
能不用StatefulSet,就不要用
只能用StatefulSet:
最近在微软的aks平台上部署服务,由于Deployment在scale的时候需要动态申请volume,采取使用volumeClaimTemplates属性的方式来申请,当前Deployment对象(1.15)不支持这一属性,只有StatefulSet才有,因此不得不使用后者。目前看来有点本末倒置,不过不排除以后k8s会支持这一属性。

注意:
如果使用StatefulSet,spec.serviceName需要指向headlessServiceName,且不能省略指定步骤,官方文档要求headlessService必须在创建StatefulSet之前创建完成,经过测试,如果没有也不会影响pod运行(pod还是running状态),只是不能拥有一个stable-network-id 集群内部不能访问到这个服务(如果这个服务不需要被发现,只需要去发现其他服务,则serviceName随便写一个也行),官方要求要在创建StatefulSet之前创建好headlessService,是为了让pod启动时能自动对应到service上。

之所以要指定一个headlessService,是因为admin可以给StatefulSet创建多个、多种类型的service,k8s不知道要用哪个service的名称当作集群内域名的一部分。

Deployment类型则不能有此参数,否则报错。

原文地址:https://blog.51cto.com/13997536/2470758

时间: 2024-10-08 21:17:17

StatefulSet的相关文章

kubernetes之StatefulSet详解

概述 RC.Deployment.DaemonSetStatefulSet都是面向无状态的服务,它们所管理的Pod的IP.名字,启停顺序等都是随机的,而StatefulSet是什么?顾名思义,有状态的集合,管理所有有状态的服务,比如MySQL.MongoDB集群等.StatefulSet本质上是Deployment的一种变体,它是t是为了解决有状态服务的问题,它所管理的Pod拥有固定的Pod名称,启停顺序,在StatefulSet中,Pod名字称为网络标识,还必须要用到共享存储,在v1.9版本中

statefulSet + headless service 学习记录

1.statefulset.yaml apiVersion: apps/v1kind: StatefulSetmetadata:   name: webspec:    serviceName: "nginx"    replicas: 2    selector:     matchLabels:        app: nginx    template:        metadata:             labels:                  app: ngin

kubernetes关于statefulset的理解

概述RC.Deployment.DaemonSet都是面向无状态的服务,它们所管理的Pod的IP.名字,启停顺序等都是随机的,而StatefulSet是什么?顾名思义,有状态的集合,管理所有有状态的服务,比如MySQL.MongoDB集群等.StatefulSet本质上是Deployment的一种变体,在v1.9版本中已成为GA版本,它为了解决有状态服务的问题,它所管理的Pod拥有固定的Pod名称,启停顺序,在StatefulSet中,Pod名字称为网络标识(hostname),还必须要用到共享

statefulSet 原理理解

1.  svc(vip)                       --              deployment 2.headless(none)                --              statefulSet   --- pod(每个pod都有唯一标识,是有先后顺序的) #headless service,即无头服务,与service的区别就是它没有Cluster IP,解析它的名称时将返回该Headless Service对应的全部Pod的Endpoint列表

Kubernetes 通过statefulset部署redis cluster集群

Kubernetes 通过statefulset部署redis cluster集群 作者: 张首富 时间: 2019-02-19 个人博客地址: https://www.zhangshoufu.com QQ群: 895291458 需要有redis基础 Redis集群架构图 每个Mater 都可以拥有多个slave.当Master掉线后,redis cluster集群会从多个Slave中选举出来一个新的Matser作为代替,而旧的Master重新上线后变成 Master 的Slave. 部署re

Kubernetes之StatefulSet控制器

目录 Kubernetes之StatefulSet控制器 简介 StatefulSet使用 滚动更新 扩展伸缩 更新策略和版本升级 Kubernetes之StatefulSet控制器 简介 StatefulSet 作为 Controller 为 Pod 提供唯?的标识. 它可以保证部署和 scale 的顺序. StatefulSet是为了解决有状态服务的问题(对应Deployments和ReplicaSets是为?状态服务?设计) , 其应?场景包括: 稳定的持久化存储, 即Pod重新调度后还是

Statefulset的拓扑状态

Statefulset: 实例之间有不对等关系,以及实例对外部数据有依赖关系的应用,就被称为“有状态应用”(Stateful Application). StatefulSet 的设计其实非常容易理解.它把真实世界里的应用状态,抽象为了两种情况: 拓扑状态.这种情况意味着,应用的多个实例之间不是完全对等的关系.这些应用实例,必须按照某些顺序启动,比如应用的主节点 A 要先于从节点 B 启动.而如果你把 A 和 B 两个 Pod 删除掉,它们再次被创建出来时也必须严格按照这个顺序才行.并且,新创建

Kubernetes之(十四)StatefulSet控制器

目录 Kubernetes之(十四)StatefulSet控制器 简介 StatefulSet使用 滚动更新 扩展伸缩 更新策略和版本升级 Kubernetes之(十四)StatefulSet控制器 简介 StatefulSet 作为 Controller 为 Pod 提供唯?的标识. 它可以保证部署和 scale 的顺序. StatefulSet是为了解决有状态服务的问题(对应Deployments和ReplicaSets是为?状态服务?设计) , 其应?场景包括: 稳定的持久化存储, 即Po

k8s实践18:statefulset学习配置记录

1.基础概念 statefulset,可以翻译成有状态的设定. 和deployment的对比 deployment部署创建的pod是无状态的,重新调度pod,pod名字hostname,启动pod顺序删除pod顺序都是随机的.deployment使用的是共享存储,所有pod共用一个存储卷. statefulset部署创建的pod是有状态的,重新调度pod,pod名字hostname保持固定不变,启动pod顺序删除pod顺序都可以根据定义的顺序有序执行操作,有序的动态更新,statefulset使

14 statefulset (sts)控制器

statefulset (sts)控制器 可以用于部署有状态的服务,比如说redis,mysql ,zk等等... 1. 稳定且唯一的网络标志符:2. 稳定且持久的存储3. 有序,平滑地部署和扩展:4. 有序,平滑地删除和终止5.有序的滚动更新 statefulset必须有三个部分组成 headless service, StatefulSet, volumeClaimTemplates 名称解析: pod_name.service_name.ns_name.svc.cluster.local