StatefulSet Service
一、认识
StatefulSet
是 Kubernetes
中专门用于管理有状态应用的控制器。它为每个 Pod
提供稳定的网络标识和独立的存储卷,同时支持有序部署、扩展和缩减。适用于需要数据一致性和稳定性的场景,例如数据库、分布式存储系统和消息队列等。与 Deployment
相比,StatefulSet
主要用于那些需要稳定网络标识、持久存储以及有序部署和扩展的场景,例如数据库、分布式文件系统或队列服务。StatefulSet
通常与 Headless Service
配合使用(clusterIP: None
),为每个 Pod
提供固定的 DNS
名称,用于直接访问特定的 Pod
。适用于需要稳定标识和数据一致性的有状态应用, 每个 Pod
有固定的 DNS
名称,通常结合 Headless Service
使用。
1.1 绑定规则
StatefulSet
与 Service
的绑定规则为: Service
的 selector
与 StatefulSet
中的 Pod
标签匹配,用于绑定 Pod
; StatefulSet
中的 serviceName
用于匹配 Service
的名称。
service.yaml
: selector
用于匹配 statefulSet.yaml
中的 spec.selector.matchLabels
apiVersion: v1
kind: Service
metadata:
name: test-service
spec:
selector:
app: test-nginx
statefulSet.yaml
: spec.selector.matchLabels
用于匹配 service.yaml
中的 selector
。但是 statefulSet.yaml
中的 spec.selector.matchLabels
必须与 spec.template.metadata.labels
一致;spec.serviceName
用于匹配 service.yaml
中的 metadata.name
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
serviceName: "web" # 绑定上面的 Headless Service
replicas: 3
selector:
matchLabels:
app: test-nginx
template:
metadata:
labels:
app: test-nginx
1.2 StatefulSet
StatefulSet
每个 Pod
有固定的名称(如 myapp-0
, myapp-1
)。Pod
的重启或迁移不会改变其名称和身份。每个 Pod
都有一个与之绑定的持久存储卷(PersistentVolume
),即使 Pod
被删除或重建,其存储仍然保持不变。Pod
按顺序创建(0 -> 1 -> 2
)或删除(2 -> 1 -> 0
)。更新时也会按顺序进行,确保服务不中断。每个 Pod
都有一个固定的 DNS
名称(如 myapp-0.myservice.default.svc.cluster.local
)。
1.3 Headless Service
在 Service
配置中,将 clusterIp
置为 None
, 将服务配置为无头服务 Headless Service
,使每个 Pod
都有独立的 DNS
。Headless Service
的 DNS
格式:
-
单个
Pod
的DNS
名称:<Pod 名称>.<Service 名称>.<命名空间>.svc.cluster.local
。例如,对于StatefulSet
名为web
的Pod
:web-0.web.default.svc.cluster.local
,web-1.web.default.svc.cluster.local
-
服务的
DNS
名称:<Service 名称>.<命名空间>.svc.cluster.local
。例如:web.default.svc.cluster.local
。
二、操作
2.1 编写 Service 文件
编写 test-service.yaml
文件,注意: 将 clusterIP: None
将服务配置为无头服务,使每个 Pod
都有独立的 DNS
。
apiVersion: v1
kind: Service
metadata:
name: test-headless-service
spec:
clusterIP: None
ports:
- name: http
port: 80
targetPort: 80
selector:
app: test-stateful-set-nginx
2.2 创建 Service 服务
应用这个 Service
kubectl apply -f test-service.yaml
2.3 编写 StatefulSet 文件
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: test-stateful-set
spec:
serviceName: "test-headless-service"
replicas: 3
selector:
matchLabels:
app: test-stateful-set-nginx
template:
metadata:
labels:
app: test-stateful-set-nginx
spec:
containers:
- name: nginx
image: registry.cn-hangzhou.aliyuncs.com/bolawen/nginx:1.27.1-perl-linux-arm64
ports:
- containerPort: 80
volumeMounts:
- name: test-volume
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: test-volume
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 1Gi
2.4 创建 SateFulSet 应用
应用这个 SateFulSet
kubectl apply -f test-stateFulSet.yaml
2.5 查看 SateFulSet 状态
kubectl get svc
kubectl get statefulset
kubectl get pods
kubectl describe statefulSet [statefulSet Name]
2.6 验证 DNS 和网络
进入任意 Pod
中测试 DNS
解析和访问:
kubectl exec -it web-0 -- sh
# 测试访问其他 Pod
ping web-1.web.default.svc.cluster.local
curl web-1.web.default.svc.cluster.local