k8s部署-47-StatefulSet的学习
2022-04-30 本文已影响0人
运维家

我们之前的都是一些无状态的应用,使用的也都是deployment,其次,也是没有启动顺序的,接下来我们就来看下有状态的应用是应该如何进行的,比如说zookeeper、etcd都等类似的服务。

1StatefulSet
它主要有以下两种特性:
1、性
比如说后面启动的服务,需要访问前面的服务
2、持久存储区分
比如说数据库之类,不止需要顺序性,而且需要数据持久存储的需要;
2创建service
在这里我们是headless-server,他是没有具体的IP地址的,是使用域名的方式来访问的,看下;
[root@node1 ~]# cd namespace/
[root@node1 namespace]# mkdir statefulset
[root@node1 namespace]# cd statefulset/
[root@node1 statefulset]# cat headless-service.yaml
apiVersion: v1
kind: Service
metadata:
name: springboot-web-svc
spec:
ports:
- port: 80
targetPort: 8080
protocol: TCP
clusterIP: None
selector:
app: springboot-web
[root@node1 statefulset]#
[root@node1 statefulset]# kubectl apply -f headless-service.yaml
service/springboot-web-svc created
[root@node1 statefulset]# kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.233.0.1 <none> 443/TCP 2m5s
springboot-web-svc ClusterIP None <none> 80/TCP 7s
[root@node1 statefulset]#
3创建pod
在这里我们创建pod的时候,有一个参数是serviceName,这里我们要写上上面service的名字;
[root@node1 statefulset]# vim statefulset.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: springboot-web
spec:
serviceName: springboot-web-svc
replicas: 2
selector:
matchLabels:
app: springboot-web
template:
metadata:
labels:
app: springboot-web
spec:
containers:
- name: springboot-web
image: registry.cn-beijing.aliyuncs.com/yunweijia0909/springboot-web:v1
ports:
- containerPort: 8080
livenessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 20
periodSeconds: 10
failureThreshold: 3
successThreshold: 1
timeoutSeconds: 5
readinessProbe:
httpGet:
path: /hello?name=test
port: 8080
scheme: HTTP
initialDelaySeconds: 20
periodSeconds: 10
failureThreshold: 1
successThreshold: 1
timeoutSeconds: 5
[root@node1 statefulset]#
[root@node1 statefulset]# kubectl apply -f statefulset.yaml
statefulset.apps/springboot-web created
[root@node1 statefulset]#
然后我们使用-w参数,实施跟踪下pod的变化;
[root@node1 statefulset]# kubectl get pod -o wide -w
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
springboot-web-0 0/1 Running 0 8s 10.200.135.6 node3 <none> <none>
springboot-web-0 1/1 Running 0 26s 10.200.135.6 node3 <none> <none>
springboot-web-1 0/1 Pending 0 0s <none> <none> <none> <none>
springboot-web-1 0/1 Pending 0 0s <none> node3 <none> <none>
springboot-web-1 0/1 ContainerCreating 0 0s <none> node3 <none> <none>
springboot-web-1 0/1 ContainerCreating 0 1s <none> node3 <none> <none>
springboot-web-1 0/1 Running 0 1s 10.200.135.5 node3 <none> <none>
springboot-web-1 1/1 Running 0 22s 10.200.135.5 node3 <none> <none>
^C
[root@node1 statefulset]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
springboot-web-0 1/1 Running 0 64s 10.200.135.6 node3 <none> <none>
springboot-web-1 1/1 Running 0 38s 10.200.135.5 node3 <none> <none>
[root@node1 statefulset]#
从上面可以看到,是当springboot-web-0启动完毕,且通过健康检查之后,springboot-web-1才开始启动的,这就是我们的顺序性;
4小操作一下子
从上面可以看到,两个pod都运行在了node3上,然后我们登录到node3上去看看;
[root@node3 ~]# crictl ps | grep springboot-web
e0019775cca37 8ad32427177e4 5 minutes ago Running springboot-web 0 add1689b2e708
d11c9c74bd1ba 8ad32427177e4 5 minutes ago Running springboot-web 0 7748dbde4cd47
[root@node3 ~]# crictl exec -it e0019775cca37 bash
root@springboot-web-1:/# hostname
springboot-web-1
root@springboot-web-1:/# exit
[root@node3 ~]# crictl exec -it d11c9c74bd1ba bash
root@springboot-web-0:/# hostname
springboot-web-0
root@springboot-web-0:/# exit
[root@node3 ~]#
可以看到主机名,一个是0,一个是1;
那么,我们如何访问到另一个pod呢?规则是如下
PodName.ServiceName.Namespace
例如:
root@springboot-web-0:/# curl springboot-web-1.springboot-web-svc.default:8080/hello?name=yunweijia;echo ""
Hello yunweijia! I'm springboot-web-demo controller!
root@springboot-web-0:/#
亦或者,自己访问自己;
root@springboot-web-0:/# curl springboot-web-0.springboot-web-svc.default:8080/hello?name=yunweijia;echo ""
Hello yunweijia! I'm springboot-web-demo controller!
root@springboot-web-0:/#
当然了,由于我们的命名空间是default,那么忽略不写也是可以的,如下:
5持久存储 首先我们要声明,上一篇中,由于系统资源的不足,我们没有成功创建GlusterFS,但是这里持久化存储要用到GlusterFS,所以只写过程,结果就不展示了;root@springboot-web-0:/# curl springboot-web-1.springboot-web-svc:8080/hello?name=yunweijia;echo ""
Hello yunweijia! I'm springboot-web-demo controller!
root@springboot-web-0:/# curl springboot-web-0.springboot-web-svc:8080/hello?name=yunweijia;echo ""
Hello yunweijia! I'm springboot-web-demo controller!
root@springboot-web-0:/#
这里的不同之处是volumeClaimTemplates,他会自动创建pvc,需要注意一下;然后运行一下;# 先把上面的资源删除
[root@node1 statefulset]# kubectl delete -f statefulset.yaml
statefulset.apps "springboot-web" deleted
[root@node1 statefulset]#
# 然后创建内容如下
[root@node1 statefulset]# vim statefulset-volume.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: springboot-web
spec:
serviceName: springboot-web-svc
replicas: 2
selector:
matchLabels:
app: springboot-web
template:
metadata:
labels:
app: springboot-web
spec:
containers:
- name: springboot-web
image: registry.cn-beijing.aliyuncs.com/yunweijia0909/springboot-web:v1
ports:
- containerPort: 8080
livenessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 20
periodSeconds: 10
failureThreshold: 3
successThreshold: 1
timeoutSeconds: 5
readinessProbe:
httpGet:
path: /hello?name=test
port: 8080
scheme: HTTP
initialDelaySeconds: 20
periodSeconds: 10
failureThreshold: 1
successThreshold: 1
timeoutSeconds: 5
volumeMounts:
- name: data
mountPath: /yunweijia-data
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes:
- ReadWriteOnce
storageClassName: glusterfs-storage-class
resources:
requests:
storage: 1Gi
[root@node1 statefulset]#