k8s-Statefulset

root
233
文章
0
评论
2021年8月16日18:41:25 评论 5303字阅读17分40秒

k8s-Statefulset

Statefulset控制器:概念、原理解读

  • StatefulSet是为了管理有状态服务的问题而设计的

扩展:

有状态服务?

StatefulSet是有状态的集合,管理有状态的服务,它所管理的Pod的名称不能随意变化。数据持久化的目录也是不一样,每一个Pod都有自己独有的数据持久化存储目录。比如MySQL主从、redis集群等。

无状态服务?

RC、Deployment、DaemonSet都是管理无状态的服务,它们所管理的Pod的IP、名字,启停顺序等都是随机的。个体对整体无影响,所有pod都是共用一个数据卷的,部署的tomcat就是无状态的服务,tomcat被删除,在启动一个新的tomcat,加入到集群即可,跟tomcat的名字无关。

StatefulSet由以下几个部分组成:

  • Headless Service:用来定义pod网路标识,生成可解析的DNS记录
  • volumeClaimTemplates:存储卷申请模板,创建pvc,指定pvc名称大小,自动创建pvc,且pvc由存储类供应。
  • StatefulSet:管理pod的

Headless Service

扩展:什么是Headless service?

Headless service不分配clusterIP,headless service可以通过解析service的DNS,返回所有Pod的dns和ip地址 (statefulSet部署的Pod才有DNS),普通的service,只能通过解析service的DNS返回service的ClusterIP。

为什么要用headless service(没有service ip的service)?

在使用Deployment时,创建的Pod名称是没有顺序的,是随机字符串,在用statefulset管理pod时要求pod名称必须是有序的 ,每一个pod不能被随意取代,pod重建后pod名称还是一样的。因为pod IP是变化的,所以要用Pod名称来识别。pod名称是pod唯一性的标识符,必须持久稳定有效。这时候要用到无头服务,它可以给每个Pod一个唯一的名称。

 

Headless service的作用

  • 1.headless service会为service分配一个域名
<service name>.$<namespace name>.svc.cluster.local

 

K8s中资源的全局FQDN格式:
  Service_NAME.NameSpace_NAME.Domain.LTD.
  Domain.LTD.=svc.cluster.local.     #这是默认k8s集群的域名。

FQDN 全称 Fully Qualified Domain Name

即全限定域名:同时带有主机名和域名的名称

FQDN = Hostname + DomainName

如 主机名是 xianchao 域名是 baidu.com

FQDN= xianchao.baidu.com

  • 2.StatefulSet会为关联的Pod保持一个不变的Pod Name

    • statefulset中Pod的名字格式为$(StatefulSet name)-$(pod序号)

 

  • 3.StatefulSet会为关联的Pod分配一个dnsName
    • $<Pod Name>.$<service name>.$<namespace name>.svc.cluster.local

volumeClaimTemplates

为什么要用volumeClaimTemplate?

对于有状态应用都会用到持久化存储,比如mysql主从,由于主从数据库的数据是不能存放在一个目录下的,每个mysql节点都需要有自己独立的存储空间。而在deployment中创建的存储卷是一个共享的存储卷,多个pod使用同一个存储卷,它们数据是同步的,而statefulset定义中的每一个pod都不能使用同一个存储卷,这就需要使用volumeClainTemplate,当在使用statefulset创建pod时,volumeClainTemplate会自动生成一个PVC,从而请求绑定一个PV,每一个pod都有自己专用的存储卷。Pod、PVC和PV对应的关系图如下

 Statefulset资源清单文件编写技巧

#查看定义Statefulset资源需要的字段

[root@master01 w]# kubectl explain statefulset
KIND:     StatefulSet
VERSION:  apps/v1
DESCRIPTION:
     StatefulSet represents a set of pods with consistent identities. Identities
     are defined as:
     - Network: A single stable DNS and hostname.
     - Storage: As many VolumeClaims as requested. The StatefulSet guarantees
     that a given network identity will always map to the same storage identity.
FIELDS:
   apiVersion	<string> #定义statefulset资源需要使用的api版本
   kind	<string>          #定义的资源类型
   metadata	<Object>     #元数据
   spec	<Object>          #定义容器相关的信息

#查看statefulset.spec字段如何定义?

[root@master01 w]# kubectl explain statefulset.spec
KIND:     StatefulSet
VERSION:  apps/v1
RESOURCE: spec <Object>
DESCRIPTION:
     Spec defines the desired identities of pods in this set.
     A StatefulSetSpec is the specification of a StatefulSet.
FIELDS:
   podManagementPolicy	<string> #pod管理策略
   replicas	<integer>  #副本数
   revisionHistoryLimit	<integer> #保留的历史版本
   selector	<Object> -required- #标签选择器,选择它所关联的pod
   serviceName	<string> -required-  #headless service的名字
   template	<Object> -required-     #生成pod的模板
   updateStrategy	<Object>   #更新策略
   volumeClaimTemplates	<[]Object> #存储卷申请模板

