StatefulSet 应用场景:分布式应用、集群
StatefulSet 控制器的优势
<statefulset-name>-<number>
示例yaml
apiVersion: v1
kind: Service
metadata:
name: statefulset-nginx
labels:
app: statefulset-nginx
spec:
selector:
app: statefulset-nginx
clusterIP: None
ports:
- name: web
port: 80
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: statefulset-nginx
spec:
serviceName: "statefulset-nginx"
replicas: 2
selector:
matchLabels:
app: statefulset-nginx
template:
metadata:
labels:
app: statefulset-nginx
spec:
terminationGracePeriodSeconds: 5
containers:
- name: statefulset-nginx
image: nginx:1.22.1
imagePullPolicy: IfNotPresent
ports:
- name: web
containerPort: 80
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: www
spec:
storageClassName: "managed-nfs-storage"
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
可以看到与deployment不同,statefulset中的每个pod都分配到了独立的pv,且重启pod后存储对应关系不变
[root@k8s-node1 ~]# kubectl get pod,pvc,pv | awk '{print $1}'
# pod NAME
pod/nfs-client-provisioner-66d6cb77fd-47hsf
pod/statefulset-nginx-0
pod/statefulset-nginx-1
# pvc NAME
persistentvolumeclaim/www-statefulset-nginx-0
persistentvolumeclaim/www-statefulset-nginx-1
# pv NAME
persistentvolume/pvc-17751fde-1b23-4535-98bb-a70342ddd6fe
persistentvolume/pvc-b7519f46-b2af-42e4-b66d-d7459be2e87c
[root@k8s-node1 ~]# ls /ifs/kubernetes/
default-www-statefulset-nginx-0-pvc-17751fde-1b23-4535-98bb-a70342ddd6fe
default-www-statefulset-nginx-1-pvc-b7519f46-b2af-42e4-b66d-d7459be2e87c
手动删除pod后除了pod的ip会变动,主机名和dns解析都正常
# POD名字固定
[root@k8s-node1 ~]# kubectl get pods -l app=statefulset-nginx
NAME READY STATUS RESTARTS AGE
statefulset-nginx-0 1/1 Running 0 5m18s
statefulset-nginx-1 1/1 Running 0 5m17s
# 主机名固定
[root@k8s-node1 ~]# for i in 0 1; do kubectl exec "statefulset-nginx-$i" -- hostname; done
statefulset-nginx-0
statefulset-nginx-1
# DNS解析固定
[root@k8s-node1 ~]# kubectl run -it --rm --restart=Never --image busybox:1.28 dns-test -- nslookup statefulset-nginx
Server: 10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
Name: statefulset-nginx
Address 1: 10.244.107.230 statefulset-nginx-1.statefulset-nginx.default.svc.cluster.local
Address 2: 10.244.169.157 statefulset-nginx-0.statefulset-nginx.default.svc.cluster.local
pod "dns-test" deleted
由于使用的是 Headless Service ,无法使用 NodePort 的方式暴露应用端口,我们可以单独创建 service 来暴露特定 pod 应用
StatefulSet 控制器中的 pod 名称都是固定的: <statefulset-name>-<number>
,可以通过 statefulset.kubernetes.io/pod-name
标签固定 pod
示例如下
apiVersion: v1
kind: Service
metadata:
name: ss-nginx-0
labels:
app: ss-nginx-0
spec:
selector:
statefulset.kubernetes.io/pod-name: statefulset-nginx-0
type: NodePort
ports:
- name: web
port: 80
targetPort: 80
nodePort: 30003
验证
[root@k8s-node1 ~]# kubectl get svc ss-nginx-0
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ss-nginx-0 NodePort 10.111.69.1 <none> 80:30003/TCP 3h53m
[root@k8s-node1 ~]# kubectl get ep ss-nginx-0
NAME ENDPOINTS AGE
ss-nginx-0 10.244.169.188:80 3h53m