k8s--StatefulSet(有状态集)

StatefulSet

StatefulSet(有状态集)常用于部署有状态的且需要有序启动的应用程序。StatefulSet主要用于管理有状态应用程序的工作负载API对象。比如在生产环境中,可以部署ElasticSearch集群、MongoDB集群或者需要持久化的RabbitMQ集群、Redis集群、Kafka集群和ZooKeeper集群等。而StatefulSet创建的Pod一般使用Headless Service(无头服务)进行通信。

StatefulSet适用于具有以下特点

  • 具有固定的网络标记(主机名)
  • 具有持久化存储
  • 需要按顺序部署和扩展
  • 需要按顺序终止及删除
  • 需要按顺序滚动更新

创建StatefluSet

[root@instance-gvpb80ao yaml]# cat statefluset.yaml
apiVersion: v1
kind: Service
metadata:
 name: nginx
 labels:
   app: nginx
spec:
 ports:
   - port: 80
     name: web
 clusterIP: None
 selector:
   app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:
  selector:
    matchLabels:
      app: nginx
  serviceName: "nginx"
  replicas: 2
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx
          ports:
            - containerPort: 80
              name: web
[root@instance-gvpb80ao yaml]# kubectl create -f statefluset.yaml
statefulset.apps/web createdCopy to clipboardErrorCopied

StatefulSet扩容

和Deployment类似,可以通过更新replicas字段扩容/缩容StatefulSet,也可以使用kubectlscale或者kubectlpatch来扩容/缩容一个StatefulSet。

[扩容scale]

[root@instance-gvpb80ao yaml]# kubectl scale statefulset web --replicas=5
statefulset.apps/web scaled
[root@instance-gvpb80ao yaml]# kubectl get -f statefluset.yaml
NAME            TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/nginx   ClusterIP   None         <none>        80/TCP    7m8s

NAME                   READY   AGE
statefulset.apps/web   2/5     3m13sCopy to clipboardErrorCopied

[扩容patch]

[root@instance-gvpb80ao yaml]# kubectl patch statefulsets.apps web -p '{"spec":{"replicas": 2}}'
statefulset.apps/web patched
[root@instance-gvpb80ao yaml]# kubectl get -f statefluset.yaml
NAME            TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/nginx   ClusterIP   None         <none>        80/TCP    8m56s

NAME                   READY   AGE
statefulset.apps/web   4/2     5m1sCopy to clipboardErrorCopied

StatefulSet删除

删除StatefulSet有两种方式,即级联删除和非级联删除。使用非级联方式删除StatefulSet时,StatefulSet的Pod不会被删除;使用级联删除时,StatefulSet和它的Pod都会被删除。

非级联删除

使用kubectl delete sts删除StatefulSet时,只需提供--cascade=false参数,就会采用非级联删除,此时删除StatefulSet不会删除它的Pod。

[root@instance-gvpb80ao yaml]# kubectl delete statefulset web --cascade=false
statefulset.apps "web" deleted
[root@instance-gvpb80ao yaml]# kubectl get pods | grep web
web-0                               1/1     Running            0          13m
web-1                               1/1     Running            0          13mCopy to clipboardErrorCopied

当再次创建此StatefulSet时,web-0会被重新创建,web-1由于已经存在而不会被再次创建,因为最初此StatefulSet的replicas是2,所以web-2会被删除,如下(忽略AlreadyExists错误)

[root@instance-gvpb80ao yaml]# kubectl create -f statefluset.yaml
statefulset.apps/web created
Error from server (AlreadyExists): error when creating "statefluset.yaml": services "nginx" already exists
[root@instance-gvpb80ao yaml]# kubectl get pods | grep web
web-0                               1/1     Running            0          14m
web-1                               1/1     Running            0          14mCopy to clipboardErrorCopied

级联删除

省略--cascade=false参数即为级联删除

[root@instance-gvpb80ao yaml]# kubectl delete -f statefluset.yaml
service "nginx" deleted
statefulset.apps "web" deleted
[root@instance-gvpb80ao yaml]# kubectl get pods | grep web
web-0                               0/1     Terminating        0          16m
web-1                               0/1     Terminating        0          16m

配合configmap配置中心搭建redis集群

##### 创建redis ######
kind: Service
apiVersion: v1
metadata:
  name: redis-svc
  labels:
    app: redis
  annotations:
    redis.baidu.com/redis: cluster
    redis.baidu.com/network: headless-svc
spec:
  selector:
    app: redis
  ports:
    - port: 6379
      protocol: TCP
      targetPort: 6379
  clusterIP: None
---
kind: StatefulSet
apiVersion: apps/v1
metadata:
  name: redis
  labels:
    app: redis
  annotations:
    redis.baidu.com/redis: cluster
spec:
  replicas: 6
  selector:
    matchLabels:
      app: redis
  serviceName: redis-svc
  template:
    metadata:
      labels:
        app: redis
    spec:
      containers:
        - name: redis
          image: redis:6.0.8
          command:
            - "/bin/sh"
            - "-c"
            - "redis-server /opt/redis/redis.conf"
          ports:
            - containerPort: 6379
              name: tcp
          volumeMounts:
            - mountPath: /opt/redis/
              name: redis-configmap

      volumes:
        - name: redis-configmap
          configMap:
            name: redis
            items:
              - key: redis.conf
                path: redis.conf

---
kind: ConfigMap
apiVersion: v1
metadata:
  name: redis
data:
  redis.conf: |
    bind 0.0.0.0
    protected-mode yes
    port 6379
    tcp-backlog 511
    timeout 0
    tcp-keepalive 300
    daemonize no
    supervised no
    pidfile /var/run/redis_6379.pid
    loglevel notice
    logfile ""
    databases 16
    always-show-logo yes
    save 900 1
    save 300 10
    save 60 10000
    stop-writes-on-bgsave-error yes
    rdbcompression yes
    rdbchecksum yes
    dbfilename dump.rdb
    rdb-del-sync-files no
    dir /tmp
    replica-serve-stale-data yes
    replica-read-only yes
    repl-diskless-sync no
    repl-diskless-sync-delay 5
    repl-diskless-load disabled
    repl-disable-tcp-nodelay no
    replica-priority 100
    acllog-max-len 128
    lazyfree-lazy-eviction no
    lazyfree-lazy-expire no
    lazyfree-lazy-server-del no
    replica-lazy-flush no
    lazyfree-lazy-user-del no
    no-appendfsyn

######### 搭建完成redis后,加入集群,下方大概意思就是进入任一redis中与其他服务器进行集群创建 ######
kubectl exec -it --name redis-client --network=redis redis:6.0.8 \
 redis-cli --cluster create 172.18.0.7:6377 172.18.0.6:6376 172.18.0.5:6375 172.18.0.4:6374 172.18.0.3:6373 172.18.0.2:6372 --cluster-replicas 1
posted @ 2020-10-17 20:35  元气少女郭德纲!!  阅读(363)  评论(0编辑  收藏  举报