K8s控制器---Statefulset(11)
一、Statefulset概述
1.1 Statefulset控制器:概念和原理解读
StatefulSet 是为了管理有状态服务的问题而设计的
扩展: 有状态服务?
StatefulSet 是有状态的集合,管理有状态的服务,它所管理的 Pod 的名称不能随意变化。数据持久化的目录也是不一样,每一个 Pod 都有自己独有的数据持久化存储目录。比如 MySQL 主 从、redis 集群等
无状态服务?
RC、Deployment、DaemonSet 都是管理无状态的服务,它们所管理的 Pod 的 IP、名字,启、停顺序等都是随机的。个体对整体无影响,所有 pod 都是共用一个数据卷的,部署的 tomcat 就 是无状态的服务,tomcat 被删除,在启动一个新的 tomcat,加入到集群即可,跟 tomcat 的名字无关
StatefulSet 由以下几个部分组成:
1. Headless Service:用来定义 pod 网路标识,生成可解析的 DNS 记录
2. volumeClaimTemplates:存储卷申请模板,创建 pvc,指定 pvc 名称大小,自动创建pvc,且 pvc 由存储类供应。
3. StatefulSet:管理 pod 的
扩展:什么是 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 一个唯一的名称.
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
例如:主机名是:monitor,域名是:test.com, FQDN=monitor.test.com 2.StatefulSet 会为关联的 Pod 保持一个不变的 Pod Name
statefulset 中 Pod 的名字格式为$(StatefulSet name)-$(pod 序号) 3.StatefulSet 会为关联的 Pod 分配一个 dnsName
$<Pod Name>.$<service name>.$<namespace name>.svc.cluster.local 为什么要用 volumeClaimTemplate?
对于有状态应用都会用到持久化存储,比如 mysql 主从,由于主从数据库的数据是不能存放在一个目录下的,每个 mysql 节点都需要有自己独立的存储空间。而在 deployment 中创建的存储卷是一个共享的存储卷,
多个 pod 使用同一个存储卷,它们数据是同步的,而 statefulset 定义中的每一个 pod 都不能使用同一个存储卷,这就需要使用volumeClainTemplate,当在使用statefulset 创建 pod 时,volumeClainTemplate 会自动
生成一个 PVC,从而请求绑定一个PV,每一个 pod 都有自己专用的存储卷。Pod、PVC 和 PV 对应的关系图如下:
1.2 Statefulset资源清单编写技巧
# 查看定义Statefulset
[root@master nfs_pro]# kubectl explain Statefulset
KIND: StatefulSet
VERSION: apps/v1 FILEDS:
apiVersion <string> > #定义 statefulset 资源需要使用的 api 版本
kind <string> #定义的资源类型
metadata <Object> #元数据
spec <Object> #定义容器相关的信息
status <Object> #查看 statefulset.spec 字段如何定义?
[root@master nfs_pro]# kubectl explain Statefulset.spec
KIND: StatefulSet
VERSION: apps/v1 RESOURCE: spec <Object>
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@master nfs_pro]# kubectl explain Statefulset.spec.template
KIND: StatefulSet
VERSION: apps/v1 RESOURCE: template <Object> metadata<Object>
spec <Object> #定义容器属性的
[root@master nfs_pro]# kubectl explain Statefulset.spec.template.spec
KIND: StatefulSet
VERSION: apps/v1
RESOURCE: 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。
1.3 Statefulset部署案例:部署web站点
# 1.创建存储类
[root@master statefulset]# cat class-web.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: nfs-web
provisioner: example.com/nfs [root@master statefulset]# kubectl apply -f class-web.yaml
storageclass.storage.k8s.io/nfs-web created
[root@master statefulset]# kubectl get storageclass
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
nfs-web example.com/nfs Delete Immediate false 10s # 节点导入nginx镜像文件
docker load -i nginx.tar.gz # 编写statefulset资源清单文件

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:
labels:
app: sts-nginx
name: web
spec:
selector:
matchLabels:
app: nginx
serviceName: "nginx"
replicas: 2
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
name: web
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: www
spec:
accessModes: ["ReadWriteOnce"] # ["ReadWriteOnce","ReadWriteMany"]
storageClassName: nfs-web
resources:
requests:
storage: 1Gi
stateful.yaml
[root@master statefulset]# kubectl apply -f web.yaml
service/nginx created
statefulset.apps/web configured
[root@master statefulset]# kubectl get statefulset
NAME READY AGE
web 2/2 57s [root@master statefulset]# kubectl get pods
NAME READY STATUS RESTARTS AGE
web-0 1/1 Running 0 83s
web-1 1/1 Running 0 79s [root@master statefulset]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
www-web-0 Bound pvc-29475068-55a9-4922-9826-548344c2acf6 1Gi RWO nfs-web 4m35s
www-web-1 Bound pvc-352accfb-2240-411c-a9b8-89998580e0de 1Gi RWO nfs-web 4m31s [root@master statefulset]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pvc-29475068-55a9-4922-9826-548344c2acf6 1Gi RWO Delete Bound kube-system/www-web-0 nfs-web 4m40s
pvc-352accfb-2240-411c-a9b8-89998580e0de 1Gi RWO Delete Bound kube-system/www-web-1 nfs-web 4m36s
[root@master nfs_pro]# ls
archived-pvc-7ee6fbf4-b64c-45c6-bcef-2390ba8b5a27 kube-system-www-web-0-pvc-29475068-55a9-4922-9826-548344c2acf6
archived-pvc-952e54e7-33e0-4b87-9b6c-bcf8b84c7a75 kube-system-www-web-1-pvc-352accfb-2240-411c-a9b8-89998580e0de
# 查看主机名
[root@master nfs_pro]# for i in 0 1; do kubectl exec web-$i -- /bin/sh -c 'hostname';done
web-0
web-1
1.4 测试Pod的dns解析
#使用 kubectl run 运行一个提供 nslookup 命令的容器的,这个命令来自于 dnsutils 包,通过 对 pod 主机名执行 nslookup,可以检查它们在集群内部的 DNS 地址:
[root@master statefulset]# kubectl exec -it web-1 -- /bin/sh
# cat /etc/issue
Debian GNU/Linux 10 \n \l
# apt-get update
# apt-get install dnsutils -y
# nslookup web-0.nginx.kube-system.svc.cluster.local
Server: 10.96.0.10
Address: 10.96.0.10#53 Name: web-0.nginx.kube-system.svc.cluster.local
Address: 10.244.135.44
# 测试Headless service的dns解析
# web-1
# nslookup nginx.kube-system.svc.cluster.local
Server: 10.96.0.10
Address: 10.96.0.10#53 Name: nginx.kube-system.svc.cluster.local
Address: 10.244.135.44
Name: nginx.kube-system.svc.cluster.local
Address: 10.244.75.241 # master
[root@master statefulset]# kubectl describe svc nginx
Name: nginx
Namespace: kube-system
Labels: app=nginx
Annotations: <none>
Selector: app=nginx
Type: ClusterIP
IP Families: <none>
IP: None
IPs: None
Port: web 80/TCP
TargetPort: 80/TCP
Endpoints: 10.244.135.44:80,10.244.75.241:80
Session Affinity: None
Events: <none> # web-1
# dig -t A nginx.kube-system.svc.cluster.local @10.96.0.10
1.5 资源清单详细解读
apiVersion: v1 #定义 api 版本
kind: Service #定义要创建的资源:service
metadata:
name: nginx #定义 service 的名字
labels:
app: nginx #service 的标签
spec:
ports:
- port: 80
name: web
clusterIP: None #创建一个没有 ip 的 service
selector:
app: nginx #选择拥有 app=nginx 标签的 pod
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
selector:
matchLabels:
app: nginx
serviceName: "nginx" #headless service 的名字
replicas: 2 #副本数
template: #定义 pod 的模板
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
name: web
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumeClaimTemplates: #存储卷申请模板
- metadata:
name: www
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: "nfs-web" #指定从哪个存储类申请 pv
resources:
requests:
storage: 1Gi #需要 1G 的 pvc,会自动跟符合条件的 pv 绑定
# 生产环境可以增加探测器之类
Statefulset 总结: 1、Statefulset 管理的 pod,pod 名字是有序的,由 statefulset 的名字-0、1、2 这种格式组成
2、创建 statefulset 资源的时候,必须事先创建好一个 service,如果创建的 service 没有 ip,那对这个 service 做dns 解析,会找到它所关联的 pod ip,如果创建的 service 有 ip,那对这个service 做 dns 解析,会解析到 service 本身 ip。
3、statefulset 管理的 pod,删除 pod,新创建的 pod 名字跟删除的 pod 名字是一样的
4、statefulset 具有 volumeclaimtemplate 这个字段,这个是卷申请模板,会自动创建 pv, pvc 也会自动生成,跟 pv 进行绑定,那如果创建的 statefulset 使用了 volumeclaimtemplate 这个字段,那创建 pod,数据目录是独享的
5、ststefulset 创建的 pod,是域名的(域名组成:pod-name.svc-name.svc- namespace.svc.cluster.local)
二、Statefulset实现pod的扩容、缩容、更新策略
2.1 扩容
1.修改statefulset.yaml文件中副本数replicas:2改为3
2.[root@master statefulset]# kubectl edit sts web 修改replicas
web-0 1/1 Running 0 60m 10.244.135.44 node3 <none> <none>
web-1 1/1 Running 0 57m 10.244.75.241 monitor <none> <none>
web-2 1/1 Running 0 58s 10.244.135.45 node3 <none> <none>
2.2 缩容:从大到小缩容
1.修改statefulset.yaml文件中副本数replicas:3改为2
2..[root@master statefulset]# kubectl edit sts web 修改replicas
web-0 1/1 Running 0 61m 10.244.135.44 node3 <none> <none>
web-1 1/1 Running 0 58m 10.244.75.241 monitor <none> <none>
2.3 Statefulset实现pod更新
[root@master ~]# kubectl explain sts.spec.updateStrategy
KIND: StatefulSet
VERSION: apps/v1 RESOURCE: updateStrategy <Object> FIELDS:
rollingUpdate <Object>
type <string> [root@master ~]# kubectl explain sts.spec.updateStrategy.rollingUpdate FIELDS:
maxUnavailable <string>
partition <integer>

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: web
spec:
updateStrategy:
rollingUpdate:
partition: 1
maxUnavailable: 0
selector:
matchLabels:
app: nginx
serviceName: "nginx"
replicas: 2
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: ikubernetes/myapp:v2
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
name: web
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: www
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: "nfs"
resources:
requests:
storage: 1Gi pod 在更新的时候,只是更新了 web-1 这个 pod, partition: 1 表示更新的时候会把 pod 序号大于等于 1 的进行更新 如果更新策略是 OnDelete,那不会自动更新 pod,需要手动删除,重新常见的 pod 才会实现更新
spec:
updateStrategy:
type: OnDelete updateStrategy更新使用
updateStrategy更新使用
1.准备好版本导入node节点
#docker load -i myapp.tar.gz
Loaded image: ikubernetes/myapp:v2
2.修改statefulset.yaml文件中image镜像
image: nginx 改为:image: ikubernetes/myapp:v2
[root@master statefulset]# kubectl get pods -w
web-1 1/1 Terminating 0 62m
web-1 1/1 Terminating 0 62m
web-1 0/1 Terminating 0 62m
web-1 0/1 Terminating 0 62m
web-1 0/1 Terminating 0 62m
web-1 0/1 Pending 0 0s
web-1 0/1 Pending 0 0s
web-1 0/1 ContainerCreating 0 0s
web-1 0/1 ContainerCreating 0 1s
web-1 1/1 Running 0 2s
web-0 1/1 Terminating 0 65m
web-0 1/1 Terminating 0 65m
web-0 0/1 Terminating 0 65m
web-0 0/1 Terminating 0 65m
web-0 0/1 Terminating 0 65m
web-0 0/1 Pending 0 0s
web-0 0/1 Pending 0 0s
web-0 0/1 ContainerCreating 0 0s
web-0 0/1 ContainerCreating 0 1s
web-0 1/1 Running 0 2s
K8s控制器---Statefulset(11)的更多相关文章
- k8s控制器资源(五)
Pod pod在之前说过,pod是kubernetes集群中是最小的调度单元,pod中可以运行多个容器,而node又可以包含多个pod,关系如下图: 在对pod的用法进行说明之前,有必要先对docke ...
- K8s控制器
K8s控制器 POD分类 #自主式pod:退出后,不会被创建 #控制器管理的pod:在控制器的生命周期内,始终位置pod的副本数 控制器类型 ReplicationController和Replica ...
- k8s控制器资源
k8s控制器资源 Pod pod在之前说过,pod是kubernetes集群中是最小的调度单元,pod中可以运行多个容器,而node又可以包含多个pod,关系如下图: 在对pod的用法进行说明之前 ...
- [原创]自动化部署K8S(v1.10.11)集群
标准运维实现自动化部署K8S集群主要分两步,第一步是部署gse-agent,拱第二步执行部署. 第一步:部署gse-agent.如下: 第二步:部署k8s集群.主要通过作业平台分为5小步执 ...
- Kubernetes(k8s)控制器(二):DaemonSet
目录 一.系统环境 二.前言 三.DaemonSet 概览 四.创建DaemonSet 4.1 创建daemonset 让其在k8s集群所有worker节点运行pod 4.2 创建daemonset让 ...
- Kubernetes(k8s)控制器(三):ReplicationController
目录 一.系统环境 二.前言 三.ReplicationController概览 四.ReplicationController工作机制 五.创建ReplicationController 六.扩展r ...
- Kubernetes(k8s)控制器(四):ReplicaSet
目录 一.系统环境 二.前言 三.ReplicaSet概览 四.ReplicaSet工作原理 五.ReplicaSet使用场景 六.创建ReplicaSet 七.扩展replicaset副本数 一.系 ...
- 容器编排系统K8s之StatefulSet控制器
前文我们聊到了k8s的configmap和secret资源的说明和相关使用示例,回顾请参考:https://www.cnblogs.com/qiuhom-1874/p/14194944.html:今天 ...
- 5.深入k8s:StatefulSet控制器
转载请声明出处哦~,本篇文章发布于luozhiyun的博客:https://www.luozhiyun.com 在上一篇中,讲解了容器持久化存储,从中我们知道什么是PV和PVC,这一篇我们讲通过Sta ...
- Kubernetes(k8s)控制器(一):deployment
目录 一.系统环境 二.前言 三.Kubernetes 控制器 四.Deployment概览 五.创建deployment 六.修改deploy副本数 6.1 kubectl edit deploy ...
随机推荐
- 记录--form 表单恢复初始数据
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 form 表单恢复初始数据 在现代的 Web 开发中,表单是不可或缺的组件之一.用户可以通过表单输入和提交数据,而开发者则需要对这些数据进 ...
- 记录--uni-app中安卓包检查更新、新版本下载、下载进度条显示功能实现
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 需求描述 如果想要做一个app的话,可以有很多种选择方案,uni-app是其中的一个性价比高一些(坑多一些)的方案.本文记录一下,uni- ...
- Linux安装Oracle12C及一些参考
目录 安装 系统配置 安装前装备 安装依赖包 创建用户和组 修改内核参数 修改系统资源限制 创建安装目录及设置权限 设置oracle环境变量 安装Oracle 一些参考 compat-libstdc+ ...
- 为什么FTP会随着时间的过去而变慢?
有人问:我在XP上有FZ客户端3.5.3,在Vista上有0.9.41服务器.通过已经很慢的连接传输大文件时,我注意到速度开始时约为40kb / s,但逐渐趋于稳定,约为20kb / s,并保持这种状 ...
- 2024-03-27:用go语言,多维费用背包。 给你一个二进制字符串数组 strs 和两个整数 m 和 n, 请你找出并返回 strs 的最大子集的长度,该子集中 最多 有 m 个 0 和 n 个
2024-03-27:用go语言,多维费用背包. 给你一个二进制字符串数组 strs 和两个整数 m 和 n, 请你找出并返回 strs 的最大子集的长度,该子集中 最多 有 m 个 0 和 n 个 ...
- Linux编写Shell脚本获取指定目录下所有文件并处理
Linux编写Shell脚本获取指定目录下所有文件进行处理并保存到新目录 #!/bin/bash app_name="shell" path="/dir" #原 ...
- #树形dp,直径#51nod 1812 树的双直径
题目 给定一棵树,边权是整数 \(c_i\) ,找出两条不相交的链(没有公共点), 使得链长的乘积最大(链长定义为这条链上所有边的权值之和,如果这条链只有1个点则链长视为0). \(n\leq 4*1 ...
- #结论#洛谷 3199 [HNOI2009]最小圈
题目 求有向图最小平均权值回路. \(n\leq 3*10^3,m\leq 10^4\) 分析 设 \(f_k(x)\) 表示从点 \(x\) 出发恰好走 \(k\) 条边的最短路, 那么答案就是 \ ...
- 学习如何使用 Python 连接 MongoDB: PyMongo 安装和基础操作教程
Python 可以用于数据库应用程序.最流行的 NoSQL 数据库之一是 MongoDB MongoDB MongoDB 将数据存储在类似 JSON 的文档中,使数据库非常灵活和可扩展. 您可以在 M ...
- KL散度和交叉熵的对比介绍
KL散度(Kullback-Leibler Divergence)和交叉熵(Cross Entropy)是在机器学习中广泛使用的概念.这两者都用于比较两个概率分布之间的相似性,但在一些方面,它们也有所 ...
