• 【CKA考试笔记】十八、StatefulSet


    实验环境

    完成初始化集群的环境:
    (vms21)192.168.26.21——master1
    (vms22)192.168.26.22——worker1
    (vms23)192.168.26.23——worker2

    一、StatefulSet介绍

    StatefulSet——简称sts,它也是一种控制器,是有状态的(stateful),与之对应的是无状态(stateless)的deployment
    回顾deployment控制器,它部署的应用是无状态的:
    1.所有pod副本没有任何不同
    2.pod的名字是随机生成的
    3.不存储数据
    4.即使存储数据,那么所有pod也是共享数据

    stateless——对于无状态来说,我们一般用来对外提供服务,用户访问svc,svc关联后端的pod副本,用户访问流量无论转发到哪个pod,访问的结果都是一样的

    stateful——对于有状态来说,适用于内部的一些应用

    如在公司内部,有一个MySQL master、三个pod分为作为slave1、slave2、slave3,salve复制master上的数据,并且每个slave上都有自己独立的数据(如每个slave都有自己的binlog二进制日志),即使把某个slave删除了,重新创建这个pod,那么它关联的还是原来的那个数据

    如下图,deployment与StatefulSet的区别:
    在这里插入图片描述
    在StatefulSet中,如上图,每个slave访问的后端存储都是不一样的,若是访问slave1,则访问的是data1的数据,因此,给各个slave配置一个svc负载均衡器是没有意义的,但是用户直接访问这个pod(这里即slave)也是不好的,因为只要是控制器管理了pod,pod一旦被删除,控制器就会去重新创建它,自然IP地址肯定也是变化了的,所以不好直接访问pod
    因此我们可以创建一种叫做headless service无头服务
    headless service(无头服务)
    什么是无头服务?——对于每个svc来说,它们都有一个ClusterIP,所谓无头服务就是不给它指定ClusterIP
    访问pod的时候,就通过一种格式:pod名字.svc名字来访问,如:slave1.svc1

    二、实验

    在官方文档中搜索StatefulSet:https://kubernetes.io/docs/home/
    (截图)
    分析文档中的sts模板

    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: k8s.gcr.io/nginx-slim:0.8
            ports:
            - containerPort: 80
              name: web
            volumeMounts:
            - name: www
              mountPath: /usr/share/nginx/html
      volumeClaimTemplates:
      - metadata:
          name: www
        spec:
          accessModes: [ "ReadWriteOnce" ]
          resources:
            requests:
              storage: 1Gi
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46

    “- - -”上下划分了Service(无头服务)和StatefulSet

    Service中:
    可以看到clusterIP配置成了None
    spec.selector——配置Service要关联到哪些pod

    StatefulSet中:
    spec.serviceName——通过名字来关联svc,因此这里的名字要和上面Service中的metadata中的名字一致
    spec.selector.matchLabels——要定位到哪些pod
    volumeClaimTemplates——因为StatefulSet中每个pod都有自己独立的数据,因此有了这项来定义卷的模板
    volumeClaimTemplates.spec.accessModes——使用的卷的格式
    volumeClaimTemplates.spec下可以配置动态卷供应,可以使用storageClassName配置

    1.根据模板创建yaml文件mysts1.yaml
    并在其中作一些修改:
    StatefulSet的名字改为mysts1
    修改pod使用nginx镜像,并加上镜像拉取策略IfNotPresent
    在卷模板下配置动态卷供应,使用之前创建的mysc,会为每个pod创建一个pvc出来
    修改后为:

    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: mysts1
    spec:
      serviceName: "nginx"
      replicas: 2
      selector:
        matchLabels:
          app: nginx
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx
            image: nginx
            imagePullPolicy: IfNotPresent
            ports:
            - containerPort: 80
              name: web
            volumeMounts:
            - name: www
              mountPath: /usr/share/nginx/html
      volumeClaimTemplates:
      - metadata:
          name: www
        spec:
          storageClassName: mysc
          accessModes: [ "ReadWriteOnce" ]
          resources:
            requests:
              storage: 1Gi
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    2.根据之前实验中创建好的sc(若没有则参考六、存储管理-动态卷供应部分内容创建)
    查看环境中的sc

    kubectl get sc
    #输出:
    NAME   PROVISIONER                                   RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
    mysc   k8s-sigs.io/nfs-subdir-external-provisioner   Delete          Immediate           false                  3m5s
    
    • 1
    • 2
    • 3
    • 4

    此时环境中没有pv、pvc

    kubectl get pv
    #输出:
    No resources found
    
    kubectl get pvc
    #输出:
    No resources found in default namespace.
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    3.创建StatefulSet

    kubectl apply -f mysts1.yaml
    
    • 1

    4.查看服务

    kubectl get svc
    #输出:
    NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
    nginx        ClusterIP   None         <none>        80/TCP    16s
    
    • 1
    • 2
    • 3
    • 4

    可以看到帮我们创建了一个名为nginx、CLUSTER-IP为None的svc

    5.查看sts

    kubectl get sts
    #输出:
    NAME     READY   AGE
    mysts1   2/2     50s
    
    • 1
    • 2
    • 3
    • 4

    有两个pod副本

    kubectl get pods
    #输出:
    NAME                                      READY   STATUS              RESTARTS       AGE
    mysts1-0                                  1/1     Running             0              1m
    mysts1-1                                  1/1     Running             0              1m
    
    • 1
    • 2
    • 3
    • 4
    • 5

    同时,查看pvc、pv,可以看到自动帮我们创建了两个pvc与两个pv,即各自都有自己独立的数据

    kubectl get pvc
    kubectl get pv
    
    • 1
    • 2

    6.进入pod中编辑index.html内容

    kubectl exec -it mysts1-0 -- sh -c "echo 111 > /usr/share/nginx/html/index.html"
    kubectl exec -it mysts1-1 -- sh -c "echo 222 > /usr/share/nginx/html/index.html"
    
    • 1
    • 2

    7.测试此时删除mysts1-0这个pod,删除后,sts会帮我们重新创建这个pod,并且pod名字还是mysts1-0

    kubectl get pods
    #输出:
    NAME                                      READY   STATUS              RESTARTS       AGE
    mysts1-0                                  0/1     ContainerCreating   0              14s
    mysts1-1                                  1/1     Running             0              3m2s
    
    • 1
    • 2
    • 3
    • 4
    • 5

    并且mysts1-0的数据存储还是原来的
    进入mysts1-0查看index.html内容,仍然是111

    kubectl exec -it mysts1-0 -- sh -c "cat /usr/share/nginx/html/index.html"
    #输出:
    111
    
    • 1
    • 2
    • 3

    8.哪么要怎么访问sts这个服务呢?
    注意:无法直接在宿主机中访问
    我们通过创建一个pod,在pod里去测试访问
    创建一个pod1,pod1.yaml如下:

    apiVersion: v1
    kind: Pod
    metadata:
      creationTimestamp: null
      labels:
        run: pod1
      name: pod1
    spec:
      terminationGracePeriodSeconds: 0
      containers:
      - image: nginx
        imagePullPolicy: IfNotPresent
        name: pod1
      dnsPolicy: ClusterFirst
      restartPolicy: Always
    status: {}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    创建这个pod

    kubectl apply -f pod1.yaml
    
    • 1

    在pod测试访问sts,通过pod名.svc名来访问

    kubectl exec -it pod1 -- bash
    curl mysts1-0.nginx
    #输出:
    111
    
    • 1
    • 2
    • 3
    • 4

    9.删除该sts

    kubectl delete -f mysts1.yaml
    
    • 1
  • 相关阅读:
    Kafka3.0.0版本——文件清理策略
    本地使用openssl生成一个sm2的私钥,并生成req请求(p10数据),将其作为申请书内容,进行证书的下载
    三栏布局,中间自适应
    SQL语句如何避免在mysql插入重复数据
    微信直播的开通方法以及特点是什么
    SpringBoot集成WebSocket实现在线聊天
    汽车智能座舱/智能驾驶SOC -2
    利用 Pandoc 将 Latex 转为 MS word 的方法
    【Vue3】全局切换字体大小
    中国电子云-隐私计算-云原生安全可信计算,物理-硬件-系统-云产品-云平台,数据安全防护
  • 原文地址:https://blog.csdn.net/weixin_41755556/article/details/126470077