1 statefulset介绍
StatefulSet是Kubernetes提供的管理有状态应用的负载管理控制器API。用于部署和扩展有状态应用的Pod资源,确保它们的运行顺序及每个Pod资源的唯一性。其与ReplicaSet控制器不同的是,虽然所有的Pod对象都基于同一个spec配置所创建,但StatefulSet需要为每个Pod维持一个唯一且固定的标识符,必要时还要为其创建专有的存储卷
StatefulSet适用于具有以下特点的应用:
稳定的持久化存储,即Pod重新调度后还是能访问到相同的持久化数据,基于 PVC来实现。
稳定的网络标识符,即 Pod 重新调度后其 PodName 和 HostName 不变。
有序部署,有序扩展,基于 init containers 来实现。
有序收缩。
Statefulset的启停顺序:
有序部署:部署StatefulSet时,如果有多个Pod副本,它们会被顺序地创建(从0到N-1)并且,在下一个Pod运行之前所有之前的Pod必须都是Running和Ready状态。
有序删除:当Pod被删除时,它们被终止的顺序是从N-1到0。
有序扩展:当对Pod执行扩展操作时,与部署一样,它前面的Pod必须都处于Running和Ready状态。
一个完整的StatefulSet控制器需要由一个Headless Service、一个StatefulSet和一个volumeClaimTemplate组成。
HeadlessService用于为Pod资源标识符生成可解析的DNS资源记录,
StatefulSet用于管控Pod资源
volumeClaimTemplate则基于静态或动态的PV供给方式为Pod资源提供专有且固定的存储
为什么要有headless??
在deployment中,每一个pod是没有名称,是随机字符串,是无序的。而statefulset中是要求有序的,每一个pod的名称必须是固定的。当节点挂了,重建之后的标识符是不变的,每一个节点的节点名称是不能改变的。pod名称是作为pod识别的唯一标识符,必须保证其标识符的稳定并且唯一。为了实现标识符的稳定,这时候就需要一个headless service 解析直达到pod,还需要给pod配置一个唯一的名称。
为什么要有volumeClainTemplate??
大部分有状态副本集都会用到持久存储,比如分布式系统来说,由于数据是不一样的,每个节点都需要自己专用的存储节点。而在deployment中pod模板中创建的存储卷是一个共享的存储卷,多个pod使用同一个存储卷,而statefulset定义中的每一个pod都不能使用同一个存储卷,由此基于pod模板创建pod是不适应的,这就需要引入volumeClainTemplate,当在使用statefulset创建pod时,会自动生成一个PVC,从而请求绑定一个PV,从而有自己专用的存储卷。
2 创建StatefulSet
2.1 创建Headless Service资源
定义了一个名为headless-svc的Headless Service资源,用于为关联到的每个Pod资源创建DNS资源记录。
[root@k8s-master01 statefulset]# cat headless-service.yaml
apiVersion: v1
kind: Service
metadata:
name: headless-svc
labels:
app: headless-svc
spec:
ports:
- port: 80
name: web
clusterIP: None
selector:
app: nginx-statefulset-pod
创建headless service
[root@k8s-master01 statefulset]# kubectl apply -f headless-service.yaml
service/headless-svc created
2.2 创建StatefulSet资源,且绑定到pod上
[root@k8s-master01 statefulset]# cat statefulset.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: nginx
spec:
serviceName: headless-svc
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.16
ports:
- containerPort: 80
name: web
volumeMounts:
- name: myappdata
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: myappdata
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: "managed-nfs-storage"
resources:
requests:
storage: 2Gi
结果
[root@k8s-master01 statefulset]# kubectl get pods --show-labels
NAME READY STATUS RESTARTS AGE LABELS
nginx-0 1/1 Running 0 99s app=nginx,controller-revision-hash=nginx-68ffb85f97,statefulset.kubernetes.io/pod-name=nginx-0
nginx-1 1/1 Running 0 98s app=nginx,controller-revision-hash=nginx-68ffb85f97,statefulset.kubernetes.io/pod-name=nginx-1
nginx-2 1/1 Running 0 96s app=nginx,controller-revision-hash=nginx-68ffb85f97,statefulset.kubernetes.io/pod-name=nginx-2
查看pvc
[root@k8s-master01 statefulset]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
myappdata-nginx-0 Bound pvc-661eccd0-bece-4877-938b-142adedca670 2Gi RWO managed-nfs-storage 3h20m
myappdata-nginx-1 Bound pvc-05a84369-2254-4a4c-9aa3-a9abc3d5332e 2Gi RWO managed-nfs-storage 3h20m
myappdata-nginx-2 Bound pvc-30a33ecf-9b83-4850-96d4-0c5959f92f9f 2Gi RWO managed-nfs-storage 3h19m
[root@k8s-master01 statefulset]# kubectl get statefulset
NAME READY AGE
nginx 3/3 3m58s
验证Pod资源的专有存储卷
[root@k8s-master01 statefulset]# kubectl exec -it nginx-0 sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl kubectl exec [POD] -- [COMMAND] instead.
# cd /usr/share/nginx/html
# ls
# pwd
/usr/share/nginx/html
# touch 111
# ls
111
查看nfs上
[root@k8s-node01 k8s-volume]# cd default-myappdata-nginx-0-pvc-661eccd0-bece-4877-938b-142adedca670
[root@k8s-node01 default-myappdata-nginx-0-pvc-661eccd0-bece-4877-938b-142adedca670]# ll
总用量 0
-rw-r--r-- 1 root root 0 4月 22 19:54 111
2.3 statefulset资源扩容
将myapp中的Pod副本数量扩展至5个:
[root@k8s-master01 statefulset]# kubectl scale statefulset nginx --replicas=5
statefulset.apps/nginx scaled
[root@k8s-master01 statefulset]# kubectl get pods
NAME READY STATUS RESTARTS AGE
busybox 1/1 Running 0 11m
hostpathtest 1/1 Running 2 14d
nfs-client-provisioner-794b747b95-27xmj 1/1 Running 0 4h35m
nginx-0 1/1 Running 0 11m
nginx-1 1/1 Running 0 11m
nginx-2 1/1 Running 0 11m
nginx-3 0/1 ContainerCreating 0 2s
执行缩容操作只需要将其副本数量调低即可
[root@k8s-master01 statefulset]# kubectl patch statefulset nginx -p '{"spec":{"replicas":3}}'
statefulset.apps/nginx patched
[root@k8s-master01 statefulset]# kubectl get pods
NAME READY STATUS RESTARTS AGE
busybox 1/1 Running 0 14m
hostpathtest 1/1 Running 2 14d
nfs-client-provisioner-794b747b95-27xmj 1/1 Running 0 4h38m
nginx-0 1/1 Running 0 14m
nginx-1 1/1 Running 0 14m
nginx-2 1/1 Running 0 14m
nginx-3 1/1 Running 0 3m13s
nginx-4 0/1 Terminating 0 3m10s
- 我的微信
- 这是我的微信扫一扫
- 我的微信公众号
- 我的微信公众号扫一扫