zl程序教程

您现在的位置是:首页 >  后端

当前栏目

kubernetes控制器之StatefulSet

Kubernetes 控制器 StatefulSet
2023-09-11 14:22:28 时间

目录

一、无状态与有状态

1.1无状态

1.2有状态

二、StatefulSet 控制器

2.1 StatefulSet 控制器概述

2.2StatefulSet 控制器:网络标识

2.3StatefulSet 控制器:独享存储


一、无状态与有状态


Deployment控制器设计原则: 管理的所有Pod一模一样,提供同一个服务, 也不考虑在哪台Node 运行,可随意扩容和缩容。这种应用称为“无状态”,例如Web服务。

在实际的场景中,并不能满足所有应用,尤其是分布式应用,会部署多个实例, 这些实例之间往往有依赖关系,例如主从关系、主备关系, 这种应用称为“有状态”, 例如MySQL主从、 Etcd集群。

1.1无状态

(1)指该服务运行的实例不会在本地存储需要持久化的数据,并且多个实例对于同一个请求响应的结果是完全一致的。

(2)多个实例可以共享相同的持久化数据。例如:nginx实例,tomcat实例等

(3)相关的k8s资源有:ReplicaSet、ReplicationController、Deployment等,由于是无状态服务,所以这些控制器创建的pod序号都是随机值。并且在缩容的时候并不会明确缩容某一个pod,而是随机的,因为所有实例得到的返回值都是一样,所以缩容任何一个pod都可以

1.2有状态

(1)有状态服务 可以说是 需要数据存储功能的服务、或者指多线程类型的服务,队列等。(mysql数据库、kafka、zookeeper等)

(2)每个实例都需要有自己独立的持久化存储,并且在k8s中是通过申明模板来进行定义。持久卷申明模板在创建pod之前创建,绑定到pod中,模板可以定义多个。


二、StatefulSet 控制器


2.1 StatefulSet 控制器概述

StatefulSet控制器用于部署有状态应用, 满足一些有状态应用的需求:

• Pod有序的部署、扩容、删除和停止

• Pod分配一个稳定的且唯一的网络标识

• Pod分配一个独享的存储

2.2StatefulSet 控制器:网络标识

稳定的网络标识: 使用Headless Service (相比普通Service只是将spec.clusterIP定义为None) 来维 护Pod网络身份,会为每个Pod分配一个数字编号并且按照编号顺序部署。还需要在StatefulSet添加 serviceName: “nginx”字段指定StatefulSet控制器要使用这个Headless Service。

稳定主要体现在主机名和Pod A记录:

主机名: <statefulset名称>- <编号>

Pod DNS A记录: <statefulset名称-编号>. <service-name> . <namespace>.svc.cluster.local

service.yaml

apiVersion: v1
kind: Service
metadata:
  name: headless-web
  namespace: default
spec:
  clusterIP: None
  ports:
  - port: 80       # service端口
    protocol: TCP  # 协议
    targetPort: 80 # 容器端口
  selector:        # 标签选择器
    app: nginx     # 指定关联的 Pod的标签
  type: ClusterIP  # 服务类型 

   查看 创建的 headless-web service

statefulset-web.yaml

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: statefulset-web
spec:
  serviceName: headless-web
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
       - name: nginx
         image: nginx
         ports: 
         - containerPort: 80 
           name: web

从web0开始创建 pod

我们发现 创建的 三个容器的主机名与pod 的名称是一致的,即使pod 删除 重新创建 主机名也是 不变的,有稳定的主机名。

启动一个容器 dns-test 查看web , headless-web service的DNS 解析结果

kubectl run -i -t dns-test --image busybox:1.28.4 /bin/sh

nslookup (全称 name server lookup) ,是一个在命令行界面下的网络工具

使用 nslookup 查看 DNS的结果

[root@k8s-master1 statefulset]# kubectl run -i -t dns-test --rm  --image busybox:1.28.4 /bin/sh
If you don't see a command prompt, try pressing enter.
/ # nslookup headless-web
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

Name:      headless-web
Address 1: 10.244.36.75 statefulset-web-1.headless-web.default.svc.cluster.local
Address 2: 10.244.36.76 statefulset-web-2.headless-web.default.svc.cluster.local
Address 3: 10.244.169.136 statefulset-web-0.headless-web.default.svc.cluster.local
/ # nslookup statefulset-web-1.headless-web.default.svc.cluster.local
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

Name:      statefulset-web-1.headless-web.default.svc.cluster.local
Address 1: 10.244.36.75 statefulset-web-1.headless-web.default.svc.cluster.local

即使我们pod 重启 IP 发生变化,三条 DNS记录名称是不变的 ,我们可以使用固定的DNS名称。

2.3StatefulSet 控制器:独享存储

独享存储: StatefulSet的存储卷使用VolumeClaimTemplate创建,称为卷申请模板, 当StatefulSet使用 VolumeClaimTemplate创建一个PersistentVolume时,同样也会为每个Pod分配并创建一个编号的PVC, 每个PVC绑定对应的PV,从而保证每个Pod都拥有独立的存储。

statefulset-web.yaml

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: statefulset-web
spec:
  serviceName: headless-web
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
       - name: nginx
         image: nginx
         ports: 
         - containerPort: 80 
           name: web
         volumeMounts:
         - name: www
           mountPath: /usr/share/nginx/html
  volumeClaimTemplates:     ## statefulset 专属
  - metadata:    
      name: www
    spec:
      storageClassName: "managed-nfs-storage" ## 基于PV的动态创建
      accessModes:
      - ReadWriteOnce
      resources:
        requests:
          storage: 1Gi

验证pvc和pv

NFS Server 服务器上成功创建存储路径

输入内容 ,可以成功访问

cd /ifs/kubernetes/
echo ' hello pod 00' > default-www-web-0-pvc-c976defd-bd81-4c7c-b489-9801fc50cc60/index.html
echo ' hello pod 01' > default-www-web-1-pvc-385c9232-4e5f-4e46-9f7a-a4ba58f45577/index.html
echo ' hello pod 02' > default-www-web-2-pvc-74ad04fa-ab96-444f-92a0-9bb3e03c1118/index.html

我们 删除 pod 后, 存储的文件还是存在的 ,如果重新创建pod , k8s会重新 创建pv 和pvc, 绑定 对用的路径,数据不会发生变化。

 小结

StatefulSet与Deployment区别:有身份的!

份三要素:

   域名

•   主机名

•   存储(PVC)