http://blog.itpub.net/28916011/viewspace-2215046/

在应用程序中,可以分为有状态应用和无状态应用。

无状态的应用更关注于群体,任何一个成员都可以被取代。

对有状态的应用是关注个体。

像我们前面用deployment控制器管理的nginx、myapp等都属于无状态应用。

像mysql、redis,zookeeper等都属于有状态应用,他们有的还有主从之分、先后顺序之分。

statefulset控制器能实现有状态应用的管理,但实现起来也是非常麻烦的。需要把我们运维管理的过程写入脚本并注入到statefulset中才能使用。虽然互联网上有人做好了stateful的脚本,但是还是建议大家不要轻易的把redis、mysql等这样有状态的应用迁移到k8s上。

在k8s中,statefulset主要管理一下特效的应用:

a)、每一个Pod稳定且有唯一的网络标识符;

b)、稳定且持久的存储设备;

c)、要求有序、平滑的部署和扩展;

d)、要求有序、平滑的终止和删除;

e)、有序的滚动更新,应该先更新从节点,再更新主节点;

statefulset由三个组件组成:

a) headless service(无头的服务,即没名字);

b)statefulset控制器

c)volumeClaimTemplate(存储卷申请模板,因为每个pod要有专用存储卷,而不能共用存储卷)

[root@master ~]# kubectl explain sts   #stateful的简称

  

创建之前删除之前创建的多余的pod和svc避免待会冲突出错,当然也可以不删,只不过yaml里有些是冲突的,自己得另行定义

kubectl delete pods pod-vol-pvc
kubectl delete pod pod-cm-3
kubectl delete pods pod-secret-1
kubectl delete deploy myapp-deploy
kubectl delete deploy tomcat-deploy
kubectl delete pvc mypvc
kubectl delete pv --all
kubectl delete svc myapp
kubectl delete svc tomcat

  

然后重新生成pv

[root@master volumes]# cat pv-demo.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv001
labels:
name: pv001
spec:
nfs:
path: /data/volumes/v1
server: 172.16.100.64
accessModes: ["ReadWriteMany","ReadWriteOnce"]
capacity:
storage: 5Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv002
labels:
name: pv002
spec:
nfs:
path: /data/volumes/v2
server: 172.16.100.64
accessModes: ["ReadWriteOnce"]
capacity:
storage: 5Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv003
labels:
name: pv003
spec:
nfs:
path: /data/volumes/v3
server: 172.16.100.64
accessModes: ["ReadWriteMany","ReadWriteOnce"]
capacity:
storage: 5Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv004
labels:
name: pv004
spec:
nfs:
path: /data/volumes/v4
server: 172.16.100.64
accessModes: ["ReadWriteMany","ReadWriteOnce"]
capacity:
storage: 5Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv005
labels:
name: pv005
spec:
nfs:
path: /data/volumes/v5
server: 172.16.100.64
accessModes: ["ReadWriteMany","ReadWriteOnce"]
capacity:
storage: 9Gi

  

[root@master stateful]# cat stateful-demo.yaml
apiVersion: v1
kind: Service
metadata:
name: myapp-svc
labels:
app: myapp-svc
spec:
ports:
- port: 80
name: web
clusterIP: None
selector:
app: myapp-pod
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: myapp
spec:
serviceName: myapp-svc
replicas: 2
selector:
matchLabels:
app: myapp-pod
template:
metadata:
labels:
app: myapp-pod
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v1
ports:
- containerPort: 80
name: web
volumeMounts:
- name: myappdata
mountPath: /usr/share/nginx/html
volumeClaimTemplates: #存储卷申请模板,可以为每个pod定义volume;可以为pod所在的名称空间自动创建pvc。
- metadata:
name: myappdata
spec:
accessModes: ["ReadWriteOnce"]
#storageClassName: "gluster-dynamic"
resources:
requests:
storage: 5Gi #2G的pvc

  

[root@master stateful]# kubectl apply -f stateful-demo.yaml
service/myapp-svc unchanged
statefulset.apps/myapp created

  

[root@master stateful]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
myapp-svc ClusterIP None <none> 80/TCP 12m

  

看到myapp-svc是无头服务。

[root@master stateful]# kubectl get sts
NAME DESIRED CURRENT AGE
myapp 2 2 6m

  

[root@master stateful]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
myappdata-myapp-0 Bound pv002 2Gi RWO 3s
myappdata-myapp-1 Bound pv003 1Gi RWO,RWX 1s

  

[root@master stateful]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv001 1Gi RWO,RWX Retain Available 1d
pv002 2Gi RWO Retain Bound default/myappdata-myapp-0 1d
pv003 1Gi RWO,RWX Retain Bound default/myappdata-myapp-1 1d
pv004 1Gi RWO,RWX Retain Bound default/mypvc 1d
pv005 1Gi RWO,RWX Retain Available

  

