k8s基础入门之有状态应用部署StatefulSet

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

  • 我的微信
  • 这是我的微信扫一扫
  • weinxin
  • 我的微信公众号
  • 我的微信公众号扫一扫
  • weinxin
avatar

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: