前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Kubernetes StatefulSet 实现原理

Kubernetes StatefulSet 实现原理

作者头像
胡齐
发布2020-07-10 16:03:35
1K0
发布2020-07-10 16:03:35
举报
文章被收录于专栏:运维猫运维猫

1、StatefulSet的设计原理

首先我们先来了解下Kubernetes的一个概念:有状态服务与无状态服务。

  • 无状态服务(Stateless Service):该服务运行的实例不会在本地存储需要持久化的数据,并且多个实例对于同一个请求响应的结果是完全一致的。这种方式适用于服务间相互没有依赖关系,如Web应用,在Deployment控制器停止掉其中的一个Pod不会对其他Pod造成影响。
  • 有状态服务(Stateful Service):服务运行的实例需要在本地存储持久化数据,比如数据库或者多个实例之间有依赖拓扑关系,比如:主从关系、主备关系。如果停止掉依赖中的一个Pod,就会导致数据丢失或者集群崩溃。这种实例之间有不对等关系,以及实例对外部数据有依赖关系的应用,就被称为“有状态应用”(Stateful Application)。

其中无状态服务在我们前面文章中使用的Deployment编排对象已经可以满足,因为无状态的应用不需要很多要求,只要保持服务正常运行就可以,Deployment删除掉任意中的Pod也不会影响服务的正常,但面对相对复杂的应用,比如有依赖关系或者需要存储数据,Deployment就无法满足条件了,Kubernetes项目也提供了另一个编排对象StatefulSet。

2、StatefulSet将有状态应用抽象为两种情况

  • 拓扑状态。这种情况意味着,应用的多个实例之间不是完全对等的关系。这些应用实例,必须按照某些顺序启动,比如应用的主节点 A 要先于从节点 B 启动。而如果你把 A 和 B 两个 Pod 删除掉,它们再次被创建出来时也必须严格按照这个顺序才行。并且,新创建出来的 Pod,必须和原来 Pod 的网络标识一样,这样原先的访问者才能使用同样的方法,访问到这个新 Pod。
  • 存储状态。这种情况意味着,应用的多个实例分别绑定了不同的存储数据。对于这些应用实例来说,Pod A 第一次读取到的数据,和隔了十分钟之后再次读取到的数据,应该是同一份,哪怕在此期间 Pod A 被重新创建过。这种情况最典型的例子,就是一个数据库应用的多个存储实例。

3、StatefulSet 的核心功能

StatefulSet 的核心功能,就是通过某种方式记录这些状态,然后在 Pod 被重新创建时,能够为新 Pod 恢复这些状态。它包含Deployment控制器ReplicaSet的所有功能,增加可以处理Pod的启动顺序,为保留每个Pod的状态设置唯一标识,同时具有以下功能:

  • 稳定的、唯一的网络标识符
  • 稳定的、持久化的存储
  • 有序的、优雅的部署和缩放

4、使用statefulset部署的pod,即使重新拉起,所有之前的状态都不变

代码语言:javascript
复制
[root@yygh-de state]# vim statefulset.yaml
apiVersion: v1
kind: Service   #定义一个负载均衡网络
metadata:
  name: stateful-tomcat
  labels:
    app: stateful-tomcat
spec:
  ports:
  - port: 8123
    name: web
    targetPort: 8080
  clusterIP: None   #NodePort:任意机器+NodePort都能访问,ClusterIP:集群内能用这个ip、service域名能访问,clusterIP: None;不要分配集群ip。headless;无头服务。稳定的域名
  selector:
    app: stateful-tomcat
---
apiVersion: apps/v1
kind: StatefulSet  #控制器。
metadata:
  name: stateful-tomcat
spec:
  selector:
    matchLabels:
      app: stateful-tomcat # has to match .spec.template.metadata.labels
  serviceName: "stateful-tomcat" #这里一定注意,必须提前有个service名字叫这个的
  replicas: 3 # by default is 1
  template:
    metadata:
      labels:
        app: stateful-tomcat # has to match .spec.selector.matchLabels
    spec:
      terminationGracePeriodSeconds: 10
      containers:
      - name: tomcat
        image: tomcat:7
        ports:
        - containerPort: 8080
          name: web

5、查看是否启动

代码语言:javascript
复制
[root@yygh-de state]# kubectl get svc,statefulset
NAME                      TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)    AGE
service/kubernetes        ClusterIP   10.96.0.1    <none>        443/TCP    15d
service/stateful-tomcat   ClusterIP   None         <none>        8123/TCP   4h24m

NAME                               READY   AGE
statefulset.apps/stateful-tomcat   3/3     4h24m
[root@yygh-de state]# kubectl get pod -l app=stateful-tomcat
NAME                READY   STATUS    RESTARTS   AGE
stateful-tomcat-0   1/1     Running   0          4h24m
stateful-tomcat-1   1/1     Running   0          3h38m

6、观察效果

删除一个,重启后名字,server名字等都是一样的。保证了状态

代码语言:javascript
复制
[root@yygh-de state]# kubectl get statefulset
NAME              READY   AGE
stateful-tomcat   3/3     4h32m
[root@yygh-de state]# kubectl get pod -l app=stateful-tomcat -o wide
NAME                READY   STATUS    RESTARTS   AGE   IP              NODE      NOMINATED NODE   READINESS GATES
stateful-tomcat-0   1/1     Running   0          17h   10.244.66.68    yygh-te   <none>           <none>
stateful-tomcat-1   1/1     Running   0          21h   10.244.66.121   yygh-te   <none>           <none>
stateful-tomcat-2   1/1     Running   0          21h   10.244.66.122   yygh-te   <none>           <none>
[root@yygh-de ~]# kubectl delete pod stateful-tomcat-0
pod "stateful-tomcat-0" deleted
[root@yygh-de ~]#  kubectl get pod -l app=stateful-tomcat -o wide
NAME                READY   STATUS    RESTARTS   AGE   IP              NODE      NOMINATED NODE   READINESS GATES
stateful-tomcat-0   1/1     Running   0          11s   10.244.66.66    yygh-te   <none>           <none>
stateful-tomcat-1   1/1     Running   0          21h   10.244.66.121   yygh-te   <none>           <none>
stateful-tomcat-2   1/1     Running   0          21h   10.244.66.122   yygh-te   <none>           <none>
# pod出现问题重新拉起,名字是固定的,ip是变的(pod有可能都不在之前的机器)但它的名字是有固定顺序的,名字不变。

7、通过主机名进行访问

代码语言:javascript
复制
[root@yygh-de ~]# kubectl exec -it stateful-tomcat-0 bash
root@stateful-tomcat-0:/usr/local/tomcat# curl stateful-tomcat-2.stateful-tomcat.default:8080
root@stateful-tomcat-0:/usr/local/tomcat# curl stateful-tomcat-2.stateful-tomcat.default:8080
root@stateful-tomcat-0:/usr/local/tomcat# curl stateful-tomcat-2.stateful-tomcat.default:8080
root@stateful-tomcat-0:/usr/local/tomcat# ping stateful-tomcat-2.stateful-tomcat.default
PING stateful-tomcat-2.stateful-tomcat.default.svc.cluster.local (10.244.66.122) 56(84) bytes of data.
64 bytes from stateful-tomcat-2.stateful-tomcat.default.svc.cluster.local (10.244.66.122): icmp_seq=1 ttl=63 time=0.063 ms
64 bytes from stateful-tomcat-2.stateful-tomcat.default.svc.cluster.local (10.244.66.122): icmp_seq=2 ttl=63 time=0.123 ms
64 bytes from stateful-tomcat-2.stateful-tomcat.default.svc.cluster.local (10.244.66.122): icmp_seq=3 ttl=63 time=0.122 ms
64 bytes from stateful-tomcat-2.stateful-tomcat.default.svc.cluster.local (10.244.66.122): icmp_seq=4 ttl=63 time=0.130 ms

8、调整k8s启动策略

代码语言:javascript
复制
[root@yygh-de ~]# kubectl explain statefulset.spec
   podManagementPolicy<string>
     podManagementPolicy controls how pods are created during initial scale up,
     when replacing pods on nodes, or when scaling down. The default policy is
     `OrderedReady`, where pods are created in increasing order (pod-0, then
     pod-1, etc) and the controller will wait until each pod is ready before
     continuing. When scaling down, the pods are removed in the opposite order.
     The alternative policy is `Parallel` which will create pods in parallel to
     match the desired scale without waiting, and on scale down will delete all
     pods at once.
# OrderedReady一台一台启动
# Parallel多台同时启动

9、需要在yaml多加一行

代码语言:javascript
复制
[root@yygh-de state]# vim statefulset.yaml
apiVersion: v1
kind: Service   #定义一个负载均衡网络
metadata:
  name: stateful-tomcat
  labels:
    app: stateful-tomcat
spec:
  ports:
  - port: 8123
    name: web
    targetPort: 8080
  clusterIP: None   #NodePort:任意机器+NodePort都能访问,ClusterIP:集群内能用这个ip、service域名能访问,clusterIP: None;不要分配集群ip。headless;无头服务。稳定的域名
  selector:
    app: stateful-tomcat
---
apiVersion: apps/v1
kind: StatefulSet  #控制器。
metadata:
  name: stateful-tomcat
spec:
  selector:
    matchLabels:
      app: stateful-tomcat # has to match .spec.template.metadata.labels
  serviceName: "stateful-tomcat" #这里一定注意,必须提前有个service名字叫这个的
  podManagementPolicy: Parallel  #指定多台同时启动
  replicas: 3 # by default is 1
  template:
    metadata:
      labels:
        app: stateful-tomcat # has to match .spec.selector.matchLabels
    spec:
      terminationGracePeriodSeconds: 10
      containers:
      - name: tomcat
        image: tomcat:7
        ports:
        - containerPort: 8080
          name: web

10、多台同时启动

代码语言:javascript
复制
[root@yygh-de state]# kubectl apply -f statefulset.yaml
[root@yygh-de ~]# kubectl get pod -l app=stateful-tomcat -o wide
NAME                READY   STATUS    RESTARTS   AGE     IP              NODE      NOMINATED NODE   READINESS GATES
stateful-tomcat-0   1/1     Running   0          2m39s   10.244.66.126   yygh-te   <none>           <none>
stateful-tomcat-1   1/1     Running   0          2m39s   10.244.66.76    yygh-te   <none>           <none>
stateful-tomcat-2   1/1     Running   0          2m39s   10.244.66.65    yygh-te   <none>           <none>

如果文章有任何错误欢迎不吝赐教,其次大家有任何关于运维的疑难杂问,也欢迎和大家一起交流讨论。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-07-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 运维猫 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、StatefulSet的设计原理
  • 2、StatefulSet将有状态应用抽象为两种情况
  • 3、StatefulSet 的核心功能
  • 4、使用statefulset部署的pod,即使重新拉起,所有之前的状态都不变
  • 5、查看是否启动
  • 6、观察效果
  • 7、通过主机名进行访问
  • 8、调整k8s启动策略
  • 9、需要在yaml多加一行
  • 10、多台同时启动
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档