[root@master stateful]# kubectl get pods
NAME READY STATUS RESTARTS AGE
myapp-0 1/1 Running 0 4m
myapp-1 1/1 Running 0 4m

  

[root@master stateful]# kubectl delete -f stateful-demo.yaml
service "myapp-svc" deleted
statefulset.apps "myapp" deleted

  

上面删除会使pod和service删除,但是pvc是不会删除,所以还能恢复。

[root@master stateful]# kubectl exec -it myapp-0 -- /bin/sh
/ # nslookup myapp-0.myapp-svc.default.svc.cluster.local
nslookup: can't resolve '(null)': Name does not resolve
Name: myapp-0.myapp-svc.default.svc.cluster.local
Address 1: 10.244.1.110 myapp-0.myapp-svc.default.svc.cluster.local
/ #
/ #
/ # nslookup myapp-1.myapp-svc.default.svc.cluster.local
nslookup: can't resolve '(null)': Name does not resolve
Name: myapp-1.myapp-svc.default.svc.cluster.local
Address 1: 10.244.2.97 myapp-1.myapp-svc.default.svc.cluster.local

  

myapp-0.myapp-svc.default.svc.cluster.local

格式为:pod_name.service_name.namespace.svc.cluster.local

下面扩展myapp pod为5个:

[root@master stateful]# kubectl scale sts myapp --replicas=5
statefulset.apps/myapp scaled

  

[root@master stateful]# kubectl get pods
NAME READY STATUS RESTARTS AGE
client 0/1 Error 0 17d
myapp-0 1/1 Running 0 37m
myapp-1 1/1 Running 0 37m
myapp-2 1/1 Running 0 46s
myapp-3 1/1 Running 0 43s
myapp-4 0/1 Pending 0 41s

  

[root@master stateful]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
myappdata-myapp-0 Bound pv002 2Gi RWO 52m
myappdata-myapp-1 Bound pv003 1Gi RWO,RWX 52m
myappdata-myapp-2 Bound pv005 1Gi RWO,RWX 2m
myappdata-myapp-3 Bound pv001 1Gi RWO,RWX 2m
myappdata-myapp-4 Pending 2m

  

另外也可以用patch打补丁的方法来进行扩容和缩容:

[root@master stateful]# kubectl patch sts myapp -p '{"spec":{"replicas":2}}'
statefulset.apps/myapp patched

  

下面我们再来介绍一下滚动更新。

[root@master stateful]# kubectl explain sts.spec.updateStrategy.rollingUpdate

  

假设有4个pod(pod0,pod1,pod2,pod3),如果设置partition为5,那么说明大于等于5的pod更新,我们四个Pod就都不更新;如果partition为4,那么说明大于等于4的pod更新,即pod3更新,其他pod都不更新;如果partiton为3,那么说明大于等于3的pod更新,那么就是pod2和pod3更新,其他pod都不更新。

[root@master stateful]# kubectl patch sts myapp -p '{"spec":{"updateStrategy":{"rollingUpdate":{"partition":4}}}}'
statefulset.apps/myapp patched

  

1.13和视频中partition是不一样,视频版本1.11??出现的是4,1.13.怎么该也不是4显示的是一大串数字。,但是更新是按照上面的策略更新的

[root@master stateful]# kubectl describe sts myapp
Update Strategy: RollingUpdate
Partition: 4

  

下面把myapp升级为v2版本

[root@master stateful]# kubectl set image sts/myapp myapp=ikubernetes/myapp:v2
statefulset.apps/myapp image updated
[root@master ~]# kubectl get sts -o wide
NAME DESIRED CURRENT AGE CONTAINERS IMAGES
myapp 2 2 1h myapp ikubernetes/myapp:v2
[root@master ~]# kubectl get pods myapp-4 -o yaml
containerStatuses:
- containerID: docker://898714f2e5bf4f642e2a908e7da67eebf6d3074c89bbd0d798d191a2061a3115
image: ikubernetes/myapp:v2

  

可以看到pod myapp-4使用的模板版本是v2了。

