k8s_day_06_04
Stateless 无状态应用
一次请求和它相应组成了完整事务,它们不受完成的连接或者现有其他连接的影响,彼此之间没有影响,并且意外中断或者关闭的时候,只要reset 连接就能重新连接就可以了。无状态 pod 示例可以同一模板创建的其他实例无缝取代
Stateful 有状态应用:StatefulSet
区别: 多个实例彼此间能否互相取代:
指的是每次客户端连接,都在先前事务的上下文中执行,而且还有可能会受到上下文影响,当连接中断时,上下文和事务可能会被存储,一边再次连接时恢复现场。 但凡是 和数据存储、事务处理相关的应用几乎都是 有状态应用。
StatefulSet : 是做通用的有状态控制器。因为大多数有状态的应用管理方式有些,StatefulSet只能做到以下2件事情:
-
每个Pod都有自己的惟一标识,故障时,它只能被拥有同一标识的新实例所取代;
格式为${STATEFULSET_NAME}-${ORDINAL}, 比如具体的实例名称为 web-0, web-1, web-2 依次创建。
使用Headless Service 标识来确保pod-ip 能反解析到唯一的pod名称 之上。headless 的作用就是让 stateful的每个个体都有唯一被识别的固定名称。 -
如果有必要,可以为被Pod配置专用的存储卷,且只能是PVC格式;通过卷模板实现
在deployments 的模板上,如果定义了存储卷,那么会被多个replicas 所共享。因为所有副本是基于同一个模板创建的 ,并且只创建了一个存储卷。
operator
如果StatefulSet只能为应用做以上2种事情,那么它的使用场景太有限了。或者准确的来说,用StatefulSet 来管理应用基本没有可能。比如管理mysql 主从复制集群,当新增从节点时,仅仅提供唯一标识和存储是不够的,还要指明复制的位置等等。
时到如今, StatefulSet 已经不被待见和使用了。只能作为基础被使用了
应该使用Operator来管理有状态应用:
https://github.com/operator-framework/awesome-operators
StatefulSet配置规范:
apiVersion: apps/v1 # API群组及版本;
kind: StatefulSet # 资源类型的特有标识
metadata:
name <string> # 资源名称,在作用域中要唯一
namespace I <string> # 名称空间;StatefulSet隶属名称空间级别
spec:
replicas <integer> # 期望的Pod副本数,默认为1
selector <object> # 标签选择器,须匹配Pod模板中的标签,必选字段
template <object> # Pod模板对象,必选字段
revisionHistoryLimit <integer> # 滚动更新历史记录数量,默认为10
updateStrategy <Object> # 滚动更新策略
type <string> # 滚动更新类型,可用值有OnDelete和Rollingupdate
rollingUpdate <Object> # 滚动更新参数,专用于RollingUpdate类型
partition <integer> # 分区指示索引值,默认为0
serviceName <string> # 相关的Headless Service的名称,必选字段
volumeClaimTemplates <[]Object> # 存储卷申请模板
apiVersion <string> # PVC资源所属的API群组及版本,可省略
kind <string> # PVC资源类型标识,可省略
metadata <Object> # 卷申请模板元数据
spec <Object> # 期望的状态,可用字段同PVC
podManagementPolicy <string> # Pod管理策略,默认的“OrderedReady”表示顺序创
#建并逆序删除,另一可用值“Parallel”表示并行模式
滚动更新的partition 指的是 pod 编号, 更新时只更新大于编号的的pod, 只能逆序,先减后加,类似金丝雀发布
podManagementPolicy: 指的是 pod 管理策略, 默认是根据编号顺序管理增添,Parallel 表示可以同时进行, 比如zookeeper ,这种内部无主次之分 或者靠选举 产生的主次可以 同时被创建
[root@node01 chapter8]# cat demodb.yaml
# demodb ,an educational Kubernetes-native NoSQL data store. It is a distributed
# key-value store, supporting permanent read and write operations.
# Environment Variables: DEMODB_DATADIR, DEMODB_HOST, DEMODB_PORT
# default port: 9907/tcp for clients, 9999/tcp for members.
# Maintainter: MageEdu <mage@magedu.com>
---
apiVersion: v1
kind: Service
metadata:
name: demodb
namespace: default
labels:
app: demodb
spec:
clusterIP: None
ports:
- port: 9907
selector:
app: demodb
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: demodb
namespace: default
spec:
selector:
matchLabels:
app: demodb
serviceName: "demodb"
replicas: 3
template:
metadata:
labels:
app: demodb
spec:
containers:
- name: demodb-shard
image: ikubernetes/demodb:v0.2
ports:
- containerPort: 9907
name: db
env:
- name: DEMODB_DATADIR
value: "/demodb/data"
livenessProbe:
initialDelaySeconds: 2
periodSeconds: 10
httpGet:
path: /status
port: db
readinessProbe:
initialDelaySeconds: 15
periodSeconds: 30
httpGet:
path: /status?level=full
port: db
volumeMounts:
- name: data
mountPath: /demodb/data
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: "longhorn"
resources:
requests:
storage: 2Gi
[root@node01 chapter8]#
查看 sts
[root@node01 chapter8]# kubectl get po -l app=demodb
NAME READY STATUS RESTARTS AGE
demodb-0 1/1 Running 0 4m4s
demodb-1 1/1 Running 0 2m43s
demodb-2 1/1 Running 0 116s
[root@node01 chapter8]# kubectl get sts
NAME READY AGE
demodb 3/3 4m12s
根据创建的age 可以判断创建的先后次序
[root@node01 chapter8]# kubectl get po -l app=demodb
NAME READY STATUS RESTARTS AGE
demodb-0 1/1 Running 0 4m14s
demodb-1 1/1 Running 0 2m53s
demodb-2 1/1 Running 0 2m6s
[root@node01 chapter8]#
验证解析:
A 记录解析 service 名称得到的 是 3个pod地址(而不是clustip 因为不存在clsuter-ip)
PTR 解析pod 地址得到的是 固定节点名称+ service 名称
root@pod-11729 # nslookup -query=A demodb
Server: 10.96.0.10
Address: 10.96.0.10#53
Name: demodb.default.svc.cluster.local
Address: 10.244.1.130
Name: demodb.default.svc.cluster.local
Address: 10.244.2.115
Name: demodb.default.svc.cluster.local
Address: 10.244.3.66
root@pod-11729 # nslookup -query=PTR 10.244.1.130
Server: 10.96.0.10
Address: 10.96.0.10#53
130.1.244.10.in-addr.arpa name = demodb-0.demodb.default.svc.cluster.local.
demodbd 数据库的使用
root@pod-11729 # echo "www.magedu.com" >/tmp/data
root@pod-11729 # curl -L -XPUT -T /tmp/data http://demodb:9907/set/data
WRITE completedroot@pod-11729 #
root@pod-11729 # curl http://demodb:9907/get/data
www.magedu.com
验证 sts 滚动逆序更新
[root@node01 chapter8]# kubectl get sts -o wide
NAME READY AGE CONTAINERS IMAGES
demodb 3/3 33m demodb-shard ikubernetes/demodb:v0.2
[root@node01 chapter8]#
当前版本是0.2 把它更新为0.1
配置清单改版本 、set image 都行 patch 打补丁都行
发现是由编号大的版本先开始更新
如果partion 设置为2 则只会更新第3个(>2)
[root@node01 ~]# kubectl apply -f demodb.yaml
[root@node01 ~]# kubectl get po -l app=demodb
NAME READY STATUS RESTARTS AGE
demodb-0 1/1 Running 0 36m
demodb-1 1/1 Running 0 34m
demodb-2 0/1 ContainerCreating 0 32s
sts 扩容
[root@node01 chapter8]# kubectl patch sts/demodb -p '{"spec":{"replicas":5}}'
statefulset.apps/demodb patched
[root@node01 chapter8]# kubectl get po -l app=demodb -w
NAME READY STATUS RESTARTS AGE
demodb-0 1/1 Running 0 9m21s
demodb-1 1/1 Running 0 10m
demodb-2 1/1 Running 0 12m
demodb-3 0/1 Running 0 31s
demodb-4 0/1 ContainerCreating 0 7s
验证结果 : 扩展顺序是正序 demodb-2 开始 从小往大扩展 顺序。 同理缩容恰恰相反
longhorn 支持多路读写
longhorn 的默认存储类 它所提供的存储设备 是以块级别接口对外输出的,而不是文件系统级别, 因此它只支持单路读写。如果同时写可能会出现问题。longhorn 为我们提供了解决方案 ,在longhorn上层添加nfs
如图 通过基础的 sc 插件创建出一块pvc ,这个pvc 用于 给nfs pod 用。 然后 这个nfs pod 再把它的pvc
当成一整块磁盘, 分别切割 为/data/dir1 /data/dir2 等等给 用户拿出去当pv 用。 用户使用 longhorn-nfs 得到的pv ,实际上是共享一整块pvc 默认20G
如sts/demodb 申请使用的磁盘是2G ,有3个副本, 那么在系统中 就会有4个。 3个是用户的pod 副本的pvc ,一个long-nfs 申请的系统pvc
[root@node01 chapter8]# kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-402583b0-5020-4e79-8b56-927ecf852fb2 2Gi RWO Delete Bound default/data-demodb-2 longhorn 98m pvc-6f5cab83-43bb-43d5-b7f3-01a1880725ec 2Gi RWO Delete Bound default/data-demodb-1 longhorn 99m pvc-ab203634-4009-46c1-bd5f-74871ee1cdd9 2Gi RWO Delete Bound default/data-demodb-0 longhorn 100m pvc-d7fb4eab-2c72-4ec7-a087-4dbf35440fc5 19Gi RWO Delete Bound longhorn-system/longhorn-nfs-provisioner longhorn 105m [root@node01 chapter8]#
wget https://raw.githubusercontent.com/longhorn/longhorn/v1.0.2/examples/rwx/01-security.yaml --no-check-certificate
wget https://raw.githubusercontent.com/longhorn/longhorn/v1.0.2/examples/rwx/02-longhorn-nfs-provisioner.yaml --no-check-certificate
把 02-longhorn-nfs-provisioner.yaml ServiceAccount的clusterIP 改为和service 网段一样就行
如:10.96.111.111
[root@node01 ~]# yum install iscsi-initiator-utils
[root@node01 ~]# kubectl apply -f 01-security.yaml
[root@node01 ~]# kubectl apply -f 02-longhorn-nfs-provisioner.yaml
验证结果
[root@node01 ~]# kubectl get storageclass/longhorn-nfs
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
longhorn-nfs nfs.longhorn.io Delete Immediate false 3m33s
[root@node01 ~]#