#查看statefulset的spec.template字段如何定义?

#对于template而言,其内部定义的就是pod,pod模板是一个独立的对象

[root@master01 w]#  kubectl explain statefulset.spec.template
KIND:     StatefulSet
VERSION:  apps/v1
RESOURCE: template <Object>
DESCRIPTION:
     template is the object that describes the pod that will be created if
     insufficient replicas are detected. Each pod stamped out by the StatefulSet
     will fulfill this Template, but have a unique identity from the rest of the
     StatefulSet.
     PodTemplateSpec describes the data a pod should have when created from a
     template
FIELDS:
   metadata	<Object>
   spec	<Object>  #定义容器属性的

通过上面可以看到,statefulset资源中有两个spec字段。第一个spec声明的是statefulset定义多少个Pod副本(默认将仅部署1个Pod)、匹配Pod标签的选择器、创建pod的模板、存储卷申请模板,第二个spec是spec.template.spec:主要用于Pod里的容器属性等配置。

.spec.template里的内容是声明Pod对象时要定义的各种属性,所以这部分也叫做PodTemplate(Pod模板)。还有一个值得注意的地方是:在.spec.selector中定义的标签选择器必须能够匹配到spec.template.metadata.labels里定义的Pod标签,否则Kubernetes将不允许创建statefulset。

Statefulset使用案例:部署web站点

#创建存储类-------------[这个存储类的前提要有供应商,供应商的创建请查看 k8s-持久化存储[PVC]]

[root@master01 w]# cat class-web.yaml 
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: nfs-web
provisioner: example.com/nfs

#更新资源清单文件

[root@master01 w]# kubectl apply -f class-web.yaml 
storageclass.storage.k8s.io/nfs-web created

#编写一个Statefulset资源清单文件

[root@master01 w]# cat nginx.yaml 
apiVersion: v1
kind: Service
metadata: 
  name: nginx
  labels:
     app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: nginx-sf
  labels:
    app: nginx
spec:
  replicas: 2
  serviceName: "nginx"       ##svc的名字
  selector:
    matchLabels:
      app: hwf
  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:
  - metadata:
      name: www
      accessModes: ["ReadWriteOnce"]   #访问模式
      storageClassName: nfs-web #存储类的名字
      resources:
        requests:
          storage: 1Gi

 

#更新资源清单文件

[root@master01 w]# kubectl apply -f nginx.yaml 
service/nginx unchanged
statefulset.apps/nginx-sf created

#查看sc

[root@master01 w]# kubectl get sc
NAME      PROVISIONER       RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
nfs       example.com/nfs   Delete          Immediate           false                  17h
nfs-web   example.com/nfs   Delete          Immediate           false                  48m
[root@master01 w]# kubectl get statefulsets
NAME       READY   AGE
nginx-sf   2/2     3m33s

#查看容器主机名

[root@master01 w]# for i in 0 1;do kubectl exec nginx-sf-$i -- sh -c 'hostname';done
nginx-sf-0
nginx-sf-1

 

测试Pod的DNS解析

#使用kubectl run运行一个提供nslookup命令的容器的,这个命令来自于dnsutils包,通过对pod主机名执行nslookup,可以检查它们在集群内部的DNS地址:

[root@master01 w]# kubectl exec -it nginx-sf-0 -- sh
# nslookup 
sh: 2: nslookup: not found
# apt-get update
# apt-get install dnsutils -y

 

# nslookup nginx-sf-0.nginx.default.svc.cluster.local
Server:		10.1.0.10
Address:	10.1.0.10#53

Name:	nginx-sf-0.nginx.default.svc.cluster.local
Address: 172.16.196.169

 

 

继续阅读
weinxin
我的微信
这是我的微信扫一扫
  • 文本由 发表于 2021年8月16日18:41:25
  • 除非特殊声明,本站文章均为原创,转载请务必保留本文链接
k8s-Service Account Kubernetes

k8s-Service Account

k8s-Service Account的授权管理 Service Account也是一种账号,是给运行在Pod里的进程提供了必要的身份证明。需要在Pod定义中指明引用的Service Account,...
k8s-RBAC Kubernetes

k8s-RBAC

k8s-RBAC认证授权策略 RBAC介绍 在Kubernetes中,所有资源对象都是通过API进行操作,他们保存在etcd里。而对etcd的操作我们需要通过访问 kube-apiserver 来实现...
k8s-Secret Kubernetes

k8s-Secret

配置管理中心Secret Secret是什么? Configmap一般是用来存放明文数据的,如配置文件,对于一些敏感数据,如密码、私钥等数据时,要用secret类型 Secret解决了密码、token...
匿名

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: