StatefulSet 是用来管理有状态应用的工作负载 API 对象。
StatefulSet 用来管理 Deployment 和扩展一组 Pod,并且能为这些 Pod 提供序号和唯一性保证。
和 Deployment 相同的是,StatefulSet 管理了基于相同容器定义的一组 Pod。但和 Deployment 不同的是,StatefulSet 为它们的每个 Pod 维护了一个固定的 ID。这些 Pod 是基于相同的声明来创建的,但是不能相互替换:无论怎么调度,每个 Pod 都有一个永久不变的 ID。
StatefulSet 和其他控制器使用相同的工作模式。你在 StatefulSet 对象 中定义你期望的状态,然后 StatefulSet 的 控制器 就会通过各种更新来达到那种你想要的状态。
StatefulSets 对于需要满足以下一个或多个需求的应用程序很有价值:
在上面,稳定意味着 Pod 调度或重调度的整个过程是有持久性的。如果应用程序不需要任何稳定的标识符或有序的部署、删除或伸缩,则应该使用由一组无状态的副本控制器提供的工作负载来部署应用程序,比如 Deployment 或者 ReplicaSet 可能更适用于您的无状态应用部署需要。
(1)创建Headless service 无头服务
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:
serviceName: "nginx"
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: reg.westos.org/k8s/nginx
ports:
- containerPort: 80
name: web
[kubeadm@server1 statefulset]$ kubectl describe svc nginx
Name: nginx
Namespace: default
Labels: app=nginx
Annotations: Selector: app=nginx
Type: ClusterIP
IP: None
Port: web 80/TCP
TargetPort: 80/TCP
Endpoints: 10.244.1.104:80,10.244.2.49:80
Session Affinity: None
Events: <none>
[kubeadm@server1 statefulset]$
StatefulSet给所有的Pod进行了编号,编号规则是
$(statefulset名称)-$(序号),从0开始。
将我们的deployment.yaml中的replicas: 0改为0时,statefulset会自动回收pod,将pod重建之后名称不变(还是web0和web1)但是ip变了。
StatefulSet将应用状态抽象成了两种情况:
StatefulSet给所有的Pod进行了编号,编号规则是:(statefulset名称)−(statefulset名称)−(序号)
,从0开始。
Pod被删除后重建,重建Pod的网络标识也不会改变,Pod的拓扑状态按照Pod的“名字+编号”的方式固定下来,并且为每个Pod提供了一个固定且唯一的访问入口,即Pod对应的DNS记录。
[kubeadm@server1 statefulset]$ kubectl run test --image=busyboxplus -itv
/ # nslookup web-0.nginx.default.svc.cluster.local # 访问web0
(pod名称+服务名称+默认命名空间+默认域)
Server: 10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
Name: web-0.nginx.default.svc.cluster.local
Address 1: 10.244.1.204 web-0.nginx.default.svc.cluster.local
/ # nslookup web-1.nginx.default.svc.cluster.local
Server: 10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
Name: web-1.nginx.default.svc.cluster.local
Address 1: 10.244.2.49 web-1.nginx.default.svc.cluster.local
/ # curl web-0.nginx # 可以解析
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
PV和PVC的设计,使得StatefulSet对存储状态的管理成为了可能
[kubeadm@server1 statefulset]$ kubectl delete -f statefulset.yaml
[kubeadm@server1 statefulset]$ cat statefulset.yaml
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: reg.westos.org/k8s/nginx
ports:
- containerPort: 80
name: web
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: www
spec:
storageClassName: managed-nfs-storage
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
[kubeadm@server1 statefulset]$ kubectl apply -f statefulset.yaml
nslookup用于查询DNS的记录,查询域名解析是否正常,在网络故障时用来诊断网络问题
自动创建了pv和pvc
Pod的创建也是严格按照编号顺序进行的。比如在web-0进入到running状态,并且Conditions为Ready之前,web-1一直会处于pending状态。
StatefulSet还会为每一个Pod分配并创建一个同样编号的PVC。这样,kubernetes就可以通过Persistent Volume机制为这个PVC绑定对应的PV,从而保证每一个Pod都拥有一个独立的Volume。
注意:在删除StatefulSet类型的文件时,将replicas设置为0,会自动回收pod
[kubeadm@server1 statefulset]$ cat statefulset.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
serviceName: "nginx"
replicas: 0
[kubeadm@server1 statefulset]$ kubectl delete -f statefulset.yaml
statefulset.apps "web" deleted
首先,想要弹缩的StatefulSet. 需先清楚是否能弹缩该应用.
[kubeadm@server1 statefulset]$ kubectl get statefulset
NAME READY AGE
web 0/0 59m
$ kubectl scale statefulsets <stateful-set-name> --replicas=<new-replicas>
如果StatefulSet开始由 kubectl apply 或 kubectl create --save-config 创建,更新StatefulSet manifests中的 .spec.replicas
(更改replicas的数目), 然后执行命令 kubectl apply:
$ kubectl apply -f <stateful-set-file-updated>
kubectl edit statefulsets <stateful-set-name>
$ kubectl patch statefulsets <stateful-set-name> -p '{"spec":{"replicas":}}'