Statefulset详细解析

StatefulSet实现Pod的拓扑状态

StatefulSet的核心功能就是通过某种方式记录这些状态,然后在Pod被重新创建时能够为新Pod恢复这些状态

只要知道一个Pod的名字以及它对应的Service的名字,就可以通过这条DNS记录访问到Pod的IP地址(pod的名称.service名称) -> Pod的IP

定义Stateful的对象中有一个serviceName字段来告诉Stateful控制器使用具体的service来解析它所管理的Pod的IP地址

Pod的名称由StatfulSet对象的名称+Pod创时所在的索引组成 StatefulSet使用这个DNS记录解析规则来维持Pod的拓扑状态

StatefulSet给它所管理的所有Pod的名字进行了编号,编号规则是: - .而且这些编号都是从0开始累加与StatefulSet的每个Pod实例一一对应 绝不重复

这些Pod的创建也是严格按照编号顺序进行的.比如,在web-0进入到Running 状态、并且细分状态(Conditions)成为Ready之前,web-1会一直处于Pending状态
     把这两个Pod删除之后Kubernetes会按照原先编号的顺序,创建出了两个新的 Pod.并且Kubernetes依然为它们分配了与原来相同的“网络身份”:web-0.nginx和 web-1.nginx

通过永远不改变Pod名称的方式StatefulSet保证了Pod网络标识的稳定性.不管Pod是被删除重启还是被调度到其他节点上都不会改变Pod的名称

StatefulSet管理的pod使用的镜像是一样的,但是每个pod的命令和初始化流程可以完全不一样来实现主从Pod的拓扑部署

尽管web-0.nginx这条DNS记录本身不会变但它解析到的Pod的IP地址并不是固定的.这就意味着,对于“有状态应用”实例的访问必须使用DNS记录或者hostname的方式而绝不应该直接访问这些Pod的IP地址

StatefulSet实现Pod的存储状态

通过PVC机制来实现存储状态管理

在StatefulSet对象中除了定义PodTemplate还会定义一个volumeClaimTemplates凡是被这个StatefulSet管理的Pod都会声明一个对应的PVC,这个PVC的定义就来自于 volumeClaimTemplates这个模板字段

这个PVC的名字,会被分配一个与这个Pod完全一致的编号

把一个Pod比如web-0删除之后,这个Pod对应的PVC和PV并不会被删除,而这个Volume 里已经写入的数据,也依然会保存在远程存储服务里

StatefulSet在重新创建web-0这个pod的时候.它声明使用的PVC的名字还是叫作:www-web-0 这个PVC的定义,还是来自于PVC模板(volumeClaimTemplates)这是StatefulSet创建 Pod的标准流程

Kubernetes为它查找名叫www-web-0的PVC时,就会直接找到旧Pod遗留下来的同名的 PVC进而找到跟这个PVC绑定在一起的PV.这样新的Pod就可以挂载到旧Pod对应的那个Volume并且获取到保存在Volume里的数据.通过这种方式Kubernetes的StatefulSet就实现了对应用存储状态的管理

StatefulSet其实就是一种特殊的Deployment,而其独特之处在于,它的每个Pod都被编号了.而且,这个编号会体现在Pod的名字和hostname等标识信息上,这不仅代表了Pod的创建顺序,也是Pod的重要网络标识(即:在整个集群里唯一的、可被的访问身份).有了这个编号后StatefulSet就使用Kubernetes里的两个标准功能:Headless Service 和 PV/PVC,实现了对 Pod 的拓扑状态和存储状态的维护

StatefulSet搭建Mysql有状态集群

1.Master节点和Slave节点需要有不同的配置文件(即:不同的 my.cnf)

只需要给主从节点分别准备两份不同的 MySQL 配置文件  然后根据Pod的序号(Index)挂载进去即可

2.Master节点和Slave节点需要能够传输备份信息文件

3.在Slave节点第一次启动之前需要执行一些初始化SQL操作

apiVersion: v1
kind: ConfigMap
metadata:
  name: mysql
  labels:
    app: mysql
data:
  master.cnf: |
     [mysqld]
     log-bin
  slave.cnf: |
     [mysqld]
     super-read-only

configmap.yaml

