# StatefulSet - 有状态的服务,http无状态,但是应用有状态
# 为了便于数据共享,此处我们使用nfs挂载
# 配置10.0.0.58 nfs server
[16:21:04 root@nfs nfs-data]#echo "/nfs-data/v1 *(rw,no_root_squash,sync)" >> /etc/exports
[16:21:39 root@nfs nfs-data]#echo "/nfs-data/v2 *(rw,no_root_squash,sync)" >> /etc/exports
[16:21:43 root@nfs nfs-data]#echo "/nfs-data/v3 *(rw,no_root_squash,sync)" >> /etc/exports
[16:21:45 root@nfs nfs-data]#echo "/nfs-data/v4 *(rw,no_root_squash,sync)" >> /etc/exports
[16:21:57 root@nfs nfs-data]#systemctl restart nfs-kernel-server.service
[16:22:07 root@nfs nfs-data]#exportfs
/nfs-data <world>
/nfs-data/v1 <world>
/nfs-data/v2 <world>
/nfs-data/v3 <world>
/nfs-data/v4 <world>
# 在主节点查看
[16:22:42 root@master1 storage]#showmount -e 10.0.0.58
Export list for 10.0.0.58:
/nfs-data/v4 *
/nfs-data/v3 *
/nfs-data/v2 *
/nfs-data/v1 *
/nfs-data *
# 开始pv和svc的资源文件
[16:22:43 root@master1 storage]#cat 25-storage-statefulset-pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv001
spec:
nfs:
path: /nfs-data/v1
server: 10.0.0.58
accessModes: ["ReadWriteOnce"]
capacity:
storage: 1Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv002
spec:
nfs:
path: /nfs-data/v2
server: 10.0.0.58
accessModes: ["ReadWriteOnce"]
capacity:
storage: 1Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv003
spec:
nfs:
path: /nfs-data/v3
server: 10.0.0.58
accessModes: ["ReadWriteOnce"]
capacity:
storage: 2Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv004
spec:
nfs:
path: /nfs-data/v4
server: 10.0.0.58
accessModes: ["ReadWriteOnce"]
capacity:
storage: 2Gi
---
apiVersion: v1
kind: Service
metadata:
name: statefulset-headless
spec:
ports:
- port: 80
clusterIP: None
selector:
app: myapp-pod
[16:24:49 root@master1 storage]#kubectl apply -f 25-storage-statefulset-pv.yaml
persistentvolume/pv001 created
persistentvolume/pv002 created
persistentvolume/pv003 created
persistentvolume/pv004 created
service/statefulset-headless created
[16:24:56 root@master1 storage]#kubectl get all -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 7d16h <none>
service/statefulset-headless ClusterIP None <none> 80/TCP 5s app=myapp-pod
[16:25:01 root@master1 storage]#kubectl get pv -o wide
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE VOLUMEMODE
pv001 1Gi RWO Retain Available 12s Filesystem
pv002 1Gi RWO Retain Available 12s Filesystem
pv003 2Gi RWO Retain Available 12s Filesystem
pv004 2Gi RWO Retain Available 12s Filesystem
# 开始配置statefulset资源文件
[16:25:49 root@master1 storage]#cat 26-storage-statefulset-test.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: myapp
spec:
serviceName: statefulset-headless
replicas: 3
selector:
matchLabels:
app: myapp-pod
template:
metadata:
labels:
app: myapp-pod
spec:
containers:
- name: myapp
image: 10.0.0.55:80/mykubernetes/nginx:1.21.3
volumeMounts:
- name: myappdata
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: myappdata
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 1Gi
[16:25:53 root@master1 storage]#kubectl apply -f 26-storage-statefulset-test.yaml
statefulset.apps/myapp created
[16:27:36 root@master1 storage]#kubectl get all -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/myapp-0 1/1 Running 0 6s 10.244.4.5 node2.noisedu.cn <none> <none>
pod/myapp-1 0/1 ContainerCreating 0 2s <none> node1.noisedu.cn <none> <none>
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 7d16h <none>
service/statefulset-headless ClusterIP None <none> 80/TCP 2m46s app=myapp-pod
NAME READY AGE CONTAINERS IMAGES
statefulset.apps/myapp 1/3 6s myapp 10.0.0.55:80/mykubernetes/nginx:1.21.3
# 查看pod创建状态,按顺序创建
[16:27:42 root@master1 storage]#kubectl get all -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/myapp-0 1/1 Running 0 9s 10.244.4.5 node2.noisedu.cn <none> <none>
pod/myapp-1 1/1 Running 0 5s 10.244.3.8 node1.noisedu.cn <none> <none>
pod/myapp-2 0/1 ContainerCreating 0 1s <none> node1.noisedu.cn <none> <none>
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 7d16h <none>
service/statefulset-headless ClusterIP None <none> 80/TCP 2m49s app=myapp-pod
NAME READY AGE CONTAINERS IMAGES
statefulset.apps/myapp 2/3 9s myapp 10.0.0.55:80/mykubernetes/nginx:1.21.3
[16:27:45 root@master1 storage]#kubectl get all -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/myapp-0 1/1 Running 0 12s 10.244.4.5 node2.noisedu.cn <none> <none>
pod/myapp-1 1/1 Running 0 8s 10.244.3.8 node1.noisedu.cn <none> <none>
pod/myapp-2 1/1 Running 0 4s 10.244.3.9 node1.noisedu.cn <none> <none>
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 7d16h <none>
service/statefulset-headless ClusterIP None <none> 80/TCP 2m52s app=myapp-pod
NAME READY AGE CONTAINERS IMAGES
statefulset.apps/myapp 3/3 12s myapp 10.0.0.55:80/mykubernetes/nginx:1.21.3
# 查看pv和pvc状态
[16:27:53 root@master1 storage]#kubectl get pv,pvc -o wide
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE VOLUMEMODE
persistentvolume/pv001 1Gi RWO Retain Bound default/myappdata-myapp-0 3m12s Filesystem
persistentvolume/pv002 1Gi RWO Retain Bound default/myappdata-myapp-1 3m12s Filesystem
persistentvolume/pv003 2Gi RWO Retain Bound default/myappdata-myapp-2 3m12s Filesystem
persistentvolume/pv004 2Gi RWO Retain Available 3m12s Filesystem
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE VOLUMEMODE
persistentvolumeclaim/myappdata-myapp-0 Bound pv001 1Gi RWO 32s Filesystem
persistentvolumeclaim/myappdata-myapp-1 Bound pv002 1Gi RWO 28s Filesystem
persistentvolumeclaim/myappdata-myapp-2 Bound pv003 2Gi RWO 24s Filesystem
# 删除也会按顺序删除,同时pv和pvc不会丢失
[16:28:08 root@master1 storage]#kubectl delete -f 26-storage-statefulset-test.yaml
statefulset.apps "myapp" deleted
[16:35:33 root@master1 storage]#kubectl get pv,pvc -o wide
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE VOLUMEMODE
persistentvolume/pv001 1Gi RWO Retain Bound default/myappdata-myapp-0 10m Filesystem
persistentvolume/pv002 1Gi RWO Retain Bound default/myappdata-myapp-1 10m Filesystem
persistentvolume/pv003 2Gi RWO Retain Bound default/myappdata-myapp-2 10m Filesystem
persistentvolume/pv004 2Gi RWO Retain Available 10m Filesystem
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE VOLUMEMODE
persistentvolumeclaim/myappdata-myapp-0 Bound pv001 1Gi RWO 8m1s Filesystem
persistentvolumeclaim/myappdata-myapp-1 Bound pv002 1Gi RWO 7m57s Filesystem
persistentvolumeclaim/myappdata-myapp-2 Bound pv003 2Gi RWO 7m53s Filesystem
# 再次创建,pod和svc等名字始终同第一次一样
[16:36:30 root@master1 storage]#kubectl get all -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/myapp-0 1/1 Running 0 10s 10.244.3.10 node1.noisedu.cn <none> <none>
pod/myapp-1 1/1 Running 0 8s 10.244.4.6 node2.noisedu.cn <none> <none>
pod/myapp-2 1/1 Running 0 6s 10.244.4.7 node2.noisedu.cn <none> <none>
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 7d17h <none>
service/statefulset-headless ClusterIP None <none> 80/TCP 11m app=myapp-pod
NAME READY AGE CONTAINERS IMAGES
statefulset.apps/myapp 3/3 10s myapp 10.0.0.55:80/mykubernetes/nginx:1.21.3