k8s系列---stateful(有状态应用副本集)控制器的更多相关文章

  1. k8s之statefulSet-有状态应用副本集控制器

    1.概述 无状态应用更关注群体,任何一个成员都可以被取代,有状态应用关注的是个体.用deployment控制器管理的nginx.myapp等都属于无状态应用,像mysql.redis.zookeepe ...

  2. MongoDB基础教程系列--第八篇 MongoDB 副本集实现复制功能

    为什么用复制 为什么要使用复制呢?如果我们的数据库只存在于一台服务器,若这台服务器宕机了,那对于我们数据将会是灾难,当然这只是其中一个原因,若数据量非常大,读写操作势必会影响数据库的性能,这时候复制就 ...

  3. mongodb系列~关于双活状态的mongodb集群

    一简介:说说我们异地双活的集群 二 背景:需要建立异地双活的架构 三 构建 1 需要保证第二机房至少两个副本集DB,这样在第一机房挂掉后才能保证第二机房的可用性 2 集群状态下第二机房启用config ...

  4. MongoDB副本集配置系列二:配置MongoDB副本集

    接上一篇博客: http://www.cnblogs.com/xiaoit/p/4479066.html 1:首先创建3台虚拟机作为配置环境 IP1:192.168.91.128 IP2:192.16 ...

  5. k8s系列----索引

    day1:k8s集群准备搭建和相关介绍 day2:k8spod介绍与创建 day3:k8sService介绍及创建 day4:ingress资源和ingress-controller day5:存储卷 ...

  6. mongodb生产环境(副本集模式)集群搭建配置

    mongodb副本集模式由如下几部分组成: 1.路由实例mongos 2.配置实例configsvr 3.副本集集群replset(一主多从) tips: 1.以上实例都是mongod守护进程 2.以 ...

  7. Mongo--03 mongo副本集、备份与恢复

    目录 一.mongo副本集配置 二.查看副本集状态 三.副本集权重调整 四.创建节点 五.仲裁节点 六.mongo备份与恢复 七.准备测试数据 一.mongo副本集配置 1.创建节点目录和数据目录 # ...

  8. mongodb系列之---副本集配置与说明

    在配置副本集之前,我们先来了解一些关于副本集的知识. 1,副本集的原理 副本集的原理与主从很相似,唯一不同的是,在主节点出现故障的时候,主从配置的从服务器不会自动的变为主服务器,而是要通过手动修改配置 ...

  9. mongoDB系列之(二):mongoDB 副本集

    1. 什么是副本集 副本集就是mongoDB副本所组成的一个集群. 同期原理是,写操作发生在主库,从库同步主库的OpLog日志. 集群中没有特定的主库,主库是选举产生,如果主库down了,会再选举出一 ...

随机推荐

  1. 【LC_Overview1_5】---学会总结回顾

    刷LeetCode题目一周,主要采用C++和Python编程手段,截至目前做了5道简单的leetcode题目,做下阶段性的小结: 小结主要通过手撕代码,复习加回顾,尽量避免自己眼高手低的情况发生,对于 ...

  2. 简单介绍HTTP的请求(get请求和post请求)以及对应的响应的内容

    链接解析: https://oa.hbgf.net.cn/login.jsp;jsessionid=47084322738F8DB18D60752944DFD1AA http或者https表示使用的是 ...

  3. 缓存读写策略 - Cache Aside.md

    场景描述 比如一条数据同时存在数据库.缓存,现在你要更新此数据,你会怎么更新? 先更新数据库?还是先更新缓存? 其实这两种方式都有问题. (1)先更新数据库,后更新缓存 这样会造成数据不一致. A 先 ...

  4. 「 Android开发 」开启第一个App应用

    每天进步一丢丢,连接梦与想 无论什么时候,永远不要以为自己知道一切   -巴普洛夫 最近玩了下Android,但遇到了一些坑,浪费了很多的时间,在此记录一下,你若是遇到了就知道怎么解决了 PS:建议使 ...

  5. rabbitmq 实现延迟队列的两种方式

    原文地址:https://blog.csdn.net/u014308482/article/details/53036770 ps: 文章里面延迟队列=延时队列 什么是延迟队列 延迟队列存储的对象肯定 ...

  6. 学习 lind api 十月 第5弹

    继续 四弹里的 自定义的api response message 但是 那上面的 那些值得也是包含

  7. 2015年3月26日 - Javascript MVC 框架DerbyJS DerbyJS 是一个 MVC 框架,帮助编写实时,交互的应用。

    2015年3月26日 -  Javascript MVC 框架DerbyJS DerbyJS 是一个 MVC 框架,帮助编写实时,交互的应用.

  8. 对于kvm配置ssh

    首先我们要让自己的机器开启ssh服务 首先更新源 sudo apt-get update 安装ssh服务 sudo apt-get install openssh-server 检测是否已启动 ps ...

  9. 从头开始,如何配置一部纯净好用的Windows

    emmm,原因是酱紫的, 鉴于许许多多的人问过我怎么重装系统,装出来的系统干净没有广告什么的, 还有问为什么我的电脑这么卡,是不是要重装系统or更换设备的, 啊,更换设备的土豪请随意

  10. Charles的安装及使用过程

    一.charles的使用 1.1  charles的说明 Charles其实是一款代理服务器,通过过将自己设置成系统(电脑或者浏览器)的网络访问代理服务器,然后截取请求和请求结果达到分析抓包的目的.该 ...