文章目录
- 实验环境
- 一、StatefulSet介绍
- 二、实验
实验环境
完成初始化集群的环境:
(vms21)192.168.26.21——master1
(vms22)192.168.26.22——worker1
(vms23)192.168.26.23——worker2
一、StatefulSet介绍
StatefulSet——简称sts,它也是一种控制器,是有状态的(stateful),与之对应的是无状态(stateless)的deployment
回顾deployment控制器,它部署的应用是无状态的:
1.所有pod副本没有任何不同
2.pod的名字是随机生成的
3.不存储数据
4.即使存储数据,那么所有pod也是共享数据
stateless——对于无状态来说,我们一般用来对外提供服务,用户访问svc,svc关联后端的pod副本,用户访问流量无论转发到哪个pod,访问的结果都是一样的
stateful——对于有状态来说,适用于内部的一些应用
如在公司内部,有一个MySQL master、三个pod分为作为slave1、slave2、slave3,salve复制master上的数据,并且每个slave上都有自己独立的数据(如每个slave都有自己的binlog二进制日志),即使把某个slave删除了,重新创建这个pod,那么它关联的还是原来的那个数据
如下图,deployment与StatefulSet的区别:
在StatefulSet中,如上图,每个slave访问的后端存储都是不一样的,若是访问slave1,则访问的是data1的数据,因此,给各个slave配置一个svc负载均衡器是没有意义的,但是用户直接访问这个pod(这里即slave)也是不好的,因为只要是控制器管理了pod,pod一旦被删除,控制器就会去重新创建它,自然IP地址肯定也是变化了的,所以不好直接访问pod
因此我们可以创建一种叫做headless service无头服务
headless service(无头服务)
什么是无头服务?——对于每个svc来说,它们都有一个ClusterIP,所谓无头服务就是不给它指定ClusterIP
访问pod的时候,就通过一种格式:pod名字.svc名字
来访问,如:slave1.svc1
二、实验
在官方文档中搜索StatefulSet:https://kubernetes.io/docs/home/
分析文档中的sts模板
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:
serviceName: "nginx"
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: k8s.gcr.io/nginx-slim:0.8
ports:
- containerPort: 80
name: web
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: www
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 1Gi
“- - -”上下划分了Service(无头服务)和StatefulSet
Service中:
可以看到clusterIP配置成了None
spec.selector——配置Service要关联到哪些pod
StatefulSet中:
spec.serviceName——通过名字来关联svc,因此这里的名字要和上面Service中的metadata中的名字一致
spec.selector.matchLabels——要定位到哪些pod
volumeClaimTemplates——因为StatefulSet中每个pod都有自己独立的数据,因此有了这项来定义卷的模板
volumeClaimTemplates.spec.accessModes——使用的卷的格式
volumeClaimTemplates.spec下可以配置动态卷供应,可以使用storageClassName配置
1.根据模板创建yaml文件mysts1.yaml
并在其中作一些修改:
StatefulSet的名字改为mysts1
修改pod使用nginx镜像,并加上镜像拉取策略IfNotPresent
在卷模板下配置动态卷供应,使用之前创建的mysc,会为每个pod创建一个pvc出来
修改后为:
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: mysts1
spec:
serviceName: "nginx"
replicas: 2
selector:
matchLabels:
app: nginx
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:
storageClassName: mysc
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 1Gi
2.根据之前实验中创建好的sc(若没有则参考六、存储管理-动态卷供应部分内容创建)
查看环境中的sc
kubectl get sc
#输出:
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
mysc k8s-sigs.io/nfs-subdir-external-provisioner Delete Immediate false 3m5s
此时环境中没有pv、pvc
kubectl get pv
#输出:
No resources found
kubectl get pvc
#输出:
No resources found in default namespace.
3.创建StatefulSet
kubectl apply -f mysts1.yaml
4.查看服务
kubectl get svc
#输出:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx ClusterIP None <none> 80/TCP 16s
可以看到帮我们创建了一个名为nginx、CLUSTER-IP为None的svc
5.查看sts
kubectl get sts
#输出:
NAME READY AGE
mysts1 2/2 50s
有两个pod副本
kubectl get pods
#输出:
NAME READY STATUS RESTARTS AGE
mysts1-0 1/1 Running 0 1m
mysts1-1 1/1 Running 0 1m
同时,查看pvc、pv,可以看到自动帮我们创建了两个pvc与两个pv,即各自都有自己独立的数据
kubectl get pvc
kubectl get pv
6.进入pod中编辑index.html内容
kubectl exec -it mysts1-0 -- sh -c "echo 111 > /usr/share/nginx/html/index.html"
kubectl exec -it mysts1-1 -- sh -c "echo 222 > /usr/share/nginx/html/index.html"
7.测试此时删除mysts1-0这个pod,删除后,sts会帮我们重新创建这个pod,并且pod名字还是mysts1-0
kubectl get pods
#输出:
NAME READY STATUS RESTARTS AGE
mysts1-0 0/1 ContainerCreating 0 14s
mysts1-1 1/1 Running 0 3m2s
并且mysts1-0的数据存储还是原来的
进入mysts1-0查看index.html内容,仍然是111
kubectl exec -it mysts1-0 -- sh -c "cat /usr/share/nginx/html/index.html"
#输出:
111
8.哪么要怎么访问sts这个服务呢?
注意:无法直接在宿主机中访问
我们通过创建一个pod,在pod里去测试访问
创建一个pod1,pod1.yaml如下:
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: pod1
name: pod1
spec:
terminationGracePeriodSeconds: 0
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: pod1
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
创建这个pod
kubectl apply -f pod1.yaml
在pod测试访问sts,通过pod名.svc名来访问
kubectl exec -it pod1 -- bash
curl mysts1-0.nginx
#输出:
111
9.删除该sts
kubectl delete -f mysts1.yaml