apiVersion: v1
kind: Service
metadata:
  name: mysql
  labels:
    app: mysql
spec:
  ports:
  - name: mysql
    port: 3306
  clusterIP: None
  selector:
    app: mysql

---
apiVersion: v1
kind: Service
metadata:
  name: mysql-read
  labels:
    app: mysql
spec:
  ports:
  - name: mysql
    port: 3306
  selector:
    app: mysql

service.yaml

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv001
  labels:
    name: pv001
spec:
  nfs:
   path: /data/volumes/v1
   server: 192.168.164.141
  accessModes: ["ReadWriteMany","ReadWriteOnce"]
  capacity:
    storage: 20Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv002
  labels:
    name: pv002
spec:
  nfs:
   path: /data/volumes/v2
   server: 192.168.164.141
  accessModes: ["ReadWriteMany","ReadWriteOnce"]
  capacity:
    storage: 20Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv003
  labels:
    name: pv003
spec:
  nfs:
   path: /data/volumes/v3
   server: 192.168.164.141
  accessModes: ["ReadWriteMany","ReadWriteOnce"]
  capacity:
    storage: 20Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv004
  labels:
    name: pv004
spec:
  nfs:
   path: /data/volumes/v4
   server: 192.168.164.141
  accessModes: ["ReadWriteMany","ReadWriteOnce"]
  capacity:
    storage: 20Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv005
  labels:
    name: pv005
spec:
  nfs:
   path: /data/volumes/v5
   server: 192.168.164.141
  accessModes: ["ReadWriteMany","ReadWriteOnce"]
  capacity:
    storage: 20Gi

pv.yaml

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql
spec:
  selector:
    matchLabels:
      app: mysql
  serviceName: mysql
  replicas: 3
  template:
    metadata:
      labels:
        app: mysql
    spec:
      initContainers:
      - name: init-mysql
        image: mysql:5.7
        command:
        - bash
        - "-c"
        - |
          set -ex
          [[ `hostname`  =~ -([0-9]+)$ ]] || exit 1
          ordinal=${BASH_REMATCH[1]}
          echo [mysqld] > /mnt/conf.d/server-id.cnf
          echo server-id=$((100 + $ordinal )) >> /mnt/conf.d/server-id.cnf
          if [[ $ordinal -eq 0 ]]; then
            cp /mnt/config-map/master.cnf /mnt/conf.d/
          else
            cp /mnt/config-map/slave.cnf /mnt/conf.d/
          fi
        volumeMounts:
        - name: conf
          mountPath: /mnt/conf.d
        - name: config-map
          mountPath: /mnt/config-map
      - name: clone-mysql
        image: gcr.io/google-samples/xtrabackup:1.0
        command:
        - bash
        - "-c"
        - |
          set -ex
          [[ -d /var/lib/mysql/mysql ]] && exit 0
          [[ `hostname` =~ -([0-9]+)$ ]] || exit 1
          ordinal=${BASH_REMATCH[1]}
          [[ $ordinal -eq 0 ]] && exit 0
          ncat --recv-only mysql-$((ordinal-1)).mysql 3307 | xbstream -x -C /var/lib/mysql
          xtrabackup --prepare  --target-dir=/var/lib/mysql
        volumeMounts:
        - name: data
          mountPath: /var/lib/mysql
          subPath: mysql
        - name: conf
          mountPath: /etc/mysql/conf.d
      containers:
      - name: mysql
        image: mysql:5.7
        env:
        - name: MYSQL_ALLOW_EMPTY_PASSWORD
          value: "1"
        ports:
        - name: mysql
          containerPort: 3306
        volumeMounts:
        - name: data
          mountPath: /var/lib/mysql
          subPath: mysql
        - name: conf
          mountPath: /etc/mysql/conf.d
        resources:
          requests:
            cpu: 500m
            memory: 500Mi
        livenessProbe:
          exec:
            command: ["mysqladmin","ping"]
          initialDelaySeconds: 30
          periodSeconds: 10
          timeoutSeconds: 5
        readinessProbe:
          exec:
            command: ["mysql","-h","127.0.0.1","-e","SELECT 1"]
          initialDelaySeconds: 5
          periodSeconds: 2
          timeoutSeconds: 1
      - name: xtrabackup
        image: gcr.io/google-samples/xtrabackup:1.0
        ports:
        - name: xtrabackup
          containerPort: 3307
        command:
        - bash
        - "-c"
        - |
          set -ex
          cd /var/lib/mysql
          if [[ -f xtrabackup_slave_info ]]; then
             mv xtrabackup_slave_info change_master_to.sql.in
             rm -f xtrabackup_binlog_info
          elif [[ -f xtrabackup_binlog_info ]]; then
             [[ `cat xtrabackup_binlog_info` =~ ^(.*)[[:space:]]+(.*?)$ ]] || exit 1
             rm xtrabackup_binlog_info
             echo "change master to master_log_file=‘${BASH_REMATCH[1]}‘,\
                  MASTER_LOG_POS=${BASH_REMATCH[2]}" > change_master_to.sql.in
          fi
          if [[ -f change_master_to.sql.in ]]; then
             echo "waiting for mysqld to be ready"
             until mysql -h 127.0.0.1 -e "SELECT 1";do sleep 1;done
             echo "Initializing replication from clone position"
             mv change_master_to.sql.in change_master_to.sql.orig
             mysql -h 127.0.0.1 <<EOF
             $(<change_master_to.sql.orig),
              MASTER_HOST=‘mysql-0.mysql‘,
              MASTER_USER=‘root‘,
              MASTER_PASSWORD=‘‘,
              MASTER_CONNECT_RETRY=10;
          START SLAVE;
          EOF
          fi

          exec ncat --listen  --keep-open --send-only  --max-conns=1 3307 -c               "xtrabackup --backup --slave-info --stream=xbstream --host=127.0.0.1 --user=root"
        volumeMounts:
        - name: data
          mountPath: /var/lib/mysql
          subPath: mysql
        - name: conf
          mountPath: /etc/mysql/conf.d
      volumes:
      - name: conf
        emptyDir: {}
      - name: config-map
        configMap:
          name: mysql
  volumeClaimTemplates:
  - metadata:
      name: data
    spec:
      accessModes: ["ReadWriteOnce"]
      resources:
        requests:
          storage: 10Gi

StatefulSet.yaml

问题调试

volumes字段属于Pod对象的
    volumesMount字段属于容器对象的
    volumeClaimTemplates字段属于StatefulSet对象的

- name: MYSQL_ALLOW_EMPTY_PASSWORD
   value: "1" 不能写成value: 1 必须加上双引号 否则会出现异常

CrashLoopBackOff状态   查看Pod中指定容器的日志信息
     kubectl   logs   mysql-0  init-mysql
     kubectl   logs   mysql-0  clone-mysql
     kubectl   logs   mysql-0  mysql
     kubectl   logs   mysql-0  xtrabackup

Pending状态
     kubectl describe pod mysql-2 一般是pod调度失败

原文地址:https://www.cnblogs.com/yxh168/p/12327404.html

时间: 2024-10-02 09:46:12

Statefulset详细解析的相关文章

linux中的压缩命令详细解析(二)

我们在<Linux中的压缩命令详细解析(一)>中已经讲解了常见的三种压缩命令,下面我们开始讲解工作中最常用到的tar命令. 为了使压缩和解压缩变得简单,tar命令就应运而生了.那么究竟该如何使用呢? tar.gz格式: 压缩命令: tar -zcvf 压缩文件名 源文件名 举例: 把abc文件压缩成后缀为tar.gz格式的文件 tar -zcvf abc.tar.gz abc 解压缩命令: 举例:解压缩abc.tar.gz文件 tar -zxvf abc.tar.gz tar.bz2格式: 压

【转】UML中的几种关系详细解析

UML图中类之间的关系:依赖,泛化,关联,聚合,组合,实现 类与类图 1) 类(Class)封装了数据和行为,是面向对象的重要组成部分,它是具有相同属性.操作.关系的对象集合的总称. 2) 在系统中,每个类具有一定的职责,职责指的是类所担任的任务,即类要完成什么样的功能,要承担什么样的义务.一个类可以有多种职责,设计得好的类一般只有一种职责,在定义类的时候,将类的职责分解成为类的属性和操作(即方法). 3) 类的属性即类的数据职责,类的操作即类的行为职责 一.依赖关系(Dependence) 依

