【K8S系列】第七讲:有状态服务 VS 无状态服务_k8s有状态和无状态服务
阿里云国内75折 回扣 微信号:monov8 |
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6 |
目录
序言
昨天有位大佬问这个问题
………………………………………………
决定学习之后有了这篇文章.
1.无状态服务介绍
1.数据方面无状态服务不会在本地存储持久化数据.多个实例可以共享相同的持久化数据
2.结果方面多个服务实例对于同一个用户请求的响应结果是完全一致的
3.关系方面这种多服务实例之间是没有依赖关系
4.影响方面在k8s控制器 中动态启停无状态服务的pod并不会对其它的pod产生影响
5.示例方面nginx实例tomcat实例web应用
6.资源方面相关的k8s资源有ReplicaSet、ReplicationController、Deployment
7.创建方式Deployment被设计用来管理无状态服务的pod
每个pod完全一致原因如下
- 无状态服务内的多个Pod创建的顺序是没有顺序的
- 无状态服务内的多个Pod的名称是随机的.pod被重新启动调度后,它的名称与IP都会发生变化
- 无状态服务内的多个Pod背后是共享存储的
8.缩容方式随机缩容
由于是无状态服务所以这些控制器创建的pod序号都是随机值。并且在缩容也是随机并不会明确缩容某一个pod。因为所有实例得到的返回值都是一样所以缩容任何一个pod都可以
2 有状态服务介绍
1.数据方面有状态服务需要在本地存储持久化数据,典型的是分布式数据库的应
2.结果方面实例之间请求结果可能存在不一致
3.关系方面分布式节点实例之间有依赖的拓扑关系.比如,主从关系.
4.影响方面如果K8S停止分布式集群中任 一实例pod,就可能会导致数据丢失或者集群的crash
5.示例方面mysql数据库、kafka、zookeeper、Redis主从架构
6.资源方面statefulSet
7.创建方式statefulSet管理
Pod的特点
- 唯一性: 每个Pod会被分配一个唯一序号
- 顺序性: Pod启动,更新,销毁是线性的按顺序进行
- 稳定的网络标识: Pod主机名,DNS地址不会随着Pod被重新调度而发生变化.
- 稳定的持久化存储: Pod被重新调度后,仍然能挂载原有的PV,从而保证了数据的完整性和一致性.
8.缩容方式有顺序的缩容
StatefulSet 缩容只会操作 一个 pod 实例因此有状态应用的缩容相对于无状态的缩容速度会慢。
举例来说 一个分布式存储应用若同时下线多个节点 则可能导致其数据丢失 。
比如说一个数据项副本数设置为 2 的数据存储应用 若同时有两个节点下线如果一份数据它正好保存在这两个节点上这份数据就会丢失。
因此缩容是线性的 则分布式存储应用需要时间把丢失的副本复制到其他节点 从而保证数据不会丢失。其实这也是第七点中所讲的顺序性。
2.1 稳定的网络标识
如何理解稳定的网络标识以redis为例可以这样理解
例如需要创建名为test-redis-pod的Stateful模型,
根据配置的Replica=3的设置,K8S会创建三个Pod,依次命名为:
- test-redis-pod-0
- test-redis-pod-1
- test-redis-pod-2
K8S为有状态的服务Pod分配稳定的网络标识,具体实现基于test-redis-pod-0名称,借助Headless DNS进行如下解析,获取后端其中一个Pod的地址.
$(pod name).$(service name).$(namespace).svc.cluster.local
下面通过Pod名称访问Redis集群的Master节点地址的方法.
session.save_path = "tcp://test-redis-pod-0.test-redis-service.default.svc.cluster.local:6379"
在Redis Pod内部,主从节点之间数据同步的需求,Slave节点对应的配置文件中需要一个稳定的Master地址.
下边脚本通过稳定访问test-redis-pod-0 名称来间接获得Redis Master节点IP地址,
然后写入到Redis Slave的配置文件中,这样后续Slave节点与Master节点可以完成增量数据的同步.
if [ "${server_host}" != "test-redis-pod-0" ];then #echo "server-count: ${server_counts}" >> /data/redistest.log while [ -z "${master_address}" ];do echo "master_address is not available, ${master_address} waiting for redis master..." >> /data/redistest.log master_address=$(replication_master_address) sleep 1s done fi echo "master_address: $(master_address)" >> /data/redistest.log if [ ! -z "$master_address" ]; then printf "\nslaveof %s 6379\n" "$master_address" >> $conf fi
在Redis Pod外部, 可以这样来访问具体的Pod服务.
$(pod name).$(service name).$(namespace).svc.cluster.local
2.2 稳定持久化存储
如何理解稳定的持久化存储可以参考下图
如图
1.唯一每个Redis Pod对应一个PVC/PV.当Pod发生调度时,需要在别的节点启动时,根据Pod背后关联的存储信息可以保证其名称的稳定性.
2.复用Pod还是会attach挂载到原来的PV/PVC中,从而确定每个Pod有自己专用的存储卷.
3 总结
主要介绍了无状态和有状态服务的基础概念从八个方面介绍了两者的区别
并以redis集群为例详细讲解了稳定的网络标识和稳定的持久化存储
介绍了
- Deployment部署无状态服务
- Stateful新的部署组件.
Stateful 主要是通过支持Pod一些特性
- 名称唯一性
- 稳定的网络标识
- 稳定的持久化存储
从而实现在K8S中部署运维有状态服务