温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

如何通过StatefulSet部署有状态服务应用

发布时间:2022-03-19 09:03:19 来源:亿速云 阅读:143 作者:iii 栏目:开发技术

这篇“如何通过StatefulSet部署有状态服务应用”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“如何通过StatefulSet部署有状态服务应用”文章吧。

    先总结后详解:

    • 具有固定的网络标识,如主机名、域名等

    • 支持持久化存储

    • 可以按顺序部署和扩展

    • 可以按顺序终止和删除

    • 滚动升级也是按照一定顺序

    StatefulSet的基本概念:

    StatefulSet主要用于管理有状态的应用程序的工作负载的API对象。比如生产中的Elastic Search集群、MongoDB集群、Kafka集群、Reids集群、Zookeeper集群等。。。

    与Deployment相似的是,StatefulSet也同样管理着基本相同容器规范的Pod。不同的是,StatefulSet为每个Pod维护了一个粘性标识。

    这些Pod是根据相同的规范创建的,但是不可互换,每个Pod都有一个持久的标识符,在重新调度时也会保留,一般格式为StatefulSetName-Number。

    比如定义一个Redis-Sentinel的StatefulSet,指定三个副本,就会依次创建名为Redis-Sentinel-0、Redis-Sentinel-1、Redis-Sentinel-2的三个副本。而StatefulSet的Pod的Service一般使用Headless Service(无头服务)进行通信。

    Headless的格式为一般为:

    statefulSetName-{0..N-1}.serviceName.namespace.svc.cluster.local
    • statefulSetName:StatefulSet的名称

    • {0…N-1}:名称后面的序号

    • serviceName:Headless Service的名称

    • namespace:服务所在的命名空间

    • cluster.local:Cluster Daemon(集群域)

    StatefulSet用于有以下一条或多条需求的应用程序:

    • 需要稳定的独一无二的网络标识符

    • 需要持久化数据

    • 需要有序的、优雅的部署和扩展

    • 需要有序的自动滚动更新

    如果都不需要,那应该使用Deployment部署。

    示例:定义一个StatefulSet资源

    创建一个nginx的StatefulSet作为示范:这个yaml启动两个副本,使用nginx镜像,注意service一定要存在。

    apiVersion: v1
    kind: Service
    metadata:
      name: nginx
      labels:
        app: nginx
    spec: 
      ports:
      - port: 80
        name: web
      clusterIP: None
      selector: 
        app: nginx
    ---
    apiVersion: apps/v1
    kind: StatefulSet
    metadata:
      name: web
    spec:
      serviceName: "nginx"
      replicas: 2
      selector:
        matchLabels:
          app: nginx
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx
            image: nginx:1.18.0
            ports:
            - containerPort: 80
              name: web

    使用kubectl创建一下:可以看到service和statefulset副本都创建了

    [root@k8s-master01 ~]# kubectl create -f nginx-sts.yaml 
    service/nginx created
    statefulset.apps/web created

    查看Pod:可以看到副本的名称是按序号从0开始的

    [root@k8s-master01 ~]# kubectl get pod
    NAME      READY   STATUS    RESTARTS       AGE
    busybox   1/1     Running   17 (50m ago)   7d18h
    web-0     1/1     Running   0              74s
    web-1     1/1     Running   0              73s

    查看service:可以看到nginx的service是没有CLUSTER-IP的

    [root@k8s-master01 ~]# kubectl get svc
    NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
    kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   7d21h
    nginx        ClusterIP   None         <none>        80/TCP    2m43s

    扩容副本:可以看到与deployment不同的是,新生成的Pod名称序号是有规律的

    [root@k8s-master01 ~]# kubectl scale --replicas=3 sts web 
    statefulset.apps/web scaled
    [root@k8s-master01 ~]# kubectl get pod
    NAME      READY   STATUS              RESTARTS       AGE
    busybox   1/1     Running             17 (55m ago)   7d18h
    web-0     1/1     Running             0              6m30s
    web-1     1/1     Running             0              6m29s
    web-2     0/1     ContainerCreating   0              28s

    测试访问一下是否可以通信:可以看到网络是通的,IP直接解析到172.18.195.18上,也就是Pod的IP而不用通过一层service代理。

    [root@k8s-master01 ~]# kubectl exec -ti busybox -- sh
    / # nslookup web-0.nginx
    Server:    10.96.0.10
    Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
    Name:      web-0.nginx
    Address 1: 172.18.195.18 web-0.nginx.default.svc.cluster.local
    / # ping web-0.nginx
    PING web-0.nginx (172.18.195.18): 56 data bytes
    64 bytes from 172.18.195.18: seq=0 ttl=62 time=1.020 ms
    64 bytes from 172.18.195.18: seq=1 ttl=62 time=0.860 ms
    [root@k8s-master01 ~]# kubectl get pod -o wide 
    NAME      READY   STATUS    RESTARTS       AGE     IP               NODE           NOMINATED NODE   READINESS GATES
    busybox   1/1     Running   18 (28s ago)   7d18h   172.27.14.193    k8s-node02     <none>           <none>
    web-0     1/1     Running   0              11m     172.18.195.18    k8s-master03   <none>           <none>
    web-1     1/1     Running   0              11m     172.25.92.78     k8s-master02   <none>           <none>
    web-2     1/1     Running   0              5m9s    172.25.244.199   k8s-master01   <none>           <none>

    StatefulSet的扩容与缩容

    StatefulSet扩容:

    扩容的时候会按照序号顺序依次创建,比如我有上图的三个web副本,我想扩容到五个,那么就会先创建web-3副本,只要web-3副本创建成功后才会创建web-4;如果web-3出现故障无法创建,那么后续任务将一直等待web-3的创建直到成功。

    StatefulSet缩容:

    缩容的时候与扩容相反,会从最后一个开始删除,按照web-4、web-3这样的顺序依次删除。

    StatefulSet更新策略

    支持两种更新策略:

    RollingUpdate:默认的更新策略为滚动更新,是从最后一个副本开始更新,成功后才会进行下一个副本,更新方式为先删除再创建。

    OnDelete:当把策略改为这个时,我们就需要先手动删除要更新的副本,才会触发副本的更新策略。

    StatefulSet灰度发布

    利用更新策略中的Partition参数进行简单的灰度发布。

    如何通过StatefulSet部署有状态服务应用

    StatefulSet的级联删除和非级联删除

    级联删除:删除StatefulSet时同时删除Pod,默认为级联删除

    [root@k8s-master01 ~]# kubectl delete sts web

    非级联删除:删除StatefulSet时不会删除Pod,注意此时再删除Pod的话就不会再重建了

    [root@k8s-master01 ~]# kubectl delete sts web --cascade=false

    以上就是关于“如何通过StatefulSet部署有状态服务应用”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注亿速云行业资讯频道。

    向AI问一下细节

    免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

    AI