字符数组的定义与使用详细解析

1. 字符数组的定义: 用来存放字符量的数组称为字符数组. 形式数值数组相同.例如: char c[10]; 由于字符型和整型通用,也可以定义为int c[10],但这时每个数组元素占2个字节的内存单元. 字符数组也可以是二维或多维数组.例如: char c[5][10]; 即为二维字符数组. 2. 字符数组的初始化 第一种方法是分别对每一个元素进行赋值操作: 字符数组也允许在定义时作初始化赋值.例如: char c[10]={'c', '  ', 'p', 'r','o', 'g', 'r',

【剧透高亮】最最最完整剧透加剧情详细解析

在美国看的,IMAX大厅爆满!只能缩在角落里的位置看,但是还是不影响观影过程,被震撼到不行!看到最后黑洞的情节都快哭出来跪在地上了!Hans Zimmer的配乐太结棍了啊! 就像诺兰所有的电影一样,Interstellar是一部烧脑+解读人性+看完后需要阅读大量相关资料补课的大片!尤其是马修麦康纳那mumbling的口音简直听得人更加confused神烦啊!伐碍紧!我们来把剧情从头到尾理一遍! OK废话不多say了,直接上剧情解析   在未来的世界,由于科技太发达,人类对于能源的过度开发导致地球

Java当中的堆与栈详细解析

总结第一句话:Java语言使用内存的时候,栈内存主要保存以下内容:基本数据类型和对象的引用,而堆内存存储对象,栈内存的速度要快于堆内存.总结成一句话就是:引用在栈而对象在堆. Java疯狂讲义的一段对话作为开场白. 一个问题:为什么有栈内存和堆内存之分? 答:当一个方法执行时,每个方法都会简历自己的内存栈,在这个方法内定义的变量将会逐个放入这块栈内存里,随着方法的执行结束,这个方法的内存栈也将自然销毁.因此,所有在方法中创建一个对象时,这个对象将被保存到运行时数据区中,以便利用(因为对象的创建成

java类生命周期详细解析

(一)详解java类的生命周期 引言 最近有位细心的朋友在阅读笔者的文章时,对java类的生命周期问题有一些疑惑,笔者打开百度搜了一下相关的问题,看到网上的资料很少有把这个问题讲明白的,主要是因为目前国内java方面的教材大多只是告诉你“怎样做”,但至于“为什么这样做”却不多说,所以造成大家在基础和原理方面的知识比较匮乏,所以笔者今天就斗胆来讲一下这个问题,权当抛砖引玉,希望对在这个问题上有疑惑的朋友有所帮助,文中有说的不对的地方,也希望各路高手前来指正. 首先来了解一下jvm(java虚拟机)

iOS中中UIView头文件详细解析

@interface UIView : UIResponder<NSCoding, UIAppearance, UIAppearanceContainer, UIDynamicItem> /** *  通过一个frame来初始化一个UI控件 */ - (id)initWithFrame:(CGRect)frame; // YES:能够跟用户进行交互 @property(nonatomic,getter=isUserInteractionEnabled) BOOL userInteraction

ios申请真机调试( xcode 5)详细解析(转载)

目录[-] 第一步:申请"开发证书" 第二步:添加App IDs 第三步:申请设备 第四步:申请描述文件 第一步:申请"开发证书" 进入苹果开发者99美元账号: 选择:Certificates, Identifiers & Profiles 关于 Certificates,Identifiers,Profiles 的介绍请看 "Certificates, Identifiers ,Profiles" 选择:Certificates 选择:

单表扫描,MySQL索引选择不正确 并 详细解析OPTIMIZER_TRACE格式

单表扫描,MySQL索引选择不正确 并 详细解析OPTIMIZER_TRACE格式 一 表结构如下:  MySQL  5.5.30  5.6.20 版本, 表大概有815万行 CREATE TABLE t_audit_operate_log (  Fid bigint(16) AUTO_INCREMENT,  Fcreate_time int(10) unsigned NOT NULL DEFAULT '0',  Fuser varchar(50) DEFAULT '',  Fip bigint