k8s之StatefulSet

这篇具有很好参考价值的文章主要介绍了k8s之StatefulSet。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

什么是StatefulSet?

是用来创建有状态应用,可以通过过某种方式记录这些状态,然后在 Pod 被重新创建时,能够为新 Pod 恢复这些状态。

什么是有状态应用?

首先是需要有数据的持久化,及时Pod被重启后,也能恢复,与重启前保持一致。然后是应用创建的所有pod有依赖关系,顺序的创建、需要运行在指定的宿主机上,并且都有对应的网络标志。

应用场景?

分布式应用,它的多个实例之间,往往有依赖关系,比如:主从关系、主备关系。

使用StatefulSet

创建StatefulSet

创建yaml文件定义StatefulSet对象如下,与Deployment比较,多了一个serviceName字段,这个是用来指定StatefulSet锁管理的pod是用域名访问是通过该service所设定的。

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: redis-sts

spec:
  serviceName: redis-svc
  replicas: 2
  selector:
    matchLabels:
      app: redis-sts

  template:
    metadata:
      labels:
        app: redis-sts
    spec:
      containers:
      - image: redis
        name: redis
        ports:
        - containerPort: 6379

创建StatefulSet对象

[root@k8s-worker1 zwf]# kubectl apply -f statefulset.yaml  -n zwf
statefulset.apps/redis-sts created

[root@k8s-worker1 zwf]# kubectl get sts -n zwf
NAME        READY   AGE
redis-sts   2/2     54s

查看创建的Pod会发现,命名不在是随机创建的名字,而是有了顺序号,从0开始,而k8s也会按照这个顺序一次创建。

[root@k8s-worker1 zwf]# kubectl get pods -n zwf
NAME          READY   STATUS    RESTARTS   AGE
redis-sts-0   1/1     Running   0          61s
redis-sts-1   1/1     Running   0          54s

输出pod中的hostname发现与pod的名称也保持一致,也就是应用可以自行决定依赖关系,比如该例子中可以使用0号pod作为主实例,而1号pod作为从实例。

[root@k8s-worker1 zwf]# kubectl exec -it redis-sts-0 -n zwf -- hostname
redis-sts-0

Service配置

定义匹配上面的创建StatefulSet对象所有管理的Service,也就是标签筛选需要和pod的标签保持一致,并且这里的metadata.name也要与StatefulSet中的serviceName一样。

apiVersion: v1
kind: Service
metadata:
  name: redis-svc

spec:
  selector:
    app: redis-sts

  ports:
  - port: 6379
    protocol: TCP
    targetPort: 6379

创建Service对象,我们可以看到已经将StatefulSet所创建的pod加入到端点列表了,也就是可以稳定的通过Service来访问到Pod

[root@k8s-worker1 zwf]# kubectl apply -f service_statefulset.yaml -n zwf
kservice/redis-svc created

[root@k8s-worker1 zwf]# kubectl get svc -n zwf
NAME                   TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)        AGE
redis-svc              ClusterIP   10.0.0.246   <none>        6379/TCP       5s

[root@k8s-worker1 zwf]# kubectl describe svc redis-svc -n zwf
Name:              redis-svc
Namespace:         zwf
Labels:            <none>
Annotations:       <none>
Selector:          app=redis-sts
Type:              ClusterIP
IP Family Policy:  SingleStack
IP Families:       IPv4
IP:                10.0.0.246
IPs:               10.0.0.246
Port:              <unset>  6379/TCP
TargetPort:        6379/TCP
Endpoints:         10.222.126.51:6379,10.222.194.84:6379
Session Affinity:  None
Events:            <none>

但是我们的Pod不是一般的的应用,是有状态的应用,需要有稳定的网络标识,所以会为每一个Pod也创建一个域名,格式是:<podName>.<serviceName>.<namesapce>.svc.cluster.local

我们进入pod中验证一下,通过ping redis-sts-1.redis-svc.zwf.svc.cluster.local发现是可以ping通的,虽然Pod的IP会变化,但是通过固定的域名就能访问到指定Pod了。

[root@k8s-worker1 zwf]# kubectl exec -it redis-sts-0 -n zwf -- ping redis-sts-1.redis-svc.zwf.svc.cluster.local
PING redis-sts-1.redis-svc.zwf.svc.cluster.local (10.222.126.51) 56(84) bytes of data.
64 bytes from redis-sts-1.redis-svc.zwf.svc.cluster.local (10.222.126.51): icmp_seq=1 ttl=62 time=0.964 ms
64 bytes from redis-sts-1.redis-svc.zwf.svc.cluster.local (10.222.126.51): icmp_seq=2 ttl=62 time=0.932 ms

