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