K8S 之 通过Statefulset部署有状态的应用

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了K8S 之 通过Statefulset部署有状态的应用相关的知识,希望对你有一定的参考价值。

一、了解Statefulset

1、Statefulset保证了pod在重新调度后保留它们的标识(容器名)和状态。
2、Statefulset做到每个pod对应相对的PV卷,每个POD都可以拥用一组独立的数据卷。
3、提供稳定的网络标识,一个Statefulset创建的每个pod都有一个从零开始的顺序索引,这个体现在pod的名称和主机名上,同样还会体现在pod对应的固定存储上。
4、让pod拥用可预知的名称和主机名,有状态的pod有时候需要通过其主机名来定位,而无状态的pod则不需要。基于以上原因,一个Statefulset通常要求你创建一个用来记录每个pod网络标记的headless Service,通过这个Service,每个pod将拥用独立的DNS记录,比如说,一个属于default命名空间,名为foo的控制服务,它的一个pod名称为A-0,那么可以通过完整域名访问它:a-0.foo.default.svc.cluster.local。

二、通过NFS设备共享挂载权限

[root@test-operator nfs-volume]# pwd
/data/nfs-volume
[root@test-operator nfs-volume]# ll
总用量 0
drwxr-xr-x 2 root root 24 5月  20 22:49 web0
drwxr-xr-x 2 root root 24 5月  20 22:49 web1
[root@test-operator nfs-volume]# cat /etc/exports
/data/nfs-volume/web0 10.3.153.0/24(rw,no_root_squash)
/data/nfs-volume/web1 10.3.153.0/24(rw,no_root_squash)
[root@test-operator nfs-volume]# cat web0/index.html
This is Web0!!!!!!!!!
[root@test-operator nfs-volume]# cat web1/index.html 
This is Web1!!!!!!!

三、根据NFS共享目录创建两个PV卷

#web0-pv卷
[root@test-nodes1 statefulset]# vi web0-pv.yaml 
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-web0
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Recycle
  nfs:
    path: /data/nfs-volume/web0
    server: test-operator.cedarhd.com

#web1-pv卷
[root@test-nodes1 statefulset]# vi web1-pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-web1
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Recycle
  nfs:
    path: /data/nfs-volume/web1
    server: test-operator.cedarhd.com

三、创建headless Service服务

apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None       #必须为None
  selector:
    app: nginx

四、创建Statefulset

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: nginx:alpine
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: www
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 1Gi

五、验证创建结果

1、查看PV与PVC绑定情况
[root@test-nodes1 statefulset]# kubectl get pv
NAME      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM               STORAGECLASS   REASON   AGE
pv-web0   1Gi        RWO            Recycle          Bound    default/www-web-0                           39m
pv-web1   1Gi        RWO            Recycle          Bound    default/www-web-1                           39m
备注:pv-web0绑定相应声明卷:www-web-0(默认表空间)
2、查看pod运维情况
[root@test-nodes1 statefulset]# kubectl get pod -o wide
NAME    READY   STATUS    RESTARTS   AGE   IP           NODE                      NOMINATED NODE   READINESS GATES
web-0   1/1     Running   0          43m   172.7.22.8   test-nodes2.cedarhd.com   <none>           <none>
web-1   1/1     Running   0          40m   172.7.21.8   test-nodes1.cedarhd.com   <none>           <none>
3、验证两个pod的网站的相对挂载情况
[root@test-nodes1 statefulset]# curl 172.7.22.8
This is Web0!!!!!!!!!
[root@test-nodes1 statefulset]# curl 172.7.21.8
This is Web1!!!!!!!
4、查看headless Service
[root@test-nodes1 statefulset]# kubectl get service -o wide
NAME         TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)   AGE   SELECTOR
kubernetes   ClusterIP   192.168.0.1   <none>        443/TCP   54d   <none>
nginx        ClusterIP   None          <none>        80/TCP    47m   app=nginx
5、验证POD之间的DNS解释是否正常
[root@test-nodes1 statefulset]# kubectl get pod
NAME    READY   STATUS    RESTARTS   AGE
web-0   1/1     Running   0          48m
web-1   1/1     Running   0          45m
[root@test-nodes1 statefulset]# kubectl exec -ti web-0 /bin/sh
/ # ping web-1.nginx.default
PING web-1.nginx.default (172.7.21.8): 56 data bytes
64 bytes from 172.7.21.8: seq=0 ttl=62 time=0.289 ms
64 bytes from 172.7.21.8: seq=1 ttl=62 time=0.275 ms

备注:完整访问域名web-1.nginx.default.svc.cluster.local
6、查看statefulset信息
[root@test-nodes1 statefulset]# kubectl get statefulset web -o wide
NAME   READY   AGE   CONTAINERS   IMAGES
web    2/2     51m   nginx        nginx:alpine
7、删除其中一个pod,查看恢复后状态是否一致
[root@test-nodes1 statefulset]# kubectl get pod -o wide
NAME    READY   STATUS    RESTARTS   AGE   IP           NODE                      NOMINATED NODE   READINESS GATES
web-0   1/1     Running   0          53m   172.7.22.8   test-nodes2.cedarhd.com   <none>           <none>
web-1   1/1     Running   0          50m   172.7.21.8   test-nodes1.cedarhd.com   <none>           <none>
[root@test-nodes1 statefulset]# kubectl delete pod web-1
pod "web-1" deleted
[root@test-nodes1 statefulset]# kubectl get pod -o wide
NAME    READY   STATUS    RESTARTS   AGE   IP           NODE                      NOMINATED NODE   READINESS GATES
web-0   1/1     Running   0          53m   172.7.22.8   test-nodes2.cedarhd.com   <none>           <none>
web-1   1/1     Running   0          5s    172.7.21.8   test-nodes1.cedarhd.com   <none>           <none>
[root@test-nodes1 statefulset]# curl 172.7.21.8
This is Web1!!!!!!!

六、statefulset缩减与扩容

可用命令:
[root@test-nodes1 ~]# kubectl edit statefulset web
# Please edit the object below. Lines beginning with a ‘#‘ will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: apps/v1
kind: StatefulSet
metadata:
  creationTimestamp: "2020-05-21T02:53:49Z"
  generation: 3
  name: web
  namespace: default
  resourceVersion: "13473136"
  selfLink: /apis/apps/v1/namespaces/default/statefulsets/web
  uid: f2336d24-8eea-41c6-8236-b45fba9cebf4
spec:
  podManagementPolicy: OrderedReady
  replicas: 2               #扩缩容副本数
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: nginx
  serviceName: nginx
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: nginx
    spec:

以上是关于K8S 之 通过Statefulset部署有状态的应用的主要内容,如果未能解决你的问题,请参考以下文章

k8s中statefulset资源类型的深入理解

k8s实践18:statefulset学习配置记录

k8s部署-47-StatefulSet的学习

k8s部署zk集群

mysql on k8s statefulset部署实践

从零开始入门 K8s | 有状态应用编排 - StatefulSet