既然我们的pod有了稳定的网络标识,Service也就不需要再分配ClusterIP了,这个时候,只需要添加字段clusterIP: None,这样就不会再分配IP了,这样的Service称为Headless Service

apiVersion: v1
kind: Service
metadata:
  name: redis-svc

spec:
  clusterIP: None
  selector:
    app: redis-sts

  ports:
  - port: 6379
    protocol: TCP
    targetPort: 6379

创建Headless Service,可以看到CLUSTER-IP为None

[root@k8s-worker1 zwf]# kubectl get svc -n zwf
NAME                   TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)        AGE
demoapp-nodeport-svc   NodePort    10.0.0.144   <none>        80:31999/TCP   21h
demoapp-svc            ClusterIP   10.0.0.74    <none>        80/TCP         22h
redis-svc              ClusterIP   None         <none>        6379/TCP       4s

Service和StatefulSet配置图如下:

k8s之StatefulSet

持久化配置

接下来是给StatefulSet对象添加持久化配置。

定义StatefulSet描述如下:

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: redis-pv-sts

spec:
  serviceName: redis-pv-svc

  volumeClaimTemplates:
  - metadata:
      name: redis-100m-pvc
    spec:
      storageClassName: nfs-client
      accessModes:
        - ReadWriteMany
      resources:
        requests:
          storage: 100Mi

  replicas: 2
  selector:
    matchLabels:
      app: redis-pv-sts

  template:
    metadata:
      labels:
        app: redis-pv-sts
    spec:
      containers:
      - image: redis:5-alpine
        name: redis

        volumeMounts:
        - name: redis-100m-pvc
          mountPath: /data

参数:

  • volumeClaimTemplates,用来将PVC的定义嵌入到StatefulSet中的字段,是创建PVC的模板,可以让每一个Pod都能自动创建PVC
  • voulumeMounts,是用来选择上面的PVC挂载在容器的/data目录中

创建StatefulSet对象,可以看到pod已经创建起来了。

[root@k8s-worker1 zwf]# kubectl apply -f statefulset_pvc.yaml -n zwf
statefulset.apps/redis-pv-sts created

[root@k8s-worker1 zwf]# kubectl get sts -n zwf
NAME           READY   AGE
redis-pv-sts   2/2     25

[root@k8s-worker1 zwf]# kubectl get pods -n zwf
NAME             READY   STATUS    RESTARTS   AGE
redis-pv-sts-0   1/1     Running   0          63s
redis-pv-sts-1   1/1     Running   0          54s

我们查看pvc,会发现创建了2个对象 ,以PVC名称-pod名称命名。

[root@k8s-worker1 zwf]# kubectl get pvc -n zwf
NAME                            STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
redis-100m-pvc-redis-pv-sts-0   Bound    pvc-2712daa4-36b4-4a63-ac2f-7d3b31e2a887   100Mi      RWX            nfs-client     109s
redis-100m-pvc-redis-pv-sts-1   Bound    pvc-a3781354-e182-42f7-b6f6-983999603653   100Mi      RWX            nfs-client     100s

进入到pod中,使用redis-cli运行redis客户端,添加一些数据

[root@k8s-worker1 zwf]# kubectl exec -it redis-pv-sts-0 -n zwf /bin/bash
[ root@redis-pv-sts-0:/data ]$ redis-cli  
127.0.0.1:6379> set name zhangsan
OK
127.0.0.1:6379> set age 18
OK
127.0.0.1:6379> keys *
1) "name"
2) "age"
127.0.0.1:6379> quit

将pod删除,然后再重新进入Pod中,查询之前创建的redis的key,还是能够查询到。

[root@k8s-worker1 zwf]# kubectl exec -it redis-pv-sts-0  -n zwf -- /bin/bash
[ root@redis-pv-sts-0:/data ]$ redis-cli  
127.0.0.1:6379> keys *
1) "name"
2) "age"
127.0.0.1:6379> get name
"zhangsan"
127.0.0.1:6379> get age
"18"

配置的关系图如下:

k8s之StatefulSet

欢迎关注,互相学习,共同进步~

我的个人博客

我的微信公众号:编程黑洞文章来源地址https://www.toymoban.com/news/detail-469122.html

到了这里,关于k8s之StatefulSet的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • k8s 控制器StatefulSet原理解析

    🐇明明跟你说过:个人主页 🏅个人专栏:《Kubernetes航线图:从船长到K8s掌舵者》 🏅 🔖行路有良友,便是天堂🔖 目录 一、前言 1、k8s概述 2、有状态服务和无状态服务  二、StatefulSet基本概念 1、StatefulSet特性  2、StatefulSet与Deployment、DaemonSet的对比  三、StatefulSet核心组件

    2024年04月17日
    浏览(54)
  • 基于K8S部署ZooKeeper准备知识(StatefulSet)

    使用k8s部署zk时,会部署一个headless service.科普一下headless service: Headless Service(无头服务)是 Kubernetes 中的一种服务类型,它与普通的 ClusterIP 服务有所不同。普通的 ClusterIP 服务会为每个服务分配一个虚拟 IP 地址,并通过负载均衡将流量转发到后端 Pod。而 Headless Service 不分

    2024年02月08日
    浏览(54)
  • 【K8S】Kubernetes 中有状态的资源对象——StatefulSet

    现在基本上很多服务中的应用都是有状态的,比如MySQL数据库、Redis等,因为其中的数据在不断地变化,所以这些应用每个时刻都处于一个不同的状态。或者一个系统中存在多个不同的应用,这些应用存在一定的依赖关系。例如一个博客服务,该服务中包含了Redis缓存和MySQL数

    2024年02月04日
    浏览(51)
  • 学习笔记二十七:K8S控制器Statefulset入门到企业实战应用

    用于管理有状态应用程序的部署。与无状态应用程序不同,有状态应用程序在运行时通常要求稳定的网络标识和持久性存储。 有状态服务:StatefulSet是有状态的集合,管理有状态的服务,它所管理的Pod的名称不能随意变化。数据持久化的目录也是不一样,每一个Pod都有自己独

    2024年02月06日
    浏览(52)
  • k8s实战案例之基于StatefulSet控制器运行MySQL一主多从

    Pod调度运⾏时,如果应⽤不需要任何稳定的标示、有序的部署、删除和扩展,则应该使⽤⼀组⽆状态副本的控制器来部署应⽤,例如 Deployment 或 ReplicaSet更适合⽆状态服务需求,⽽StatefulSet适合管理所有有状态的服务,⽐如MySQL、MongoDB集群等。 StatefulSet本质上是Deployment的⼀种

    2024年02月09日
    浏览(39)
  • k8s之工作负载、Deployment、DaemonSet、StatefulSet、Job、CronJob及GC

    1.1、定义 工作负载能让Pod能拥有自恢复能力,会写Pod,研究不同的工作负载怎么控制Pod的行为 1.2、分类 2.1、定义 一个 Deployment 为 Pods 和 ReplicaSets 提供声明式的更新能力。 你负责描述 Deployment 中的 目标状态,而 Deployment 控制器(Controller) 以受控速率更改实际状态, 使其变

    2024年02月11日
    浏览(42)
  • 飞天使-k8s知识点20-kubernetes实操5-pod更新与暂停-statefulset

    资源调度 Deployment:扩缩容 资源调度 Deployment:更新的暂停与恢复 资源调度 StatefulSet:定义一个有状态服务 headless service 金丝雀发布 参考文档:https://support.huaweicloud.com/basics-cce/kubernetes_0015.html

    2024年02月20日
    浏览(49)
  • K8s(Kubernetes)学习(四):Controller 控制器:Deployment、StatefulSet、Daemonset、Job

    什么是 Controller 以及作用 常见的 Controller 控制器 Controller 如何管理 Pod Deployment 基本操作与应用 通过控制器实现 Pod 升级回滚和弹性伸缩 StatefulSet 基本操作与应用 Daemonset 基本操作与应用 Job 基本操作与应用 Controller 无法解决问题 1 Controller 控制器 官网: http://kubernetes.p2hp.com/

    2024年02月09日
    浏览(56)
  • [Kubernetes]5. k8s集群StatefulSet详解,以及数据持久化(SC PV PVC)

    前面通过 deployment 结合 service 来部署 无状态的应用 ,下面来讲解通过 satefulSet 结合 service 来部署 有状态的应用 无状态: 无状态 (stateless) 、牲畜 (cattle) 、无名 (nameless) 、可丢弃 (disposable) 有状态: 有状态 (stateful) 、宠物 (pet) 、具有名 (haviing name) 、不可丢弃 (non-disposable) St

    2024年02月01日
    浏览(44)
  • K8s基础10——数据卷、PV和PVC、StorageClass动态补给、StatefulSet控制器

    为什么需要数据卷? 容器中的文件在磁盘上是临时存放的,这给容器中运行比较重要的应用程序带来一些问题。 当容器升级或者崩溃时,kubelet会重建容器,容器内文件会丢失。 一个Pod中运行多个容器时,需要共享文件。 而K8s 数据卷就可以解决这两个问题。 Volume概念: V

    2024年02月05日
    浏览(100)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包