• StatefulSet


    一、简介

    在Kubernetes系统中,Pod的管理对象RC、Deployment、DaemonSet和Job都面向无状态的服务。但是有很多服务是有状态的,特别是一些复杂的中间件集群,例如MySQL集群、MongoDB集群、Kafka集群、zookeeper集群等,这些应用集群有4个共同点:

    • 每个节点都有固定的身份ID,通过这个ID,集群中的成员可以相互发现并通信

    • 集群的规模是比较固定的,集群规模不能随意变动

    • 集群中的每个节点都是有状态的,通常会持久化数据到永久存储中

    • 如果磁盘损坏,则集群里的某个节点无法正常运行,集群功能受损

     

    StatefulSet旨在与有状态的应用及分布式系统一起使用,它有如下特性:

    • StatefulSet里每个Pod都有稳定、唯一的网络标识,可以用来发现集群内的其他成员。假设StatefulSet的名称为Kafka,那么第一个Pod叫Kafka-0,第二个叫Kafka-1,以此类推

    • StatefulSet控制的Pod副本启停顺序是受控的,操作第n个Pod时,前n-1个Pod已经是运行且准备好的状态

    • StatefulSet的Pod采用稳定的持久化存储卷,通过PV或者PVC来实现,删除Pod时默认不会删除与StatefulSet相关的存储卷

     

    StatefulSet除了要与PV卷捆绑使用以存储Pod的状态数据,还要与Headless Service配合使用,即在每个StatefulSet定义中都要声明它属于哪个Headless Service。Headless Service于普通Service的关键区别在于,它没有Cluster IP,如果解析Headless Service的DNS域名,则返回的是该Service对应的全部Pod的Endpoint列表。StatefulSet在Headless Service的基础上又为StatefulSet控制的每个Pod实例创建了一个DNS域名,这个域名格式为: $(podname).$(headless service name)

    二、使用StatefulSet搭建MongoDB集群

    为了完成MongoDB集群的搭建,需要创建如下三个资源对象

    • 一个StorageClass,用于StatefulSet自动为各个应用Pod申请PVC

    • 一个Headless Service,用于维护MongoDB的集群状态

    • 一个StatefulSet

    2.1创建一个StorageClass对象

    storageclass-fast.yaml

    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
      name: fast
    provisioner: kubernetes.io/glusterfs
    parameters:
      restful: http://192.168.10.106:18080

    执行kubectl create创建该storage class

    # kubectl create -f storageclass-fast.yaml 
    storageclass.storage.k8s.io/fast created

    2.2 授权ServiceAccount

    在2.4步骤需要使用mongo-sidecar的pod来配置管理mongo pod。

    由于默认的service account仅仅只能获取当前Pod自身的相关属性,无法观察到其他名称空间Pod的相关属性信息。如果想要扩展Pod,或者一个Pod需要用于管理其他Pod或者是其他资源对象,是无法通过自身的名称空间的serviceaccount进行获取其他Pod的相关属性信息的,因此需要进行手动创建一个serviceaccount,并在创建Pod时进行定义。或者直接将默认的serviceaccount进行授权。

    defaultaccount.yaml

    kind: ClusterRoleBinding
    metadata:
      name: default-view
    subjects:
      - kind: ServiceAccount
        name: default
        namespace: default
    roleRef:
      kind: ClusterRole
      name: view
      apiGroup: rbac.authorization.k8s.io

    2.3 创建Headless Service

    mongodb-sidecar作为MongoDB集群的管理者,将使用此Headless Service来维护各个MongoDB实例之间的集群关系,以及集群规模变化时的自动更新

    mongodb-headless-service.yaml

    apiVersion: v1
    kind: Service
    metadata:
      name: mongo
      labels:
        name: mongo
    spec:
      ports:
      - port: 27017
        targetPort: 27017
      clusterIP: None
      selector:
        role: mongo

    执行kubectl create命令创建该Headless Service

    # kubectl create -f mongodb-headless-service.yaml 
    service/mongo created

    2.4 MongoDB StatefulSet

    statefulset-mongo.yaml

    apiVersion: apps/v1
    kind: StatefulSet
    metadata:
      name: mongo
    spec:
      serviceName: mongo  # 声明它属于哪个Headless Service
      replicas: 3
      selector:         # has to match .sepc.template.metadata.labels
        matchLabels:
          role: mongo
          environment: test
      template:
        metadata:
          labels:      # has to match .spec.selector.matchLabels
            role: mongo
            environment: test
        spec:
          terminationGracePeriodSeconds: 10
          containers:
          - name: mongo
            image: mongo:3.4
            command:
            - mongod
            - "--replSet"
            - rs0
            - "--bind_ip"
            - 0.0.0.0
            - "--smallfiles"
            - "--noprealloc"
            ports:
            - containerPort: 27017
            volumeMounts:
            - name: mongo-persistent-storage
              mountPath: /data/db
          - name: mongo-sidecar
            image: cvallance/mongo-k8s-sidecar
            env:
            - name: MONGO_SIDECAR_POD_LABELS
              value: "role=mongo,environment=test"
            - name: KUBERNETES_MONGO_SERVICE_NAME
              value: "mongo"
      volumeClaimTemplates:
      - metadata:
          name: mongo-persistent-storage
          annotations:
            volume.beta.kubernetes.io/storage-class: "fast"
        spec:
          accessModes: [ "ReadWriteOnce" ]
          resources:
            requests:
              storage: 2Gi

    其中主要配置说明如下:

    (1)在该statefulset定义中包含连个容器:mongo和mongo-sidecar。mongo是主服务程序,mongo-sidecar是将多个mongo实例进行集群设置的工具。mongo-sidecar中的环境变量如下:

    • MONGO_SIDECAR_POD_LABELS:设置为mongo容器的标签,用于sidecar查询它所要管理的MongoDB集群实例

    • KUBERNETES_MONGO_SERVICE_NAME: 它的值为mongo,表示sidecar将使用mongo这个服务名来完成MongoDB集群的设置

       

      (2)replicas=3 表示MongoDB集群由3个mongo实例组成

      (3)volumeClaimTemplates是 StatefulSet最重要的存储设置。在annotations段设置volume.beta.kubernetes.io/storage-class="fast" 表示使用名为fast的StorageClass自动为每个mongo Pod实例分配后端存储

      (4)resources.requests.storage=2Gi 表示为每个mongo实例都分配2G的磁盘空间

     

    2.5 验证MongoDB集群

    最终可以看到StatefulSet依次创建并启动了3个mongo Pod实例,它们的名字依次为mongo-0、mongo-1、mongo-2:

    # kubectl get pods -l role=mongo
    NAME      READY   STATUS    RESTARTS   AGE
    mongo-0   2/2     Running   0          72m
    mongo-1   2/2     Running   0          71m
    mongo-2   2/2     Running   0          64m

    StatefulSet会用volumeClaimTemplates中定义为每个Pod副本都创建一个PVC实例,每个PVC的名称由StatefulSet定义中volumeClaimTemplates的名称和Pod副本的名称组合而成:

    # kubectl get pvc -l role=mongo
    NAME                               STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
    mongo-persistent-storage-mongo-0   Bound    pvc-63b576fc-1324-46db-b708-0c40f5896103   2Gi        RWO            fast           86m
    mongo-persistent-storage-mongo-1   Bound    pvc-6b2dfbc3-f57e-4e05-9cd7-dfabb3c5b00e   2Gi        RWO            fast           75m
    mongo-persistent-storage-mongo-2   Bound    pvc-24ed1a31-b9a8-4214-a189-137cf9eccc12   2Gi        RWO            fast           67m

    下面是mongo-0这个Pod中volume设置,可以看到系统自动为其挂载了对应的PVC:

    # kubectl get pod mongo-0 -o yaml | grep -A 3 volumes
      volumes:
      - name: mongo-persistent-storage
        persistentVolumeClaim:
          claimName: mongo-persistent-storage-mongo-0

    登入任意一个mongo Pod,在mongo命令行界面使用rs.status()命令查看MongoDB集群状态,该mongodb集群已由sidecar完成了创建。在集群中包含3个节点的名称都是StatefulSet设置的DNS域名格式的网络标识名称:

    mongo-0.mongo.default.svc.cluster.local
    mongo-1.mongo.default.svc.cluster.local
    mongo-2.mongo.default.svc.cluster.local

    同时,可以查看每个mongodb实例的各自角色(PRIMARY或SECONDARY)

    rs.status()
    ...
    ...
    ...
    "members" : [
            {
                "_id" : 0,
                "name" : "mongo-0.mongo.default.svc.cluster.local:27017",
                "health" : 1,
                "state" : 1,
                "stateStr" : "PRIMARY",
                "uptime" : 100,
                "optime" : {
                    "ts" : Timestamp(1592286258, 1),
                    "t" : NumberLong(1)
                },
                "optimeDate" : ISODate("2020-06-16T05:44:18Z"),
                "syncingTo" : "",
                "syncSourceHost" : "",
                "syncSourceId" : -1,
                "infoMessage" : "could not find member to sync from",
                "electionTime" : Timestamp(1592286196, 2),
                "electionDate" : ISODate("2020-06-16T05:43:16Z"),
                "configVersion" : 5,
                "self" : true,
                "lastHeartbeatMessage" : ""
            },
            {
                "_id" : 1,
                "name" : "mongo-1.mongo.default.svc.cluster.local:27017",
                "health" : 1,
                "state" : 2,
                "stateStr" : "SECONDARY",
                "uptime" : 45,
                "optime" : {
    ...
    ...
     
  • 相关阅读:
    OpenCV特征描述
    OpenCV特征点检测
    expect实现无交互操作
    文件的修改时间
    sshd登录攻击
    tcp三次握手和syn 洪水攻击
    vim使用
    PHP拓展开发
    【转】LINUX 手动建立SWAP文件及删除
    Ubuntu下crontab命令的用法
  • 原文地址:https://www.cnblogs.com/bigberg/p/13494583.html
Copyright © 2020-2023  润新知